Initial commit: TKB Timeshift Schedule Management Application
- Next.js 15.2.4 with React 19 and TypeScript - Monthly schedule generator with Excel-like formatting - Complete employee list from example.xlsx (18 employees) - Excel-style column naming (A, B, C, ..., Z, AA, AB, ...) - Counter-clockwise text rotation for data values - Weekend highlighting and shift color coding - Team selection for TKB, METRO, D8 - 7 days from previous month + full current month date range - jspreadsheet integration for Excel-like interface 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
156
components/schedule-history.tsx
Normal file
156
components/schedule-history.tsx
Normal file
@@ -0,0 +1,156 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Search, Download, Eye, Calendar, Clock } from "lucide-react"
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||||
|
||||
interface ScheduleHistoryProps {
|
||||
teamId: string
|
||||
teamName: string
|
||||
}
|
||||
|
||||
// Sample historical data
|
||||
const getHistoricalSchedules = (teamId: string) => [
|
||||
{
|
||||
id: "1",
|
||||
name: "Week 45 - November 2024",
|
||||
dateRange: "Nov 4-10, 2024",
|
||||
createdBy: "John Manager",
|
||||
createdAt: "2024-11-01",
|
||||
status: "completed",
|
||||
employees: 8,
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Week 44 - October 2024",
|
||||
dateRange: "Oct 28 - Nov 3, 2024",
|
||||
createdBy: "Sarah Admin",
|
||||
createdAt: "2024-10-25",
|
||||
status: "completed",
|
||||
employees: 7,
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
name: "Week 43 - October 2024",
|
||||
dateRange: "Oct 21-27, 2024",
|
||||
createdBy: "John Manager",
|
||||
createdAt: "2024-10-18",
|
||||
status: "completed",
|
||||
employees: 8,
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
name: "Holiday Schedule - Christmas",
|
||||
dateRange: "Dec 23-29, 2023",
|
||||
createdBy: "Admin",
|
||||
createdAt: "2023-12-15",
|
||||
status: "archived",
|
||||
employees: 5,
|
||||
},
|
||||
]
|
||||
|
||||
export function ScheduleHistory({ teamId, teamName }: ScheduleHistoryProps) {
|
||||
const [searchTerm, setSearchTerm] = React.useState("")
|
||||
const historicalSchedules = getHistoricalSchedules(teamId)
|
||||
|
||||
const filteredSchedules = historicalSchedules.filter(
|
||||
(schedule) =>
|
||||
schedule.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
schedule.dateRange.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
schedule.createdBy.toLowerCase().includes(searchTerm.toLowerCase()),
|
||||
)
|
||||
|
||||
const getStatusColor = (status: string) => {
|
||||
switch (status) {
|
||||
case "completed":
|
||||
return "bg-green-100 text-green-800"
|
||||
case "archived":
|
||||
return "bg-gray-100 text-gray-800"
|
||||
default:
|
||||
return "bg-blue-100 text-blue-800"
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className="w-full">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Clock className="size-5" />
|
||||
{teamName} - Schedule History
|
||||
</CardTitle>
|
||||
<CardDescription>Browse and restore previous schedules for your team</CardDescription>
|
||||
<div className="flex items-center gap-4 mt-4">
|
||||
<div className="relative flex-1 max-w-sm">
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 size-4 text-gray-400" />
|
||||
<Input
|
||||
placeholder="Search schedules..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="pl-10"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Schedule Name</TableHead>
|
||||
<TableHead>Date Range</TableHead>
|
||||
<TableHead>Created By</TableHead>
|
||||
<TableHead>Created Date</TableHead>
|
||||
<TableHead>Employees</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{filteredSchedules.map((schedule) => (
|
||||
<TableRow key={schedule.id}>
|
||||
<TableCell className="font-medium">{schedule.name}</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-2">
|
||||
<Calendar className="size-4 text-gray-400" />
|
||||
{schedule.dateRange}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>{schedule.createdBy}</TableCell>
|
||||
<TableCell>{new Date(schedule.createdAt).toLocaleDateString()}</TableCell>
|
||||
<TableCell>{schedule.employees}</TableCell>
|
||||
<TableCell>
|
||||
<Badge className={getStatusColor(schedule.status)}>{schedule.status}</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="outline" size="sm">
|
||||
<Eye className="size-4 mr-1" />
|
||||
View
|
||||
</Button>
|
||||
<Button variant="outline" size="sm">
|
||||
<Download className="size-4 mr-1" />
|
||||
Export
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
{filteredSchedules.length === 0 && (
|
||||
<div className="text-center py-8">
|
||||
<Clock className="size-12 mx-auto mb-4 text-gray-400" />
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-2">No schedules found</h3>
|
||||
<p className="text-gray-500">
|
||||
{searchTerm ? "Try adjusting your search terms" : "No historical schedules available yet"}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user