"use client";
import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Calendar } from "@/components/ui/calendar";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import type { ResultFilters } from "@/lib/form/admin-form-results";
import { Download, X, CalendarDays } from "lucide-react";
import { format, parseISO } from "date-fns";
function DateFilterPicker({
label,
value,
onChange,
}: {
label: string;
value: string;
onChange: (value: string) => void;
}) {
const selected = value ? parseISO(value) : undefined;
return (
onChange(date ? format(date, "yyyy-MM-dd") : "")}
/>
{selected && (
)}
);
}
export function ResultsFilters({
formId,
filters,
onFiltersChange,
}: {
formId: string;
filters: ResultFilters;
onFiltersChange?: (filters: ResultFilters) => void;
}) {
const router = useRouter();
const [values, setValues] = useState(filters);
const base = `/admin/form/${formId}/result`;
const updateValues = (
update: (current: ResultFilters) => ResultFilters
) => {
setValues((current) => {
const next = update(current);
onFiltersChange?.(next);
return next;
});
};
const filterQuery = useMemo(() => {
const params = new URLSearchParams();
if (values.q) params.set("q", values.q);
if (values.sort !== "submittedAt") params.set("sort", values.sort);
if (values.direction !== "desc") params.set("direction", values.direction);
if (values.edited !== "all") params.set("edited", values.edited);
if (values.dateFrom) params.set("dateFrom", values.dateFrom);
if (values.dateTo) params.set("dateTo", values.dateTo);
return params.toString();
}, [values]);
const appliedQuery = useMemo(() => {
const params = new URLSearchParams();
if (filters.q) params.set("q", filters.q);
if (filters.sort !== "submittedAt") params.set("sort", filters.sort);
if (filters.direction !== "desc") params.set("direction", filters.direction);
if (filters.edited !== "all") params.set("edited", filters.edited);
if (filters.dateFrom) params.set("dateFrom", filters.dateFrom);
if (filters.dateTo) params.set("dateTo", filters.dateTo);
return params.toString();
}, [filters]);
useEffect(() => {
if (onFiltersChange) return;
if (filterQuery === appliedQuery) return;
const timeout = window.setTimeout(() => {
router.replace(`${base}${filterQuery ? `?${filterQuery}` : ""}`, {
scroll: false,
});
}, 350);
return () => window.clearTimeout(timeout);
}, [appliedQuery, base, filterQuery, onFiltersChange, router]);
return (
updateValues((current) => ({ ...current, q: event.target.value }))
}
placeholder="Search name or Discord ID"
aria-label="Search responses"
/>
updateValues((current) => ({ ...current, dateFrom }))
}
/>
updateValues((current) => ({ ...current, dateTo }))
}
/>
{(values.q ||
values.edited !== "all" ||
values.sort !== "submittedAt" ||
values.direction !== "desc" ||
values.dateFrom ||
values.dateTo) && (
)}
);
}