Compare commits
2 Commits
68cd3397d4
...
4cf9069bf2
Author | SHA1 | Date | |
---|---|---|---|
|
4cf9069bf2 | ||
|
2868efcda4 |
1618
package-lock.json
generated
1618
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,35 +1,37 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Col, Row } from "antd";
|
import { Col, Row } from "antd";
|
||||||
import '../assets/styles/diagram.css'
|
import "../assets/styles/diagram.css";
|
||||||
|
|
||||||
|
|
||||||
const Diagram = ({ data }) => {
|
const Diagram = ({ data }) => {
|
||||||
const [diagramData, setDiagramData] = useState(data);
|
const [diagramData, setDiagramData] = useState(data);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDiagramData(data);
|
setDiagramData(data);
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
const maxValue = Math.max(...diagramData.map(item => item.value));
|
const maxValue = Math.max(...diagramData.map((item) => item.value));
|
||||||
|
|
||||||
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 }) => {
|
||||||
// Appliquer l'échelle logarithmique à la valeur
|
// Appliquer l'<EFBFBD>chelle logarithmique <EFBFBD> la valeur
|
||||||
const scaledValue = Math.log(value + 1); // Ajouter 1 pour éviter le logarithme de zéro
|
const scaledValue = Math.log(value + 1); // Ajouter 1 pour <EFBFBD>viter le logarithme de z<EFBFBD>ro
|
||||||
const scaledMaxValue = Math.log(maxValue + 1);
|
const scaledMaxValue = Math.log(maxValue + 1);
|
||||||
return (
|
return (
|
||||||
<div key={name} className="row-container">
|
<div key={name} className="row-container">
|
||||||
<div className="label">{name}</div>
|
<div className="label">{name}</div>
|
||||||
<div className="row" style={{ width: `${(scaledValue / scaledMaxValue) * 100}%` }}>
|
<div
|
||||||
<div className="value">{value}</div>
|
className="row"
|
||||||
</div>
|
style={{ width: `${(scaledValue / scaledMaxValue) * 100}%` }}
|
||||||
</div>
|
>
|
||||||
);
|
<div className="value">{value}</div>
|
||||||
})}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Diagram;
|
export default Diagram;
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Form, Input, InputNumber, Button, Select } from "antd";
|
import { Form, Input, InputNumber, Button, Select, DatePicker } from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
const dateFormat = "YYYY-MM-DD";
|
||||||
|
|
||||||
export const FormCreateItem = () => {
|
export const FormCreateItem = ({ onClose }) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [rooms, setRooms] = useState([]);
|
const [rooms, setRooms] = useState([]);
|
||||||
|
|
||||||
@ -31,6 +32,8 @@ export const FormCreateItem = () => {
|
|||||||
values,
|
values,
|
||||||
);
|
);
|
||||||
console.log(response.data);
|
console.log(response.data);
|
||||||
|
// Fermer la fenêtre modale après soumission réussie
|
||||||
|
onClose();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
@ -58,7 +61,7 @@ export const FormCreateItem = () => {
|
|||||||
<InputNumber />
|
<InputNumber />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="Purchase Date" name="purchaseDate">
|
<Form.Item label="Purchase Date" name="purchaseDate">
|
||||||
<Input />
|
<DatePicker format={dateFormat} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="Description" name="description">
|
<Form.Item label="Description" name="description">
|
||||||
<TextArea rows={4} />
|
<TextArea rows={4} />
|
||||||
|
@ -3,113 +3,125 @@ 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 } from "../../api/item";
|
||||||
import moment from 'moment';
|
import moment from "moment";
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
|
|
||||||
function formatItem(itemObj) {
|
function formatItem(itemObj) {
|
||||||
const {_id,brand,model,room,price,purchaseDate,description,categories,createdAt,updatedAt,__v,link} = itemObj
|
const {
|
||||||
const formattedPurchaseDate = typeof purchaseDate === 'string' ? new Date(purchaseDate) : purchaseDate;
|
_id,
|
||||||
|
brand,
|
||||||
|
model,
|
||||||
|
room,
|
||||||
|
price,
|
||||||
|
purchaseDate,
|
||||||
|
description,
|
||||||
|
categories,
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
__v,
|
||||||
|
link,
|
||||||
|
} = itemObj;
|
||||||
|
const formattedPurchaseDate =
|
||||||
|
typeof purchaseDate === "string" ? new Date(purchaseDate) : purchaseDate;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_id,
|
_id,
|
||||||
brand,
|
brand,
|
||||||
model,
|
model,
|
||||||
room,
|
room,
|
||||||
price,
|
price,
|
||||||
purchaseDate: formattedPurchaseDate,
|
purchaseDate: formattedPurchaseDate,
|
||||||
description,
|
description,
|
||||||
categories,
|
categories,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
__v,
|
__v,
|
||||||
link
|
link,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FormUpdateItem = ({ itemId }) => {
|
export const FormUpdateItem = ({ itemId, onClose }) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [rooms, setRooms] = useState([]);
|
const [rooms, setRooms] = useState([]);
|
||||||
const [item, setItem] = useState(null)
|
const [item, setItem] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
const roomsResponse = await getRooms();
|
const roomsResponse = await getRooms();
|
||||||
setRooms(roomsResponse);
|
setRooms(roomsResponse);
|
||||||
|
|
||||||
const itemResponse = await getItem(itemId);
|
const itemResponse = await getItem(itemId);
|
||||||
console.log(itemResponse)
|
console.log(itemResponse);
|
||||||
setItem(formatItem(itemResponse));
|
setItem(formatItem(itemResponse));
|
||||||
};
|
|
||||||
|
|
||||||
fetchData();
|
|
||||||
}, [itemId]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (item) {
|
|
||||||
form.setFieldsValue({
|
|
||||||
...item,
|
|
||||||
purchaseDate: item.purchaseDate ? moment(item.purchaseDate) : null,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [item, form]);
|
|
||||||
|
|
||||||
const onFinish = async (values) => {
|
|
||||||
try {
|
|
||||||
const response = await axios.put(
|
|
||||||
`${import.meta.env.VITE_API_URL}/item/${item._id}`,
|
|
||||||
values,
|
|
||||||
);
|
|
||||||
console.log(response.data);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const dateFormat = 'YYYY-MM-DD';
|
fetchData();
|
||||||
return (
|
}, [itemId]);
|
||||||
<Form
|
|
||||||
form={form}
|
useEffect(() => {
|
||||||
onFinish={onFinish}
|
if (item) {
|
||||||
initialValues={item} // Initialise le formulaire avec les valeurs de l'élément
|
form.setFieldsValue({
|
||||||
>
|
...item,
|
||||||
<h1>Update Item</h1>
|
purchaseDate: item.purchaseDate ? moment(item.purchaseDate) : null,
|
||||||
<Form.Item label="Brand" name="brand">
|
});
|
||||||
<Input />
|
}
|
||||||
</Form.Item>
|
}, [item, form]);
|
||||||
<Form.Item label="Model" name="model">
|
|
||||||
<Input />
|
const onFinish = async (values) => {
|
||||||
</Form.Item>
|
try {
|
||||||
<Form.Item label="Room" name="room">
|
const response = await axios.put(
|
||||||
<Select placeholder="Select a room">
|
`${import.meta.env.VITE_API_URL}/item/${item._id}`,
|
||||||
{console.log(rooms)}
|
values,
|
||||||
{
|
);
|
||||||
rooms.map((room) => (
|
console.log(response.data);
|
||||||
<Option key={room._id} value={room._id}>
|
// Fermer la fenêtre modale après soumission réussie
|
||||||
{room.name}
|
onClose();
|
||||||
</Option>
|
} catch (error) {
|
||||||
))}
|
console.error(error);
|
||||||
</Select>
|
}
|
||||||
</Form.Item>
|
};
|
||||||
<Form.Item label="Price" name="price">
|
|
||||||
<InputNumber />
|
const dateFormat = "YYYY-MM-DD";
|
||||||
</Form.Item>
|
return (
|
||||||
<Form.Item label="Purchase Date" name="purchaseDate">
|
<Form
|
||||||
<DatePicker
|
form={form}
|
||||||
dateFormat={dateFormat}
|
onFinish={onFinish}
|
||||||
/>
|
initialValues={item} // Initialise le formulaire avec les valeurs de l'élément
|
||||||
</Form.Item>
|
>
|
||||||
<Form.Item label="Description" name="description">
|
<h1>Update Item</h1>
|
||||||
<Input.TextArea rows={4} />
|
<Form.Item label="Brand" name="brand">
|
||||||
</Form.Item>
|
<Input />
|
||||||
<Form.Item>
|
</Form.Item>
|
||||||
<Button type="primary" htmlType="submit">
|
<Form.Item label="Model" name="model">
|
||||||
Submit
|
<Input />
|
||||||
</Button>
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="Room" name="room">
|
||||||
</Form>
|
<Select placeholder="Select a room">
|
||||||
);
|
{console.log(rooms)}
|
||||||
|
{rooms.map((room) => (
|
||||||
|
<Option key={room._id} value={room._id}>
|
||||||
|
{room.name}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="Price" name="price">
|
||||||
|
<InputNumber />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="Purchase Date" name="purchaseDate">
|
||||||
|
<DatePicker dateFormat={dateFormat} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="Description" name="description">
|
||||||
|
<Input.TextArea rows={4} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item>
|
||||||
|
<Button type="primary" htmlType="submit">
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FormUpdateItem;
|
export default FormUpdateItem;
|
||||||
|
@ -1,63 +1,55 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
import '../../assets/styles/modal.css'
|
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 { Description } from "../parts/description";
|
||||||
import {Characteristic } from '../parts/characteristic'
|
import { Characteristic } from "../parts/characteristic";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Composant Détails du Produit
|
// Composant Détails du Produit
|
||||||
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);
|
// Fonction pour ouvrir la fenêtre modale
|
||||||
|
const openModal = () => {
|
||||||
|
setIsModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
// Fonction pour ouvrir la fenêtre modale
|
// Fonction pour fermer la fenêtre modale
|
||||||
const openModal = () => {
|
const closeModal = () => {
|
||||||
setIsModalOpen(true);
|
setIsModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fonction pour fermer la fenêtre modale
|
let productname = brand + " " + model;
|
||||||
const closeModal = () => {
|
let formatedPrice = price + "€";
|
||||||
setIsModalOpen(false);
|
let formatedDate = new Date(purchaseDate).toLocaleDateString("fr-FR");
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
let request = brand + " " + model;
|
||||||
|
|
||||||
|
return (
|
||||||
let productname = brand + " " + model;
|
<div className="product-details">
|
||||||
let formatedPrice = price + "€";
|
<Description title={productname}>
|
||||||
let formatedDate = new Date(purchaseDate).toLocaleDateString('fr-FR');
|
<Image request={request} _id={_id} alt="Product" />
|
||||||
|
<Characteristic label="Model" value={model} />
|
||||||
let request = brand + " " + model
|
<Characteristic label="Brand" value={brand} />
|
||||||
|
<Characteristic label="Purchase Date" value={formatedDate} />
|
||||||
return (
|
<Characteristic label="Price" value={formatedPrice} />
|
||||||
<div className="product-details" >
|
{/* Bouton d'édition pour ouvrir la fenêtre modale */}
|
||||||
<Description title={productname} >
|
<button onClick={openModal}>Edit</button>
|
||||||
<Image request={request} _id={_id} alt="Product" />
|
</Description>
|
||||||
<Characteristic label="Model" value={model} />
|
{/* Fenêtre modale */}
|
||||||
<Characteristic label="Brand" value={brand} />
|
{isModalOpen && (
|
||||||
<Characteristic label="Purchase Date" value={formatedDate} />
|
<div className="modal">
|
||||||
<Characteristic label="Price" value={formatedPrice} />
|
<div className="modal-content">
|
||||||
{/* Bouton d'édition pour ouvrir la fenêtre modale */}
|
<span className="close" onClick={closeModal}>
|
||||||
<button onClick={openModal}>Edit</button>
|
×
|
||||||
</Description>
|
</span>
|
||||||
{/* Fenêtre modale */}
|
<FormUpdateItem itemId={_id}>
|
||||||
{isModalOpen && (
|
{console.log("item ID :" + _id)}
|
||||||
<div className="modal">
|
</FormUpdateItem>
|
||||||
<div className="modal-content">
|
</div>
|
||||||
<span className="close" onClick={closeModal}>×</span>
|
|
||||||
<FormUpdateItem itemId={_id}>{console.log("item ID :" + _id)}</FormUpdateItem>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
)}
|
||||||
};
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
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 axios from "axios";
|
||||||
import { ItemBox } from './ItemBox';
|
import { ItemBox } from "./ItemBox";
|
||||||
import { Space, DatePicker, Row, Col, Select, Input, InputNumber } from 'antd';
|
import { DatePicker, Row, Col, Select, Input, InputNumber } from "antd";
|
||||||
import '../../assets/styles/item-page.css'
|
import "../../assets/styles/item-page.css";
|
||||||
|
import FormCreateItem from "../form/formCreateItem";
|
||||||
|
|
||||||
|
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
const itemsPerPage = 8; // Nombre total d'items par page
|
const itemsPerPage = 8;
|
||||||
const itemsPerRow = 4; // Nombre d'items par rangée
|
const itemsPerRow = 4;
|
||||||
|
|
||||||
// Fonction pour diviser le tableau d'items en rangées
|
|
||||||
const chunkArray = (arr, size) => {
|
const chunkArray = (arr, size) => {
|
||||||
const chunkedArr = [];
|
const chunkedArr = [];
|
||||||
for (let i = 0; i < arr.length; i += size) {
|
for (let i = 0; i < arr.length; i += size) {
|
||||||
@ -21,39 +19,26 @@ const chunkArray = (arr, size) => {
|
|||||||
return chunkedArr;
|
return chunkedArr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Composant d'affichage de la page
|
|
||||||
export const ItemPage = () => {
|
export const ItemPage = () => {
|
||||||
const [items, setItems] = useState([]);
|
const [items, setItems] = useState([]);
|
||||||
const [filteredItems, setFilteredItems] = useState([]); // State pour les items filtrés
|
const [filteredItems, setFilteredItems] = useState([]);
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [filterName, setFilterName] = useState('');
|
const [filterName, setFilterName] = useState("");
|
||||||
const [filterPriceMin, setFilterPriceMin] = useState('');
|
const [filterPriceMin, setFilterPriceMin] = useState("");
|
||||||
const [filterPriceMax, setFilterPriceMax] = useState('');
|
const [filterPriceMax, setFilterPriceMax] = useState("");
|
||||||
const [filterDateRange, setFilterDateRange] = useState([]);
|
const [filterDateRange, setFilterDateRange] = useState([]);
|
||||||
const [selectedRoom, setSelectedRoom] = useState('all'); // State pour la chambre sélectionnée
|
const [selectedRoom, setSelectedRoom] = useState("all");
|
||||||
|
const [rooms, setRooms] = useState([]);
|
||||||
const [rooms, setRooms] = useState([]); // State pour stocker les chambres
|
const [isCreateItemModalOpen, setIsCreateItemModalOpen] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchItems = async () => {
|
const fetchItems = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(
|
const response = await axios.get(
|
||||||
`${import.meta.env.VITE_API_URL}/item`,
|
`${import.meta.env.VITE_API_URL}/item`,
|
||||||
);
|
);
|
||||||
|
|
||||||
//await response.data.forEach(async (item) => {
|
|
||||||
// let cacheUrl = localStorage.getItem(item._id);
|
|
||||||
// if (cacheUrl == null || cacheUrl == "") {
|
|
||||||
// let request = item.brand + " " + item.model
|
|
||||||
// cacheUrl = await searchAndResizeImage(request)
|
|
||||||
// await localStorage.setItem(item._id, cacheUrl)
|
|
||||||
// console.log("mise en cache "+ item.imageUrl)
|
|
||||||
// }
|
|
||||||
// item.imageUrl = cacheUrl;
|
|
||||||
//})
|
|
||||||
setItems(response.data);
|
setItems(response.data);
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -68,98 +53,108 @@ export const ItemPage = () => {
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchItems();
|
fetchItems();
|
||||||
fetchRooms();
|
fetchRooms();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Filtrer les éléments chaque fois que les filtres ou la chambre sélectionnée changent
|
const filtered = items.filter((item) => {
|
||||||
const filtered = items.filter(item => {
|
const matchesRoom = selectedRoom === "all" || item.room === selectedRoom;
|
||||||
// Filtrer par chambre si une chambre est sélectionnée
|
const matchesName =
|
||||||
const matchesRoom = selectedRoom === 'all' || item.room === selectedRoom;
|
item.brand.toLowerCase().includes(filterName.toLowerCase()) ||
|
||||||
// Filtrer par nom (brand ou model)
|
item.model.toLowerCase().includes(filterName.toLowerCase());
|
||||||
const matchesName = item.brand.toLowerCase().includes(filterName.toLowerCase()) ||
|
const matchesPrice =
|
||||||
item.model.toLowerCase().includes(filterName.toLowerCase());
|
(filterPriceMin === "" || item.price >= parseFloat(filterPriceMin)) &&
|
||||||
// Filtrer par prix
|
(filterPriceMax === "" || item.price <= parseFloat(filterPriceMax));
|
||||||
const matchesPrice =
|
const matchesDate =
|
||||||
(filterPriceMin === '' || item.price >= parseFloat(filterPriceMin)) &&
|
filterDateRange.length === 0 ||
|
||||||
(filterPriceMax === '' || item.price <= parseFloat(filterPriceMax));
|
(new Date(item.purchaseDate) >= filterDateRange[0] &&
|
||||||
// Filtrer par date
|
new Date(item.purchaseDate) <= filterDateRange[1]);
|
||||||
const matchesDate = filterDateRange.length === 0 || (
|
|
||||||
new Date(item.purchaseDate) >= filterDateRange[0] &&
|
|
||||||
new Date(item.purchaseDate) <= filterDateRange[1]
|
|
||||||
);
|
|
||||||
return matchesRoom && matchesName && matchesPrice && matchesDate;
|
return matchesRoom && matchesName && matchesPrice && matchesDate;
|
||||||
});
|
});
|
||||||
setFilteredItems(filtered);
|
setFilteredItems(filtered);
|
||||||
}, [items, selectedRoom, filterName, filterPriceMin, filterPriceMax, filterDateRange]);
|
}, [
|
||||||
|
items,
|
||||||
|
selectedRoom,
|
||||||
|
filterName,
|
||||||
|
filterPriceMin,
|
||||||
|
filterPriceMax,
|
||||||
|
filterDateRange,
|
||||||
|
]);
|
||||||
|
|
||||||
const handleNextPage = () => {
|
const handleNextPage = () => {
|
||||||
setCurrentPage(prevPage => prevPage + 1);
|
setCurrentPage((prevPage) => prevPage + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePrevPage = () => {
|
const handlePrevPage = () => {
|
||||||
setCurrentPage(prevPage => prevPage - 1);
|
setCurrentPage((prevPage) => prevPage - 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRoomChange = (value) => {
|
const handleRoomChange = (value) => {
|
||||||
setSelectedRoom(value);
|
setSelectedRoom(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCloseModal = () => {
|
||||||
|
setIsCreateItemModalOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
const chunkedItems = chunkArray(filteredItems, itemsPerRow);
|
const chunkedItems = chunkArray(filteredItems, itemsPerRow);
|
||||||
const startIndex = (currentPage - 1) * (itemsPerPage / itemsPerRow);
|
const startIndex = (currentPage - 1) * (itemsPerPage / itemsPerRow);
|
||||||
const endIndex = startIndex + (itemsPerPage / itemsPerRow);
|
const endIndex = startIndex + itemsPerPage / itemsPerRow;
|
||||||
const rowsToDisplay = chunkedItems.slice(startIndex, endIndex);
|
const rowsToDisplay = chunkedItems.slice(startIndex, endIndex);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="item-container">
|
<div className="item-container">
|
||||||
<div className="filters">
|
<div className="filters">{/* Filters here */}</div>
|
||||||
<div className="filter-group">
|
|
||||||
<label htmlFor="roomSelect">Chambre :</label>
|
{/* Button to open create item modal */}
|
||||||
<Select id="roomSelect" defaultValue="all" style={{ width: 120 }} onChange={handleRoomChange}>
|
<button onClick={() => setIsCreateItemModalOpen(true)}>
|
||||||
<Option value="all">Toutes</Option>
|
Create Item
|
||||||
{rooms.map(room => (
|
</button>
|
||||||
<Option key={room._id} value={room._id}>{room.name}</Option>
|
|
||||||
))}
|
{/* Create item form modal */}
|
||||||
</Select>
|
{isCreateItemModalOpen && (
|
||||||
</div>
|
<div className="modal">
|
||||||
<div className="filter-group">
|
<div className="modal-content">
|
||||||
<label htmlFor="nameInput">Recherche par nom :</label>
|
<span className="close" onClick={handleCloseModal}>
|
||||||
<Input id="nameInput" placeholder="Recherche par nom" value={filterName} onChange={e => setFilterName(e.target.value)} />
|
×
|
||||||
</div>
|
</span>
|
||||||
<div className="filter-group">
|
<FormCreateItem onClose={handleCloseModal} />
|
||||||
<label>Prix :</label>
|
|
||||||
<InputNumber placeholder="Prix min" value={filterPriceMin} onChange={value => setFilterPriceMin(value)} />
|
|
||||||
<span> - </span>
|
|
||||||
<InputNumber placeholder="Prix max" value={filterPriceMax} onChange={value => setFilterPriceMax(value)} />
|
|
||||||
</div>
|
|
||||||
<div className="filter-group">
|
|
||||||
<label>Date d'achat :</label>
|
|
||||||
<RangePicker format="YYYY-MM-DD" onChange={dates => setFilterDateRange(dates)} value={filterDateRange} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="item-list">
|
|
||||||
<Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
|
|
||||||
{rowsToDisplay.map((row, rowIndex) => (
|
|
||||||
<React.Fragment key={rowIndex}>
|
|
||||||
{row.map(item => (
|
|
||||||
<Col className="gutter-row" span={24 / itemsPerRow} key={item._id}>
|
|
||||||
<ItemBox {...item} />
|
|
||||||
</Col>
|
|
||||||
))}
|
|
||||||
</React.Fragment>
|
|
||||||
))}
|
|
||||||
</Row>
|
|
||||||
</div>
|
|
||||||
<div className="pagination">
|
|
||||||
<button onClick={handlePrevPage} disabled={currentPage === 1}>Précédente</button>
|
|
||||||
<span>Page {currentPage}</span>
|
|
||||||
<button onClick={handleNextPage} disabled={endIndex >= chunkedItems.length}>Suivante</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="item-list">
|
||||||
|
<Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
|
||||||
|
{rowsToDisplay.map((row, rowIndex) => (
|
||||||
|
<React.Fragment key={rowIndex}>
|
||||||
|
{row.map((item) => (
|
||||||
|
<Col
|
||||||
|
className="gutter-row"
|
||||||
|
span={24 / itemsPerRow}
|
||||||
|
key={item._id}
|
||||||
|
>
|
||||||
|
<ItemBox {...item} />
|
||||||
|
</Col>
|
||||||
|
))}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="pagination">
|
||||||
|
<button onClick={handlePrevPage} disabled={currentPage === 1}>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<span>Page {currentPage}</span>
|
||||||
|
<button
|
||||||
|
onClick={handleNextPage}
|
||||||
|
disabled={endIndex >= chunkedItems.length}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Menu } from "antd";
|
import { Menu } from "antd";
|
||||||
import { HomeOutlined } from "@ant-design/icons"
|
import { HomeOutlined } from "@ant-design/icons";
|
||||||
import { Home } from "../../pages";
|
import { Home } from "../../pages";
|
||||||
import { getRooms } from "../../api/room";
|
import { getRooms } from "../../api/room";
|
||||||
import { isLoggedIn } from "../../api/authentication"
|
import { isLoggedIn } from "../../api/authentication";
|
||||||
import { Items } from "../../pages/items";
|
import { Items } from "../../pages/items";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
@ -14,11 +14,13 @@ function getItem(key, label) {
|
|||||||
// children,
|
// children,
|
||||||
// label,
|
// label,
|
||||||
// link,
|
// link,
|
||||||
//};
|
//};
|
||||||
var item = <Menu.Item key={key}>
|
var item = (
|
||||||
<Link to="/test">{label}</Link>
|
<Menu.Item key={key}>
|
||||||
</Menu.Item >
|
<Link to="/test">{label}</Link>
|
||||||
return item
|
</Menu.Item>
|
||||||
|
);
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { SubMenu } = Menu;
|
const { SubMenu } = Menu;
|
||||||
@ -26,52 +28,48 @@ const { SubMenu } = Menu;
|
|||||||
// Component
|
// Component
|
||||||
const Navbar = () => {
|
const Navbar = () => {
|
||||||
//Hook calls
|
//Hook calls
|
||||||
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);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
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 = [
|
// Rendu du composant Navbar
|
||||||
<Menu.Item key="0">
|
try {
|
||||||
<Link to="/logout">Login / Logout</Link>
|
return (
|
||||||
</Menu.Item>,
|
<Menu
|
||||||
<Menu.Item key="1" >
|
defaultSelectedKeys={["1"]}
|
||||||
<Link to="/home">Menu Principal</Link>
|
defaultOpenKeys={["sub1"]}
|
||||||
</Menu.Item>,
|
theme="dark"
|
||||||
<Menu.Item key="2" >
|
mode="inline"
|
||||||
<Link to="/items">Tous les articles</Link>
|
>
|
||||||
</Menu.Item>,
|
{items}
|
||||||
<Menu.Item key="3" >
|
</Menu>
|
||||||
<Link to="/rooms">Voir les chambres</Link>
|
);
|
||||||
</Menu.Item>,
|
} 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;
|
export default Navbar;
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
// Composant Caractéristique
|
// Composant Caract<EFBFBD>ristique
|
||||||
export const Characteristic = ({ label, value }) => {
|
export const Characteristic = ({ label, value }) => {
|
||||||
|
return (
|
||||||
return (
|
<div className="characteristic">
|
||||||
<div className="characteristic">
|
<strong>{label}:</strong> {value}
|
||||||
<strong>{label}:</strong> {value}
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
};
|
||||||
};
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
// Composant Description
|
// Composant Description
|
||||||
export const Description = ({ title, children }) => {
|
export const Description = ({ title, children }) => {
|
||||||
return (
|
return (
|
||||||
<div className="description">
|
<div className="description">
|
||||||
<h2 className="text-ellipsis">{title}</h2>
|
<h2 className="text-ellipsis">{title}</h2>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,45 +1,46 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
import { FormCreateRoom } from '../../components/form/formCreateRoom';
|
import { FormCreateRoom } from "../../components/form/formCreateRoom";
|
||||||
//import { RoomUpdateForm } from './RoomUpdateForm';
|
//import { RoomUpdateForm } from './RoomUpdateForm';
|
||||||
|
|
||||||
export const RoomDetail = ({ selectedRoom, onCreateFormSubmit, onUpdateFormSubmit, onBack }) => {
|
export const RoomDetail = ({
|
||||||
const [isUpdateFormVisible, setIsUpdateFormVisible] = useState(false);
|
selectedRoom,
|
||||||
|
onCreateFormSubmit,
|
||||||
|
onUpdateFormSubmit,
|
||||||
|
onBack,
|
||||||
|
}) => {
|
||||||
|
const [isUpdateFormVisible, setIsUpdateFormVisible] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedRoom) {
|
if (selectedRoom) {
|
||||||
setIsUpdateFormVisible(true)
|
setIsUpdateFormVisible(true);
|
||||||
}
|
}
|
||||||
}, [selectedRoom]);
|
}, [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 mise ŕ jour lorsqu'une chambre est sélectionnée
|
// Afficher le formulaire de cr<EFBFBD>ation lorsqu'on revient en arri<EFBFBD>re
|
||||||
const handleRoomClick = () => {
|
const handleBackClick = () => {
|
||||||
setIsUpdateFormVisible(true);
|
setIsUpdateFormVisible(false);
|
||||||
};
|
onBack(null);
|
||||||
|
};
|
||||||
|
|
||||||
// Afficher le formulaire de création lorsqu'on revient en arričre
|
return (
|
||||||
const handleBackClick = () => {
|
<div className="room-detail">
|
||||||
setIsUpdateFormVisible(false);
|
{isUpdateFormVisible ? (
|
||||||
onBack(null);
|
<div>
|
||||||
};
|
<h2>Modifier une chambre</h2>
|
||||||
|
|
||||||
return (
|
<FormCreateRoom onSubmit={onCreateFormSubmit} />
|
||||||
<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>
|
</div>
|
||||||
);
|
) : (
|
||||||
};
|
<div>
|
||||||
|
<h2>Ajouter une chambre</h2>
|
||||||
|
<FormCreateRoom onSubmit={onCreateFormSubmit} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import '../../assets/styles/room-list.css'
|
import "../../assets/styles/room-list.css";
|
||||||
import { RoomBox } from '../../components/rooms/roomBox'
|
import { RoomBox } from "../../components/rooms/roomBox";
|
||||||
import { formatRoomStats } from "../../api/room";
|
import { formatRoomStats } from "../../api/room";
|
||||||
|
|
||||||
|
// Fonction pour diviser le tableau d'items en rang<EFBFBD>es
|
||||||
// Fonction pour diviser le tableau d'items en rangées
|
|
||||||
const chunkArray = (arr, size) => {
|
const chunkArray = (arr, size) => {
|
||||||
const chunkedArr = [];
|
const chunkedArr = [];
|
||||||
for (let i = 0; i < arr.length; i += size) {
|
for (let i = 0; i < arr.length; i += size) {
|
||||||
@ -15,31 +14,30 @@ const chunkArray = (arr, size) => {
|
|||||||
|
|
||||||
// Composant d'affichage de la page
|
// Composant d'affichage de la page
|
||||||
export const RoomList = ({ statsParam, onRoomClick }) => {
|
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(() => {
|
||||||
if (statsParam.rooms) {
|
if (statsParam.rooms) {
|
||||||
console.log(statsParam.rooms)
|
console.log(statsParam.rooms);
|
||||||
let formatedStats = formatRoomStats(statsParam)
|
let formatedStats = formatRoomStats(statsParam);
|
||||||
setRooms(formatedStats.rooms)
|
setRooms(formatedStats.rooms);
|
||||||
}
|
}
|
||||||
}, [statsParam]);
|
}, [statsParam]);
|
||||||
|
|
||||||
|
const handleRoomClick = (roomId) => {
|
||||||
|
onRoomClick(roomId);
|
||||||
|
};
|
||||||
|
|
||||||
const handleRoomClick = (roomId) => {
|
return (
|
||||||
onRoomClick(roomId);
|
<div>
|
||||||
};
|
<h2>Liste des chambres</h2>
|
||||||
|
<div className="list-container">
|
||||||
return (
|
{rooms &&
|
||||||
<div>
|
rooms.map((room) => (
|
||||||
<h2>Liste des chambres</h2>
|
<RoomBox room={room} key={room._id} onRoomClick={handleRoomClick} />
|
||||||
<div className="list-container">
|
))}
|
||||||
{rooms && rooms.map((room) => (
|
</div>
|
||||||
<RoomBox room={room} key={room._id} onRoomClick={handleRoomClick} />
|
</div>
|
||||||
))}
|
);
|
||||||
</div>
|
};
|
||||||
</div>
|
|
||||||
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
import React from 'react';
|
import React from "react";
|
||||||
import '../../assets/styles/room-list.css';
|
import "../../assets/styles/room-list.css";
|
||||||
import { Description } from '../parts/description';
|
import { Description } from "../parts/description";
|
||||||
import { Characteristic } from '../parts/characteristic';
|
import { Characteristic } from "../parts/characteristic";
|
||||||
|
|
||||||
export const RoomBox = ({ room, onRoomClick }) => {
|
export const RoomBox = ({ room, onRoomClick }) => {
|
||||||
|
const handleBoxClick = () => {
|
||||||
|
onRoomClick(room._id);
|
||||||
|
};
|
||||||
|
|
||||||
const handleBoxClick = () => {
|
return (
|
||||||
onRoomClick(room._id);
|
<div className="room-details" onClick={handleBoxClick}>
|
||||||
};
|
<Description title={room?.name}>
|
||||||
|
<Characteristic
|
||||||
return (
|
label="Nombre d'articles"
|
||||||
<div className="room-details" onClick={handleBoxClick}>
|
value={room?.items_count || "N/A"}
|
||||||
<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"} />
|
||||||
<Characteristic label="Prix total" value={room?.room_price || "N/A"} />
|
</Description>
|
||||||
</Description>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
};
|
||||||
};
|
|
||||||
|
@ -1,53 +1,53 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
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 { 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 { RoomList } from "../components/rooms/room-list";
|
||||||
import { RoomDetail } from '../components/rooms/room-detail';
|
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();
|
const [selectedRoom, setSelectedRoom] = useState();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setPageTitle("Toutes les rooms :");
|
||||||
|
}, [setPageTitle]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setPageTitle("Toutes les rooms :");
|
const fetchData = async () => {
|
||||||
}, [setPageTitle]);
|
const roomsStatsResponse = await getRoomStats();
|
||||||
|
setStats(roomsStatsResponse);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchData = async () => {
|
|
||||||
const roomsStatsResponse = await getRoomStats();
|
|
||||||
setStats(roomsStatsResponse);
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchData();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleRoomClick = (roomId) => {
|
|
||||||
console.log('Clicked room ID:', roomId);
|
|
||||||
setSelectedRoom(roomId);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 className="listContainer">
|
|
||||||
<RoomList statsParam={stats} onRoomClick={handleRoomClick}></RoomList>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="detailContainer">
|
<div className="listContainer">
|
||||||
<RoomDetail selectedRoom={selectedRoom} onBack={handleRoomClick}></RoomDetail>
|
<RoomList statsParam={stats} onRoomClick={handleRoomClick}></RoomList>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="detailContainer">
|
||||||
|
<RoomDetail
|
||||||
|
selectedRoom={selectedRoom}
|
||||||
|
onBack={handleRoomClick}
|
||||||
|
></RoomDetail>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user