Skip to content

Commit

Permalink
Merge pull request #80 from Hello-Kitchen/62-orders-tab
Browse files Browse the repository at this point in the history
62 orders tab
  • Loading branch information
JulesGresset authored Jan 16, 2025
2 parents abbe1cc + 8c0b83f commit 8007573
Show file tree
Hide file tree
Showing 10 changed files with 561 additions and 68 deletions.
8 changes: 4 additions & 4 deletions src/Components/CurrentCommand/CurrentCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const Stop = () => (
*/
const Order = ({ order, border, config }) => (
<div className={`w-full h-auto p-2 ${border ? 'border-t border-t-kitchen-yellow' : ''}`}>
{order.plat && order.price && <Food name={order.plat} price={order.price} />}
{order.name && order.price && <Food name={order.name} price={order.price} />}
{order.details && order.details.map((detail, index) => (
<Detail key={index} text={detail} />
))}
Expand Down Expand Up @@ -125,7 +125,7 @@ function Footer({ config, orders, setOrders, setConfig, price, priceLess, payLis
return;
}
let newObj = Object.keys(order).reduce((acc, key) => {
if (key !== "plat" && key !== "price") {
if (key !== "name" && key !== "price") {
acc[key] = order[key];
}
return acc;
Expand All @@ -139,8 +139,8 @@ function Footer({ config, orders, setOrders, setConfig, price, priceLess, payLis

let obj = {
date: new Date().toISOString(),
channel: orders[3].channel,
number: (orders[3].channel === "En salle") ? `Table ${orders[0].nb}` : `${orders[0].nb}`,
channel: orders[2].channel,
number: orders[0].nb,
part: 1,
food_ordered: orderedFood,
served: false,
Expand Down
39 changes: 39 additions & 0 deletions src/Components/OrdersView/FilterButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from "react";

import PropTypes from 'prop-types';

/**
* FilterButton component renders a button with different styles based on its state.
*
* @param {Object} props - The properties object.
* @param {function} props.onClick - The function to call when the button is clicked.
* @param {boolean} props.selected - Indicates if the button is selected.
* @param {string} props.text - The text to display inside the button.
* @returns {JSX.Element} The rendered FilterButton component.
*/
export default function FilterButton({onClick, selected, text}) {
const [hovered, setHovered] = React.useState(false);

return (
<div
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
className={`${selected ?
`bg-kitchen-yellow text-kitchen-blue font-semibold border-kitchen-yellow` :
hovered ?
`bg-kitchen-blue text-kitchen-yellow border-kitchen-blue` :
`bg-white border-kitchen-yellow`
}
border-2 rounded-xl px-3`}
onClick={onClick}
>
{text}
</div>
)
}

FilterButton.propTypes = {
onClick: PropTypes.func.isRequired,
selected: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}
48 changes: 48 additions & 0 deletions src/Components/OrdersView/OrderRow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from "react";

import { IoIosArrowForward } from "react-icons/io";
import PropTypes from 'prop-types';


/**
* OrdersRow component renders a row displaying order details.
*
* @param {Object} props - The properties object.
* @param {string|number} props.number - The order number.
* @param {string} props.channel - The channel through which the order was placed.
* @param {string} props.time - The time when the order was placed.
* @param {string} props.chrono - The duration since the order was opened.
* @returns {JSX.Element} The rendered OrdersRow component.
*/
export default function OrdersRow({ number, channel, time, chrono}) {
return (
<div className="flex flex-row justify-between items-center">
<div>
<div className="flex flex-row">
<div className="text-lg font-semibold pr-1">
{number}
</div>
<div className="text-lg font-medium">
- {channel}
</div>
</div>
<div className="flex flex-row text-sm font-medium text-gray-600">
<div className=" pr-1">
{time}
</div>
<div className="">
- Ouverte depuis {chrono}
</div>
</div>
</div>
<IoIosArrowForward size={25}/>
</div>
)
}

OrdersRow.propTypes = {
number: PropTypes.string.isRequired,
channel: PropTypes.string.isRequired,
time: PropTypes.string.isRequired,
chrono: PropTypes.string.isRequired
}
167 changes: 167 additions & 0 deletions src/Components/OrdersView/OrdersView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import React, { useEffect } from "react";

import OrdersRow from "./OrderRow";
import FilterButton from "./FilterButton";

import PropTypes from 'prop-types';
import { IoSwapHorizontal } from "react-icons/io5";

/**
* OrdersView component displays a list of orders and allows filtering by channel.
*
* @component
* @param {Object} props - The component props.
* @param {function} props.orderSelect - Function to handle order selection.
*
* @returns {JSX.Element} The OrdersView component.
*
* @example
* <OrdersView orderSelect={handleOrderSelect} />
*
* @typedef {Object} Order
* @property {string} id - The unique identifier of the order.
* @property {string} number - The order number or table number.
* @property {string} channel - The channel through which the order was placed.
* @property {string} time - The time the order was placed.
* @property {string} chrono - The elapsed time since the order was placed.
*/
export default function OrdersView({ orderSelect }) {
const [displayPastOrders, setPastDisplayOrders] = React.useState(false);
const [selectedChannel, setSelectedChannel] = React.useState("Tous");
const [orders, setOrders] = React.useState([]);
const [displayedOrders, setDisplayedOrders] = React.useState([]);

const handleChannelChange = () => {
setPastDisplayOrders(!displayPastOrders);
};

useEffect(() => {
fetch(
`http://${process.env.REACT_APP_BACKEND_URL}:${process.env.REACT_APP_BACKEND_PORT}/api/${process.env.REACT_APP_NBR_RESTAURANT}/orders`,
{
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
}
)
.then((response) => {
if (response.status === 401) {
throw new Error("Unauthorized access. Please log in.");
}
return response.json();
})
.then((data) => {
const orders = data.map((order) => {
const time = new Date(order.date);
const chronoMs = Date.now() - time.getTime();
let chronoString = "";
let channel = '';

const hours = Math.floor(chronoMs / (1000 * 60 * 60));
const minutes = Math.floor((chronoMs % (1000 * 60 * 60)) / (1000 * 60));

if (hours > 0) {
chronoString = String(hours).padStart(2, "0") + "h" + String(minutes).padStart(2, "0");
} else {
chronoString = String(minutes).padStart(2, "0") + "m";
}

switch (order.channel) {
case "Sur place":
channel = "Table " + order.number;
break;
case "A emporter":
channel = "N°" + order.number;
break;
default:
channel = order.number;
break;
}

return {
id: order.id,
number: channel,
channel: order.channel,
time: String(time.getHours()).padStart(2, "0") + "h" + String(time.getMinutes()).padStart(2, "0"),
chrono: chronoString,
};
});

setOrders(orders);
console.log(data);
})
.catch((error) => {
console.log(error);
});
}, []);

useEffect(() => {
if (selectedChannel === "Tous") {
setDisplayedOrders(orders);
} else {
setDisplayedOrders(
orders.filter((order) => order.channel === selectedChannel)
);
}
}, [orders, selectedChannel]);

return (
<div className="flex flex-col p-3">
<div className="flex flex-row pb-2 items-center">
<div className="text-2xl font-bold pr-2">
{displayPastOrders ? "Commandes passées" : "Commandes en cours"}
</div>
<IoSwapHorizontal
size={20}
onClick={() => {
handleChannelChange();
}}
/>
</div>
<div className="flex flex-row items-center space-x-1 pb-2">
<div className="text-lg font-semibold pr-2">Canal</div>
<FilterButton
selected={selectedChannel === "Tous"}
text={"Tous"}
onClick={() => setSelectedChannel("Tous")}
/>
<FilterButton
selected={selectedChannel === "Sur place"}
text={"Sur place"}
onClick={() => setSelectedChannel("Sur place")}
/>
<FilterButton
selected={selectedChannel === "A emporter"}
text={"A emporter"}
onClick={() => setSelectedChannel("A emporter")}
/>
<FilterButton
selected={selectedChannel === "LAD"}
text={"LAD"}
onClick={() => setSelectedChannel("LAD")}
/>
</div>
<div className="h-auto flex flex-col space-y-1">
{displayedOrders.map((order) => (
<div key={order.id}>
<div
className="w-full h-1 border-b-[1px] border-black"
/>
<div className="px-2 pt-1" onClick={() => orderSelect(order.id)}>
<OrdersRow
number={order.number}
channel={order.channel}
time={order.time}
chrono={order.chrono}
/>
</div>
</div>
))}
</div>
</div>
);
}

OrdersView.propTypes = {
orderSelect: PropTypes.func.isRequired,
}
Loading

0 comments on commit 8007573

Please sign in to comment.