162 lines
7.2 KiB
TypeScript
162 lines
7.2 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
||
import { useAuth } from '../context/AuthContext';
|
||
import { Store, LayoutDashboard, Calendar as CalendarIcon, Users, Clock, UserCircle } from 'lucide-react';
|
||
import Dashboard from './Dashboard';
|
||
import Calendar from './Calendar';
|
||
import PersonnelList from './PersonnelList';
|
||
import { startOfWeek, endOfWeek } from 'date-fns';
|
||
|
||
export default function AdminOverview() {
|
||
const { token } = useAuth();
|
||
const [branches, setBranches] = useState<any[]>([]);
|
||
const [selectedBranchId, setSelectedBranchId] = useState<number | null>(null);
|
||
const [activeTab, setActiveTab] = useState<'dashboard' | 'calendar' | 'personnel'>('dashboard');
|
||
const [summary, setSummary] = useState<{ totalBranches: number, totalActiveEmployees: number, totalPlannedShifts: number } | null>(null);
|
||
|
||
useEffect(() => {
|
||
const fetchBranches = async () => {
|
||
try {
|
||
const res = await fetch('/api/admin/branches', { headers: { Authorization: `Bearer ${token}` } });
|
||
if (res.ok) {
|
||
const data = await res.json();
|
||
setBranches(data);
|
||
if (data.length > 0) setSelectedBranchId(data[0].id);
|
||
}
|
||
} catch (err) {
|
||
console.error(err);
|
||
}
|
||
};
|
||
|
||
const fetchSummary = async () => {
|
||
try {
|
||
const currentWeekStart = startOfWeek(new Date(), { weekStartsOn: 1 }).getTime();
|
||
const currentWeekEnd = endOfWeek(new Date(), { weekStartsOn: 1 }).getTime();
|
||
const res = await fetch(`/api/admin/summary?start=${currentWeekStart}&end=${currentWeekEnd}`, { headers: { Authorization: `Bearer ${token}` } });
|
||
if (res.ok) {
|
||
const data = await res.json();
|
||
setSummary(data);
|
||
}
|
||
} catch (err) {
|
||
console.error(err);
|
||
}
|
||
};
|
||
|
||
if (token) {
|
||
fetchBranches();
|
||
fetchSummary();
|
||
}
|
||
}, [token]);
|
||
|
||
return (
|
||
<div className="space-y-6 pb-20 md:pb-6">
|
||
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
|
||
<h1 className="text-2xl font-bold text-mua-text">Şube Raporları & Vardiyalar</h1>
|
||
|
||
{/* Branch Selector */}
|
||
<div className="flex items-center bg-mua-surface border border-mua-border rounded-xl px-3 py-2 shadow-sm">
|
||
<Store className="h-5 w-5 text-mua-text-muted mr-2" />
|
||
<select
|
||
value={selectedBranchId || ''}
|
||
onChange={(e) => setSelectedBranchId(Number(e.target.value))}
|
||
className="bg-transparent border-none focus:ring-0 text-sm font-medium text-mua-text w-full md:w-48 cursor-pointer outline-none"
|
||
>
|
||
{branches.map(b => (
|
||
<option key={b.id} value={b.id}>{b.name}</option>
|
||
))}
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
{selectedBranchId ? (
|
||
<div className="bg-mua-surface rounded-2xl shadow-sm border border-mua-border overflow-hidden">
|
||
<div className="flex border-b border-mua-border">
|
||
<button
|
||
onClick={() => setActiveTab('dashboard')}
|
||
className={`flex-1 py-4 text-sm font-medium flex items-center justify-center transition-colors ${
|
||
activeTab === 'dashboard'
|
||
? 'text-mua-primary border-b-2 border-mua-primary bg-mua-primary-light/50'
|
||
: 'text-mua-text-muted hover:text-mua-text hover:bg-mua-bg'
|
||
}`}
|
||
>
|
||
<LayoutDashboard className="h-4 w-4 mr-2" />
|
||
Özet Dashboard
|
||
</button>
|
||
<button
|
||
onClick={() => setActiveTab('calendar')}
|
||
className={`flex-1 py-4 text-sm font-medium flex items-center justify-center transition-colors ${
|
||
activeTab === 'calendar'
|
||
? 'text-mua-primary border-b-2 border-mua-primary bg-mua-primary-light/50'
|
||
: 'text-mua-text-muted hover:text-mua-text hover:bg-mua-bg'
|
||
}`}
|
||
>
|
||
<CalendarIcon className="h-4 w-4 mr-2" />
|
||
Vardiya Takvimi
|
||
</button>
|
||
<button
|
||
onClick={() => setActiveTab('personnel')}
|
||
className={`flex-1 py-4 text-sm font-medium flex items-center justify-center transition-colors ${
|
||
activeTab === 'personnel'
|
||
? 'text-mua-primary border-b-2 border-mua-primary bg-mua-primary-light/50'
|
||
: 'text-mua-text-muted hover:text-mua-text hover:bg-mua-bg'
|
||
}`}
|
||
>
|
||
<UserCircle className="h-4 w-4 mr-2" />
|
||
Personel & Yöneticiler
|
||
</button>
|
||
</div>
|
||
|
||
{/* Global Summary Section (Below Tabs) */}
|
||
{summary && (
|
||
<div className="bg-mua-bg border-b border-mua-border p-4 md:px-6">
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||
<div className="bg-mua-surface rounded-xl shadow-sm border border-mua-border p-4 flex items-center">
|
||
<div className="bg-mua-primary-light p-3 rounded-xl mr-4">
|
||
<Store className="h-5 w-5 text-mua-primary" />
|
||
</div>
|
||
<div>
|
||
<p className="text-xs font-medium text-mua-text-muted mb-1">Toplam Şube</p>
|
||
<p className="text-xl font-bold text-mua-text">{summary.totalBranches}</p>
|
||
</div>
|
||
</div>
|
||
<div className="bg-mua-surface rounded-xl shadow-sm border border-mua-border p-4 flex items-center">
|
||
<div className="bg-blue-50 p-3 rounded-xl mr-4">
|
||
<Users className="h-5 w-5 text-blue-500" />
|
||
</div>
|
||
<div>
|
||
<p className="text-xs font-medium text-mua-text-muted mb-1">Tüm Şubeler - Aktif Personel</p>
|
||
<p className="text-xl font-bold text-mua-text">{summary.totalActiveEmployees}</p>
|
||
</div>
|
||
</div>
|
||
<div className="bg-mua-surface rounded-xl shadow-sm border border-mua-border p-4 flex items-center">
|
||
<div className="bg-mua-pistachio-light p-3 rounded-xl mr-4">
|
||
<Clock className="h-5 w-5 text-mua-pistachio" />
|
||
</div>
|
||
<div>
|
||
<p className="text-xs font-medium text-mua-text-muted mb-1">Tüm Şubeler - Haftalık Vardiya</p>
|
||
<p className="text-xl font-bold text-mua-text">{summary.totalPlannedShifts}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
<div className="p-4 md:p-6 bg-mua-bg">
|
||
{activeTab === 'dashboard' ? (
|
||
<Dashboard branchId={selectedBranchId} />
|
||
) : activeTab === 'calendar' ? (
|
||
<Calendar branchId={selectedBranchId} />
|
||
) : (
|
||
<PersonnelList />
|
||
)}
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<div className="bg-mua-surface rounded-2xl shadow-sm border border-mua-border p-12 flex flex-col items-center justify-center text-center">
|
||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-mua-primary mb-4"></div>
|
||
<p className="text-mua-text-muted">Şubeler yükleniyor...</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|