222 lines
8.5 KiB
TypeScript
222 lines
8.5 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { Users, Plus, Edit, Trash2, Phone, Mail } from 'lucide-react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { useToast } from '@/hooks/use-toast';
|
|
import { apiClient } from '@/services/adminApi';
|
|
import { useLanguage } from '@/contexts/LanguageContext';
|
|
|
|
const Staff = () => {
|
|
const { t } = useLanguage();
|
|
const [staff, setStaff] = useState<any[]>([]);
|
|
const [establishments, setEstablishments] = useState<any[]>([]);
|
|
const { toast } = useToast();
|
|
|
|
const [formData, setFormData] = useState({
|
|
firstName: '',
|
|
lastName: '',
|
|
email: '',
|
|
phone: '',
|
|
role: 'waiter',
|
|
establishmentId: '',
|
|
salary: 0
|
|
});
|
|
|
|
useEffect(() => {
|
|
loadData();
|
|
}, []);
|
|
|
|
const loadData = async () => {
|
|
try {
|
|
const [estResponse] = await Promise.all([
|
|
apiClient.get('/commerce/establishments')
|
|
]);
|
|
setEstablishments(Array.isArray(estResponse) ? estResponse : (estResponse as any)?.establishments || []);
|
|
// Mock staff data for now
|
|
setStaff([]);
|
|
} catch (error) {
|
|
console.error('Error loading data:', error);
|
|
}
|
|
};
|
|
|
|
const handleSubmit = async () => {
|
|
try {
|
|
// This would be a call to create staff member
|
|
toast({ title: 'Éxito', description: 'Empleado agregado correctamente' });
|
|
setFormData({
|
|
firstName: '',
|
|
lastName: '',
|
|
email: '',
|
|
phone: '',
|
|
role: 'waiter',
|
|
establishmentId: '',
|
|
salary: 0
|
|
});
|
|
} catch (error: any) {
|
|
toast({ title: 'Error', description: error?.message || 'No se pudo agregar el empleado', variant: 'destructive' });
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 p-6">
|
|
<div className="max-w-7xl mx-auto">
|
|
<div className="flex items-center gap-3 mb-6">
|
|
<Users className="w-8 h-8 text-orange-600" />
|
|
<div>
|
|
<h1 className="text-3xl font-bold text-gray-900">Gestión de Personal</h1>
|
|
<p className="text-gray-600">Administra empleados y roles</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex justify-end mb-4">
|
|
<Dialog>
|
|
<DialogTrigger asChild>
|
|
<Button>
|
|
<Plus className="w-4 h-4 mr-2" />
|
|
Nuevo Empleado
|
|
</Button>
|
|
</DialogTrigger>
|
|
<DialogContent className="max-w-2xl">
|
|
<DialogHeader>
|
|
<DialogTitle>Agregar Empleado</DialogTitle>
|
|
</DialogHeader>
|
|
<div className="grid gap-4">
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<Label>Nombre</Label>
|
|
<Input
|
|
value={formData.firstName}
|
|
onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}
|
|
placeholder="Nombre"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Label>Apellido</Label>
|
|
<Input
|
|
value={formData.lastName}
|
|
onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}
|
|
placeholder="Apellido"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<Label>Email</Label>
|
|
<Input
|
|
type="email"
|
|
value={formData.email}
|
|
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
|
placeholder="email@ejemplo.com"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Label>Teléfono</Label>
|
|
<Input
|
|
value={formData.phone}
|
|
onChange={(e) => setFormData({ ...formData, phone: e.target.value })}
|
|
placeholder="+1 809 123 4567"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<Label>Rol</Label>
|
|
<Select value={formData.role} onValueChange={(value) => setFormData({ ...formData, role: value })}>
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="waiter">Mesero</SelectItem>
|
|
<SelectItem value="chef">Chef</SelectItem>
|
|
<SelectItem value="bartender">Bartender</SelectItem>
|
|
<SelectItem value="manager">Gerente</SelectItem>
|
|
<SelectItem value="receptionist">Recepcionista</SelectItem>
|
|
<SelectItem value="housekeeping">Limpieza</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
<div>
|
|
<Label>Establecimiento</Label>
|
|
<Select value={formData.establishmentId} onValueChange={(value) => setFormData({ ...formData, establishmentId: value })}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Selecciona establecimiento" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{establishments.map((est) => (
|
|
<SelectItem key={est.id} value={est.id.toString()}>
|
|
{est.name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<Label>Salario</Label>
|
|
<Input
|
|
type="number"
|
|
value={formData.salary}
|
|
onChange={(e) => setFormData({ ...formData, salary: parseFloat(e.target.value) })}
|
|
placeholder="0.00"
|
|
/>
|
|
</div>
|
|
<Button onClick={handleSubmit}>Agregar Empleado</Button>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</div>
|
|
|
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
{staff.length === 0 ? (
|
|
<div className="col-span-full text-center py-12 text-muted-foreground">
|
|
No hay empleados registrados. Agrega el primer empleado.
|
|
</div>
|
|
) : (
|
|
staff.map((member) => (
|
|
<Card key={member.id}>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<div>
|
|
<CardTitle className="text-base">{member.firstName} {member.lastName}</CardTitle>
|
|
<p className="text-sm text-muted-foreground">{member.role}</p>
|
|
</div>
|
|
<div className="flex gap-1">
|
|
<Button variant="outline" size="sm">
|
|
<Edit className="w-4 h-4" />
|
|
</Button>
|
|
<Button variant="outline" size="sm">
|
|
<Trash2 className="w-4 h-4" />
|
|
</Button>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-2 text-sm">
|
|
<div className="flex items-center gap-2">
|
|
<Mail className="w-4 h-4 text-muted-foreground" />
|
|
<span>{member.email}</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<Phone className="w-4 h-4 text-muted-foreground" />
|
|
<span>{member.phone}</span>
|
|
</div>
|
|
<div className="flex justify-between items-center pt-2">
|
|
<Badge>{member.establishment?.name}</Badge>
|
|
<span className="font-bold">${member.salary}</span>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
))
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Staff;
|