register + deletions + image request changes

This commit is contained in:
Simon CATANESE 2024-05-13 19:42:49 +02:00
parent baf31f7959
commit 22ec7f8fdd
16 changed files with 220 additions and 87 deletions

View File

@ -24,3 +24,45 @@ export const getItems = async () => {
return error.response.data; return error.response.data;
} }
}; };
export const createItem = async (values) => {
try {
const response = await axios.post(
`${import.meta.env.VITE_API_URL}/item`,
values,
);
console.log(response.data);
return response;
} catch (error) {
console.error(error);
}
}
export const updateItem = async (_id, values) => {
try {
const response = await axios.put(
`${import.meta.env.VITE_API_URL}/item/${_id}`,
values,
);
console.log(response.data);
return response;
} catch (error) {
console.error(error);
}
}
export const deleteItem = async (_id) => {
try {
const response = await axios.delete(
`${import.meta.env.VITE_API_URL}/item/${_id}`
);
console.log(response.data);
return response;
} catch (error) {
console.error(error);
}
}

View File

@ -26,6 +26,56 @@ export const getRooms = async () => {
} }
}; };
export const createRoom = async (values) => {
try {
const response = await axios.post(
`${import.meta.env.VITE_API_URL}/room`,
values,
);
console.log(response.data);
return response;
} catch (error) {
console.error(error);
}
}
export const updateRoom = async(_id, values) => {
try {
const response = await axios.put(
`${import.meta.env.VITE_API_URL}/room/${_id}`,
values,
);
console.log(response.data);
return response;
} catch (error) {
console.error(error);
}
}
export const deleteRoom = async (_id) => {
try {
const itemsResponse = await axios.get(
`${import.meta.env.VITE_API_URL}/item`,
);
const items = itemsResponse.data;
items?.forEach(async (item) => {
await axios.delete(
`${import.meta.env.VITE_API_URL}/item/${item._id}`,
);
})
const response = await axios.delete(
`${import.meta.env.VITE_API_URL}/room/${_id}`
);
console.log(response.data);
return response;
} catch (error) {
console.error(error);
}
}
export const getRoomStats = async () => { export const getRoomStats = async () => {
try { try {
const response = await axios.get("/room/stats"); const response = await axios.get("/room/stats");

View File

@ -78,8 +78,7 @@
} }
.item-list { .item-list {
width: 100%; width: 50vw;
max-width:50vw;
} }
.pagination { .pagination {

View File

@ -57,3 +57,34 @@
.product-details button:hover { .product-details button:hover {
background-color: #0056b3; background-color: #0056b3;
} }
.button-group {
margin-top: 10px;
display: flex;
}
.edit-button,
.delete-button {
flex: 1;
padding: 10px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.edit-button {
background-color: #007bff;
color: #fff;
margin-right: 10px;
}
.delete-button {
background-color: #dc3545;
color: #fff;
}
.edit-button:hover,
.delete-button:hover {
background-color: #0056b3;
}

View File

@ -1,7 +1,8 @@
import React from "react"; import React, { useContext } from "react";
import { AuthenticationProvider } from "../contexts"; import { AuthenticationProvider } from "../contexts";
export const Authenticated = ({ children }) => { export const Authenticated = ({ children }) => {
return <AuthenticationProvider>{children}</AuthenticationProvider>; return <AuthenticationProvider>{children}</AuthenticationProvider>;
}; };

View File

@ -1,6 +1,9 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { Form, Input, InputNumber, Button, Select, DatePicker } from "antd"; import { Form, Input, InputNumber, Button, Select, DatePicker } from "antd";
import axios from "axios"; import axios from "axios";
import { createItem } from '../../api/item'
const { TextArea } = Input; const { TextArea } = Input;
const { Option } = Select; const { Option } = Select;
@ -26,16 +29,10 @@ export const FormCreateItem = ({ onClose }) => {
}, []); }, []);
const onFinish = async (values) => { const onFinish = async (values) => {
try { let response = await createItem(values);
const response = await axios.post( if (response?.status >= 200 && response?.status < 300) {
`${import.meta.env.VITE_API_URL}/item`, window.location.reload();
values, }
);
console.log(response.data);
} catch (error) {
console.error(error);
}
}; };
return ( return (

View File

@ -1,20 +1,16 @@
import React from "react"; import React from "react";
import { Form, Input, Button } from "antd"; import { Form, Input, Button } from "antd";
import axios from "axios"; import axios from "axios";
export const FormCreateRoom = () => { export const FormCreateRoom = () => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const onFinish = async (values) => { const onFinish = async (values) => {
try { let response = await createRoom(values);
const response = await axios.post( if (response?.status >= 200 && response?.status < 300) {
`${import.meta.env.VITE_API_URL}/room`, window.location.reload();
values, }
);
console.log(response.data);
} catch (error) {
console.error(error);
}
}; };
return ( return (

View File

@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
import { Form, Input, InputNumber, Button, Select, DatePicker } from "antd"; import { Form, Input, InputNumber, Button, Select, DatePicker } from "antd";
import axios from "axios"; import axios from "axios";
import { getRooms } from "../../api/room"; import { getRooms } from "../../api/room";
import { getItem } from "../../api/item"; import { getItem, updateItem } from "../../api/item";
import moment from "moment"; import moment from "moment";
const { Option } = Select; const { Option } = Select;
@ -69,16 +69,10 @@ export const FormUpdateItem = ({ itemId, onClose }) => {
}, [item, form]); }, [item, form]);
const onFinish = async (values) => { const onFinish = async (values) => {
try { let response = await updateItem(item._id, values);
const response = await axios.put( if (response?.status >= 200 && response?.status < 300) {
`${import.meta.env.VITE_API_URL}/item/${item._id}`, window.location.reload();
values, }
);
console.log(response.data);
} catch (error) {
console.error(error);
}
}; };
const dateFormat = "YYYY-MM-DD"; const dateFormat = "YYYY-MM-DD";

View File

@ -1,5 +1,5 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import {getRoom } from '../../api/room' import {getRoom, updateRoom, deleteRoom } from '../../api/room'
import { Form, Input, Button } from "antd"; import { Form, Input, Button } from "antd";
import axios from "axios"; import axios from "axios";
@ -26,20 +26,23 @@ export const FormUpdateRoom = ({_id}) => {
} }
}, [room, form]); }, [room, form]);
const onFinish = async (values) => { const onFinish = async (values) => {
try { let response = await updateRoom(_id, values);
const response = await axios.put( if (response?.status >= 200 && response?.status < 300) {
`${import.meta.env.VITE_API_URL}/room/${_id}`, window.location.reload();
values, }
); };
console.log(response.data);
} catch (error) { const onDelete = async () => {
console.error(error); let response = await deleteRoom(_id);
} if (response?.status >= 200 && response?.status < 300) {
}; window.location.reload();
}
}
return ( return (
<Form form={form} onFinish={onFinish}> <Form form={form} onFinish={onFinish}>
<button onClick={onDelete}> Supprimer </button>
<Form.Item <Form.Item
label="Room Name" label="Room Name"
name="name" name="name"

View File

@ -5,6 +5,8 @@ import FormUpdateItem from "../form/formUpdateItem";
import { Image } from "../parts/image"; import { Image } from "../parts/image";
import { Description } from "../parts/description"; import { Description } from "../parts/description";
import { Characteristic } from "../parts/characteristic"; import { Characteristic } from "../parts/characteristic";
import { deleteItem } from '../../api/item'
export const ItemBox = ({ model, brand, purchaseDate, price, _id }) => { export const ItemBox = ({ model, brand, purchaseDate, price, _id }) => {
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
@ -15,7 +17,14 @@ export const ItemBox = ({ model, brand, purchaseDate, price, _id }) => {
const closeModal = () => { const closeModal = () => {
setIsModalOpen(false); setIsModalOpen(false);
}; };
const onDelete = async () => {
let response = await deleteItem(_id);
if (response?.status >= 200 && response?.status < 300) {
window.location.reload();
}
}
let productname = brand + " " + model; let productname = brand + " " + model;
let formatedPrice = price + "€"; let formatedPrice = price + "€";
@ -23,30 +32,33 @@ export const ItemBox = ({ model, brand, purchaseDate, price, _id }) => {
let request = brand + " " + model; let request = brand + " " + model;
return ( return (
<div className="product-details"> <div className="product-details">
<Description title={productname}> <Description title={productname}>
<Image request={request} _id={_id} alt="Product" /> <Image request={request} alt="Product" />
<Characteristic label="Model" value={model} /> <Characteristic label="Model" value={model} />
<Characteristic label="Brand" value={brand} /> <Characteristic label="Brand" value={brand} />
<Characteristic label="Purchase Date" value={formatedDate} /> <Characteristic label="Purchase Date" value={formatedDate} />
<Characteristic label="Price" value={formatedPrice} /> <Characteristic label="Price" value={formatedPrice} />
{/* Bouton d'édition pour ouvrir la fenêtre modale */} {/* Boutons d'édition et de suppression */}
<button onClick={openModal}>Edit</button> <div className="button-group">
</Description> <button className="edit-button" onClick={openModal}>Edit</button>
{/* Fenêtre modale */} <button className="delete-button" onClick={onDelete}>Delete</button>
{isModalOpen && ( </div>
<div className="modal"> </Description>
<div className="modal-content"> {/* Fenêtre modale */}
<span className="close" onClick={closeModal}> {isModalOpen && (
&times; <div className="modal">
</span> <div className="modal-content">
<FormUpdateItem itemId={_id}> <span className="close" onClick={closeModal}>
{console.log("item ID :" + _id)} &times;
</FormUpdateItem> </span>
</div> <FormUpdateItem itemId={_id}>
{console.log("item ID :" + _id)}
</FormUpdateItem>
</div>
</div>
)}
</div> </div>
)} );
</div>
);
}; };

View File

@ -26,16 +26,17 @@ function getItem(key, label) {
const { SubMenu } = Menu; const { SubMenu } = Menu;
const Navbar = () => { const Navbar = () => {
const [rooms, setRooms] = useState([]); const [rooms, setRooms] = useState([]);
useEffect(() => { useEffect(() => {
console.log("NAVBAR EFFECT"); console.log("NAVBAR EFFECT");
isLoggedIn().then((user) => { isLoggedIn().then((user) => {
if (user !== "Unauthorized") { if (user !== "Unauthorized") {
getRooms().then((result) => { getRooms().then((result) => {
setRooms(result); setRooms(result);
}); });
} }
}); });
}, []); }, []);
@ -57,7 +58,7 @@ const Navbar = () => {
try { try {
return ( return (
<Menu <Menu
defaultSelectedKeys={["1"]} defaultSelectedKeys={["0"]}
defaultOpenKeys={["sub1"]} defaultOpenKeys={["sub1"]}
theme="dark" theme="dark"
mode="inline" mode="inline"

View File

@ -2,17 +2,17 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { searchAndResizeImage } from '../../api/image-request' import { searchAndResizeImage } from '../../api/image-request'
export const Image = ({ src, alt, request, _id }) => { export const Image = ({ src, alt, request }) => {
const [cacheUrl, setCacheUrl] = useState(null); const [cacheUrl, setCacheUrl] = useState(null);
useEffect(() => { useEffect(() => {
const fetchData = async () => { const fetchData = async () => {
let cachedUrl = localStorage.getItem(_id); let cachedUrl = localStorage.getItem(request);
if (!cachedUrl) { if (!cachedUrl) {
try { try {
cachedUrl = await searchAndResizeImage(request); cachedUrl = await searchAndResizeImage(request);
localStorage.setItem(_id, cachedUrl); localStorage.setItem(request, cachedUrl);
console.log("Mise en cache de l'image avec l'ID : " + _id); console.log("Mise en cache de l'image avec la requête : " + request);
} catch (error) { } catch (error) {
console.error("Erreur lors de la récupération de l'image : ", error); console.error("Erreur lors de la récupération de l'image : ", error);
} }
@ -21,7 +21,7 @@ export const Image = ({ src, alt, request, _id }) => {
}; };
fetchData(); fetchData();
}, [request, _id]); }, [request]);
if (src) { if (src) {
return <img src={src} alt={alt} style={{ display: 'block', margin: 'auto' }} width='150px' height='150px' />; return <img src={src} alt={alt} style={{ display: 'block', margin: 'auto' }} width='150px' height='150px' />;

View File

@ -24,7 +24,7 @@ export const RoomDetail = ({
<div className="room-detail"> <div className="room-detail">
{isUpdateFormVisible ? ( {isUpdateFormVisible ? (
<div> <div>
<h2>Modifier une chambre (non fonctionnel)</h2> <h2>Modifier une chambre</h2>
<button onClick={handleBackClick}>Annuler </button> <button onClick={handleBackClick}>Annuler </button>
<FormUpdateRoom _id={selectedRoom} /> <FormUpdateRoom _id={selectedRoom} />
</div> </div>

View File

@ -6,7 +6,8 @@ import { Characteristic } from "../parts/characteristic";
export const RoomBox = ({ room, onRoomClick }) => { export const RoomBox = ({ room, onRoomClick }) => {
const handleBoxClick = () => { const handleBoxClick = () => {
onRoomClick(room._id); onRoomClick(room._id);
}; };
return ( return (
<div className="room-details" onClick={handleBoxClick}> <div className="room-details" onClick={handleBoxClick}>

View File

@ -16,7 +16,11 @@ export const Login = () => {
if (response && !response.success) { if (response && !response.success) {
setError(response.error); setError(response.error);
} }
}; };
const onRegister = () => {
window.location.href = '/register'
}
return ( return (
<div> <div>
@ -36,6 +40,7 @@ export const Login = () => {
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
/> />
<button type="submit">submit</button> <button type="submit">submit</button>
<button onClick={onRegister}>Register</button>
</form> </form>
</div> </div>
); );

View File

@ -21,7 +21,8 @@ export const Register = () => {
return ( return (
<div> <div>
<h1>Register page</h1> <h1>Register page</h1>
<p>Password must include a capital letter, a digit and a symbol</p>
{error && <p className="text-red-500">{error}</p>} {error && <p className="text-red-500">{error}</p>}
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
<input <input