$
This commit is contained in:
parent
7402661aaa
commit
873dd8c458
@ -17,6 +17,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.7",
|
"axios": "^1.6.7",
|
||||||
|
"clipboard-copy": "^4.0.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-apexcharts": "^1.4.1",
|
"react-apexcharts": "^1.4.1",
|
||||||
"react-chartjs-2": "^5.2.0",
|
"react-chartjs-2": "^5.2.0",
|
||||||
|
@ -37,36 +37,6 @@ export default defineConfig({
|
|||||||
name: "chromium",
|
name: "chromium",
|
||||||
use: { ...devices["Desktop Chrome"] },
|
use: { ...devices["Desktop Chrome"] },
|
||||||
},
|
},
|
||||||
|
|
||||||
// {
|
|
||||||
// name: "firefox",
|
|
||||||
// use: { ...devices["Desktop Firefox"] },
|
|
||||||
// },
|
|
||||||
|
|
||||||
// {
|
|
||||||
// name: "webkit",
|
|
||||||
// use: { ...devices["Desktop Safari"] },
|
|
||||||
// },
|
|
||||||
|
|
||||||
/* Test against mobile viewports. */
|
|
||||||
// {
|
|
||||||
// name: 'Mobile Chrome',
|
|
||||||
// use: { ...devices['Pixel 5'] },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: 'Mobile Safari',
|
|
||||||
// use: { ...devices['iPhone 12'] },
|
|
||||||
// },
|
|
||||||
|
|
||||||
/* Test against branded browsers. */
|
|
||||||
// {
|
|
||||||
// name: 'Microsoft Edge',
|
|
||||||
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: 'Google Chrome',
|
|
||||||
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
|
||||||
// },
|
|
||||||
],
|
],
|
||||||
|
|
||||||
//Run your local dev server before starting the tests /
|
//Run your local dev server before starting the tests /
|
||||||
|
7
pnpm-lock.yaml
generated
7
pnpm-lock.yaml
generated
@ -8,6 +8,9 @@ dependencies:
|
|||||||
axios:
|
axios:
|
||||||
specifier: ^1.6.7
|
specifier: ^1.6.7
|
||||||
version: 1.6.8
|
version: 1.6.8
|
||||||
|
clipboard-copy:
|
||||||
|
specifier: ^4.0.1
|
||||||
|
version: 4.0.1
|
||||||
react:
|
react:
|
||||||
specifier: ^18.2.0
|
specifier: ^18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
@ -1143,6 +1146,10 @@ packages:
|
|||||||
string-width: 7.1.0
|
string-width: 7.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/clipboard-copy@4.0.1:
|
||||||
|
resolution: {integrity: sha512-wOlqdqziE/NNTUJsfSgXmBMIrYmfd5V0HCGsR8uAKHcg+h9NENWINcfRjtWGU77wDHC8B8ijV4hMTGYbrKovng==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/color-convert@1.9.3:
|
/color-convert@1.9.3:
|
||||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3,7 +3,6 @@ import axios from "axios";
|
|||||||
export const isLoggedIn = async () => {
|
export const isLoggedIn = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get("/authenticate");
|
const response = await axios.get("/authenticate");
|
||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return error.response.data;
|
return error.response.data;
|
||||||
|
@ -1,41 +1,56 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
export const createItem = async (settings) => {
|
export const createItem = async (settings) => {
|
||||||
console.log(settings);
|
try {
|
||||||
|
console.log(settings);
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("room", settings.room);
|
formData.append("room", settings.room);
|
||||||
formData.append("brand", settings.brand);
|
formData.append("brand", settings.brand);
|
||||||
formData.append("model", settings.model);
|
formData.append("model", settings.model);
|
||||||
formData.append("price", settings.price);
|
formData.append("price", settings.price);
|
||||||
formData.append("purchaseDate", settings.purchaseDate);
|
formData.append("purchaseDate", settings.purchaseDate);
|
||||||
formData.append("link", settings.link);
|
formData.append("link", settings.link);
|
||||||
formData.append("description", settings.description);
|
formData.append("description", settings.description);
|
||||||
formData.append("image", settings.image);
|
formData.append("image", settings.image);
|
||||||
formData.append("invoice", settings.invoice);
|
formData.append("invoice", settings.invoice);
|
||||||
|
|
||||||
const response = await axios.post("/item", formData);
|
const response = await axios.post("/item", formData);
|
||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateItem = async (settings) => {
|
export const updateItem = async (settings) => {
|
||||||
console.log(settings);
|
try {
|
||||||
|
console.log(settings);
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("brand", settings.brand);
|
formData.append("brand", settings.brand);
|
||||||
formData.append("model", settings.model);
|
formData.append("model", settings.model);
|
||||||
formData.append("price", settings.price);
|
formData.append("price", settings.price);
|
||||||
formData.append("description", settings.description);
|
formData.append("description", settings.description);
|
||||||
formData.append("purchaseDate", settings.purchaseDate);
|
formData.append("purchaseDate", settings.purchaseDate);
|
||||||
formData.append("link", settings.link);
|
formData.append("link", settings.link);
|
||||||
|
|
||||||
const response = await axios.put(`/item/${settings._id}`, formData);
|
const response = await axios.put(`/item/${settings._id}`, formData);
|
||||||
return response.data;
|
return response.data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteItem = async (id) => {
|
export const deleteItem = async (id) => {
|
||||||
console.log(id);
|
try {
|
||||||
const response = await axios.delete(`/item/${id}`);
|
console.log(id);
|
||||||
return response.data;
|
const response = await axios.delete(`/item/${id}`);
|
||||||
|
return response.data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
101
src/api/rooms.js
101
src/api/rooms.js
@ -1,10 +1,76 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { createItem } from "./items";
|
||||||
|
|
||||||
|
export const importRooms = async (data) => {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(data);
|
||||||
|
|
||||||
|
if (parsed.length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let e of parsed) {
|
||||||
|
const room = await createRoom(e.name);
|
||||||
|
|
||||||
|
for (let f of e.items) {
|
||||||
|
const settings = { ...f, room: room._id };
|
||||||
|
await createItem(settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const exportRooms = async () => {
|
||||||
|
try {
|
||||||
|
const rooms = await getRooms();
|
||||||
|
|
||||||
|
let stock = [];
|
||||||
|
|
||||||
|
for (let room of rooms) {
|
||||||
|
const roomData = await getRoom(room._id);
|
||||||
|
|
||||||
|
delete roomData._id;
|
||||||
|
delete roomData.__v;
|
||||||
|
delete roomData.user;
|
||||||
|
delete roomData.updatedAt;
|
||||||
|
delete roomData.createdAt;
|
||||||
|
|
||||||
|
await roomData.items.forEach((f) => {
|
||||||
|
delete f.createdAt;
|
||||||
|
delete f.image;
|
||||||
|
delete f.invoice;
|
||||||
|
delete f.updatedAt;
|
||||||
|
delete f.room;
|
||||||
|
delete f.user;
|
||||||
|
delete f.__v;
|
||||||
|
delete f._id;
|
||||||
|
});
|
||||||
|
|
||||||
|
stock.push(roomData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const final = JSON.stringify(stock);
|
||||||
|
return final;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const createRoom = async (name) => {
|
export const createRoom = async (name) => {
|
||||||
const response = await axios.post("/room", {
|
try {
|
||||||
name,
|
const response = await axios.post("/room", {
|
||||||
});
|
name,
|
||||||
return response.data;
|
});
|
||||||
|
return response.data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getState = async () => {
|
export const getState = async () => {
|
||||||
@ -18,16 +84,31 @@ export const getState = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const deleteRoom = async (id) => {
|
export const deleteRoom = async (id) => {
|
||||||
const response = await axios.delete(`/room/${id}`);
|
try {
|
||||||
return response.data;
|
const response = await axios.delete(`/room/${id}`);
|
||||||
|
return response.data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRooms = async () => {
|
export const getRooms = async () => {
|
||||||
const response = await axios.get(`/room`);
|
try {
|
||||||
return response.data;
|
const response = await axios.get(`/room`);
|
||||||
|
return response.data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRoom = async (id) => {
|
export const getRoom = async (id) => {
|
||||||
const response = await axios.get(`/room/${id}`);
|
try {
|
||||||
return response.data;
|
const response = await axios.get(`/room/${id}`);
|
||||||
|
return response.data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -18,8 +18,9 @@ export const createUser = async (username, password, confirmation) => {
|
|||||||
confirmation,
|
confirmation,
|
||||||
});
|
});
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
return error.response.data;
|
console.error(err);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background: $primary;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
a {
|
a {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { MagnifyingGlass } from "react-loader-spinner";
|
import { MagnifyingGlass } from "react-loader-spinner";
|
||||||
import "./LoaderSpace.scss";
|
import "./LoaderSpace.scss";
|
||||||
|
|
||||||
export default function LoaderSpace({ isVisible }) {
|
export default function LoaderSpace({ isVisible, isCenterLoader }) {
|
||||||
return (
|
return (
|
||||||
<div className="loader-space-container">
|
<div className={`loader-space-container${isCenterLoader ? "-center" : ""}`}>
|
||||||
<MagnifyingGlass
|
<MagnifyingGlass
|
||||||
visible={isVisible}
|
visible={isVisible}
|
||||||
height="100"
|
height="100"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.loader-space-container {
|
.loader-space-container-center {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -6,3 +6,6 @@
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader-space-container {
|
||||||
|
}
|
||||||
|
@ -16,9 +16,9 @@ const initState = {
|
|||||||
|
|
||||||
export const AuthenticationContext = React.createContext({
|
export const AuthenticationContext = React.createContext({
|
||||||
...initState,
|
...initState,
|
||||||
login: () => {},
|
login: async () => {},
|
||||||
register: () => {},
|
register: () => {},
|
||||||
logout: () => {},
|
logout: async () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AuthenticationProvider = ({ children }) => {
|
export const AuthenticationProvider = ({ children }) => {
|
||||||
@ -46,6 +46,7 @@ export const AuthenticationProvider = ({ children }) => {
|
|||||||
const register = async (username, password, confirmation) => {
|
const register = async (username, password, confirmation) => {
|
||||||
try {
|
try {
|
||||||
const user = await registerApi(username, password, confirmation);
|
const user = await registerApi(username, password, confirmation);
|
||||||
|
console.log(user);
|
||||||
setAuthState({ user });
|
setAuthState({ user });
|
||||||
redirect();
|
redirect();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import NavBar from "../components/NavBar/NavBar";
|
import NavBar from "../components/NavBar/NavBar";
|
||||||
import "./Layout.css";
|
import "./Layout.scss";
|
||||||
|
|
||||||
export default function Layout({ children }) {
|
export default function Layout({ children }) {
|
||||||
return (
|
return (
|
||||||
<div id="layout-container">
|
<div id="layout-container">
|
||||||
<NavBar />
|
<NavBar />
|
||||||
<main>{children}</main>
|
<main>{children}</main>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#layout-container {
|
#layout-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
38
src/pages/authenticated/authanticated.scss
Normal file
38
src/pages/authenticated/authanticated.scss
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
@import "../../assets/styles/vars.scss";
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
gap: 20px;
|
||||||
|
margin-top: 30px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: $good_black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: red;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: $my_border_rad;
|
||||||
|
border: 1px dashed $good_black;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.ipt {
|
||||||
|
width: 300px;
|
||||||
|
height: 35px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useAuth } from "../../hooks";
|
import { useAuth } from "../../hooks";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
import "./authanticated.scss";
|
||||||
|
import "../../components/StylizedBtn/StylizedBtn.scss";
|
||||||
|
|
||||||
export const Login = () => {
|
export const Login = () => {
|
||||||
const { login } = useAuth();
|
const { login } = useAuth();
|
||||||
@ -18,32 +20,36 @@ export const Login = () => {
|
|||||||
const response = await login(username, password);
|
const response = await login(username, password);
|
||||||
|
|
||||||
if (response && !response.success) {
|
if (response && !response.success) {
|
||||||
console.log("salut");
|
|
||||||
setError(response.error);
|
setError(response.error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="container">
|
||||||
<h1>Login page</h1>
|
<form className="form" onSubmit={onSubmit}>
|
||||||
{error && <p className="text-red-500">{error}</p>}
|
<h3 className="title">Connexion</h3>
|
||||||
|
{error && <p>{error}</p>}
|
||||||
|
|
||||||
<form onSubmit={onSubmit}>
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={username}
|
value={username}
|
||||||
placeholder="username"
|
placeholder="Pseudo"
|
||||||
|
className="ipt"
|
||||||
required
|
required
|
||||||
onChange={(e) => setUsername(e.target.value)}
|
onChange={(e) => setUsername(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
value={password}
|
value={password}
|
||||||
placeholder="password"
|
placeholder="Mot de passe"
|
||||||
|
className="ipt"
|
||||||
required
|
required
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<button type="submit">submit</button>
|
|
||||||
|
<button className="stylized-btn" type="submit">
|
||||||
|
Go
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
|
import "../../components/StylizedBtn/StylizedBtn.scss";
|
||||||
import { useAuth } from "../../hooks";
|
import { useAuth } from "../../hooks";
|
||||||
|
|
||||||
export const Register = () => {
|
export const Register = () => {
|
||||||
@ -8,49 +8,69 @@ export const Register = () => {
|
|||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [confirmation, setConfirmation] = useState("");
|
const [confirmation, setConfirmation] = useState("");
|
||||||
const [error, setError] = useState();
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = "Inscription";
|
document.title = "Inscription";
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSubmit = async (e) => {
|
const onSubmit = async (e) => {
|
||||||
e.preventDefault();
|
try {
|
||||||
const response = await register(username, password, confirmation);
|
e.preventDefault();
|
||||||
console.log(response);
|
const response = await register(username, password, confirmation);
|
||||||
|
|
||||||
if (response && !response.success) {
|
if (!response) {
|
||||||
setError(response.error);
|
setError(
|
||||||
|
"Assurez vous que le mot de passe contient au moins 8 caracteres dont une majuscule, un symbole special et au minimum un chiffre.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response && !response.success) {
|
||||||
|
setError(
|
||||||
|
"Assurez vous que le mot de passe contient au moins 8 caracteres dont une majuscule, un symbole special et au minimum un chiffre.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="container">
|
||||||
<h1>Register page</h1>
|
<form className="form" onSubmit={onSubmit}>
|
||||||
{error && <p className="text-red-500">{error}</p>}
|
<h3 className="title">Inscription</h3>
|
||||||
<form onSubmit={onSubmit}>
|
|
||||||
|
{error ? <div className="error">{error}</div> : null}
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={username}
|
value={username}
|
||||||
placeholder="username"
|
placeholder="Pseudo"
|
||||||
|
className="ipt"
|
||||||
required
|
required
|
||||||
onChange={(e) => setUsername(e.target.value)}
|
onChange={(e) => setUsername(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
|
className="ipt"
|
||||||
value={password}
|
value={password}
|
||||||
required
|
required
|
||||||
placeholder="password"
|
min={8}
|
||||||
|
placeholder="Mot de passe"
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
|
className="ipt"
|
||||||
|
min={8}
|
||||||
required
|
required
|
||||||
value={confirmation}
|
value={confirmation}
|
||||||
placeholder="confirmation"
|
placeholder="Confirmation du mot de passe"
|
||||||
onChange={(e) => setConfirmation(e.target.value)}
|
onChange={(e) => setConfirmation(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<button type="submit">submit</button>
|
<button className="stylized-btn" type="submit">
|
||||||
|
Go
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -85,7 +85,7 @@ export const Home = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<LoaderSpace isVisible={isLoad} />
|
<LoaderSpace isVisible={isLoad} isCenterLoader={true} />
|
||||||
|
|
||||||
{dataset ? (
|
{dataset ? (
|
||||||
<div id="stats-container">
|
<div id="stats-container">
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
import { useAuth } from "../../hooks";
|
import { useAuth } from "../../hooks";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import "./Profile.scss";
|
import "./Profile.scss";
|
||||||
import { updateUser, deleteUser, logout } from "../../api";
|
import {
|
||||||
|
updateUser,
|
||||||
|
deleteUser,
|
||||||
|
logout,
|
||||||
|
exportRooms,
|
||||||
|
importRooms,
|
||||||
|
} from "../../api";
|
||||||
import StylizedBtn from "../../components/StylizedBtn/StylizedBtn";
|
import StylizedBtn from "../../components/StylizedBtn/StylizedBtn";
|
||||||
import passwordCheck from "../../services/password";
|
import passwordCheck from "../../services/password";
|
||||||
|
import LoaderSpace from "./../../components/LoaderSpace/LoaderSpace";
|
||||||
|
import clipboardCopy from "clipboard-copy";
|
||||||
//Bilouuuuuuu94!@@
|
//Bilouuuuuuu94!@@
|
||||||
|
|
||||||
export default function Profile() {
|
export default function Profile() {
|
||||||
@ -13,6 +21,10 @@ export default function Profile() {
|
|||||||
const [oldPPassword, setOldPPassword] = useState("");
|
const [oldPPassword, setOldPPassword] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [confirmPassword, setConfirmPassword] = useState("");
|
const [confirmPassword, setConfirmPassword] = useState("");
|
||||||
|
const [isIELoad, setIsIELoad] = useState(false);
|
||||||
|
const [exportDatas, setExportDatas] = useState(null);
|
||||||
|
const [importMsg, setImportMsg] = useState("");
|
||||||
|
const [isInAfterImport, setIsInAfterImport] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = `Profile`;
|
document.title = `Profile`;
|
||||||
@ -40,6 +52,37 @@ export default function Profile() {
|
|||||||
setOldPPassword(e.target.value);
|
setOldPPassword(e.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const importData = () => {
|
||||||
|
const data = prompt("Veuillez coller le code que vous avez copier");
|
||||||
|
if (!data) return;
|
||||||
|
|
||||||
|
setExportDatas(null);
|
||||||
|
setIsInAfterImport(true);
|
||||||
|
setIsIELoad(true);
|
||||||
|
setImportMsg("Chargement ...");
|
||||||
|
|
||||||
|
importRooms(data).then((res) => {
|
||||||
|
if (!res) {
|
||||||
|
setImportMsg("Une erreur est survenue");
|
||||||
|
} else {
|
||||||
|
setImportMsg("Vos depenses ont ete transfere avec sucess.");
|
||||||
|
}
|
||||||
|
setIsIELoad(false);
|
||||||
|
console.log(res);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const exportData = () => {
|
||||||
|
setIsIELoad(true);
|
||||||
|
setIsInAfterImport(false);
|
||||||
|
|
||||||
|
exportRooms().then((res) => {
|
||||||
|
setExportDatas(res);
|
||||||
|
setIsIELoad(false);
|
||||||
|
clipboardCopy(`${res}`).then();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleSubmitPassword = () => {
|
const handleSubmitPassword = () => {
|
||||||
if (!passwordCheck(password, confirmPassword)) {
|
if (!passwordCheck(password, confirmPassword)) {
|
||||||
alert(
|
alert(
|
||||||
@ -148,18 +191,36 @@ export default function Profile() {
|
|||||||
|
|
||||||
<div className="profile-modifier-container">
|
<div className="profile-modifier-container">
|
||||||
<span onClick={handleHelpIE} className="profile-modifier-title ">
|
<span onClick={handleHelpIE} className="profile-modifier-title ">
|
||||||
Fais voyager tes depenses.
|
Fais voyager tes depenses !
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<StylizedBtn
|
<LoaderSpace isCenterLoader={false} isVisible={isIELoad} />
|
||||||
perso_style={{ width: "100px" }}
|
|
||||||
handle={null}
|
{exportDatas ? (
|
||||||
text="Exporter"
|
<div id="exported-datas-container">
|
||||||
/>
|
<div id="exported-datas-tips">
|
||||||
|
Vos données ont été copiées dans le presse-papier. Pour pouvoir
|
||||||
|
les importer, il suffira juste de cliquer sur le bouton ci-dessous{" "}
|
||||||
|
<b>"Importer"</b>, puis de coller les données dans le champ de
|
||||||
|
saisie qui s'ouvrira en haut de l'écran.
|
||||||
|
</div>
|
||||||
|
<div id="exported-datas">{exportDatas}</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{isInAfterImport ? <div>{importMsg}</div> : null}
|
||||||
|
|
||||||
|
{!exportDatas ? (
|
||||||
|
<StylizedBtn
|
||||||
|
perso_style={{ width: "100px" }}
|
||||||
|
handle={exportData}
|
||||||
|
text="Exporter"
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<StylizedBtn
|
<StylizedBtn
|
||||||
perso_style={{ width: "100px" }}
|
perso_style={{ width: "100px" }}
|
||||||
handle={null}
|
handle={importData}
|
||||||
text="Importer"
|
text="Importer"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,11 +33,31 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
border-radius: $my_border_rad;
|
border-radius: $my_border_rad;
|
||||||
|
|
||||||
|
#exported-datas-container {
|
||||||
|
width: 80%;
|
||||||
|
max-height: 300px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
#exported-datas-tips {
|
||||||
|
border: 1px solid $good_black;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#exported-datas {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 200px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 770px) {
|
@media (max-width: 770px) {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-modifier-title {
|
.profile-modifier-title {
|
||||||
|
cursor: pointer;
|
||||||
color: $black_text;
|
color: $black_text;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import "./Room.scss";
|
|||||||
import AddBtn from "../../components/AddBtn/AddBtn";
|
import AddBtn from "../../components/AddBtn/AddBtn";
|
||||||
import { createItem, deleteItem, updateItem } from "../../api/";
|
import { createItem, deleteItem, updateItem } from "../../api/";
|
||||||
import StylizedBtn from "../../components/StylizedBtn/StylizedBtn";
|
import StylizedBtn from "../../components/StylizedBtn/StylizedBtn";
|
||||||
|
import LoaderSpace from "../../components/LoaderSpace/LoaderSpace";
|
||||||
|
|
||||||
export default function Room() {
|
export default function Room() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@ -12,12 +13,16 @@ export default function Room() {
|
|||||||
const [isInForm, setInForm] = useState(false);
|
const [isInForm, setInForm] = useState(false);
|
||||||
const [isInFormUpdate, setIsInFormUpdate] = useState(false);
|
const [isInFormUpdate, setIsInFormUpdate] = useState(false);
|
||||||
const [formUpdateData, setFormUpdateData] = useState(null);
|
const [formUpdateData, setFormUpdateData] = useState(null);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
getRoom(id).then((res) => {
|
getRoom(id).then((res) => {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
document.title = `Piece - ${res.name}`;
|
document.title = `Piece - ${res.name}`;
|
||||||
setData(res);
|
setData(res);
|
||||||
|
setIsLoading(false);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -109,6 +114,10 @@ export default function Room() {
|
|||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
{isLoading ? (
|
||||||
|
<LoaderSpace isCenterLoader={true} isVisible={isLoading} />
|
||||||
|
) : null}
|
||||||
|
|
||||||
{isInForm || isInFormUpdate ? <div id="blur"></div> : null}
|
{isInForm || isInFormUpdate ? <div id="blur"></div> : null}
|
||||||
|
|
||||||
{data.items && data.items.length > 0 ? (
|
{data.items && data.items.length > 0 ? (
|
||||||
@ -176,11 +185,7 @@ export default function Room() {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : null}
|
||||||
<div>
|
|
||||||
<span>Cette piece ne contient pas d'objet.</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{isInForm && (
|
{isInForm && (
|
||||||
<div id="form-container">
|
<div id="form-container">
|
||||||
|
@ -106,6 +106,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
.item-description {
|
.item-description {
|
||||||
color: $black;
|
color: $black;
|
||||||
@ -117,6 +118,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
.item-price {
|
.item-price {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -126,6 +128,7 @@
|
|||||||
.item-buy-date-container {
|
.item-buy-date-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
|
||||||
.item-buy-date {
|
.item-buy-date {
|
||||||
|
@ -3,6 +3,7 @@ import { useState, useEffect } from "react";
|
|||||||
import { createRoom, getRooms, deleteRoom } from "../../api";
|
import { createRoom, getRooms, deleteRoom } from "../../api";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import LoaderSpace from "../../components/LoaderSpace/LoaderSpace";
|
import LoaderSpace from "../../components/LoaderSpace/LoaderSpace";
|
||||||
|
import AddBtn from "./../../components/AddBtn/AddBtn";
|
||||||
|
|
||||||
export default function Rooms() {
|
export default function Rooms() {
|
||||||
const [rooms, setRooms] = useState(null);
|
const [rooms, setRooms] = useState(null);
|
||||||
@ -85,7 +86,7 @@ export default function Rooms() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<LoaderSpace isVisible={isLoad} />
|
<LoaderSpace isVisible={isLoad} isCenterLoader={true} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isErr && !isLoad ? (
|
{isErr && !isLoad ? (
|
||||||
@ -94,9 +95,7 @@ export default function Rooms() {
|
|||||||
|
|
||||||
<div id="rooms-add-container">
|
<div id="rooms-add-container">
|
||||||
<div id="rooms-text-on">Creer une nouvelle piece</div>
|
<div id="rooms-text-on">Creer une nouvelle piece</div>
|
||||||
<button id="add-rooms" onClick={onClickCreate}>
|
<AddBtn handle={onClickCreate} />
|
||||||
+
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,26 +1,32 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
import { test, expect } from "@playwright/test";
|
import { test, expect } from "@playwright/test";
|
||||||
import { waitFor } from "@testing-library/react";
|
|
||||||
|
|
||||||
test("Test de connexion", async ({ page }) => {
|
test("Test de connexion", async ({ page }) => {
|
||||||
|
const account = "Bilouuuuuuu94!@@";
|
||||||
|
|
||||||
await page.goto("/login");
|
await page.goto("/login");
|
||||||
|
await page.waitForURL("/login");
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.locator(
|
.locator(
|
||||||
"#layout-container > main > div > form > input[type=text]:nth-child(1)",
|
"#layout-container > main > div > form > input[type=text]:nth-child(1)",
|
||||||
)
|
)
|
||||||
.fill("Bilouuuuuuu94!@@");
|
.fill(account);
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.locator(
|
.locator(
|
||||||
"#layout-container > main > div > form > input[type=password]:nth-child(2)",
|
"#layout-container > main > div > form > input[type=password]:nth-child(2)",
|
||||||
)
|
)
|
||||||
.fill("Bilouuuuuuu94!@@");
|
.fill(account);
|
||||||
|
|
||||||
await page.locator("#layout-container > main > div > form > button").click({
|
await page.locator("#layout-container > main > div > form > button").click({
|
||||||
button: "left",
|
button: "left",
|
||||||
});
|
});
|
||||||
|
|
||||||
await page.waitForURL("/");
|
await page.waitForURL("/");
|
||||||
const title = await page.title();
|
|
||||||
console.log(title);
|
expect(await page.title()).toBe("Accueil");
|
||||||
|
expect(await page.locator("#title").innerText()).toBe(`Bonjour ${account} !`);
|
||||||
|
|
||||||
|
test.setTimeout(10000);
|
||||||
|
|
||||||
|
await page.waitForURL("/");
|
||||||
});
|
});
|
||||||
|
33
tests/authenticated/register.test.js
Normal file
33
tests/authenticated/register.test.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// @ts-check
|
||||||
|
import { test, expect } from "@playwright/test";
|
||||||
|
|
||||||
|
test("Test de connexion", async ({ page }) => {
|
||||||
|
const account = "Eheheh9400$$!@@";
|
||||||
|
|
||||||
|
await page.goto("/register");
|
||||||
|
await page.waitForURL("/register");
|
||||||
|
|
||||||
|
await page
|
||||||
|
.locator(
|
||||||
|
"#layout-container > main > div > form > input[type=text]:nth-child(1)",
|
||||||
|
)
|
||||||
|
.fill(account);
|
||||||
|
await page
|
||||||
|
.locator(
|
||||||
|
"#layout-container > main > div > form > input[type=password]:nth-child(2)",
|
||||||
|
)
|
||||||
|
.fill(account);
|
||||||
|
await page
|
||||||
|
.locator(
|
||||||
|
"#layout-container > main > div > form > input[type=password]:nth-child(3)",
|
||||||
|
)
|
||||||
|
.fill(account);
|
||||||
|
await page
|
||||||
|
.locator("#layout-container > main > div > form > button")
|
||||||
|
.click({ button: "left" });
|
||||||
|
|
||||||
|
await page.waitForURL("/");
|
||||||
|
|
||||||
|
expect(await page.title()).toBe("Accueil");
|
||||||
|
expect(await page.locator("#title").innerText()).toBe(`Bonjour ${account} !`);
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user