StaffManagement.tsx
Golden-Hour-backend-layer-2/pages/StaffManagement.tsx
import React, { useState } from 'react';
interface StaffMember {
name: string;
role: string;
dept: string;
status: 'On Duty' | 'On Leave' | 'Remote';
shift: string;
}
interface ToDoItem {
id: string;
task: string;
completed: boolean;
}
const ProtocolBar: React.FC = () => (
<div className="fixed bottom-12 left-1/2 -translate-x-1/2 bg-white/90 backdrop-blur-md border border-[#c5a059]/20 px-10 py-5 rounded-full gallery-shadow flex items-center space-x-12 z-50 transition-all hover:border-[#c5a059]/40 group">
<button className="flex items-center space-x-3 text-slate-400 hover:text-slate-900 transition-all">
<i className="fa-solid fa-magnifying-glass text-[9px] text-[#c5a059]"></i>
<span className="text-[8px] font-bold uppercase tracking-[0.3em]">Search</span>
</button>
<div className="w-[0.5px] h-4 bg-[#c5a059]/20"></div>
<button className="flex items-center space-x-3 text-slate-400 hover:text-slate-900 transition-all">
<i className="fa-solid fa-plus text-[9px] text-[#c5a059]"></i>
<span className="text-[8px] font-bold uppercase tracking-[0.3em]">Create</span>
</button>
</div>
);
const StaffManagement: React.FC = () => {
const [activeTab, setActiveTab] = useState<'Workspace' | 'Directory'>('Workspace');
const [isOnDuty, setIsOnDuty] = useState(false);
const [todos, setTodos] = useState<ToDoItem[]>([
{ id: '1', task: 'Review Villa 04 maintenance report', completed: false },
{ id: '2', task: 'Coordinate with Chef for tonight\'s VIP dinner', completed: true },
{ id: '3', task: 'Verify arrival details for the Miller party', completed: false },
{ id: '4', task: 'Update inventory for cleaning supplies', completed: false },
]);
const staff: StaffMember[] = [
{ name: 'Admin One', role: 'IT Manager', dept: 'IT', status: 'On Duty', shift: 'Morning' },
{ name: 'Maria Garcia', role: 'Housekeeping Supervisor', dept: 'Operations', status: 'On Leave', shift: 'N/A' },
{ name: 'James Wilson', role: 'Front Desk Lead', dept: 'Guest Services', status: 'On Duty', shift: 'Evening' },
{ name: 'Linda Zhang', role: 'Chief Accountant', dept: 'Finance', status: 'Remote', shift: 'Morning' },
];
const toggleTodo = (id: string) => {
setTodos(todos.map(t => t.id === id ? { ...t, completed: !t.completed } : t));
};
return (
<div className="relative pb-32">
<div className="fade-in-section space-y-16">
{/* Editorial Header */}
<div className="flex flex-col md:flex-row md:items-end justify-between gap-10 border-b border-[#c5a059]/10 pb-12 px-2">
<div className="flex items-baseline space-x-6">
<span className="font-serif italic text-6xl text-slate-200">Staff</span>
<div>
<h2 className="font-serif italic text-6xl text-slate-900 tracking-tight">Atelier</h2>
<p className="text-[10px] font-black uppercase tracking-[0.6em] text-[#c5a059] mt-2">Operations & Personnel Hub</p>
</div>
</div>
<div className="flex bg-[#fdfcf9] p-1 border border-[#c5a059]/10 rounded-full">
<button
onClick={() => setActiveTab('Workspace')}
className={`px-10 py-3 rounded-full text-[9px] font-black uppercase tracking-[0.4em] transition-all ${activeTab === 'Workspace' ? 'bg-black text-white shadow-xl' : 'text-slate-300 hover:text-slate-600'}`}
>
Workspace
</button>
<button
onClick={() => setActiveTab('Directory')}
className={`px-10 py-3 rounded-full text-[9px] font-black uppercase tracking-[0.4em] transition-all ${activeTab === 'Directory' ? 'bg-black text-white shadow-xl' : 'text-slate-300 hover:text-slate-600'}`}
>
Directory
</button>
</div>
</div>
{activeTab === 'Workspace' ? (
<div className="grid grid-cols-1 lg:grid-cols-3 gap-12">
<div className="lg:col-span-2 space-y-12">
<div className="bg-[#1a1a1a] rounded-[3rem] p-12 gallery-shadow relative overflow-hidden group">
<div className="absolute top-0 right-0 w-32 h-32 bg-[#c5a059]/10 rounded-full blur-3xl -mr-16 -mt-16 group-hover:bg-[#c5a059]/20 transition-all duration-1000"></div>
<div className="relative z-10">
<div className="flex items-center justify-between mb-8">
<span className="text-[10px] font-black uppercase tracking-[0.6em] text-[#c5a059]">Golden Hour Bulletins</span>
<span className="text-[9px] font-serif italic text-slate-500">Edition: {new Date().toLocaleDateString()}</span>
</div>
<div className="space-y-6">
<div className="border-l-2 border-[#c5a059]/30 pl-8 py-2">
<h3 className="font-serif italic text-3xl text-white mb-2">Quarterly Gala Scheduled</h3>
<p className="text-slate-400 text-sm leading-relaxed">All staff are required for the orientation on the 15th. Please ensure shift swaps are finalized by Friday.</p>
</div>
<div className="border-l-2 border-[#c5a059]/30 pl-8 py-2">
<h3 className="font-serif italic text-3xl text-white mb-2">New Security Protocol</h3>
<p className="text-slate-400 text-sm leading-relaxed">Biometric updates for the main vault will take place starting 09:00 tomorrow.</p>
</div>
</div>
</div>
</div>
<div className="bg-white rounded-[3rem] p-12 border border-[#c5a059]/10 gallery-shadow">
<div className="flex items-center justify-between mb-10 border-b border-[#c5a059]/5 pb-8">
<div>
<h3 className="font-serif italic text-4xl text-slate-900">Daily Protocol</h3>
<p className="text-[9px] font-black uppercase tracking-[0.4em] text-slate-300 mt-2">Personal Tasks & Assignments</p>
</div>
</div>
<div className="space-y-1">
{todos.map(todo => (
<div
key={todo.id}
onClick={() => toggleTodo(todo.id)}
className="flex items-center py-5 px-4 group cursor-pointer hover:bg-[#fdfcf9] transition-all rounded-2xl"
>
<div className={`w-6 h-6 rounded-full border flex items-center justify-center transition-all mr-6 ${
todo.completed ? 'bg-black border-black' : 'bg-transparent border-[#c5a059]/20 group-hover:border-[#c5a059]'
}`}>
{todo.completed && <i className="fa-solid fa-check text-[10px] text-[#c5a059]"></i>}
</div>
<span className={`text-lg font-serif italic transition-all ${
todo.completed ? 'text-slate-300 line-through' : 'text-slate-700'
}`}>
{todo.task}
</span>
</div>
))}
</div>
</div>
</div>
<div className="space-y-12">
<div className="bg-white rounded-[3rem] p-12 border border-[#c5a059]/10 gallery-shadow text-center">
<span className="text-[10px] font-black uppercase tracking-[0.6em] text-slate-300 block mb-10">Attendance Console</span>
<div className="mb-12">
<p className="font-serif italic text-6xl text-slate-900 tabular-nums">{new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</p>
<p className="text-[10px] font-black uppercase tracking-[0.3em] text-[#c5a059] mt-4">{new Date().toLocaleDateString('en-US', { weekday: 'long' })}</p>
</div>
<div className="grid grid-cols-1 gap-4">
<button
onClick={() => setIsOnDuty(true)}
className={`py-8 rounded-[2rem] text-[10px] font-black uppercase tracking-[0.5em] transition-all duration-700 ${
isOnDuty
? 'bg-[#c5a059]/10 text-[#c5a059] border border-[#c5a059]/20'
: 'bg-white border border-slate-100 text-slate-300 hover:border-[#c5a059] hover:text-black'
}`}
>
{isOnDuty ? <i className="fa-solid fa-circle-dot mr-3 animate-pulse"></i> : <i className="fa-solid fa-power-off mr-3"></i>}
Clock In
</button>
<button
onClick={() => setIsOnDuty(false)}
className="py-8 rounded-[2rem] bg-white border border-slate-100 text-slate-300 hover:text-rose-600 hover:border-rose-100 transition-all text-[10px] font-black uppercase tracking-[0.5em]"
>
Clock Out
</button>
</div>
</div>
</div>
</div>
) : (
<div className="bg-white rounded-[4rem] border border-[#c5a059]/5 overflow-hidden gallery-shadow">
<div className="p-12 border-b border-[#c5a059]/5 flex flex-col md:flex-row md:items-center justify-between gap-8">
<h3 className="font-serif italic text-4xl text-slate-900">Personnel Archive</h3>
</div>
<div className="p-12 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
{staff.map((person, idx) => (
<div key={idx} className="bg-[#fdfcf9] rounded-[2.5rem] p-10 border border-[#c5a059]/5 hover:border-[#c5a059]/20 transition-all duration-700 group relative">
<div className="absolute top-8 right-8 flex space-x-2 opacity-0 group-hover:opacity-100 transition-all">
<button className="text-slate-300 hover:text-[#c5a059]"><i className="fa-solid fa-pen-nib text-xs"></i></button>
<button className="text-slate-300 hover:text-rose-600"><i className="fa-solid fa-trash-can text-xs"></i></button>
</div>
<img src={`https://picsum.photos/seed/${person.name}/100/100`} className="w-20 h-20 rounded-2xl grayscale group-hover:grayscale-0 transition-all duration-1000 mb-8" />
<h4 className="font-serif italic text-2xl text-slate-900">{person.name}</h4>
<p className="text-[10px] font-black uppercase tracking-[0.4em] text-[#c5a059] mt-2 mb-8">{person.role}</p>
<div className="space-y-4 pt-8 border-t border-[#c5a059]/5">
<div className="flex justify-between items-center">
<span className="text-[8px] font-black uppercase tracking-widest text-slate-300">Section</span>
<span className="text-[9px] font-bold uppercase tracking-widest text-slate-600">{person.dept}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-[8px] font-black uppercase tracking-widest text-slate-300">Protocol</span>
<span className={`text-[9px] font-black uppercase tracking-widest ${
person.status === 'On Duty' ? 'text-emerald-500' : 'text-slate-300'
}`}>{person.status}</span>
</div>
</div>
</div>
))}
</div>
</div>
)}
</div>
<ProtocolBar />
</div>
);
};
export default StaffManagement;
相關文章
App.tsx
App.tsx — typescript source code from the Golden-Hour-backend-layer-2 learning materials (Golden-Hour-backend-layer-2/App.tsx).
閱讀文章 →Header.tsx
Header.tsx — typescript source code from the Golden-Hour-backend-layer-2 learning materials (Golden-Hour-backend-layer-2/components/Header.tsx).
閱讀文章 →Sidebar.tsx
Sidebar.tsx — typescript source code from the Golden-Hour-backend-layer-2 learning materials (Golden-Hour-backend-layer-2/components/Sidebar.tsx).
閱讀文章 →index.tsx
index.tsx — typescript source code from the Golden-Hour-backend-layer-2 learning materials (Golden-Hour-backend-layer-2/index.tsx).
閱讀文章 →ContentManagement.tsx
ContentManagement.tsx — typescript source code from the Golden-Hour-backend-layer-2 learning materials (Golden-Hour-backend-layer-2/pages/ContentManagement.tsx).
閱讀文章 →CustomerManagement.tsx
CustomerManagement.tsx — typescript source code from the Golden-Hour-backend-layer-2 learning materials (Golden-Hour-backend-layer-2/pages/CustomerManagement.tsx).
閱讀文章 →