feat:update form

This commit is contained in:
2026-07-28 00:02:34 +07:00 Unverified
parent 0e8c816276
commit fa35f00f38
25 changed files with 919 additions and 149 deletions
+28 -21
View File
@@ -1,6 +1,6 @@
"use client";
import { useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@@ -19,7 +19,7 @@ import {
PopoverTrigger,
} from "@/components/ui/popover";
import type { ResultFilters } from "@/lib/admin-form-results";
import { Download, Search, X, CalendarDays } from "lucide-react";
import { Download, X, CalendarDays } from "lucide-react";
import { format, parseISO } from "date-fns";
function DateFilterPicker({
@@ -80,7 +80,7 @@ export function ResultsFilters({
const [values, setValues] = useState(filters);
const base = `/admin/form/${formId}/result`;
const apply = () => {
const filterQuery = useMemo(() => {
const params = new URLSearchParams();
if (values.q) params.set("q", values.q);
if (values.sort !== "submittedAt") params.set("sort", values.sort);
@@ -88,17 +88,31 @@ export function ResultsFilters({
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);
router.push(`${base}?${params}`);
};
return params.toString();
}, [values]);
const exportParams = new URLSearchParams({
q: values.q,
sort: values.sort,
direction: values.direction,
edited: values.edited,
dateFrom: values.dateFrom,
dateTo: values.dateTo,
});
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 (filterQuery === appliedQuery) return;
const timeout = window.setTimeout(() => {
router.replace(`${base}${filterQuery ? `?${filterQuery}` : ""}`, {
scroll: false,
});
}, 350);
return () => window.clearTimeout(timeout);
}, [appliedQuery, base, filterQuery, router]);
return (
<div className="flex flex-col gap-3">
@@ -108,9 +122,6 @@ export function ResultsFilters({
onChange={(event) =>
setValues((current) => ({ ...current, q: event.target.value }))
}
onKeyDown={(event) => {
if (event.key === "Enter") apply();
}}
placeholder="Search name or Discord ID"
aria-label="Search responses"
/>
@@ -167,12 +178,8 @@ export function ResultsFilters({
setValues((current) => ({ ...current, dateTo }))
}
/>
<Button onClick={apply}>
<Search data-icon="inline-start" />
Apply
</Button>
<Button variant="outline" asChild>
<a href={`${base}/export?${exportParams}`}>
<a href={`${base}/export${filterQuery ? `?${filterQuery}` : ""}`}>
<Download data-icon="inline-start" />
CSV
</a>