$
This commit is contained in:
14
src/App.jsx
14
src/App.jsx
@@ -4,12 +4,12 @@ import { Authenticated } from "./components";
|
||||
import Layout from "./layout/Layout";
|
||||
import { Router } from "./router";
|
||||
|
||||
const App = () => (
|
||||
export default function App() {
|
||||
return (
|
||||
<Authenticated>
|
||||
<Layout>
|
||||
<Router />
|
||||
</Layout>
|
||||
<Layout>
|
||||
<Router />
|
||||
</Layout>
|
||||
</Authenticated>
|
||||
);
|
||||
|
||||
export default App;
|
||||
);
|
||||
}
|
||||
|
@@ -1,34 +1,35 @@
|
||||
import axios from "axios";
|
||||
|
||||
export const isLoggedIn = async () => {
|
||||
try {
|
||||
const response = await axios.get("/authenticate");
|
||||
try {
|
||||
const response = await axios.get("/authenticate");
|
||||
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return error.response.data;
|
||||
}
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return error.response.data;
|
||||
}
|
||||
};
|
||||
|
||||
export const login = async (username, password) => {
|
||||
try {
|
||||
const response = await axios.post("/authenticate", {
|
||||
username,
|
||||
password,
|
||||
});
|
||||
try {
|
||||
const response = await axios.post("/authenticate", {
|
||||
username,
|
||||
password,
|
||||
});
|
||||
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return error.response.data;
|
||||
}
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
window.location.reload();
|
||||
return error.response.data;
|
||||
}
|
||||
};
|
||||
|
||||
export const logout = async () => {
|
||||
try {
|
||||
const response = await axios.delete("/authenticate");
|
||||
try {
|
||||
const response = await axios.delete("/authenticate");
|
||||
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return error.response.data;
|
||||
}
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return error.response.data;
|
||||
}
|
||||
};
|
||||
|
@@ -26,6 +26,7 @@ export const updateItem = async (settings) => {
|
||||
formData.append("brand", settings.brand);
|
||||
formData.append("model", settings.model);
|
||||
formData.append("price", settings.price);
|
||||
formData.append("description", settings.description);
|
||||
formData.append("purchaseDate", settings.purchaseDate);
|
||||
formData.append("link", settings.link);
|
||||
|
||||
|
@@ -1,23 +1,33 @@
|
||||
import axios from "axios";
|
||||
|
||||
export const createRoom = async (name) => {
|
||||
const response = await axios.post("/room", {
|
||||
name,
|
||||
});
|
||||
const response = await axios.post("/room", {
|
||||
name,
|
||||
});
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const getState = async () => {
|
||||
try {
|
||||
const response = await axios.get("/room/stats");
|
||||
return response.data;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteRoom = async (id) => {
|
||||
const response = await axios.delete(`/room/${id}`);
|
||||
return response.data;
|
||||
const response = await axios.delete(`/room/${id}`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const getRooms = async () => {
|
||||
const response = await axios.get(`/room`);
|
||||
return response.data;
|
||||
const response = await axios.get(`/room`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const getRoom = async (id) => {
|
||||
const response = await axios.get(`/room/${id}`);
|
||||
return response.data;
|
||||
const response = await axios.get(`/room/${id}`);
|
||||
return response.data;
|
||||
};
|
||||
|
@@ -1,5 +1,15 @@
|
||||
import axios from "axios";
|
||||
|
||||
export const deleteUser = async (userId) => {
|
||||
try {
|
||||
const response = await axios.delete(`/user/${userId}`);
|
||||
return response.data;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const createUser = async (username, password, confirmation) => {
|
||||
try {
|
||||
const response = await axios.post("/user", {
|
||||
@@ -13,5 +23,20 @@ export const createUser = async (username, password, confirmation) => {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: REgarde postman
|
||||
export const updateUser = 0;
|
||||
export const updateUser = async (settings) => {
|
||||
try {
|
||||
console.log("try");
|
||||
const formData = new FormData();
|
||||
formData.append("_id", settings._id);
|
||||
formData.append("username", settings.username);
|
||||
formData.append("password", settings.password);
|
||||
formData.append("confirmation", settings.confirmation);
|
||||
formData.append("old_password", settings.old_password);
|
||||
|
||||
const response = await axios.put(`/user/${settings._id}`, formData);
|
||||
return response.data;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
@@ -1,13 +1,13 @@
|
||||
body {
|
||||
height: 100vh;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
@import "./vars.scss";
|
||||
|
||||
* {
|
||||
a {
|
||||
color: rgb(123, 106, 156);
|
||||
font-weight: bold;
|
||||
}
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
a {
|
||||
color: $primary;
|
||||
font-weight: bold;
|
||||
}
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
9
src/assets/styles/vars.scss
Normal file
9
src/assets/styles/vars.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
$primary: #7b6a9c;
|
||||
$good_black: #363636;
|
||||
$black_text: #252525;
|
||||
$white: #fff;
|
||||
$black: #000;
|
||||
$red: #ce5353;
|
||||
$orange: #f6a439;
|
||||
$shadow_box_def: rgba(0, 0, 0, 0.1) 0px 4px 12px;
|
||||
$my_border_rad: 6px;
|
@@ -1,3 +1,5 @@
|
||||
@import "../../assets/styles/vars.scss";
|
||||
|
||||
.add-btn-container {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
@@ -11,8 +13,8 @@
|
||||
height: 100%;
|
||||
border-radius: 50px;
|
||||
border: none;
|
||||
background: rgb(123, 106, 156);
|
||||
color: white;
|
||||
background: $primary;
|
||||
color: $white;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
|
||||
|
@@ -4,47 +4,51 @@ import { logout } from "../../api";
|
||||
import { Link } from "react-router-dom/";
|
||||
|
||||
export default function NavBar() {
|
||||
const { user } = useAuth();
|
||||
console.log(user);
|
||||
const { user } = useAuth();
|
||||
|
||||
const onLogout = () => {
|
||||
logout().then((res) => {
|
||||
if (res === "Ok") {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
};
|
||||
const onLogout = () => {
|
||||
logout().then((res) => {
|
||||
if (res === "Ok") {
|
||||
alert("etes vous sur de vouloir quitter");
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<nav id="nav-container">
|
||||
<ul id="leafs-container">
|
||||
<li className="leaf">
|
||||
<Link to="/">Accueil</Link>
|
||||
</li>
|
||||
return (
|
||||
<nav id="nav-container">
|
||||
<ul id="leafs-container">
|
||||
{user && (
|
||||
<li className="leaf">
|
||||
<Link to="/">Accueil</Link>
|
||||
</li>
|
||||
)}
|
||||
|
||||
<li className="leaf">
|
||||
<Link to="rooms">Pieces</Link>
|
||||
</li>
|
||||
{user && (
|
||||
<li className="leaf">
|
||||
<Link to="rooms">Pieces</Link>
|
||||
</li>
|
||||
)}
|
||||
|
||||
{user ? (
|
||||
<div className="leaf-into">
|
||||
<li className="leaf">
|
||||
<Link to="profile">Profile</Link>
|
||||
</li>
|
||||
{user ? (
|
||||
<div className="leaf-into">
|
||||
<li className="leaf">
|
||||
<Link to="profile">Profile</Link>
|
||||
</li>
|
||||
|
||||
<button className="leaf-btn" onClick={onLogout}>
|
||||
Deconnexion
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<li className="leaf-into">
|
||||
<span className="leaf-txt">
|
||||
<Link to="login">Connexion</Link> /
|
||||
<Link to="register">Inscription</Link>
|
||||
</span>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
<button className="leaf-btn" onClick={onLogout}>
|
||||
Deconnexion
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<li className="leaf-into">
|
||||
<span className="leaf-txt">
|
||||
<Link to="login">Connexion</Link> /
|
||||
<Link to="register">Inscription</Link>
|
||||
</span>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
@@ -1,14 +1,16 @@
|
||||
@import "../../assets/styles/vars.scss";
|
||||
|
||||
#nav-container {
|
||||
background: rgb(123, 106, 156);
|
||||
background: $primary;
|
||||
padding: 15px;
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
color: $white;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
border-bottom: 1.5px solid white;
|
||||
border-bottom: 1.5px solid $white;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,14 +19,26 @@
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
color: white;
|
||||
color: $white;
|
||||
gap: 50px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
|
||||
.leaf-into {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
|
||||
.leaf-btn {
|
||||
background: $white;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.leaf {
|
||||
|
3
src/components/Stats/Stats.jsx
Normal file
3
src/components/Stats/Stats.jsx
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function Stats({ chart = null, datas }) {
|
||||
return <div>{chart ? chart : null}</div>;
|
||||
}
|
13
src/components/StylizedBtn/StylizedBtn.jsx
Normal file
13
src/components/StylizedBtn/StylizedBtn.jsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import "./StylizedBtn.scss";
|
||||
|
||||
export default function StylizedBtn({ text, handle, perso_style = null }) {
|
||||
return (
|
||||
<button
|
||||
className="stylized-btn"
|
||||
style={perso_style ? perso_style : null}
|
||||
onClick={handle}
|
||||
>
|
||||
{text}
|
||||
</button>
|
||||
);
|
||||
}
|
17
src/components/StylizedBtn/StylizedBtn.scss
Normal file
17
src/components/StylizedBtn/StylizedBtn.scss
Normal file
@@ -0,0 +1,17 @@
|
||||
@import "../../assets/styles/vars.scss";
|
||||
|
||||
.stylized-btn {
|
||||
background: $primary;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
width: 50px;
|
||||
color: $white;
|
||||
font-weight: bold;
|
||||
height: 30px;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
transform: scale(1.05);
|
||||
transition: 0.2s;
|
||||
}
|
||||
}
|
@@ -1,100 +1,99 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import {
|
||||
createUser as registerApi,
|
||||
isLoggedIn,
|
||||
login as loginApi,
|
||||
logout as logoutApi,
|
||||
createUser as registerApi,
|
||||
isLoggedIn,
|
||||
login as loginApi,
|
||||
logout as logoutApi,
|
||||
} from "../api";
|
||||
import { useQuery } from "../hooks";
|
||||
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
|
||||
const initState = {
|
||||
user: undefined,
|
||||
user: undefined,
|
||||
};
|
||||
|
||||
export const AuthenticationContext = React.createContext({
|
||||
...initState,
|
||||
login: () => {},
|
||||
register: () => {},
|
||||
logout: () => {},
|
||||
...initState,
|
||||
login: () => {},
|
||||
register: () => {},
|
||||
logout: () => {},
|
||||
});
|
||||
|
||||
export const AuthenticationProvider = ({ children }) => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const query = useQuery();
|
||||
const [authState, setAuthState] = useState(initState);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const query = useQuery();
|
||||
const [authState, setAuthState] = useState(initState);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const redirect = () => {
|
||||
navigate(query.get("redirect_uri") || "/");
|
||||
};
|
||||
const redirect = () => {
|
||||
navigate(query.get("redirect_uri") || "/");
|
||||
};
|
||||
|
||||
const login = async (email, password) => {
|
||||
loginApi(email, password)
|
||||
.then((user) => {
|
||||
setAuthState({ user });
|
||||
redirect();
|
||||
})
|
||||
.catch(() => {
|
||||
setAuthState({ user: undefined });
|
||||
});
|
||||
};
|
||||
const login = async (email, password) => {
|
||||
loginApi(email, password)
|
||||
.then((user) => {
|
||||
setAuthState({ user });
|
||||
redirect();
|
||||
})
|
||||
.catch(() => {
|
||||
console.error("ici ca catch fort");
|
||||
setAuthState({ user: undefined });
|
||||
});
|
||||
};
|
||||
|
||||
const register = async (username, password, confirmation) => {
|
||||
registerApi(username, password, confirmation).then((user) => {
|
||||
setAuthState({ user });
|
||||
redirect();
|
||||
});
|
||||
};
|
||||
const register = async (username, password, confirmation) => {
|
||||
registerApi(username, password, confirmation).then((user) => {
|
||||
setAuthState({ user });
|
||||
redirect();
|
||||
});
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
logoutApi().then(() => {
|
||||
setAuthState(initState);
|
||||
navigate(`/login`);
|
||||
});
|
||||
};
|
||||
const logout = () => {
|
||||
logoutApi().then(() => {
|
||||
setAuthState(initState);
|
||||
navigate(`/login`);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
isLoggedIn()
|
||||
.then((user) => {
|
||||
if (user === "Unauthorized") throw new Error("Unauthorized");
|
||||
setAuthState({ user });
|
||||
if (location.pathname === "/login") {
|
||||
redirect();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setAuthState({ user: undefined });
|
||||
|
||||
if (!location.pathname.match(/^(\/|\/login|\/register)$/)) {
|
||||
navigate(
|
||||
`/login?redirect_uri=${encodeURI(location.pathname)}`
|
||||
);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
setIsLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (location.pathname === "/logout") {
|
||||
logout();
|
||||
useEffect(() => {
|
||||
isLoggedIn()
|
||||
.then((user) => {
|
||||
if (user === "Unauthorized") throw new Error("Unauthorized");
|
||||
setAuthState({ user });
|
||||
if (location.pathname === "/login") {
|
||||
redirect();
|
||||
}
|
||||
}, [location]);
|
||||
})
|
||||
.catch(() => {
|
||||
setAuthState({ user: undefined });
|
||||
|
||||
if (isLoading) {
|
||||
return <p>Loading...</p>;
|
||||
if (!location.pathname.match(/^(\/|\/login|\/register)$/)) {
|
||||
navigate(`/login?redirect_uri=${encodeURI(location.pathname)}`);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
setIsLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (location.pathname === "/logout") {
|
||||
logout();
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
return (
|
||||
<AuthenticationContext.Provider
|
||||
value={{ ...authState, login, logout, register }}
|
||||
>
|
||||
{children}
|
||||
</AuthenticationContext.Provider>
|
||||
);
|
||||
if (isLoading) {
|
||||
return <p>Loading...</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthenticationContext.Provider
|
||||
value={{ ...authState, login, logout, register }}
|
||||
>
|
||||
{children}
|
||||
</AuthenticationContext.Provider>
|
||||
);
|
||||
};
|
||||
|
@@ -1,9 +1,4 @@
|
||||
#layout-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
|
||||
main {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
16
src/main.jsx
16
src/main.jsx
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App.jsx";
|
||||
import "./assets/styles/index.css";
|
||||
import "./assets/styles/index.scss";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { CookiesProvider } from "react-cookie";
|
||||
import setupAxios from "./setupAxios";
|
||||
@@ -9,11 +9,11 @@ import setupAxios from "./setupAxios";
|
||||
setupAxios();
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<BrowserRouter>
|
||||
<CookiesProvider>
|
||||
<App />
|
||||
</CookiesProvider>
|
||||
</BrowserRouter>
|
||||
</React.StrictMode>
|
||||
<React.StrictMode>
|
||||
<BrowserRouter>
|
||||
<CookiesProvider>
|
||||
<App />
|
||||
</CookiesProvider>
|
||||
</BrowserRouter>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
@@ -3,40 +3,44 @@ import React, { useState } from "react";
|
||||
import { useAuth } from "../../hooks";
|
||||
|
||||
export const Login = () => {
|
||||
const { login } = useAuth();
|
||||
const { login } = useAuth();
|
||||
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [error, setError] = useState();
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [error, setError] = useState();
|
||||
|
||||
const onSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
const response = await login(username, password);
|
||||
const onSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
const response = await login(username, password);
|
||||
|
||||
if (response && !response.success) {
|
||||
setError(response.error);
|
||||
}
|
||||
};
|
||||
if (response && !response.success) {
|
||||
console.log("salut");
|
||||
setError(response.error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Login page</h1>
|
||||
{error && <p className="text-red-500">{error}</p>}
|
||||
<form onSubmit={onSubmit}>
|
||||
<input
|
||||
type="text"
|
||||
value={username}
|
||||
placeholder="username"
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
placeholder="password"
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<button type="submit">submit</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
<h1>Login page</h1>
|
||||
{error && <p className="text-red-500">{error}</p>}
|
||||
|
||||
<form onSubmit={onSubmit}>
|
||||
<input
|
||||
type="text"
|
||||
value={username}
|
||||
placeholder="username"
|
||||
required
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
placeholder="password"
|
||||
required
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<button type="submit">submit</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@@ -3,48 +3,51 @@ import React, { useState } from "react";
|
||||
import { useAuth } from "../../hooks";
|
||||
|
||||
export const Register = () => {
|
||||
const { register } = useAuth();
|
||||
const { register } = useAuth();
|
||||
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmation, setConfirmation] = useState("");
|
||||
const [error, setError] = useState();
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmation, setConfirmation] = useState("");
|
||||
const [error, setError] = useState();
|
||||
|
||||
const onSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
const response = await register(username, password, confirmation);
|
||||
console.log(response);
|
||||
const onSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
const response = await register(username, password, confirmation);
|
||||
console.log(response);
|
||||
|
||||
if (response && !response.success) {
|
||||
setError(response.error);
|
||||
}
|
||||
};
|
||||
if (response && !response.success) {
|
||||
setError(response.error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Register page</h1>
|
||||
{error && <p className="text-red-500">{error}</p>}
|
||||
<form onSubmit={onSubmit}>
|
||||
<input
|
||||
type="text"
|
||||
value={username}
|
||||
placeholder="username"
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
placeholder="password"
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
value={confirmation}
|
||||
placeholder="confirmation"
|
||||
onChange={(e) => setConfirmation(e.target.value)}
|
||||
/>
|
||||
<button type="submit">submit</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
<h1>Register page</h1>
|
||||
{error && <p className="text-red-500">{error}</p>}
|
||||
<form onSubmit={onSubmit}>
|
||||
<input
|
||||
type="text"
|
||||
value={username}
|
||||
placeholder="username"
|
||||
required
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
required
|
||||
placeholder="password"
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
required
|
||||
value={confirmation}
|
||||
placeholder="confirmation"
|
||||
onChange={(e) => setConfirmation(e.target.value)}
|
||||
/>
|
||||
<button type="submit">submit</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@@ -1,15 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
import { useAuth } from "../hooks";
|
||||
|
||||
export const Home = () => {
|
||||
const { user } = useAuth();
|
||||
console.log(user);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Home page</h1>
|
||||
{user && <h2>Hello {user.user.username}</h2>}
|
||||
</div>
|
||||
);
|
||||
};
|
184
src/pages/home/home.jsx
Normal file
184
src/pages/home/home.jsx
Normal file
@@ -0,0 +1,184 @@
|
||||
import React from "react";
|
||||
import { useAuth } from "../../hooks";
|
||||
import { useEffect } from "react";
|
||||
import { getState } from "../../api";
|
||||
import { useState } from "react";
|
||||
import Chart from "react-apexcharts";
|
||||
import "./home.scss";
|
||||
import { Link } from "react-router-dom";
|
||||
import { MagnifyingGlass } from "react-loader-spinner";
|
||||
|
||||
export const Home = () => {
|
||||
const { user } = useAuth();
|
||||
const [dataset, setDataset] = useState(null);
|
||||
const [generalStat, setGeneralStat] = useState(null);
|
||||
const [roomsStats, setRoomsState] = useState(null);
|
||||
const [isLoad, setIsLoad] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
getState().then((res) => {
|
||||
try {
|
||||
setIsLoad(false);
|
||||
console.log(res);
|
||||
setDataset(res);
|
||||
setupRoomsStats(res.rooms);
|
||||
setupGlobalStat({ years: res.years, global: res.global });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const setupRoomsStats = (rooms) => {
|
||||
setRoomsState(
|
||||
Object.values(rooms).sort((a, b) => b.room_price - a.room_price),
|
||||
);
|
||||
};
|
||||
|
||||
const setupGlobalStat = (data) => {
|
||||
const stats = {
|
||||
options: {
|
||||
chart: {
|
||||
id: "",
|
||||
},
|
||||
xaxis: {
|
||||
categories: [],
|
||||
},
|
||||
stroke: {
|
||||
curve: "smooth",
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "",
|
||||
type: "line",
|
||||
data: [],
|
||||
color: "#7b6a9c",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
for (let i in data.years) {
|
||||
if (data.years[i] === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
stats.options.xaxis.categories.push(i);
|
||||
stats.series[0].data.push(data.years[i]);
|
||||
}
|
||||
|
||||
const component = (
|
||||
<Chart options={stats.options} series={stats.series} width="500" />
|
||||
);
|
||||
|
||||
setGeneralStat(component);
|
||||
};
|
||||
|
||||
return (
|
||||
<div id="home-container">
|
||||
{user && (
|
||||
<div id="home-title">
|
||||
<h3 id="title">Bonjour {user.user.username} !</h3>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<MagnifyingGlass
|
||||
visible={isLoad}
|
||||
height="100"
|
||||
width="100"
|
||||
ariaLabel="magnifying-glass-loading"
|
||||
wrapperStyle={{}}
|
||||
wrapperClass="magnifying-glass-wrapper"
|
||||
glassColor="#ffffff"
|
||||
color="#7B6A9C"
|
||||
/>
|
||||
|
||||
{dataset ? (
|
||||
<div id="stats-container">
|
||||
<div className="stats">
|
||||
<div className="header">
|
||||
<h3 className="header-title">Statistique general</h3>
|
||||
</div>
|
||||
|
||||
{generalStat ? generalStat : null}
|
||||
|
||||
<div id="others-container">
|
||||
<div className="others">
|
||||
<div className="others-label">Moyenne de vos depenses</div>
|
||||
<div className="others-value">
|
||||
{dataset.global.average_price}e
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="others">
|
||||
<div className="others-label">Nombre total d'objet</div>
|
||||
<div className="others-value">
|
||||
{dataset.global.items_count}e
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="others">
|
||||
<div className="others-label">Nombre de piece</div>
|
||||
<div className="others-value">{dataset.global.rooms_count}</div>
|
||||
</div>
|
||||
|
||||
<div className="others">
|
||||
<div className="others-label">Prix total</div>
|
||||
<div className="others-value">
|
||||
{dataset.global.total_price}e
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="others">
|
||||
<div className="others-label">Piece la plus cher</div>
|
||||
<div className="others-value">
|
||||
{dataset.global.most_expensive_room.name} (
|
||||
{dataset.global.most_expensive_room.count}e)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="others">
|
||||
<div className="others-label">Piece avec le plus d'objet</div>
|
||||
<div className="others-value">
|
||||
{dataset.global.most_item_room.name} (
|
||||
{dataset.global.most_item_room.count}).
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="others">
|
||||
<div className="others-label">Piece avec le plus d'objet</div>
|
||||
<div className="others-value">
|
||||
{dataset.global.most_item_room.name} (
|
||||
{dataset.global.most_item_room.count}).
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="stats">
|
||||
<div className="header">
|
||||
<h3 className="header-title">Pieces</h3>
|
||||
</div>
|
||||
|
||||
<div id="rooms-container">
|
||||
{roomsStats.length >= 1
|
||||
? roomsStats.map((r, i) => (
|
||||
<div className="rooms" key={i}>
|
||||
<span>- </span>
|
||||
<Link to={`/room/${r._id}`}>{r.name}</Link>
|
||||
|
||||
<span>
|
||||
{" "}
|
||||
contient <b>{r.items_count}</b> objet(s) pour une valeur
|
||||
total de <b>{r.room_price}e</b>{" "}
|
||||
</span>
|
||||
</div>
|
||||
))
|
||||
: null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
84
src/pages/home/home.scss
Normal file
84
src/pages/home/home.scss
Normal file
@@ -0,0 +1,84 @@
|
||||
@import "../../assets/styles/vars.scss";
|
||||
|
||||
#home-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
#home-title {
|
||||
#title {
|
||||
margin-top: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
#stats-container {
|
||||
margin-top: 50px;
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
gap: 20px;
|
||||
|
||||
.stats {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.header {
|
||||
.header-title {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
#rooms-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
margin-top: 20px;
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
|
||||
.rooms {
|
||||
border: 1px dashed $good_black;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#others-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
gap: 10px;
|
||||
|
||||
.others {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
border: 1px dashed $good_black;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
|
||||
.others-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.others-value {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 90px;
|
||||
height: 30px;
|
||||
transform: rotate(10deg);
|
||||
background: $primary;
|
||||
color: $white;
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,2 +1,2 @@
|
||||
export * from "./authenticated";
|
||||
export * from "./home";
|
||||
export * from "./home/home";
|
||||
|
@@ -1,45 +1,102 @@
|
||||
import { useAuth } from "../../hooks";
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import "./Profile.scss";
|
||||
import { updateUser, deleteUser, logout } from "../../api";
|
||||
import StylizedBtn from "../../components/StylizedBtn/StylizedBtn";
|
||||
import passwordCheck from "../../services/password";
|
||||
//Bilouuuuuuu94!@@
|
||||
|
||||
export default function Profile() {
|
||||
const { user } = useAuth();
|
||||
const [username, setUsername] = useState("");
|
||||
const [oldPUsername, setOldPUsername] = useState("");
|
||||
|
||||
const [pUsername, setPUsername] = useState("");
|
||||
const [oldPPassword, setOldPPassword] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
if (!user.user.username) {
|
||||
console.log("pas de login");
|
||||
}
|
||||
});
|
||||
|
||||
const handleUsername = (e) => {
|
||||
setUsername(e.target.value);
|
||||
};
|
||||
const handlePUsername = (e) => {
|
||||
setPUsername(e.target.value);
|
||||
};
|
||||
const handlePassword = (e) => {
|
||||
setPassword(e.target.value);
|
||||
};
|
||||
const handleConfirmPassword = (e) => {
|
||||
setConfirmPassword(e.target.value);
|
||||
};
|
||||
const handleOldPUsername = (e) => {
|
||||
setOldPUsername(e.target.value);
|
||||
};
|
||||
const handleOldPPassword = (e) => {
|
||||
setOldPPassword(e.target.value);
|
||||
};
|
||||
|
||||
// TODO: Faire la paire de fonction
|
||||
const handleSubmitPassword = () => {};
|
||||
const handleSubmitUsername = () => {};
|
||||
const handleSubmitPassword = () => {
|
||||
if (!passwordCheck(password, confirmPassword)) {
|
||||
alert(
|
||||
"Verifiez que les mdps sont identiques, contiennent au moins un caractere special, font au moins 8 characteres",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
updateUser({
|
||||
username: user.user.username,
|
||||
password: password,
|
||||
confirmation: confirmPassword,
|
||||
old_password: oldPPassword,
|
||||
_id: user.user._id,
|
||||
}).then((res) => {
|
||||
logout().then((_) => {
|
||||
window.location.reload();
|
||||
});
|
||||
console.log(res);
|
||||
console.log(oldPPassword, password, confirmPassword);
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmitUsername = () => {
|
||||
updateUser({
|
||||
username: username,
|
||||
password: pUsername,
|
||||
confirmation: pUsername,
|
||||
old_password: pUsername,
|
||||
_id: user.user._id,
|
||||
}).then((res) => {
|
||||
console.log(res);
|
||||
console.log(username, pUsername);
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeleteUser = () => {
|
||||
deleteUser(user.user._id).then((_) => {
|
||||
logout().then((res) => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div id="profile-container">
|
||||
<div id="title-container">
|
||||
<h3 id="title">
|
||||
<span id="title">
|
||||
Heureux de vous voir <b>{user.user.username}</b> !
|
||||
</h3>
|
||||
</span>
|
||||
|
||||
<button onClick={null}>Supprimer mon compte</button>
|
||||
<StylizedBtn
|
||||
perso_style={{
|
||||
width: "100px",
|
||||
height: "50px",
|
||||
background: "red",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
handle={handleDeleteUser}
|
||||
text="Supprimer mon compte"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="profile-modifier-container">
|
||||
@@ -47,46 +104,42 @@ export default function Profile() {
|
||||
|
||||
<input
|
||||
className="profile-modifier-ipt"
|
||||
type="password"
|
||||
placeholder="Ancien mot de passe"
|
||||
onChange={handleOldPUsername}
|
||||
type="text"
|
||||
placeholder="Nouveau pseudo"
|
||||
onChange={handleUsername}
|
||||
/>
|
||||
|
||||
<input
|
||||
className="profile-modifier-ipt"
|
||||
type="text"
|
||||
placeholder="Nouveau nom"
|
||||
onChange={handleUsername}
|
||||
type="password"
|
||||
placeholder="Mot de passe"
|
||||
onChange={handlePUsername}
|
||||
/>
|
||||
|
||||
<button>OK</button>
|
||||
<StylizedBtn handle={handleSubmitUsername} text="OK" />
|
||||
</div>
|
||||
|
||||
<div className="profile-modifier-container">
|
||||
<span className="profile-modifier-title">Change ton mot de passe</span>
|
||||
|
||||
<input
|
||||
className="profile-modifier-ipt"
|
||||
type="password"
|
||||
placeholder="Ancien mot de passe"
|
||||
onChange={handleOldPPassword}
|
||||
/>
|
||||
|
||||
<input
|
||||
className="profile-modifier-ipt"
|
||||
type="password"
|
||||
placeholder="Nouveau mot de passe"
|
||||
onChange={handlePassword}
|
||||
/>
|
||||
|
||||
<input
|
||||
className="profile-modifier-ipt"
|
||||
type="password"
|
||||
placeholder="Confirmation"
|
||||
onChange={handleConfirmPassword}
|
||||
/>
|
||||
|
||||
<button>OK</button>
|
||||
<StylizedBtn handle={handleSubmitPassword} text="OK" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@@ -1,3 +1,5 @@
|
||||
@import "../../assets/styles/vars.scss";
|
||||
|
||||
#profile-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -7,12 +9,21 @@
|
||||
margin-top: 15px;
|
||||
|
||||
#title-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
|
||||
#title {
|
||||
}
|
||||
|
||||
.stylized-btn {
|
||||
}
|
||||
}
|
||||
|
||||
.profile-modifier-container {
|
||||
border: 1px dashed rgb(61, 61, 61);
|
||||
border: 1px dashed $good_black;
|
||||
width: 450px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -20,13 +31,14 @@
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
border-radius: $my_border_rad;
|
||||
|
||||
@media (max-width: 770px) {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.profile-modifier-title {
|
||||
color: rgb(49, 49, 49);
|
||||
color: $black_text;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
@@ -4,6 +4,7 @@ import { getRoom } from "../../api";
|
||||
import "./Room.scss";
|
||||
import AddBtn from "../../components/AddBtn/AddBtn";
|
||||
import { createItem, deleteItem, updateItem } from "../../api/";
|
||||
import StylizedBtn from "../../components/StylizedBtn/StylizedBtn";
|
||||
|
||||
export default function Room() {
|
||||
const { id } = useParams();
|
||||
@@ -14,11 +15,13 @@ export default function Room() {
|
||||
|
||||
useEffect(() => {
|
||||
getRoom(id).then((res) => {
|
||||
console.log(res);
|
||||
setData(res);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleFormUpdateDataChange = (e, name) => {
|
||||
console.log(e.target.value);
|
||||
const cpy = { ...formUpdateData };
|
||||
cpy[name] =
|
||||
name === "purchaseDate"
|
||||
@@ -40,7 +43,6 @@ export default function Room() {
|
||||
delete cpy.user;
|
||||
delete cpy.updatedAt;
|
||||
delete cpy.__v;
|
||||
delete cpy.description;
|
||||
setFormUpdateData(cpy);
|
||||
}
|
||||
|
||||
@@ -106,6 +108,8 @@ export default function Room() {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{isInForm || isInFormUpdate ? <div id="blur"></div> : null}
|
||||
|
||||
{data.items && data.items.length > 0 ? (
|
||||
<div id="items-container">
|
||||
{data.items.map((e, i) => (
|
||||
@@ -159,7 +163,7 @@ export default function Room() {
|
||||
</div>
|
||||
|
||||
<div className="item-price-container">
|
||||
Montant ➜<span className="item-price"> {e.price}$</span>
|
||||
Montant ➜<span className="item-price"> {e.price}e</span>
|
||||
</div>
|
||||
|
||||
<div className="item-buy-date-container">
|
||||
@@ -239,6 +243,13 @@ export default function Room() {
|
||||
type="text"
|
||||
placeholder={formUpdateData.model}
|
||||
/>
|
||||
<input
|
||||
onChange={(e) => {
|
||||
handleFormUpdateDataChange(e, "description");
|
||||
}}
|
||||
type="text"
|
||||
placeholder={formUpdateData.description}
|
||||
/>
|
||||
<input
|
||||
onChange={(e) => {
|
||||
handleFormUpdateDataChange(e, "price");
|
||||
@@ -251,6 +262,9 @@ export default function Room() {
|
||||
handleFormUpdateDataChange(e, "purchaseDate");
|
||||
}}
|
||||
type="date"
|
||||
min="1900-01-01"
|
||||
max="2100-01-01"
|
||||
value={`${new Date(formUpdateData.purchaseDate).toISOString().split("T")[0].replace(/-/g, "-")}`}
|
||||
/>
|
||||
<input
|
||||
onChange={(e) => {
|
||||
@@ -261,12 +275,16 @@ export default function Room() {
|
||||
/>
|
||||
|
||||
<div id="actions">
|
||||
<button className="actions-btn" onClick={handleFormUpdate}>
|
||||
Annuler
|
||||
</button>
|
||||
<button onClick={handleSubmitUpdate} className="actions-btn">
|
||||
Confirmer
|
||||
</button>
|
||||
<StylizedBtn
|
||||
perso_style={{ width: "75px" }}
|
||||
text={"Annuler"}
|
||||
handle={handleFormUpdate}
|
||||
/>
|
||||
<StylizedBtn
|
||||
perso_style={{ width: "75px" }}
|
||||
text={"Confirmer"}
|
||||
handle={handleSubmitUpdate}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,8 +1,20 @@
|
||||
@import "../../assets/styles/vars.scss";
|
||||
|
||||
#room-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
#blur {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
filter: blur(30px);
|
||||
background: $primary;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
#items-container {
|
||||
margin-top: 20px;
|
||||
@@ -18,7 +30,7 @@
|
||||
.item-container {
|
||||
padding: 10px;
|
||||
gap: 10px;
|
||||
border: 1px dashed rgb(54, 54, 54);
|
||||
border: 1px dashed $good_black;
|
||||
width: 370px;
|
||||
border-radius: 6px;
|
||||
height: 370px;
|
||||
@@ -41,7 +53,7 @@
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
background-color: orange;
|
||||
background-color: $orange;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
@@ -53,8 +65,8 @@
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
background: red;
|
||||
color: white;
|
||||
background: $red;
|
||||
color: $white;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -82,12 +94,12 @@
|
||||
|
||||
.item-image {
|
||||
width: 200px;
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
|
||||
box-shadow: $shadow_box_def;
|
||||
}
|
||||
}
|
||||
|
||||
.item-no-img {
|
||||
color: red;
|
||||
color: $red;
|
||||
}
|
||||
|
||||
.item-description-container {
|
||||
@@ -96,7 +108,7 @@
|
||||
width: 100%;
|
||||
|
||||
.item-description {
|
||||
color: black;
|
||||
color: $black;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
@@ -125,18 +137,21 @@
|
||||
|
||||
#form-container,
|
||||
#form-update-container {
|
||||
border: 1px solid black;
|
||||
z-index: 9999;
|
||||
border: 1px solid $black;
|
||||
width: 300px;
|
||||
height: 400px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: white;
|
||||
border-radius: $my_border_rad;
|
||||
background: $white;
|
||||
|
||||
#form-closure-container {
|
||||
position: absolute;
|
||||
@@ -149,11 +164,12 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
border-top-right-radius: $my_border_rad;
|
||||
|
||||
&:hover {
|
||||
background: red;
|
||||
background: $red;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
color: $white;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
@@ -2,14 +2,18 @@ import "./Rooms.scss";
|
||||
import { useState, useEffect } from "react";
|
||||
import { createRoom, getRooms, deleteRoom } from "../../api";
|
||||
import { Link } from "react-router-dom";
|
||||
import { MagnifyingGlass } from "react-loader-spinner";
|
||||
|
||||
export default function Rooms() {
|
||||
const [rooms, setRooms] = useState([]);
|
||||
const [rooms, setRooms] = useState(null);
|
||||
const [isLoad, setIsLoad] = useState(true);
|
||||
const [isErr, setIsErr] = useState(false);
|
||||
|
||||
const onClickCreate = () => {
|
||||
const name = prompt("Nom de la piece ?");
|
||||
|
||||
createRoom(name).then((res) => {
|
||||
setIsErr(false);
|
||||
const values = [...rooms];
|
||||
values.push(res);
|
||||
setRooms(values);
|
||||
@@ -22,7 +26,7 @@ export default function Rooms() {
|
||||
"non",
|
||||
);
|
||||
|
||||
if (confirmation.toLocaleLowerCase() !== "oui") return;
|
||||
if (!confirmation || !confirmation.toLocaleLowerCase() !== "oui") return;
|
||||
|
||||
deleteRoom(id).then((res) => {
|
||||
const values = rooms.filter((e) => e._id !== id);
|
||||
@@ -32,15 +36,18 @@ export default function Rooms() {
|
||||
|
||||
useEffect(() => {
|
||||
getRooms().then((res) => {
|
||||
if (res.length === 0) {
|
||||
setIsLoad(false);
|
||||
setIsErr(true);
|
||||
}
|
||||
|
||||
setRooms(res);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div id="rooms-container">
|
||||
{rooms.length === 0 ? (
|
||||
<span id="err-no-rooms">Aucune piece enregistree</span>
|
||||
) : (
|
||||
{rooms ? (
|
||||
<div id="rooms-list-container">
|
||||
{rooms.map((i, j) => (
|
||||
<div className="room" key={j}>
|
||||
@@ -75,8 +82,25 @@ export default function Rooms() {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<MagnifyingGlass
|
||||
visible={isLoad}
|
||||
height="100"
|
||||
width="100"
|
||||
ariaLabel="magnifying-glass-loading"
|
||||
wrapperStyle={{}}
|
||||
wrapperClass="magnifying-glass-wrapper"
|
||||
glassColor="#ffffff"
|
||||
color="#7B6A9C"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isErr && !isLoad ? (
|
||||
<span id="err-no-rooms">Vous n'avez pas de piece pour le moment !</span>
|
||||
) : null}
|
||||
|
||||
<div id="rooms-add-container">
|
||||
<div id="rooms-text-on">Creer une nouvelle piece</div>
|
||||
<button id="add-rooms" onClick={onClickCreate}>
|
||||
|
@@ -1,3 +1,5 @@
|
||||
@import "../../assets/styles/vars.scss";
|
||||
|
||||
#rooms-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -5,7 +7,7 @@
|
||||
#err-no-rooms {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
color: red;
|
||||
color: $red;
|
||||
font-weight: bold;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@@ -26,7 +28,8 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
border: 1px dashed rgb(54, 54, 54);
|
||||
border: 1px dashed $good_black;
|
||||
border-radius: $my_border_rad;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
@@ -41,8 +44,9 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background: red;
|
||||
background: $red;
|
||||
display: none;
|
||||
border-top-right-radius: $my_border_rad;
|
||||
|
||||
.room-delete-ascii {
|
||||
display: flex;
|
||||
@@ -50,7 +54,7 @@
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: white;
|
||||
color: $white;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
@@ -95,8 +99,8 @@
|
||||
|
||||
#rooms-text-on {
|
||||
width: 100px;
|
||||
background: rgb(123, 106, 156);
|
||||
color: white;
|
||||
background: $primary;
|
||||
color: $white;
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -106,8 +110,8 @@
|
||||
height: 40px;
|
||||
border-radius: 50px;
|
||||
border: none;
|
||||
background: rgb(123, 106, 156);
|
||||
color: white;
|
||||
background: $primary;
|
||||
color: $white;
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
|
||||
|
@@ -6,12 +6,13 @@ import Room from "./pages/room/Room";
|
||||
import { Home, Login, Register } from "./pages";
|
||||
|
||||
export const Router = () => (
|
||||
<Routes>
|
||||
<Route index element={<Home />} />
|
||||
<Route path="login" element={<Login />} />
|
||||
<Route path="register" element={<Register />} />
|
||||
<Route path="rooms" element={<Rooms />} />
|
||||
<Route path="room/:id" element={<Room />} />
|
||||
<Route path="profile" element={<Profile />} />
|
||||
</Routes>
|
||||
<Routes>
|
||||
<Route index element={<Home />} />
|
||||
<Route path="login" element={<Login />} />
|
||||
<Route path="register" element={<Register />} />
|
||||
<Route path="rooms/" element={<Rooms />} />
|
||||
{/* maybe <Route path="rooms/:page" element={<Rooms />} /> */}
|
||||
<Route path="room/:id" element={<Room />} />
|
||||
<Route path="profile" element={<Profile />} />
|
||||
</Routes>
|
||||
);
|
||||
|
31
src/services/password.js
Normal file
31
src/services/password.js
Normal file
@@ -0,0 +1,31 @@
|
||||
export default function passwordCheck(p1, p2) {
|
||||
const specialChars = [
|
||||
"@",
|
||||
"#",
|
||||
"$",
|
||||
"%",
|
||||
"!",
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
];
|
||||
|
||||
const containsLetter = /[a-zA-Z]/.test(p1);
|
||||
const containsDigit = /[0-9]/.test(p1);
|
||||
const containsSpecialChar = specialChars.some((char) => p1.includes(char));
|
||||
|
||||
return (
|
||||
p1 === p2 &&
|
||||
p1.length >= 8 &&
|
||||
containsLetter &&
|
||||
containsDigit &&
|
||||
containsSpecialChar
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user