restaurante / src /components /admin /EmployeeSchedules.jsx
dimensionalpulsar's picture
Upload 48 files
76823f0 verified
import React, { useState, useEffect } from 'react';
import { db } from '../../firebase/config';
import { ref, onValue, set } from 'firebase/database';
import { Clock, Save, User as UserIcon } from 'lucide-react';
export default function EmployeeSchedules() {
const [employees, setEmployees] = useState([]);
const [schedules, setSchedules] = useState({});
useEffect(() => {
// Fetch Employees (Users with role 'mesero' or 'admin')
onValue(ref(db, 'users'), (snapshot) => {
const data = snapshot.val();
if (data) {
setEmployees(Object.keys(data).map(k => ({ email: k.replace(',', '.'), ...data[k] })));
}
});
// Fetch Schedules
onValue(ref(db, 'schedules'), (snapshot) => {
if (snapshot.exists()) setSchedules(snapshot.val());
});
}, []);
const handleUpdateSchedule = async (email, field, value) => {
const safeEmail = email.replace(/\./g, ',');
await set(ref(db, `schedules/${safeEmail}/${field}`), value);
};
return (
<div className="animate-fade-in" style={{ padding: '0 1rem' }}>
<header style={{ marginBottom: '2rem' }}>
<h2 className="text-gradient" style={{ fontSize: '2rem', fontWeight: '800', display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
<Clock size={28} /> Control de Horarios
</h2>
<p style={{ color: 'var(--text-muted)' }}>Asignación de turnos y disponibilidad de personal</p>
</header>
<div className="glass-panel" style={{ overflow: 'hidden' }}>
<table style={{ width: '100%', borderCollapse: 'collapse', textAlign: 'left' }}>
<thead>
<tr style={{ borderBottom: '1px solid var(--border-subtle)', background: 'rgba(255,255,255,0.02)' }}>
<th style={{ padding: '1.25rem', color: 'var(--text-muted)', fontWeight: '500' }}>Empleado</th>
<th style={{ padding: '1.25rem', color: 'var(--text-muted)', fontWeight: '500' }}>Rol</th>
<th style={{ padding: '1.25rem', color: 'var(--text-muted)', fontWeight: '500' }}>Entrada</th>
<th style={{ padding: '1.25rem', color: 'var(--text-muted)', fontWeight: '500' }}>Salida</th>
<th style={{ padding: '1.25rem', color: 'var(--text-muted)', fontWeight: '500' }}>Estado</th>
</tr>
</thead>
<tbody>
{employees.map((emp) => {
const safeEmail = emp.email.replace(/\./g, ',');
const sched = schedules[safeEmail] || { start: '09:00', end: '17:00' };
return (
<tr key={emp.email} style={{ borderBottom: '1px solid var(--border-subtle)' }} className="table-row-hover">
<td style={{ padding: '1.25rem' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
<div style={{ width: '32px', height: '32px', borderRadius: '50%', background: 'var(--primary)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<UserIcon size={16} color="#fff" />
</div>
<span style={{ fontWeight: '600' }}>{emp.email}</span>
</div>
</td>
<td style={{ padding: '1.25rem' }}>
<span style={{ fontSize: '0.75rem', textTransform: 'uppercase', background: 'rgba(255,255,255,0.05)', padding: '4px 10px', borderRadius: '12px', color: 'var(--text-muted)' }}>
{emp.role}
</span>
</td>
<td style={{ padding: '1.25rem' }}>
<input
type="time"
value={sched.start}
onChange={(e) => handleUpdateSchedule(emp.email, 'start', e.target.value)}
style={inputStyle}
/>
</td>
<td style={{ padding: '1.25rem' }}>
<input
type="time"
value={sched.end}
onChange={(e) => handleUpdateSchedule(emp.email, 'end', e.target.value)}
style={inputStyle}
/>
</td>
<td style={{ padding: '1.25rem' }}>
<span style={{ color: 'var(--success)', fontSize: '0.8rem', fontWeight: '600' }}>Activo</span>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
);
}
const inputStyle = {
padding: '0.5rem',
borderRadius: '6px',
background: 'rgba(255,255,255,0.05)',
border: '1px solid var(--border-subtle)',
color: '#fff',
outline: 'none',
fontSize: '0.9rem'
};