chore: add project files and setup gitignore
This commit is contained in:
159
reserva-mesa-dashboard/app/(dashboard)/configuracoes/page.tsx
Normal file
159
reserva-mesa-dashboard/app/(dashboard)/configuracoes/page.tsx
Normal file
@@ -0,0 +1,159 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useAuth } from "@/contexts/AuthContext";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Store, Mail, Phone, MapPin, Save, CheckCircle2 } from "lucide-react";
|
||||
|
||||
export default function ConfiguracoesPage() {
|
||||
const { user, updateRestaurantProfile } = useAuth();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [success, setSuccess] = useState(false);
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
establishmentName: "",
|
||||
category: "",
|
||||
phoneNumber: "",
|
||||
address: "",
|
||||
isAvailable: true,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
setFormData({
|
||||
establishmentName: user.establishmentName || "",
|
||||
category: user.category || "",
|
||||
phoneNumber: user.phoneNumber || "",
|
||||
address: user.address || "",
|
||||
isAvailable: user.isAvailable !== false, // default true
|
||||
});
|
||||
}
|
||||
}, [user]);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
setSuccess(false);
|
||||
|
||||
const res = await updateRestaurantProfile(formData);
|
||||
|
||||
if (res.success) {
|
||||
setSuccess(true);
|
||||
setTimeout(() => setSuccess(false), 3000);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="text-3xl font-display font-bold text-foreground">Configurações</h1>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<Card className="border-border/50">
|
||||
<CardHeader>
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<CardTitle>Perfil do Estabelecimento</CardTitle>
|
||||
<CardDescription>Gerencie as informações que os clientes veem na App.</CardDescription>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 bg-muted/30 px-4 py-2 rounded-lg border">
|
||||
<Label htmlFor="available" className="text-sm font-medium">Estado do Restaurante</Label>
|
||||
<Switch
|
||||
id="available"
|
||||
checked={formData.isAvailable}
|
||||
onCheckedChange={(checked) => setFormData({...formData, isAvailable: checked})}
|
||||
/>
|
||||
<span className={`text-xs font-bold uppercase ${formData.isAvailable ? "text-green-500" : "text-destructive"}`}>
|
||||
{formData.isAvailable ? "Aberto" : "Fechado"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="name">Nome do Estabelecimento</Label>
|
||||
<div className="relative">
|
||||
<Store className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="name"
|
||||
className="pl-10"
|
||||
value={formData.establishmentName}
|
||||
onChange={(e) => setFormData({...formData, establishmentName: e.target.value})}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="category">Categoria / Cozinha</Label>
|
||||
<Input
|
||||
id="category"
|
||||
value={formData.category}
|
||||
onChange={(e) => setFormData({...formData, category: e.target.value})}
|
||||
placeholder="Ex: Portuguesa, Italiana..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="email">Email de Contacto (Não editável)</Label>
|
||||
<div className="relative">
|
||||
<Mail className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="email"
|
||||
className="pl-10 bg-muted/50"
|
||||
value={user?.email || ""}
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="phone">Telefone</Label>
|
||||
<div className="relative">
|
||||
<Phone className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="phone"
|
||||
className="pl-10"
|
||||
value={formData.phoneNumber}
|
||||
onChange={(e) => setFormData({...formData, phoneNumber: e.target.value})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="address">Morada Completa</Label>
|
||||
<div className="relative">
|
||||
<MapPin className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="address"
|
||||
className="pl-10"
|
||||
value={formData.address}
|
||||
onChange={(e) => setFormData({...formData, address: e.target.value})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<div className="flex items-center justify-end gap-4">
|
||||
{success && (
|
||||
<div className="flex items-center gap-2 text-green-500 font-medium animate-in fade-in slide-in-from-right-4">
|
||||
<CheckCircle2 className="h-5 w-5" /> Alterações guardadas!
|
||||
</div>
|
||||
)}
|
||||
<Button type="submit" disabled={loading} className="px-8 gap-2">
|
||||
{loading ? "A guardar..." : <><Save className="h-4 w-4" /> Guardar Alterações</>}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user