151 lines
6.2 KiB
TypeScript
151 lines
6.2 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState } from "react";
|
|
import { useMesas } from "@/hooks/useMesas";
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Label } from "@/components/ui/label";
|
|
import { Table as TableIcon, Users, Plus, Trash2 } from "lucide-react";
|
|
import { useToast } from "@/components/ui/toast";
|
|
|
|
export default function MesasPage() {
|
|
const { mesas, loading, updateMesaEstado, addMesa, deleteMesa } = useMesas();
|
|
const { toast } = useToast();
|
|
const [showAddForm, setShowAddForm] = useState(false);
|
|
const [newMesa, setNewMesa] = useState({ numero: "", capacidade: "" });
|
|
|
|
const handleAddMesa = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
const res = await addMesa(parseInt(newMesa.numero), parseInt(newMesa.capacidade));
|
|
if (res.success) {
|
|
setNewMesa({ numero: "", capacidade: "" });
|
|
setShowAddForm(false);
|
|
toast("Mesa adicionada com sucesso!", "success");
|
|
} else {
|
|
toast("Erro ao adicionar mesa.", "error");
|
|
}
|
|
};
|
|
|
|
const handleDelete = async (id: string) => {
|
|
const res = await deleteMesa(id);
|
|
if (res.success) {
|
|
toast("Mesa removida.", "success");
|
|
}
|
|
};
|
|
|
|
const handleUpdateEstado = async (id: string, estado: any) => {
|
|
const res = await updateMesaEstado(id, estado);
|
|
if (res.success) {
|
|
toast(`Estado da mesa atualizado para ${estado}`, "info");
|
|
}
|
|
};
|
|
|
|
const getStatusColor = (estado: string) => {
|
|
switch (estado) {
|
|
case "Ocupada": return "bg-primary text-primary-foreground border-primary";
|
|
case "Reservada": return "bg-amber-500 text-white border-amber-500";
|
|
default: return "bg-muted text-muted-foreground border-border";
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="flex items-center justify-between">
|
|
<h1 className="text-3xl font-display font-bold text-foreground">Estado das Mesas</h1>
|
|
<Button onClick={() => setShowAddForm(!showAddForm)} className="gap-2">
|
|
<Plus className="h-4 w-4" /> Nova Mesa
|
|
</Button>
|
|
</div>
|
|
|
|
{showAddForm && (
|
|
<Card className="border-primary/30 bg-primary/5">
|
|
<CardHeader>
|
|
<CardTitle className="text-lg">Adicionar Nova Mesa</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<form onSubmit={handleAddMesa} className="flex flex-wrap items-end gap-4">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="numero">Número da Mesa</Label>
|
|
<Input
|
|
id="numero"
|
|
type="number"
|
|
value={newMesa.numero}
|
|
onChange={(e) => setNewMesa({...newMesa, numero: e.target.value})}
|
|
required
|
|
className="w-32"
|
|
/>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="capacidade">Capacidade (Lugares)</Label>
|
|
<Input
|
|
id="capacidade"
|
|
type="number"
|
|
value={newMesa.capacidade}
|
|
onChange={(e) => setNewMesa({...newMesa, capacidade: e.target.value})}
|
|
required
|
|
className="w-32"
|
|
/>
|
|
</div>
|
|
<Button type="submit">Criar Mesa</Button>
|
|
<Button type="button" variant="ghost" onClick={() => setShowAddForm(false)}>Cancelar</Button>
|
|
</form>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{loading ? (
|
|
<div className="flex items-center justify-center py-20">
|
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
|
|
</div>
|
|
) : (
|
|
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6">
|
|
{mesas.map((mesa) => (
|
|
<Card key={mesa.id} className="relative group overflow-hidden border-border/50 hover:border-primary/30 transition-all duration-200">
|
|
<CardContent className="p-6 flex flex-col items-center text-center">
|
|
<div className={`mb-4 flex h-16 w-16 items-center justify-center rounded-2xl border-2 font-display text-2xl font-bold transition-colors ${getStatusColor(mesa.estado)}`}>
|
|
{mesa.numero}
|
|
</div>
|
|
<div className="space-y-1">
|
|
<p className="font-bold uppercase text-[10px] tracking-widest text-muted-foreground">Estado</p>
|
|
<p className="text-sm font-medium">{mesa.estado}</p>
|
|
</div>
|
|
<div className="mt-4 flex items-center gap-2 text-xs text-muted-foreground bg-muted px-2 py-1 rounded-md">
|
|
<Users className="h-3 w-3" /> {mesa.capacidade} lugares
|
|
</div>
|
|
|
|
<div className="mt-6 flex gap-2">
|
|
<select
|
|
className="text-xs bg-background border rounded px-1"
|
|
value={mesa.estado}
|
|
onChange={(e) => handleUpdateEstado(mesa.id, e.target.value as any)}
|
|
>
|
|
<option value="Livre">Livre</option>
|
|
<option value="Ocupada">Ocupada</option>
|
|
<option value="Reservada">Reservada</option>
|
|
</select>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="h-6 w-6 text-destructive hover:bg-destructive/10"
|
|
onClick={() => handleDelete(mesa.id)}
|
|
>
|
|
<Trash2 className="h-4 w-4" />
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
{mesas.length === 0 && !showAddForm && (
|
|
<div className="col-span-full py-20 flex flex-col items-center justify-center text-center text-muted-foreground border-2 border-dashed rounded-xl">
|
|
<TableIcon className="h-12 w-12 opacity-20 mb-4" />
|
|
<p>Nenhuma mesa configurada.</p>
|
|
<Button variant="link" onClick={() => setShowAddForm(true)}>Clique aqui para adicionar a primeira mesa</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|