Fix formatting, add types

This commit is contained in:
2025-10-16 10:00:31 +02:00
parent 35c4317925
commit 6d9e307318

View File

@@ -1,18 +1,15 @@
"use client"; "use client";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { TopBar } from "@/components/ui/topbar"; import { TopBar } from "@/components/ui/topbar";
import { RefreshCw } from "lucide-react"; import { RefreshCw } from "lucide-react";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
const API_URL = ""; const API_URL = "";
type User = { type User = {
id: number; id: number;
username: string; username: string;
@@ -31,11 +28,10 @@ type Order = {
type FinalizedSummary = { pickup: string[]; kitchen: string[] }; type FinalizedSummary = { pickup: string[]; kitchen: string[] };
type MenuItem = {
type MenuItem = { id: number;
id: number; category: string;
category: string; name: string;
name: string
}; };
export default function AdminPage() { export default function AdminPage() {
@@ -55,40 +51,40 @@ export default function AdminPage() {
const [lastSummary, setLastSummary] = useState<FinalizedSummary | null>(null); const [lastSummary, setLastSummary] = useState<FinalizedSummary | null>(null);
const auth = (): Record<string, string> => { const auth = (): Record<string, string> => {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
return token ? { Authorization: `Bearer ${token}` } : {}; return token ? { Authorization: `Bearer ${token}` } : {};
}; };
useEffect(() => { useEffect(() => {
fetch(`${API_URL}/api/admin/finalize/time`, { headers: auth() }) fetch(`${API_URL}/api/admin/finalize/time`, { headers: auth() })
.then(r => r.json()) .then((r) => r.json())
.then(data => setFinalizeTime(data.time)); .then((data) => setFinalizeTime(data.time));
}, []); }, []);
useEffect(() => { useEffect(() => {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
if (!token) { if (!token) {
router.push("/auth"); router.push("/auth");
return; return;
} }
fetch(`${API_URL}/api/me`, { fetch(`${API_URL}/api/me`, {
headers: { Authorization: `Bearer ${token}` } headers: { Authorization: `Bearer ${token}` },
}) })
.then(res => res.json()) .then((res) => res.json())
.then(data => { .then((data) => {
if (!data.role || data.role > 1) { if (!data.role || data.role > 1) {
router.push("/landing"); router.push("/landing");
} }
}) })
.catch(() => router.push("/auth")); .catch(() => router.push("/auth"));
}, [router]); }, [router]);
useEffect(() => { useEffect(() => {
fetch(`${API_URL}/api/admin/users`, { headers: auth() }) fetch(`${API_URL}/api/admin/users`, { headers: auth() })
.then(r => r.ok ? r.json() : []) .then((r) => (r.ok ? r.json() : []))
.then(setUsers) .then(setUsers)
.catch(() => setUsers([])); .catch(() => setUsers([]));
}, []); }, []);
useEffect(() => { useEffect(() => {
@@ -97,9 +93,9 @@ export default function AdminPage() {
useEffect(() => { useEffect(() => {
fetch(`${API_URL}/api/admin/menu`, { headers: auth() }) fetch(`${API_URL}/api/admin/menu`, { headers: auth() })
.then((res) => res.json()) .then((res) => res.json())
.then((data: MenuItem[]) => setMenuItems(data || [])) .then((data: MenuItem[]) => setMenuItems(data || []))
.catch(() => setMenuItems([])); .catch(() => setMenuItems([]));
}, []); }, []);
useEffect(() => { useEffect(() => {
@@ -108,15 +104,17 @@ export default function AdminPage() {
async function refreshOrders() { async function refreshOrders() {
try { try {
const res = await fetch(`${API_URL}/api/admin/orders`, { headers: auth() }); const res = await fetch(`${API_URL}/api/admin/orders`, {
if (res.ok) { headers: auth(),
});
if (res.ok) {
const data: Order[] = await res.json(); const data: Order[] = await res.json();
setOrders(data || []); setOrders(data || []);
} else { } else {
setOrders([]); setOrders([]);
} }
} catch { } catch {
setOrders([]); setOrders([]);
} }
} }
@@ -128,9 +126,13 @@ export default function AdminPage() {
async function addMenuItem() { async function addMenuItem() {
await fetch(`${API_URL}/api/admin/menu`, { await fetch(`${API_URL}/api/admin/menu`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json", ...auth() }, headers: { "Content-Type": "application/json", ...auth() },
body: JSON.stringify({ action: "add", category: newCategory, name: newItem }), body: JSON.stringify({
action: "add",
category: newCategory,
name: newItem,
}),
}); });
setNewItem(""); setNewItem("");
await refreshMenu(); await refreshMenu();
@@ -139,9 +141,13 @@ export default function AdminPage() {
async function updateMenuItem() { async function updateMenuItem() {
if (!editingItem) return; if (!editingItem) return;
await fetch(`${API_URL}/api/admin/menu`, { await fetch(`${API_URL}/api/admin/menu`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json", ...auth() }, headers: { "Content-Type": "application/json", ...auth() },
body: JSON.stringify({ action: "update", id: editingItem.id, name: editingItem.name }), body: JSON.stringify({
action: "update",
id: editingItem.id,
name: editingItem.name,
}),
}); });
setEditingItem(null); setEditingItem(null);
await refreshMenu(); await refreshMenu();
@@ -149,47 +155,55 @@ export default function AdminPage() {
async function deleteMenuItem(id: number) { async function deleteMenuItem(id: number) {
await fetch(`${API_URL}/api/admin/menu`, { await fetch(`${API_URL}/api/admin/menu`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json", ...auth() }, headers: { "Content-Type": "application/json", ...auth() },
body: JSON.stringify({ action: "delete", id }), body: JSON.stringify({ action: "delete", id }),
}); });
await refreshMenu(); await refreshMenu();
} }
async function deleteUser(id: number) { async function deleteUser(id: number) {
if (!confirm("Biztos törlöd a felhasználót?")) return; if (!confirm("Biztos törlöd a felhasználót?")) return;
await fetch(`${API_URL}/api/admin/users/${id}`, { method: "DELETE", headers: auth() }); await fetch(`${API_URL}/api/admin/users/${id}`, {
method: "DELETE",
headers: auth(),
});
setUsers((prev) => prev.filter((u) => u.id !== id)); setUsers((prev) => prev.filter((u) => u.id !== id));
} }
async function updateUser(id: number) { async function updateUser(id: number) {
const body: any = {}; const body: {
username?: string;
password?: string;
role?: number;
} = {};
if (newUsername) body.username = newUsername; if (newUsername) body.username = newUsername;
if (newPassword) body.password = newPassword; if (newPassword) body.password = newPassword;
if (newRole !== null) body.role = newRole; if (newRole !== null) body.role = newRole;
await fetch(`${API_URL}/api/admin/users/${id}`, { await fetch(`${API_URL}/api/admin/users/${id}`, {
method: "PUT", method: "PUT",
headers: { "Content-Type": "application/json", ...auth() }, headers: { "Content-Type": "application/json", ...auth() },
body: JSON.stringify(body), body: JSON.stringify(body),
}); });
setUsers((prev) => setUsers((prev) =>
prev.map((u) => prev.map((u) =>
u.id === id ? { ...u, username: body.username || u.username } : u u.id === id ? { ...u, username: body.username || u.username } : u
) )
); );
setUsers((prev) => setUsers((prev) =>
prev.map((u) => prev.map((u) =>
u.id === id u.id === id
? { ? {
...u, ...u,
username: body.username ?? u.username, username: body.username ?? u.username,
role: body.role ?? u.role, role: body.role ?? u.role,
} }
: u : u
) )
); );
setEditing(null); setEditing(null);
@@ -200,17 +214,17 @@ export default function AdminPage() {
function toggleSelect(id: number) { function toggleSelect(id: number) {
setSelectedOrders((prev) => setSelectedOrders((prev) =>
prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id] prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]
); );
} }
async function updateStatusSelected(status: string) { async function updateStatusSelected(status: string) {
for (const id of selectedOrders) { for (const id of selectedOrders) {
await fetch(`${API_URL}/api/admin/orders/${id}/status`, { await fetch(`${API_URL}/api/admin/orders/${id}/status`, {
method: "PUT", method: "PUT",
headers: { "Content-Type": "application/json", ...auth() }, headers: { "Content-Type": "application/json", ...auth() },
body: JSON.stringify({ status }), body: JSON.stringify({ status }),
}); });
} }
setSelectedOrders([]); setSelectedOrders([]);
@@ -219,14 +233,17 @@ export default function AdminPage() {
async function deleteSelected() { async function deleteSelected() {
await Promise.all( await Promise.all(
selectedOrders.map(async (id) => { selectedOrders.map(async (id) => {
await fetch(`${API_URL}/api/admin/orders/${id}/status`, { await fetch(`${API_URL}/api/admin/orders/${id}/status`, {
method: "PUT", method: "PUT",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status: "history" }), body: JSON.stringify({ status: "history" }),
}); });
await fetch(`${API_URL}/api/admin/orders/${id}`, { method: "DELETE", headers: auth() }); await fetch(`${API_URL}/api/admin/orders/${id}`, {
}) method: "DELETE",
headers: auth(),
});
})
); );
const res = await fetch(`${API_URL}/api/admin/orders`); const res = await fetch(`${API_URL}/api/admin/orders`);
setSelectedOrders([]); setSelectedOrders([]);
@@ -235,14 +252,16 @@ export default function AdminPage() {
async function saveFinalizeTime() { async function saveFinalizeTime() {
await fetch(`${API_URL}/api/admin/finalize/time`, { await fetch(`${API_URL}/api/admin/finalize/time`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json", ...auth() }, headers: { "Content-Type": "application/json", ...auth() },
body: JSON.stringify({ time: finalizeTime }), body: JSON.stringify({ time: finalizeTime }),
}); });
} }
async function loadLastSummary() { async function loadLastSummary() {
const res = await fetch(`${API_URL}/api/mod/finalize/last`, { headers: auth() }); const res = await fetch(`${API_URL}/api/mod/finalize/last`, {
headers: auth(),
});
const data = await res.json(); const data = await res.json();
if (data.status !== "none") setLastSummary(data); if (data.status !== "none") setLastSummary(data);
else setLastSummary(null); else setLastSummary(null);
@@ -250,341 +269,360 @@ export default function AdminPage() {
async function triggerFinalizeNow() { async function triggerFinalizeNow() {
await fetch(`${API_URL}/api/admin/finalize/now`, { await fetch(`${API_URL}/api/admin/finalize/now`, {
method: "POST", method: "POST",
headers: auth(), headers: auth(),
}); });
await loadLastSummary(); await loadLastSummary();
} }
return ( return (
<main className="relative flex flex-col min-h-screen items-center p-4 pb-16 space-y-6"> <main className="relative flex flex-col min-h-screen items-center p-4 pb-16 space-y-6">
<TopBar /> <TopBar />
<div className="h-10" /> <div className="h-10" />
<h1 className="text-white text-3xl sm:text-4xl font-bold text-center"> <h1 className="text-white text-3xl sm:text-4xl font-bold text-center">
Users Users
</h1> </h1>
<div className="w-full max-w-3xl"> <div className="w-full max-w-3xl">
<div className="glass-panel max-h-[400px] overflow-y-auto space-y-4 p-4"> <div className="glass-panel max-h-[400px] overflow-y-auto space-y-4 p-4">
{users.length > 0 ? ( {users.length > 0 ? (
users.map((u) => ( users.map((u) => (
<Card <Card
key={u.id} key={u.id}
className="glass-panel flex flex-col sm:flex-row sm:items-center sm:justify-between p-4 gap-3" className="glass-panel flex flex-col sm:flex-row sm:items-center sm:justify-between p-4 gap-3"
> >
{editing === u.id ? ( {editing === u.id ? (
<div className="flex flex-col sm:flex-row gap-2 w-full items-center justify-between"> <div className="flex flex-col sm:flex-row gap-2 w-full items-center justify-between">
{/* Keep current username visible */} {/* Keep current username visible */}
<span className="text-white font-medium"> <span className="text-white font-medium">
{u.username} <span className="text-sm text-white/60">(role: {u.role})</span> {u.username}{" "}
</span> <span className="text-sm text-white/60">
(role: {u.role})
</span>
</span>
{/* Inputs + buttons */} {/* Inputs + buttons */}
<div className="flex flex-col sm:flex-row gap-2"> <div className="flex flex-col sm:flex-row gap-2">
<Input <Input
placeholder="New Username" placeholder="New Username"
value={newUsername} value={newUsername}
onChange={(e) => setNewUsername(e.target.value)} onChange={(e) => setNewUsername(e.target.value)}
className="bg-white/70 text-black sm:w-40 border-white" className="bg-white/70 text-black sm:w-40 border-white"
/> />
<Input <Input
type="password" type="password"
placeholder="New Password" placeholder="New Password"
value={newPassword} value={newPassword}
onChange={(e) => setNewPassword(e.target.value)} onChange={(e) => setNewPassword(e.target.value)}
className="bg-white/70 text-black sm:w-40 border-white" className="bg-white/70 text-black sm:w-40 border-white"
/> />
<Input <Input
type="number" type="number"
placeholder="Role" placeholder="Role"
value={newRole !== null ? newRole : ""} value={newRole !== null ? newRole : ""}
onChange={(e) => setNewRole(Number(e.target.value))} onChange={(e) => setNewRole(Number(e.target.value))}
className="bg-white/70 text-black sm:w-20 border-white" className="bg-white/70 text-black sm:w-20 border-white"
/> />
<div className="flex gap-2"> <div className="flex gap-2">
<Button <Button
size="sm" size="sm"
onClick={() => updateUser(u.id)} onClick={() => updateUser(u.id)}
className="bg-black/35 hover:bg-green-700/35 px-3" className="bg-black/35 hover:bg-green-700/35 px-3"
> >
Save Save
</Button> </Button>
<Button <Button
size="sm" size="sm"
onClick={() => setEditing(null)} onClick={() => setEditing(null)}
className="bg-black/35 hover:bg-blue-700/35 px-3" className="bg-black/35 hover:bg-blue-700/35 px-3"
> >
Cancel Cancel
</Button> </Button>
</div> </div>
</div>
</div> </div>
) : ( </div>
<> ) : (
<span className="text-white font-medium"> <>
{u.username} <span className="text-sm text-white/60">(role: {u.role})</span> <span className="text-white font-medium">
</span> {u.username}{" "}
<div className="flex gap-2"> <span className="text-sm text-white/60">
<Button (role: {u.role})
size="sm" </span>
onClick={() => setEditing(u.id)} </span>
className="bg-black/35 hover:bg-blue-700/35 px-3" <div className="flex gap-2">
> <Button
Edit size="sm"
</Button> onClick={() => setEditing(u.id)}
<Button className="bg-black/35 hover:bg-blue-700/35 px-3"
size="sm" >
onClick={() => deleteUser(u.id)} Edit
className="bg-red-600 hover:bg-red-700 px-3" </Button>
> <Button
Delete size="sm"
</Button> onClick={() => deleteUser(u.id)}
</div> className="bg-red-600 hover:bg-red-700 px-3"
</> >
)} Delete
</Button>
</Card> </div>
</>
)}
</Card>
)) ))
) : ( ) : (
<p className="text-white/70 text-center">No registered users.</p> <p className="text-white/70 text-center">No registered users.</p>
)} )}
</div>
</div> </div>
</div>
{/* Orders panel */} {/* Orders panel */}
<h2 className="text-white text-2xl sm:text-3xl font-semibold text-center mt-8"> <h2 className="text-white text-2xl sm:text-3xl font-semibold text-center mt-8">
Orders Orders
</h2> </h2>
<div className="glass-panel w-full max-w-3xl"> <div className="glass-panel w-full max-w-3xl">
<div className="max-h-[400px] overflow-y-auto space-y-2 p-4"> <div className="max-h-[400px] overflow-y-auto space-y-2 p-4">
{orders.length > 0 ? ( {orders.length > 0 ? (
orders.map((o) => ( orders.map((o) => (
<Card <Card
key={o.id} key={o.id}
onClick={() => toggleSelect(o.id)} onClick={() => toggleSelect(o.id)}
className={`glass-panel p-3 cursor-pointer ${ className={`glass-panel p-3 cursor-pointer ${
selectedOrders.includes(o.id) ? "ring-2 ring-orange-400" : "" selectedOrders.includes(o.id) ? "ring-2 ring-orange-400" : ""
}`} }`}
> >
<CardContent className="text-white flex flex-col sm:flex-row sm:justify-between sm:items-center gap-2"> <CardContent className="text-white flex flex-col sm:flex-row sm:justify-between sm:items-center gap-2">
<div> <div>
<strong>{o.username}:</strong>{" "} <strong>{o.username}:</strong>{" "}
{o.soup && o.soup.trim() !== "" ? `${o.soup}, ` : ""} {o.soup && o.soup.trim() !== "" ? `${o.soup}, ` : ""}
{o.main}, {o.side} {o.main}, {o.side}
<span <span
className={`ml-2 px-2 py-0.5 rounded text-xs ${ className={`ml-2 px-2 py-0.5 rounded text-xs ${
o.status === "active" o.status === "active"
? "bg-green-600/70" ? "bg-green-600/70"
: o.status === "history" : o.status === "history"
? "bg-gray-600/70" ? "bg-gray-600/70"
: "bg-red-600/70" : "bg-red-600/70"
}`} }`}
> >
{o.status} {o.status}
</span> </span>
</div> </div>
<span className="text-sm text-white/60"> <span className="text-sm text-white/60">
{new Date(o.created_at).toLocaleString()} {new Date(o.created_at).toLocaleString()}
</span> </span>
</CardContent> </CardContent>
</Card> </Card>
)) ))
) : ( ) : (
<p className="text-white/70 text-center">No orders to display.</p> <p className="text-white/70 text-center">No orders to display.</p>
)} )}
</div> </div>
{/* Action buttons */} {/* Action buttons */}
<div className="flex gap-3 justify-center mt-4 pb-4"> <div className="flex gap-3 justify-center mt-4 pb-4">
<Button <Button
size="sm" size="sm"
variant="ghost" variant="ghost"
onClick={refreshOrders} onClick={refreshOrders}
className="text-white hover:bg-blue-700/40 rounded-full p-2" className="text-white hover:bg-blue-700/40 rounded-full p-2"
title="Frissítés" title="Frissítés"
> >
<RefreshCw className="h-4 w-4" /> <RefreshCw className="h-4 w-4" />
</Button> </Button>
<Button <Button
size="sm" size="sm"
className="bg-green-600 hover:bg-green-700 px-4" className="bg-green-600 hover:bg-green-700 px-4"
onClick={() => updateStatusSelected("active")} onClick={() => updateStatusSelected("active")}
> >
Set Active Set Active
</Button> </Button>
<Button <Button
size="sm" size="sm"
className="bg-gray-600 hover:bg-gray-700 px-4" className="bg-gray-600 hover:bg-gray-700 px-4"
onClick={() => updateStatusSelected("history")} onClick={() => updateStatusSelected("history")}
> >
Set History Set History
</Button> </Button>
<Button <Button
size="sm" size="sm"
className="bg-red-600 hover:bg-red-700 px-4" className="bg-red-600 hover:bg-red-700 px-4"
onClick={deleteSelected} onClick={deleteSelected}
> >
Delete Delete
</Button> </Button>
</div> </div>
</div> </div>
{/* Menu Management Panel */}
<h2 className="text-white text-2xl sm:text-3xl font-semibold text-center mt-8">
Menu Editor
</h2>
<div className="glass-panel w-full max-w-6xl p-4"> {/* Menu Management Panel */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6"> <h2 className="text-white text-2xl sm:text-3xl font-semibold text-center mt-8">
{["soup", "main", "side"].map((cat) => ( Menu Editor
<div key={cat} className="flex flex-col"> </h2>
<h3 className="text-center text-xl font-semibold text-white mb-2">
{cat === "soup" ? "Soups" : cat === "main" ? "Main courses" : "Sides"}
</h3>
<div className="max-h-[300px] overflow-y-auto space-y-2"> <div className="glass-panel w-full max-w-6xl p-4">
{menuItems.filter((i) => i.category === cat).map((item) => ( <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card {["soup", "main", "side"].map((cat) => (
key={item.id} <div key={cat} className="flex flex-col">
className="glass-panel flex flex-col lg:flex-row md:items-center sm:justify-between p-2 gap-2" <h3 className="text-center text-xl font-semibold text-white mb-2">
> {cat === "soup"
{editingItem?.id === item.id ? ( ? "Soups"
<div className="flex flex-col lg:flex-row gap-2 w-full items-center justify-between"> : cat === "main"
<Input ? "Main courses"
value={editingItem.name} : "Sides"}
onChange={(e) => </h3>
setEditingItem({ ...editingItem, name: e.target.value })
}
className="bg-white/70 text-black sm:w-40 border-white"
/>
<div className="flex gap-2">
<Button
size="sm"
onClick={updateMenuItem}
className="bg-green-600 hover:bg-green-700 px-3"
>
Save
</Button>
<Button
size="sm"
onClick={() => setEditingItem(null)}
className="bg-gray-600 hover:bg-gray-700 px-3"
>
Cancel
</Button>
</div>
</div>
) : (
<>
<span className="text-white font-medium">{item.name}</span>
<div className="flex gap-2">
<Button
size="sm"
onClick={() => setEditingItem(item)}
className="bg-black/35 hover:bg-blue-700/35 px-3"
>
Edit
</Button>
<Button
size="sm"
onClick={() => deleteMenuItem(item.id)}
className="bg-red-600 hover:bg-red-700 px-3"
>
Del
</Button>
</div>
</>
)}
</Card>
))}
</div>
{/* Add new item for this category */} <div className="max-h-[300px] overflow-y-auto space-y-2">
<div className="flex flex-col sm:flex-row gap-2 mt-3"> {menuItems
<Input .filter((i) => i.category === cat)
placeholder={`Új ${cat === "soup" ? "Soup" : cat === "main" ? "Main" : "Side"}`} .map((item) => (
value={newCategory === cat ? newItem : ""} <Card
onChange={(e) => { key={item.id}
setNewItem(e.target.value); className="glass-panel flex flex-col lg:flex-row md:items-center sm:justify-between p-2 gap-2"
setNewCategory(cat);
}}
className="bg-white/70 text-black sm:w-2/3 border-white"
/>
<Button
size="sm"
onClick={addMenuItem}
className="bg-green-600 hover:bg-green-700 px-4"
> >
Add {editingItem?.id === item.id ? (
</Button> <div className="flex flex-col lg:flex-row gap-2 w-full items-center justify-between">
</div> <Input
</div> value={editingItem.name}
))} onChange={(e) =>
</div> setEditingItem({
</div> ...editingItem,
name: e.target.value,
})
}
className="bg-white/70 text-black sm:w-40 border-white"
/>
<div className="flex gap-2">
<Button
size="sm"
onClick={updateMenuItem}
className="bg-green-600 hover:bg-green-700 px-3"
>
Save
</Button>
<Button
size="sm"
onClick={() => setEditingItem(null)}
className="bg-gray-600 hover:bg-gray-700 px-3"
>
Cancel
</Button>
</div>
</div>
) : (
<>
<span className="text-white font-medium">
{item.name}
</span>
<div className="flex gap-2">
<Button
size="sm"
onClick={() => setEditingItem(item)}
className="bg-black/35 hover:bg-blue-700/35 px-3"
>
Edit
</Button>
<Button
size="sm"
onClick={() => deleteMenuItem(item.id)}
className="bg-red-600 hover:bg-red-700 px-3"
>
Del
</Button>
</div>
</>
)}
</Card>
))}
</div>
<h2 className="text-white text-2xl sm:text-3xl font-semibold text-center mt-8"> {/* Add new item for this category */}
Order Finalization <div className="flex flex-col sm:flex-row gap-2 mt-3">
</h2> <Input
placeholder={`Új ${
<div className="glass-panel flex flex-col sm:items-center w-full max-w-3xl p-4 space-y-4"> cat === "soup" ? "Soup" : cat === "main" ? "Main" : "Side"
<div className="flex flex-col sm:flex-row sm:items-center gap-3"> }`}
<input value={newCategory === cat ? newItem : ""}
type="time" onChange={(e) => {
value={finalizeTime} setNewItem(e.target.value);
onChange={(e) => setFinalizeTime(e.target.value)} setNewCategory(cat);
className="bg-white/70 text-black rounded px-2 py-1 border border-white w-full sm:w-40" }}
className="bg-white/70 text-black sm:w-2/3 border-white"
/> />
<Button <Button
onClick={saveFinalizeTime} size="sm"
className="bg-green-600 hover:bg-green-700 px-4 w-full sm:w-auto" onClick={addMenuItem}
className="bg-green-600 hover:bg-green-700 px-4"
> >
Save Time Add
</Button>
<Button
onClick={triggerFinalizeNow}
className="bg-red-600 hover:bg-red-700 px-4 w-full sm:w-auto"
>
Finalize Orders Now
</Button> </Button>
</div>
</div>
))}
</div>
</div>
<h2 className="text-white text-2xl sm:text-3xl font-semibold text-center mt-8">
Order Finalization
</h2>
<div className="glass-panel flex flex-col sm:items-center w-full max-w-3xl p-4 space-y-4">
<div className="flex flex-col sm:flex-row sm:items-center gap-3">
<input
type="time"
value={finalizeTime}
onChange={(e) => setFinalizeTime(e.target.value)}
className="bg-white/70 text-black rounded px-2 py-1 border border-white w-full sm:w-40"
/>
<Button
onClick={saveFinalizeTime}
className="bg-green-600 hover:bg-green-700 px-4 w-full sm:w-auto"
>
Save Time
</Button>
<Button
onClick={triggerFinalizeNow}
className="bg-red-600 hover:bg-red-700 px-4 w-full sm:w-auto"
>
Finalize Orders Now
</Button>
</div>
</div>
{/* Finalized Order Summary Panel */}
<h2 className="text-white text-2xl sm:text-3xl font-semibold text-center mt-8">
Legutóbbi összesítés
</h2>
<div className="glass-panel w-full max-w-4xl p-4 space-y-4">
{lastSummary ? (
<>
<div>
<h3 className="text-xl font-semibold text-white mb-2">
Átvételi nézet
</h3>
<ul className="list-disc list-inside text-white space-y-1">
{lastSummary.pickup.map((line, idx) => (
<li key={idx}>{line}</li>
))}
</ul>
</div> </div>
</div> <div>
<h3 className="text-xl font-semibold text-white mb-2">
{/* Finalized Order Summary Panel */} Konyha nézet
<h2 className="text-white text-2xl sm:text-3xl font-semibold text-center mt-8"> </h3>
Legutóbbi összesítés <ul className="list-disc list-inside text-white space-y-1">
</h2> {lastSummary.kitchen.map((line, idx) => (
<li key={idx}>{line}</li>
<div className="glass-panel w-full max-w-4xl p-4 space-y-4"> ))}
{lastSummary ? ( </ul>
<> </div>
<div> </>
<h3 className="text-xl font-semibold text-white mb-2">Átvételi nézet</h3> ) : (
<ul className="list-disc list-inside text-white space-y-1"> <p className="text-white italic">Nincs elérhető összesítés.</p>
{lastSummary.pickup.map((line, idx) => ( )}
<li key={idx}>{line}</li> </div>
))}
</ul>
</div>
<div>
<h3 className="text-xl font-semibold text-white mb-2">Konyha nézet</h3>
<ul className="list-disc list-inside text-white space-y-1">
{lastSummary.kitchen.map((line, idx) => (
<li key={idx}>{line}</li>
))}
</ul>
</div>
</>
) : (
<p className="text-white italic">Nincs elérhető összesítés.</p>
)}
</div>
</main> </main>
); );
} }