diff --git a/src/api/items.js b/src/api/items.js index 8b85f4f..c286d39 100644 --- a/src/api/items.js +++ b/src/api/items.js @@ -18,3 +18,23 @@ export const createItem = async (settings) => { return response.data; }; + +export const updateItem = async (settings) => { + console.log(settings); + + const formData = new FormData(); + formData.append("brand", settings.brand); + formData.append("model", settings.model); + formData.append("price", settings.price); + formData.append("purchaseDate", settings.purchaseDate); + formData.append("link", settings.link); + + const response = await axios.put(`/item/${settings._id}`, formData); + return response.data; +}; + +export const deleteItem = async (id) => { + console.log(id); + const response = await axios.delete(`/item/${id}`); + return response.data; +}; diff --git a/src/api/user.js b/src/api/user.js index 6fb3768..5f2b13d 100644 --- a/src/api/user.js +++ b/src/api/user.js @@ -1,14 +1,17 @@ import axios from "axios"; export const createUser = async (username, password, confirmation) => { - try { - const response = await axios.post("/user", { - username, - password, - confirmation, - }); - return response.data; - } catch (error) { - return error.response.data; - } + try { + const response = await axios.post("/user", { + username, + password, + confirmation, + }); + return response.data; + } catch (error) { + return error.response.data; + } }; + +// TODO: REgarde postman +export const updateUser = 0; diff --git a/src/assets/styles/index.css b/src/assets/styles/index.css index 273f49c..74c6818 100644 --- a/src/assets/styles/index.css +++ b/src/assets/styles/index.css @@ -4,6 +4,10 @@ body { } * { + a { + color: rgb(123, 106, 156); + font-weight: bold; + } margin: 0; padding: 0; } diff --git a/src/components/AddBtn/AddBtn.scss b/src/components/AddBtn/AddBtn.scss index 4739087..54c2517 100644 --- a/src/components/AddBtn/AddBtn.scss +++ b/src/components/AddBtn/AddBtn.scss @@ -1,6 +1,6 @@ .add-btn-container { display: flex; - position: absolute; + position: fixed; bottom: 20px; right: 20px; width: 45px; @@ -15,5 +15,11 @@ color: white; font-weight: bold; font-size: 15px; + + &:hover { + transform: scale(1.05); + transition: 0.2s; + cursor: pointer; + } } } diff --git a/src/pages/profile/Profile.jsx b/src/pages/profile/Profile.jsx index 7318b9f..f7ab9a4 100644 --- a/src/pages/profile/Profile.jsx +++ b/src/pages/profile/Profile.jsx @@ -1,50 +1,93 @@ import { useAuth } from "../../hooks"; +import { useState } from "react"; import "./Profile.scss"; //Bilouuuuuuu94!@@ export default function Profile() { - const { user } = useAuth(); + const { user } = useAuth(); + const [username, setUsername] = useState(""); + const [oldPUsername, setOldPUsername] = useState(""); - return ( - <div id="profile-container"> - <div id="title-container"> - <h3 id="title"> - Heureux de vous voir <b>{user.user.username}</b> ! - </h3> - </div> + const [oldPPassword, setOldPPassword] = useState(""); + const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); - <div className="profile-modifier-container"> - <span className="profile-modifier-title"> - Change ton pseudo - </span> + const handleUsername = (e) => { + setUsername(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); + }; - <input - className="profile-modifier-ipt" - type="text" - placeholder="Nouveau nom" - /> + // TODO: Faire la paire de fonction + const handleSubmitPassword = () => {}; + const handleSubmitUsername = () => {}; - <button>OK</button> - </div> + return ( + <div id="profile-container"> + <div id="title-container"> + <h3 id="title"> + Heureux de vous voir <b>{user.user.username}</b> ! + </h3> - <div className="profile-modifier-container"> - <span className="profile-modifier-title"> - Change ton mot de passe - </span> + <button onClick={null}>Supprimer mon compte</button> + </div> - <input - className="profile-modifier-ipt" - type="password" - placeholder="Nouveau mot de passe" - /> - <input - className="profile-modifier-ipt" - type="password" - placeholder="Confirmation" - /> + <div className="profile-modifier-container"> + <span className="profile-modifier-title">Change ton pseudo</span> - <button>OK</button> - </div> - </div> - ); + <input + className="profile-modifier-ipt" + type="password" + placeholder="Ancien mot de passe" + onChange={handleOldPUsername} + /> + + <input + className="profile-modifier-ipt" + type="text" + placeholder="Nouveau nom" + onChange={handleUsername} + /> + + <button>OK</button> + </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> + </div> + </div> + ); } diff --git a/src/pages/profile/Profile.scss b/src/pages/profile/Profile.scss index d656b89..3feb699 100644 --- a/src/pages/profile/Profile.scss +++ b/src/pages/profile/Profile.scss @@ -12,8 +12,8 @@ } .profile-modifier-container { - border: 1px dashed black; - width: 500px; + border: 1px dashed rgb(61, 61, 61); + width: 450px; display: flex; flex-direction: column; padding: 10px; @@ -21,8 +21,12 @@ align-items: center; gap: 10px; + @media (max-width: 770px) { + width: 80%; + } + .profile-modifier-title { - color: rgb(70, 70, 70); + color: rgb(49, 49, 49); font-weight: bold; } diff --git a/src/pages/room/Room.jsx b/src/pages/room/Room.jsx index 7b5bbe1..ab5a6f1 100644 --- a/src/pages/room/Room.jsx +++ b/src/pages/room/Room.jsx @@ -3,24 +3,73 @@ import { useState, useEffect } from "react"; import { getRoom } from "../../api"; import "./Room.scss"; import AddBtn from "../../components/AddBtn/AddBtn"; -import { createItem } from "../../api/"; +import { createItem, deleteItem, updateItem } from "../../api/"; export default function Room() { const { id } = useParams(); const [data, setData] = useState({}); const [isInForm, setInForm] = useState(false); + const [isInFormUpdate, setIsInFormUpdate] = useState(false); + const [formUpdateData, setFormUpdateData] = useState(null); useEffect(() => { getRoom(id).then((res) => { - console.log(res); setData(res); }); }, []); + const handleFormUpdateDataChange = (e, name) => { + const cpy = { ...formUpdateData }; + cpy[name] = + name === "purchaseDate" + ? new Date(e.target.value).toISOString() + : e.target.value; + setFormUpdateData(cpy); + }; + const handleForm = () => { setInForm(!isInForm); }; + const handleFormUpdate = (item = null) => { + if (item) { + const cpy = { ...item }; + delete cpy.createdAt; + delete cpy.image; + delete cpy.invoice; + delete cpy.user; + delete cpy.updatedAt; + delete cpy.__v; + delete cpy.description; + setFormUpdateData(cpy); + } + + setIsInFormUpdate(!isInFormUpdate); + }; + + const handleDelete = (id) => { + deleteItem(id).then((_) => { + const cpy = [...data.items]; + const filtered = cpy.filter((e) => e._id !== id); + setData({ ...data, items: filtered }); + }); + }; + + const handleSubmitUpdate = () => { + try { + updateItem(formUpdateData).then((_) => { + // TODO: Je ferai une modification unitaire plus tard + getRoom(id).then((res) => { + handleFormUpdate(); + setData(res); + }); + }); + } catch (err) { + console.log(err); + handleFormUpdate(); + } + }; + const handleSubmit = (e) => { try { const settings = {}; @@ -34,8 +83,10 @@ export default function Room() { settings.image = e.target[6].files[0]; settings.invoice = e.target[7].files[0]; - createItem(settings).then((res) => { - console.log(res); + createItem(settings).then((_) => { + // Je prefere faire ca que d'actualiser le state[data.items] car + // l'image ne se charge pas correctement + window.location.reload(); }); handleForm(); @@ -59,15 +110,32 @@ export default function Room() { <div id="items-container"> {data.items.map((e, i) => ( <div className="item-container" key={i}> + <div id="item-actions-container"> + <button + onClick={() => { + handleDelete(e._id); + }} + id="item-delete-btn" + > + × + </button> + + <button + onClick={() => { + handleFormUpdate(e); + }} + id="item-update-btn" + > + ✏️ + </button> + </div> <div className="item-brand-container"> - Marque <a className="item-brand" href={e.link}> {e.brand} </a> </div> <div className="item-model-container"> - Modele <a className="item-model" href={e.link}> {e.model} </a> @@ -86,19 +154,18 @@ export default function Room() { )} <div className="item-description-container"> - Description + Description ➜ <span className="item-description"> {e.description}</span> </div> <div className="item-price-container"> - Montant - <span className="item-price"> {e.price}$</span> + Montant ➜<span className="item-price"> {e.price}$</span> </div> <div className="item-buy-date-container"> - Date d'achat + Date d'achat ➜ <span className="item-buy-date"> - {new Date(e.purchaseDate).toDateString()} + {new Date(e.purchaseDate).toLocaleDateString("FR-fr")} </span> </div> </div> @@ -131,7 +198,9 @@ export default function Room() { <input type="file" placeholder="Facture ..." /> <div id="actions"> - <button className="actions-btn">Annuler</button> + <button className="actions-btn" onClick={handleForm}> + Annuler + </button> <button className="actions-btn" type="submit"> Confirmer </button> @@ -140,6 +209,69 @@ export default function Room() { </div> )} + {isInFormUpdate && ( + <div id="form-update-container"> + <span> + Modification de{" "} + <b> + {formUpdateData.brand} {formUpdateData.model} + </b> + </span> + + <div id="form-closure-container"> + <button id="form-closure" onClick={handleFormUpdate}> + × + </button> + </div> + + <div id="form-update"> + <input + onChange={(e) => { + handleFormUpdateDataChange(e, "brand"); + }} + type="text" + placeholder={formUpdateData.brand} + /> + <input + onChange={(e) => { + handleFormUpdateDataChange(e, "model"); + }} + type="text" + placeholder={formUpdateData.model} + /> + <input + onChange={(e) => { + handleFormUpdateDataChange(e, "price"); + }} + type="number" + placeholder={formUpdateData.price} + /> + <input + onChange={(e) => { + handleFormUpdateDataChange(e, "purchaseDate"); + }} + type="date" + /> + <input + onChange={(e) => { + handleFormUpdateDataChange(e, "link"); + }} + type="text" + placeholder={formUpdateData.link} + /> + + <div id="actions"> + <button className="actions-btn" onClick={handleFormUpdate}> + Annuler + </button> + <button onClick={handleSubmitUpdate} className="actions-btn"> + Confirmer + </button> + </div> + </div> + </div> + )} + <AddBtn handle={handleForm} /> </div> ); diff --git a/src/pages/room/Room.scss b/src/pages/room/Room.scss index 0294fd3..28e6250 100644 --- a/src/pages/room/Room.scss +++ b/src/pages/room/Room.scss @@ -19,17 +19,51 @@ padding: 10px; gap: 10px; border: 1px dashed rgb(54, 54, 54); - width: 340px; - height: 340px; + width: 370px; + border-radius: 6px; + height: 370px; display: flex; flex-direction: column; + position: relative; overflow: auto; + #item-actions-container { + position: absolute; + width: 25px; + height: 25px; + top: 10px; + right: 10px; + + #item-update-btn { + width: 100%; + height: 100%; + border-radius: 50px; + border: none; + + &:hover { + background-color: orange; + cursor: pointer; + } + } + + #item-delete-btn { + width: 100%; + height: 100%; + border-radius: 50px; + border: none; + + &:hover { + background: red; + color: white; + font-weight: bold; + cursor: pointer; + } + } + } + .item-brand-container { text-align: center; .item-brand { - color: black; - font-weight: bold; } } @@ -38,26 +72,28 @@ gap: 5px; .item-model { - color: black; - font-weight: bold; } } .item-image-container { - width: 200px; + width: 100%; height: auto; + text-align: center; + .item-image { - width: 100%; + width: 200px; + box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px; } } .item-no-img { + color: red; } .item-description-container { display: flex; - width: 100%; gap: 5px; + width: 100%; .item-description { color: black; @@ -87,15 +123,20 @@ } } - #form-container { + #form-container, + #form-update-container { border: 1px solid black; width: 300px; height: 400px; display: flex; flex-direction: column; - position: relative; + position: fixed; gap: 20px; padding: 20px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: white; #form-closure-container { position: absolute; @@ -118,7 +159,8 @@ } } - #form { + #form, + #form-update { display: flex; flex-direction: column; gap: 15px; diff --git a/src/pages/rooms/Rooms.jsx b/src/pages/rooms/Rooms.jsx index c8728b1..b763b66 100644 --- a/src/pages/rooms/Rooms.jsx +++ b/src/pages/rooms/Rooms.jsx @@ -4,84 +4,85 @@ import { createRoom, getRooms, deleteRoom } from "../../api"; import { Link } from "react-router-dom"; export default function Rooms() { - const [rooms, setRooms] = useState([]); + const [rooms, setRooms] = useState([]); - const onClickCreate = () => { - const name = prompt("Nom de la piece ?"); + const onClickCreate = () => { + const name = prompt("Nom de la piece ?"); - createRoom(name).then((res) => { - const values = [...rooms]; - values.push(res); - setRooms(values); - }); - }; + createRoom(name).then((res) => { + const values = [...rooms]; + values.push(res); + setRooms(values); + }); + }; - const onClickDelete = (id, name) => { - const confirmation = prompt( - `Etes-vous sur de vouloir supprimer ${name} ? (Oui ou non)` - ); - - if (confirmation.toLocaleLowerCase() !== "oui") return; - - deleteRoom(id).then((res) => { - const values = rooms.filter((e) => e._id !== id); - setRooms(values); - }); - }; - - useEffect(() => { - getRooms().then((res) => { - setRooms(res); - }); - }, []); - - return ( - <div id="rooms-container"> - {rooms.length === 0 ? ( - <span id="err-no-rooms">Aucune piece enregistree</span> - ) : ( - <div id="rooms-list-container"> - {rooms.map((i, j) => ( - <div className="room" key={j}> - <div - className="room-delete" - onClick={() => { - onClickDelete(i._id, i.name); - }} - > - <span className="room-delete-ascii">×</span> - </div> - - <div className="room-id-container"> - <span className="label-id">ID</span> - <span className="room-id"> - {i._id[0]} - {i._id[1]} - {i._id[2]} - {i._id[3]} - {i._id[4]} - {i._id[5]} - ... - </span> - </div> - - <div className="room-name-container"> - <span className="label-name">Nom </span> - <Link to={`/room/${i._id}`}> - <span className="room-name">{i.name}</span> - </Link> - </div> - </div> - ))} - </div> - )} - - <div id="rooms-add-container"> - <div id="rooms-text-on">Creer une nouvelle piece</div> - <button id="add-rooms" onClick={onClickCreate}> - + - </button> - </div> - </div> + const onClickDelete = (id, name) => { + const confirmation = prompt( + `Etes-vous sur de vouloir supprimer ${name} ? (Oui ou non)`, + "non", ); + + if (confirmation.toLocaleLowerCase() !== "oui") return; + + deleteRoom(id).then((res) => { + const values = rooms.filter((e) => e._id !== id); + setRooms(values); + }); + }; + + useEffect(() => { + getRooms().then((res) => { + setRooms(res); + }); + }, []); + + return ( + <div id="rooms-container"> + {rooms.length === 0 ? ( + <span id="err-no-rooms">Aucune piece enregistree</span> + ) : ( + <div id="rooms-list-container"> + {rooms.map((i, j) => ( + <div className="room" key={j}> + <div + className="room-delete" + onClick={() => { + onClickDelete(i._id, i.name); + }} + > + <span className="room-delete-ascii">×</span> + </div> + + <div className="room-id-container"> + <span className="label-id">ID</span> + <span className="room-id"> + {i._id[0]} + {i._id[1]} + {i._id[2]} + {i._id[3]} + {i._id[4]} + {i._id[5]} + ... + </span> + </div> + + <div className="room-name-container"> + <span className="label-name">Nom </span> + <Link to={`/room/${i._id}`}> + <span className="room-name">{i.name}</span> + </Link> + </div> + </div> + ))} + </div> + )} + + <div id="rooms-add-container"> + <div id="rooms-text-on">Creer une nouvelle piece</div> + <button id="add-rooms" onClick={onClickCreate}> + + + </button> + </div> + </div> + ); }