51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
|
|
import Link from 'next/link';
|
||
|
|
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/card';
|
||
|
|
import { Button } from '@/components/ui/button';
|
||
|
|
import { Progress } from '@/components/ui/progress';
|
||
|
|
import { Badge } from '@/components/ui/badge';
|
||
|
|
import { ShiftListItemDto } from '@/hooks/useShifts';
|
||
|
|
|
||
|
|
interface ShiftCardProps {
|
||
|
|
shift: ShiftListItemDto;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function ShiftCard({ shift }: ShiftCardProps) {
|
||
|
|
const capacityPercentage = (shift.currentSignups / shift.capacity) * 100;
|
||
|
|
const isFull = shift.currentSignups >= shift.capacity;
|
||
|
|
const isPast = new Date(shift.startTime) < new Date();
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Card>
|
||
|
|
<CardHeader>
|
||
|
|
<div className="flex justify-between items-start">
|
||
|
|
<CardTitle>{shift.title}</CardTitle>
|
||
|
|
{isPast && <Badge variant="secondary">Past</Badge>}
|
||
|
|
</div>
|
||
|
|
<CardDescription>
|
||
|
|
{new Date(shift.startTime).toLocaleString()} - {new Date(shift.endTime).toLocaleTimeString()}
|
||
|
|
</CardDescription>
|
||
|
|
</CardHeader>
|
||
|
|
<CardContent>
|
||
|
|
<div className="space-y-3">
|
||
|
|
<div>
|
||
|
|
<div className="flex justify-between text-sm mb-1">
|
||
|
|
<span>Capacity</span>
|
||
|
|
<span>{shift.currentSignups}/{shift.capacity} spots filled</span>
|
||
|
|
</div>
|
||
|
|
<Progress value={capacityPercentage} />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="flex gap-2">
|
||
|
|
<Link href={`/shifts/${shift.id}`}>
|
||
|
|
<Button variant="outline" size="sm">View Details</Button>
|
||
|
|
</Link>
|
||
|
|
{!isPast && !isFull && (
|
||
|
|
<Button size="sm">Sign Up</Button>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
);
|
||
|
|
}
|