Files
twotalesanimation 0fbe856dce Initial commit
2026-05-19 22:20:29 +02:00

169 lines
5.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { addWeeks, subWeeks, addDays, format } from "date-fns";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { ChevronLeft, ChevronRight, CalendarDays } from "lucide-react";
import { ScheduleArtist } from "@/app/(dashboard)/schedule/SchedulePageClient";
const STATUS_OPTIONS = [
{ value: "TODO", label: "To Do" },
{ value: "IN_PROGRESS", label: "In Progress" },
{ value: "INTERNAL_REVIEW", label: "Internal Review" },
{ value: "CLIENT_REVIEW", label: "Client Review" },
{ value: "CHANGES", label: "Changes" },
];
interface ScheduleFiltersProps {
projects: { id: string; name: string; code: string }[];
artists: ScheduleArtist[];
filterProject: string;
filterArtist: string;
filterStatus: string;
viewStart: Date;
onProjectChange: (v: string) => void;
onArtistChange: (v: string) => void;
onStatusChange: (v: string) => void;
onViewStartChange: (d: Date) => void;
}
export function ScheduleFilters({
projects,
artists,
filterProject,
filterArtist,
filterStatus,
viewStart,
onProjectChange,
onArtistChange,
onStatusChange,
onViewStartChange,
}: ScheduleFiltersProps) {
const goPrev = () => onViewStartChange(subWeeks(viewStart, 1));
const goNext = () => onViewStartChange(addWeeks(viewStart, 1));
const goToday = () => {
const today = new Date();
const monday = addDays(today, -((today.getDay() + 6) % 7));
onViewStartChange(monday);
};
return (
<div className="flex items-center gap-3 px-4 py-2 border-b border-zinc-800 bg-zinc-950 shrink-0 flex-wrap">
{/* Week navigation */}
<div className="flex items-center gap-1">
<Button
variant="ghost"
size="icon"
className="h-7 w-7 text-zinc-400 hover:text-white"
onClick={goPrev}
>
<ChevronLeft className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="sm"
className="h-7 px-2 text-xs text-zinc-400 hover:text-white gap-1.5"
onClick={goToday}
>
<CalendarDays className="h-3 w-3" />
Today
</Button>
<Button
variant="ghost"
size="icon"
className="h-7 w-7 text-zinc-400 hover:text-white"
onClick={goNext}
>
<ChevronRight className="h-4 w-4" />
</Button>
<span className="text-xs text-zinc-500 ml-1">
{format(viewStart, "MMM d")} {format(addDays(viewStart, 34), "MMM d, yyyy")}
</span>
</div>
<div className="h-4 w-px bg-zinc-800" />
{/* Project filter */}
<Select
value={filterProject || "__all__"}
onValueChange={(v) => onProjectChange(v === "__all__" ? "" : v)}
>
<SelectTrigger className="h-7 text-xs w-36 bg-zinc-900 border-zinc-700">
<SelectValue placeholder="All projects" />
</SelectTrigger>
<SelectContent className="bg-zinc-900 border-zinc-700">
<SelectItem value="__all__" className="text-xs">
All projects
</SelectItem>
{projects.map((p) => (
<SelectItem key={p.id} value={p.id} className="text-xs">
[{p.code}] {p.name}
</SelectItem>
))}
</SelectContent>
</Select>
{/* Artist filter */}
<Select
value={filterArtist || "__all__"}
onValueChange={(v) => onArtistChange(v === "__all__" ? "" : v)}
>
<SelectTrigger className="h-7 text-xs w-36 bg-zinc-900 border-zinc-700">
<SelectValue placeholder="All artists" />
</SelectTrigger>
<SelectContent className="bg-zinc-900 border-zinc-700">
<SelectItem value="__all__" className="text-xs">
All artists
</SelectItem>
{artists.map((a) => (
<SelectItem key={a.id} value={a.id} className="text-xs">
{a.name ?? a.email.split("@")[0]}
</SelectItem>
))}
</SelectContent>
</Select>
{/* Status filter */}
<Select
value={filterStatus || "__all__"}
onValueChange={(v) => onStatusChange(v === "__all__" ? "" : v)}
>
<SelectTrigger className="h-7 text-xs w-36 bg-zinc-900 border-zinc-700">
<SelectValue placeholder="All statuses" />
</SelectTrigger>
<SelectContent className="bg-zinc-900 border-zinc-700">
<SelectItem value="__all__" className="text-xs">
All statuses
</SelectItem>
{STATUS_OPTIONS.map((s) => (
<SelectItem key={s.value} value={s.value} className="text-xs">
{s.label}
</SelectItem>
))}
</SelectContent>
</Select>
{(filterProject || filterArtist || filterStatus) && (
<Button
variant="ghost"
size="sm"
className="h-7 px-2 text-xs text-zinc-500 hover:text-white"
onClick={() => {
onProjectChange("");
onArtistChange("");
onStatusChange("");
}}
>
Clear filters
</Button>
)}
</div>
);
}