Axion/src/pages/TeamSchedules.tsx
2025-12-07 12:14:33 -04:00

195 lines
9.3 KiB
TypeScript

import React, { useState } from 'react';
import { Layout } from '../components/Layout/Layout';
import { Calendar, Plus, Copy, Zap, Send, Edit, Trash2 } from 'lucide-react';
import { format, startOfWeek, addDays } from 'date-fns';
export const TeamSchedules: React.FC = () => {
const [currentWeek] = useState(startOfWeek(new Date()));
const [selectedShift, setSelectedShift] = useState<string | null>(null);
const employees = ['John Doe', 'Jane Smith', 'Bob Johnson', 'Alice Brown', 'Charlie Wilson'];
const weekDays = Array.from({ length: 7 }, (_, i) => addDays(currentWeek, i));
const shifts: Record<string, Record<string, { start: string; end: string; role: string }>> = {
'John Doe': {
'0': { start: '8:00 AM', end: '5:00 PM', role: 'Cashier' },
'1': { start: '8:00 AM', end: '5:00 PM', role: 'Cashier' },
'3': { start: '9:00 AM', end: '6:00 PM', role: 'Manager' },
},
'Jane Smith': {
'1': { start: '9:00 AM', end: '6:00 PM', role: 'Stock' },
'2': { start: '8:00 AM', end: '5:00 PM', role: 'Cashier' },
'4': { start: '8:00 AM', end: '5:00 PM', role: 'Cashier' },
},
};
return (
<Layout>
<div>
<div className="flex items-center justify-between mb-6">
<h1 className="text-3xl font-bold text-gray-900">Team Schedules</h1>
<div className="flex gap-2">
<button className="px-4 py-2 bg-gray-200 text-gray-700 rounded-lg font-medium hover:bg-gray-300 flex items-center gap-2">
<Calendar className="w-4 h-4" />
Week Selector
</button>
<button className="px-4 py-2 bg-primary-600 text-white rounded-lg font-medium hover:bg-primary-700 flex items-center gap-2">
<Send className="w-4 h-4" />
Publish Week
</button>
</div>
</div>
{/* Top Controls */}
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-4 mb-6">
<div className="flex items-center gap-2 flex-wrap">
<button className="px-4 py-2 bg-primary-600 text-white rounded-lg font-medium hover:bg-primary-700 flex items-center gap-2">
<Plus className="w-4 h-4" />
Add Shift
</button>
<button className="px-4 py-2 bg-gray-200 text-gray-700 rounded-lg font-medium hover:bg-gray-300 flex items-center gap-2">
<Copy className="w-4 h-4" />
Copy Last Week
</button>
<button className="px-4 py-2 bg-gray-200 text-gray-700 rounded-lg font-medium hover:bg-gray-300 flex items-center gap-2">
<Zap className="w-4 h-4" />
Auto-Generate
</button>
</div>
</div>
<div className="flex gap-6">
{/* Main Grid */}
<div className="flex-1 bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-gray-50 border-b border-gray-200">
<tr>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sticky left-0 bg-gray-50 z-10 border-r border-gray-200">
Employee
</th>
{weekDays.map((day, idx) => (
<th key={idx} className="px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider min-w-[120px]">
<div>{format(day, 'EEE')}</div>
<div className="text-xs text-gray-400">{format(day, 'MMM d')}</div>
</th>
))}
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{employees.map((emp, empIdx) => (
<tr key={empIdx}>
<td className="px-4 py-3 font-medium text-gray-900 sticky left-0 bg-white z-10 border-r border-gray-200">
{emp}
</td>
{weekDays.map((day, dayIdx) => {
const shift = shifts[emp]?.[dayIdx.toString()];
return (
<td key={dayIdx} className="px-2 py-2">
{shift ? (
<div
className="p-2 bg-primary-100 border border-primary-300 rounded cursor-pointer hover:bg-primary-200 transition-colors"
onClick={() => setSelectedShift(`${emp}-${dayIdx}`)}
>
<div className="text-xs font-medium text-primary-900">{shift.start} - {shift.end}</div>
<div className="text-xs text-primary-700">{shift.role}</div>
</div>
) : (
<div className="p-2 border-2 border-dashed border-gray-200 rounded cursor-pointer hover:border-primary-300 transition-colors text-center text-xs text-gray-400">
Click to add
</div>
)}
</td>
);
})}
</tr>
))}
</tbody>
</table>
</div>
</div>
{/* Sidebar */}
<div className="w-64 bg-white rounded-lg shadow-sm border border-gray-200 p-4">
<h3 className="font-semibold text-gray-900 mb-4">Unassigned Shifts</h3>
<div className="space-y-2">
<div className="p-3 bg-yellow-50 border border-yellow-200 rounded-lg">
<p className="text-sm font-medium">Monday 8:00 AM</p>
<p className="text-xs text-gray-600">Cashier needed</p>
</div>
</div>
<div className="mt-6">
<h3 className="font-semibold text-gray-900 mb-4">Coverage</h3>
<div className="space-y-2">
{weekDays.map((day, idx) => (
<div key={idx} className="flex items-center justify-between p-2 bg-gray-50 rounded">
<span className="text-xs text-gray-600">{format(day, 'EEE')}</span>
<span className="text-xs font-medium text-green-600"> Covered</span>
</div>
))}
</div>
</div>
</div>
</div>
{/* Shift Edit Drawer */}
{selectedShift && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg shadow-xl p-6 w-full max-w-md">
<h2 className="text-xl font-bold text-gray-900 mb-4">Edit Shift</h2>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Start Time</label>
<input type="time" className="w-full px-3 py-2 border border-gray-300 rounded-lg" defaultValue="08:00" />
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">End Time</label>
<input type="time" className="w-full px-3 py-2 border border-gray-300 rounded-lg" defaultValue="17:00" />
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Role</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-lg">
<option>Cashier</option>
<option>Stock Associate</option>
<option>Manager</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Location</label>
<input type="text" className="w-full px-3 py-2 border border-gray-300 rounded-lg" defaultValue="Main Store" />
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Notes</label>
<textarea className="w-full px-3 py-2 border border-gray-300 rounded-lg" rows={3}></textarea>
</div>
<div>
<label className="flex items-center gap-2">
<input type="checkbox" className="rounded" />
<span className="text-sm text-gray-700">Repeat weekly</span>
</label>
</div>
</div>
<div className="flex gap-2 mt-6">
<button
onClick={() => setSelectedShift(null)}
className="flex-1 px-4 py-2 bg-gray-200 text-gray-700 rounded-lg font-medium hover:bg-gray-300"
>
Cancel
</button>
<button className="flex-1 px-4 py-2 bg-primary-600 text-white rounded-lg font-medium hover:bg-primary-700">
Save
</button>
<button className="px-4 py-2 bg-red-600 text-white rounded-lg font-medium hover:bg-red-700">
<Trash2 className="w-4 h-4" />
</button>
</div>
</div>
</div>
)}
</div>
</Layout>
);
};