premier commit final
This commit is contained in:
commit
4cf9069bf2
Binary file not shown.
BIN
.vs/slnx.sqlite
BIN
.vs/slnx.sqlite
Binary file not shown.
2
package-lock.json
generated
2
package-lock.json
generated
@ -16,7 +16,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-cookie": "^7.0.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.21.3"
|
||||
"react-router-dom": "^6.23.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.42.1",
|
||||
|
@ -22,7 +22,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-cookie": "^7.0.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.21.3"
|
||||
"react-router-dom": "^6.23.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.42.1",
|
||||
|
38
src/assets/styles/room-list.css
Normal file
38
src/assets/styles/room-list.css
Normal 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;
|
||||
}
|
@ -1,30 +1,37 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Col, Row } from "antd";
|
||||
import '../assets/styles/diagram.css'
|
||||
|
||||
import "../assets/styles/diagram.css";
|
||||
|
||||
const Diagram = ({ data }) => {
|
||||
const [diagramData, setDiagramData] = useState(data);
|
||||
const [diagramData, setDiagramData] = useState(data);
|
||||
|
||||
useEffect(() => {
|
||||
setDiagramData(data);
|
||||
}, [data]);
|
||||
useEffect(() => {
|
||||
setDiagramData(data);
|
||||
}, [data]);
|
||||
|
||||
const maxValue = Math.max(...diagramData.map(item => item.value));
|
||||
const maxValue = Math.max(...diagramData.map((item) => item.value));
|
||||
|
||||
return (
|
||||
<div className="diagram-container">
|
||||
<h2>Prix total par an</h2>
|
||||
{diagramData.map(({ name, value }) => (
|
||||
<div key={name} className="row-container">
|
||||
<div className="label">{name}</div>
|
||||
<div className="row" style={{ width: `${(value / maxValue) * 100}%` }}>
|
||||
<div className="value">{value}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className="diagram-container">
|
||||
<h2>Prix total par an</h2>
|
||||
{diagramData.map(({ name, value }) => {
|
||||
// Appliquer l'<EFBFBD>chelle logarithmique <EFBFBD> la valeur
|
||||
const scaledValue = Math.log(value + 1); // Ajouter 1 pour <EFBFBD>viter le logarithme de z<EFBFBD>ro
|
||||
const scaledMaxValue = Math.log(maxValue + 1);
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
export default Diagram;
|
||||
export default Diagram;
|
||||
|
@ -1,27 +1,10 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import "../../assets/styles/modal.css";
|
||||
import "../../assets/styles/itembox.css";
|
||||
import FormUpdateItem from "../form/formUpdateItem";
|
||||
import { Image } from "../parts/image";
|
||||
|
||||
// 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>
|
||||
);
|
||||
};
|
||||
import { Description } from "../parts/description";
|
||||
import { Characteristic } from "../parts/characteristic";
|
||||
|
||||
// Composant Détails du Produit
|
||||
export const ItemBox = ({ model, brand, purchaseDate, price, _id }) => {
|
||||
@ -54,14 +37,16 @@ export const ItemBox = ({ model, brand, purchaseDate, price, _id }) => {
|
||||
{/* Bouton d'édition pour ouvrir la fenêtre modale */}
|
||||
<button onClick={openModal}>Edit</button>
|
||||
</Description>
|
||||
{/* Fenêtre modale pour la mise à jour */}
|
||||
{/* Fenêtre modale */}
|
||||
{isModalOpen && (
|
||||
<div className="modal">
|
||||
<div className="modal-content">
|
||||
<span className="close" onClick={closeModal}>
|
||||
×
|
||||
</span>
|
||||
<FormUpdateItem itemId={_id} onClose={closeModal} />
|
||||
<FormUpdateItem itemId={_id}>
|
||||
{console.log("item ID :" + _id)}
|
||||
</FormUpdateItem>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Menu } from "antd";
|
||||
import { HomeOutlined } from "@ant-design/icons"
|
||||
import { HomeOutlined } from "@ant-design/icons";
|
||||
import { Home } from "../../pages";
|
||||
import { getRooms } from "../../api/room";
|
||||
import { isLoggedIn } from "../../api/authentication"
|
||||
import { isLoggedIn } from "../../api/authentication";
|
||||
import { Items } from "../../pages/items";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
@ -14,11 +14,13 @@ function getItem(key, label) {
|
||||
// children,
|
||||
// label,
|
||||
// link,
|
||||
//};
|
||||
var item = <Menu.Item key={key}>
|
||||
<Link to="/test">{label}</Link>
|
||||
</Menu.Item >
|
||||
return item
|
||||
//};
|
||||
var item = (
|
||||
<Menu.Item key={key}>
|
||||
<Link to="/test">{label}</Link>
|
||||
</Menu.Item>
|
||||
);
|
||||
return item;
|
||||
}
|
||||
|
||||
const { SubMenu } = Menu;
|
||||
@ -26,52 +28,48 @@ const { SubMenu } = Menu;
|
||||
// Component
|
||||
const Navbar = () => {
|
||||
//Hook calls
|
||||
const [rooms, setRooms] = useState([]);
|
||||
const [rooms, setRooms] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("NAVBAR EFFECT")
|
||||
isLoggedIn().then((user) => {
|
||||
if (user !== "Unauthorized") {
|
||||
getRooms().then((result) => {
|
||||
setRooms(result);
|
||||
})
|
||||
}
|
||||
})
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
console.log("NAVBAR EFFECT");
|
||||
isLoggedIn().then((user) => {
|
||||
if (user !== "Unauthorized") {
|
||||
getRooms().then((result) => {
|
||||
setRooms(result);
|
||||
});
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const items = [
|
||||
<Menu.Item key="0">
|
||||
<Link to="/logout">Login / Logout</Link>
|
||||
</Menu.Item>,
|
||||
<Menu.Item key="1">
|
||||
<Link to="/home">Menu Principal</Link>
|
||||
</Menu.Item>,
|
||||
<Menu.Item key="2">
|
||||
<Link to="/items">Tous les articles</Link>
|
||||
</Menu.Item>,
|
||||
<Menu.Item key="3">
|
||||
<Link to="/rooms">Voir les chambres</Link>
|
||||
</Menu.Item>,
|
||||
];
|
||||
|
||||
const items = [
|
||||
<Menu.Item key="0">
|
||||
<Link to="/">Menu Principal</Link>
|
||||
</Menu.Item>,
|
||||
<Menu.Item key="1" >
|
||||
<Link to="/home">Home</Link>
|
||||
</Menu.Item>,
|
||||
<Menu.Item key="2" >
|
||||
<Link to="/items">Tous les articles</Link>
|
||||
</Menu.Item>,
|
||||
<Menu.Item key="3" >
|
||||
<Link to="/rooms">Voir les chambres</Link>
|
||||
</Menu.Item>,
|
||||
|
||||
|
||||
];
|
||||
|
||||
// Rendu du composant Navbar
|
||||
try {
|
||||
return (
|
||||
<Menu
|
||||
defaultSelectedKeys={["1"]}
|
||||
defaultOpenKeys={["sub1"]}
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
>
|
||||
{items}
|
||||
|
||||
</Menu>
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error.stack)
|
||||
}
|
||||
// Rendu du composant Navbar
|
||||
try {
|
||||
return (
|
||||
<Menu
|
||||
defaultSelectedKeys={["1"]}
|
||||
defaultOpenKeys={["sub1"]}
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
>
|
||||
{items}
|
||||
</Menu>
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error.stack);
|
||||
}
|
||||
};
|
||||
export default Navbar;
|
||||
|
10
src/components/parts/characteristic.jsx
Normal file
10
src/components/parts/characteristic.jsx
Normal file
@ -0,0 +1,10 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
// Composant Caract<EFBFBD>ristique
|
||||
export const Characteristic = ({ label, value }) => {
|
||||
return (
|
||||
<div className="characteristic">
|
||||
<strong>{label}:</strong> {value}
|
||||
</div>
|
||||
);
|
||||
};
|
11
src/components/parts/description.jsx
Normal file
11
src/components/parts/description.jsx
Normal 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>
|
||||
);
|
||||
};
|
46
src/components/rooms/room-detail.jsx
Normal file
46
src/components/rooms/room-detail.jsx
Normal file
@ -0,0 +1,46 @@
|
||||
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 <EFBFBD> jour lorsqu'une chambre est s<EFBFBD>lectionn<EFBFBD>e
|
||||
const handleRoomClick = () => {
|
||||
setIsUpdateFormVisible(true);
|
||||
};
|
||||
|
||||
// Afficher le formulaire de cr<EFBFBD>ation lorsqu'on revient en arri<EFBFBD>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>
|
||||
);
|
||||
};
|
@ -1,18 +1,9 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import axios from 'axios'; // Assurez-vous que le chemin d'importation soit correct
|
||||
import { ItemBox } from './ItemBox';
|
||||
import { Space, DatePicker, Row, Col, Select, Input, InputNumber } from 'antd';
|
||||
import '../../assets/styles/item-page.css'
|
||||
import "../../assets/styles/room-list.css";
|
||||
import { RoomBox } from "../../components/rooms/roomBox";
|
||||
import { formatRoomStats } from "../../api/room";
|
||||
|
||||
|
||||
|
||||
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<EFBFBD>es
|
||||
const chunkArray = (arr, size) => {
|
||||
const chunkedArr = [];
|
||||
for (let i = 0; i < arr.length; i += size) {
|
||||
@ -22,25 +13,31 @@ const chunkArray = (arr, size) => {
|
||||
};
|
||||
|
||||
// Composant d'affichage de la page
|
||||
export const RoomList = (roomsParam) => {
|
||||
export const RoomList = ({ statsParam, onRoomClick }) => {
|
||||
const [rooms, setRooms] = useState([]);
|
||||
const [selectedRoom, setSelectedRoom] = useState('all');
|
||||
const [selectedRoom, setSelectedRoom] = useState("all");
|
||||
|
||||
useEffect(() => {
|
||||
setRooms(roomsParam)
|
||||
}, [roomsParam]);
|
||||
useEffect(() => {
|
||||
if (statsParam.rooms) {
|
||||
console.log(statsParam.rooms);
|
||||
let formatedStats = formatRoomStats(statsParam);
|
||||
setRooms(formatedStats.rooms);
|
||||
}
|
||||
}, [statsParam]);
|
||||
|
||||
const handleRoomChange = (value) => {
|
||||
setSelectedRoom(value);
|
||||
const handleRoomClick = (roomId) => {
|
||||
onRoomClick(roomId);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Liste des chambres</h2>
|
||||
<div className="list-container">
|
||||
<div className="room-list">
|
||||
{rooms.forEach((room) => {
|
||||
<roomB
|
||||
}) }
|
||||
</div>
|
||||
{rooms &&
|
||||
rooms.map((room) => (
|
||||
<RoomBox room={room} key={room._id} onRoomClick={handleRoomClick} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
@ -1,23 +1,22 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import '../../assets/styles/itembox.css'
|
||||
import { } from '../item/ItemBox'
|
||||
import React from "react";
|
||||
import "../../assets/styles/room-list.css";
|
||||
import { Description } from "../parts/description";
|
||||
import { Characteristic } from "../parts/characteristic";
|
||||
|
||||
export const RoomBox = ({ room, onRoomClick }) => {
|
||||
const handleBoxClick = () => {
|
||||
onRoomClick(room._id);
|
||||
};
|
||||
|
||||
// Composant Détails du Produit
|
||||
export const RoomBox = ({ name, itemCount, roomPrice, _id }) => {
|
||||
const [roomData, setRoomData] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
setRoomData({name, itemCount, roomPrice, _id})
|
||||
}, [name, itemCount, roomPrice, _id]);
|
||||
|
||||
|
||||
return (
|
||||
<div className="product-details" >
|
||||
<Description title={roomData.name} >
|
||||
<Characteristic label="Nombre d'articles" value={roomData.itemCount} />
|
||||
<Characteristic label="Prix total" value={roomData.roomPrice} />
|
||||
</Description>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div className="room-details" onClick={handleBoxClick}>
|
||||
<Description title={room?.name}>
|
||||
<Characteristic
|
||||
label="Nombre d'articles"
|
||||
value={room?.items_count || "N/A"}
|
||||
/>
|
||||
<Characteristic label="Prix total" value={room?.room_price || "N/A"} />
|
||||
</Description>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,46 +1,53 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import '../assets/styles/room-page.css'
|
||||
import React, { useEffect, useState } from "react";
|
||||
import "../assets/styles/room-page.css";
|
||||
|
||||
import { useAuth } from "../hooks";
|
||||
import { formatRoomStats, getRooms, getRoomStats } from "../api/room";
|
||||
import { usePageTitle } from '../hooks/page-title-context';
|
||||
import RoomStats from '../components/rooms/room-stats';
|
||||
import { getRoomStats } from "../api/room";
|
||||
import { usePageTitle } from "../hooks/page-title-context";
|
||||
import RoomStats from "../components/rooms/room-stats";
|
||||
import { RoomList } from "../components/rooms/room-list";
|
||||
import { RoomDetail } from "../components/rooms/room-detail";
|
||||
|
||||
export const Rooms = () => {
|
||||
const { user } = useAuth();
|
||||
const { setPageTitle } = usePageTitle();
|
||||
const [stats, setStats] = useState({});
|
||||
const { setPageTitle } = usePageTitle();
|
||||
const [stats, setStats] = useState({});
|
||||
const [selectedRoom, setSelectedRoom] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
setPageTitle("Toutes les rooms :");
|
||||
}, [setPageTitle]);
|
||||
|
||||
// Mettre à jour le titre de la page dans le contexte
|
||||
useEffect(() => {
|
||||
setPageTitle("Toutes les rooms :");
|
||||
}, [setPageTitle]);
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const roomsStatsResponse = await getRoomStats();
|
||||
setStats(roomsStatsResponse);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const roomsStatsResponse = await getRoomStats();
|
||||
setStats(roomsStatsResponse);
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const handleRoomClick = (roomId) => {
|
||||
console.log("Clicked room ID:", roomId);
|
||||
setSelectedRoom(roomId);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="manContainer">
|
||||
<div className="topContainer">
|
||||
<div className="statsContainer">
|
||||
<RoomStats statsParam={stats} />
|
||||
|
||||
</div>
|
||||
<div className="listContainer">
|
||||
</div>
|
||||
<div className="topContainer">
|
||||
<div className="statsContainer">
|
||||
<RoomStats statsParam={stats} />
|
||||
</div>
|
||||
<div className="detailContainer">
|
||||
<RoomStats statsParam={stats} />
|
||||
|
||||
<div className="listContainer">
|
||||
<RoomList statsParam={stats} onRoomClick={handleRoomClick}></RoomList>
|
||||
</div>
|
||||
</div>
|
||||
<div className="detailContainer">
|
||||
<RoomDetail
|
||||
selectedRoom={selectedRoom}
|
||||
onBack={handleRoomClick}
|
||||
></RoomDetail>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user