Compare commits

...

2 Commits

14 changed files with 189 additions and 90 deletions

Binary file not shown.

Binary file not shown.

26
package-lock.json generated
View File

@ -16,7 +16,7 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-cookie": "^7.0.2", "react-cookie": "^7.0.2",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.21.3" "react-router-dom": "^6.23.1"
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.42.1", "@playwright/test": "^1.42.1",
@ -990,9 +990,9 @@
} }
}, },
"node_modules/@remix-run/router": { "node_modules/@remix-run/router": {
"version": "1.14.2", "version": "1.16.1",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz",
"integrity": "sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg==", "integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==",
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
} }
@ -5312,11 +5312,11 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}, },
"node_modules/react-router": { "node_modules/react-router": {
"version": "6.21.3", "version": "6.23.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.3.tgz", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz",
"integrity": "sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==", "integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==",
"dependencies": { "dependencies": {
"@remix-run/router": "1.14.2" "@remix-run/router": "1.16.1"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
@ -5326,12 +5326,12 @@
} }
}, },
"node_modules/react-router-dom": { "node_modules/react-router-dom": {
"version": "6.21.3", "version": "6.23.1",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.3.tgz", "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz",
"integrity": "sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==", "integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==",
"dependencies": { "dependencies": {
"@remix-run/router": "1.14.2", "@remix-run/router": "1.16.1",
"react-router": "6.21.3" "react-router": "6.23.1"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"

View File

@ -22,7 +22,7 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-cookie": "^7.0.2", "react-cookie": "^7.0.2",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.21.3" "react-router-dom": "^6.23.1"
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.42.1", "@playwright/test": "^1.42.1",

View File

@ -0,0 +1,38 @@
.list-container {
width: 100%;
max-height:500px;
overflow-y: auto; /* Activer le défilement vertical si nécessaire */
padding: 20px; /* Espace intérieur de la liste */
}
.room-details {
width: 100%; /* Largeur de chaque boîte */
background-color: #f9f9f9;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 20px;
margin-bottom: 20px; /* Espace entre chaque boîte */
transition: transform 0.3s ease;
}
.room-details:hover {
transform: translateY(-5px); /* Effet d'élévation au survol */
}
.room-details .title {
font-size: 18px;
font-weight: bold;
margin-bottom: 10px;
}
.room-details .characteristic {
margin-bottom: 10px;
}
.room-details .label {
font-weight: bold;
}
.room-details .value {
color: #666;
}

View File

@ -14,15 +14,20 @@ const Diagram = ({ data }) => {
return ( return (
<div className="diagram-container"> <div className="diagram-container">
<h2>Prix total par an</h2> <h2>Prix total par an</h2>
{diagramData.map(({ name, value }) => ( {diagramData.map(({ name, value }) => {
<div key={name} className="row-container"> // Appliquer l'échelle logarithmique à la valeur
<div className="label">{name}</div> const scaledValue = Math.log(value + 1); // Ajouter 1 pour éviter le logarithme de zéro
<div className="row" style={{ width: `${(value / maxValue) * 100}%` }}> const scaledMaxValue = Math.log(maxValue + 1);
<div className="value">{value}</div> return (
<div key={name} className="row-container">
<div className="label">{name}</div>
<div className="row" style={{ width: `${(scaledValue / scaledMaxValue) * 100}%` }}>
<div className="value">{value}</div>
</div>
</div> </div>
</div> );
))} })}
</div> </div>
); );
}; };

View File

@ -3,28 +3,14 @@ import '../../assets/styles/modal.css'
import '../../assets/styles/itembox.css' import '../../assets/styles/itembox.css'
import FormUpdateItem from '../form/formUpdateItem'; import FormUpdateItem from '../form/formUpdateItem';
import {Image } from '../parts/image' import {Image } from '../parts/image'
import {Description } from '../parts/description'
import {Characteristic } from '../parts/characteristic'
// Composant Description
const Description = ({ title, children }) => {
return (
<div className="description">
<h2 className="text-ellipsis">{title}</h2>
{children}
</div>
);
};
// Composant Caractéristique
const Characteristic = ({ label, value }) => {
return (
<div className="characteristic">
<strong>{label}:</strong> {value}
</div>
);
};

View File

@ -42,10 +42,10 @@ const Navbar = () => {
const items = [ const items = [
<Menu.Item key="0"> <Menu.Item key="0">
<Link to="/">Menu Principal</Link> <Link to="/logout">Login / Logout</Link>
</Menu.Item>, </Menu.Item>,
<Menu.Item key="1" > <Menu.Item key="1" >
<Link to="/home">Home</Link> <Link to="/home">Menu Principal</Link>
</Menu.Item>, </Menu.Item>,
<Menu.Item key="2" > <Menu.Item key="2" >
<Link to="/items">Tous les articles</Link> <Link to="/items">Tous les articles</Link>

View File

@ -0,0 +1,11 @@
import React, { useEffect, useState } from 'react';
// Composant Caractéristique
export const Characteristic = ({ label, value }) => {
return (
<div className="characteristic">
<strong>{label}:</strong> {value}
</div>
);
};

View File

@ -0,0 +1,11 @@
import React, { useEffect, useState } from 'react';
// Composant Description
export const Description = ({ title, children }) => {
return (
<div className="description">
<h2 className="text-ellipsis">{title}</h2>
{children}
</div>
);
};

View File

@ -0,0 +1,45 @@
import React, { useEffect, useState } from 'react';
import { FormCreateRoom } from '../../components/form/formCreateRoom';
//import { RoomUpdateForm } from './RoomUpdateForm';
export const RoomDetail = ({ selectedRoom, onCreateFormSubmit, onUpdateFormSubmit, onBack }) => {
const [isUpdateFormVisible, setIsUpdateFormVisible] = useState(false);
useEffect(() => {
if (selectedRoom) {
setIsUpdateFormVisible(true)
}
}, [selectedRoom]);
// Afficher le formulaire de mise ŕ jour lorsqu'une chambre est sélectionnée
const handleRoomClick = () => {
setIsUpdateFormVisible(true);
};
// Afficher le formulaire de création lorsqu'on revient en arričre
const handleBackClick = () => {
setIsUpdateFormVisible(false);
onBack(null);
};
return (
<div className="room-detail">
{isUpdateFormVisible
? (
<div>
<h2>Modifier une chambre</h2>
<FormCreateRoom onSubmit={onCreateFormSubmit} />
</div>
)
: (
<div>
<h2>Ajouter une chambre</h2>
<FormCreateRoom onSubmit={onCreateFormSubmit} />
</div>
)
}
</div>
);
};

View File

@ -1,17 +1,9 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import axios from 'axios'; // Assurez-vous que le chemin d'importation soit correct import '../../assets/styles/room-list.css'
import { ItemBox } from './ItemBox'; import { RoomBox } from '../../components/rooms/roomBox'
import { Space, DatePicker, Row, Col, Select, Input, InputNumber } from 'antd'; import { formatRoomStats } from "../../api/room";
import '../../assets/styles/item-page.css'
const { RangePicker } = DatePicker;
const { Option } = Select;
const itemsPerPage = 8; // Nombre total d'items par page
const itemsPerRow = 4; // Nombre d'items par rangée
// Fonction pour diviser le tableau d'items en rangées // Fonction pour diviser le tableau d'items en rangées
const chunkArray = (arr, size) => { const chunkArray = (arr, size) => {
const chunkedArr = []; const chunkedArr = [];
@ -22,25 +14,32 @@ const chunkArray = (arr, size) => {
}; };
// Composant d'affichage de la page // Composant d'affichage de la page
export const RoomList = (roomsParam) => { export const RoomList = ({ statsParam, onRoomClick }) => {
const [rooms, setRooms] = useState([]); const [rooms, setRooms] = useState([]);
const [selectedRoom, setSelectedRoom] = useState('all'); const [selectedRoom, setSelectedRoom] = useState('all');
useEffect(() => { useEffect(() => {
setRooms(roomsParam) if (statsParam.rooms) {
}, [roomsParam]); console.log(statsParam.rooms)
let formatedStats = formatRoomStats(statsParam)
setRooms(formatedStats.rooms)
}
}, [statsParam]);
const handleRoomChange = (value) => {
setSelectedRoom(value);
};
return ( const handleRoomClick = (roomId) => {
<div className="list-container"> onRoomClick(roomId);
<div className="room-list"> };
{rooms.forEach((room) => {
<roomB return (
}) } <div>
</div> <h2>Liste des chambres</h2>
</div> <div className="list-container">
); {rooms && rooms.map((room) => (
<RoomBox room={room} key={room._id} onRoomClick={handleRoomClick} />
))}
</div>
</div>
);
}; };

View File

@ -1,22 +1,19 @@
import React, { useEffect, useState } from 'react'; import React from 'react';
import '../../assets/styles/itembox.css' import '../../assets/styles/room-list.css';
import { } from '../item/ItemBox' import { Description } from '../parts/description';
import { Characteristic } from '../parts/characteristic';
export const RoomBox = ({ room, onRoomClick }) => {
// Composant Détails du Produit const handleBoxClick = () => {
export const RoomBox = ({ name, itemCount, roomPrice, _id }) => { onRoomClick(room._id);
const [roomData, setRoomData] = useState(); };
useEffect(() => {
setRoomData({name, itemCount, roomPrice, _id})
}, [name, itemCount, roomPrice, _id]);
return ( return (
<div className="product-details" > <div className="room-details" onClick={handleBoxClick}>
<Description title={roomData.name} > <Description title={room?.name}>
<Characteristic label="Nombre d'articles" value={roomData.itemCount} /> <Characteristic label="Nombre d'articles" value={room?.items_count || "N/A"} />
<Characteristic label="Prix total" value={roomData.roomPrice} /> <Characteristic label="Prix total" value={room?.room_price || "N/A"} />
</Description> </Description>
</div> </div>
); );

View File

@ -2,21 +2,24 @@ import React, { useEffect, useState } from 'react';
import '../assets/styles/room-page.css' import '../assets/styles/room-page.css'
import { useAuth } from "../hooks"; import { useAuth } from "../hooks";
import { formatRoomStats, getRooms, getRoomStats } from "../api/room"; import { getRoomStats } from "../api/room";
import { usePageTitle } from '../hooks/page-title-context'; import { usePageTitle } from '../hooks/page-title-context';
import RoomStats from '../components/rooms/room-stats'; import RoomStats from '../components/rooms/room-stats';
import { RoomList } from '../components/rooms/room-list';
import { RoomDetail } from '../components/rooms/room-detail';
export const Rooms = () => { export const Rooms = () => {
const { user } = useAuth(); const { user } = useAuth();
const { setPageTitle } = usePageTitle(); const { setPageTitle } = usePageTitle();
const [stats, setStats] = useState({}); const [stats, setStats] = useState({});
const [selectedRoom, setSelectedRoom] = useState();
// Mettre à jour le titre de la page dans le contexte
useEffect(() => { useEffect(() => {
setPageTitle("Toutes les rooms :"); setPageTitle("Toutes les rooms :");
}, [setPageTitle]); }, [setPageTitle]);
useEffect(() => { useEffect(() => {
const fetchData = async () => { const fetchData = async () => {
const roomsStatsResponse = await getRoomStats(); const roomsStatsResponse = await getRoomStats();
@ -26,20 +29,24 @@ export const Rooms = () => {
fetchData(); fetchData();
}, []); }, []);
const handleRoomClick = (roomId) => {
console.log('Clicked room ID:', roomId);
setSelectedRoom(roomId);
};
return ( return (
<div className="manContainer"> <div className="manContainer">
<div className="topContainer"> <div className="topContainer">
<div className="statsContainer"> <div className="statsContainer">
<RoomStats statsParam={stats} /> <RoomStats statsParam={stats} />
</div> </div>
<div className="listContainer"> <div className="listContainer">
<RoomList statsParam={stats} onRoomClick={handleRoomClick}></RoomList>
</div> </div>
</div> </div>
<div className="detailContainer"> <div className="detailContainer">
<RoomStats statsParam={stats} /> <RoomDetail selectedRoom={selectedRoom} onBack={handleRoomClick}></RoomDetail>
</div> </div>
</div> </div>
); );