fix(admin-dashboard): refine filter reset controls

This commit is contained in:
2026-06-15 21:46:20 +03:30
parent 021bee9444
commit da8d82955e

View File

@@ -213,13 +213,17 @@ function DateRangeFilter({
value,
onChange,
onReset,
resetDisabled,
showReset = true,
}: {
value: DateRangeState;
onChange: (next: DateRangeState) => void;
onReset: () => void;
resetDisabled?: boolean;
showReset?: boolean;
}) {
return (
<div className="grid gap-3 md:grid-cols-[1fr_1fr_auto]">
<div className={cn("grid gap-3", showReset ? "md:grid-cols-[1fr_1fr_auto]" : "md:grid-cols-2")}>
<div className="space-y-2">
<Label>از تاریخ</Label>
<DatePicker
@@ -248,16 +252,31 @@ function DateRangeFilter({
containerClassName="w-full"
/>
</div>
<div className="flex items-end">
<Button variant="destructive" className="w-full gap-2 md:w-auto" onClick={onReset}>
<Eraser className="h-4 w-4" />
پاککردن
</Button>
</div>
{showReset ? (
<div className="flex items-end">
<FilterResetButton disabled={resetDisabled ?? (!value.from && !value.to)} onClick={onReset} />
</div>
) : null}
</div>
);
}
function FilterResetButton({ disabled, onClick }: { disabled: boolean; onClick: () => void }) {
return (
<Button
variant="destructive"
className="w-full gap-2 md:w-10 md:px-0"
onClick={onClick}
disabled={disabled}
title="پاک‌کردن"
aria-label="پاک‌کردن فیلترها"
>
<Eraser className="h-4 w-4" />
<span className="md:sr-only">پاککردن</span>
</Button>
);
}
function FilterCard({
title,
description,
@@ -1047,7 +1066,6 @@ function TopPostsCard({ posts }: { posts: BlogAnalyticsSchema["top_posts"] }) {
{formatNumberPersian(post.comments)} کامنت
</p>
</div>
<Badge variant="secondary">{toPersianDigits(index + 1)}</Badge>
</div>
))
) : (
@@ -1073,7 +1091,12 @@ function UsersSection({
return (
<div className="space-y-6" dir="rtl">
<FilterCard title="فیلتر کاربران" description="این فیلتر فقط روی کاربران و تاریخ عضویت آن‌ها اعمال می‌شود.">
<DateRangeFilter value={filters} onChange={onFiltersChange} onReset={() => onFiltersChange({ from: "", to: "" })} />
<DateRangeFilter
value={filters}
onChange={onFiltersChange}
onReset={() => onFiltersChange({ from: "", to: "" })}
resetDisabled={!filters.from && !filters.to}
/>
</FilterCard>
{query.isLoading ? <SectionLoading /> : null}
{query.isError ? <SectionError error={query.error} /> : null}
@@ -1131,12 +1154,13 @@ function EventsSection({
return (
<div className="space-y-6">
<FilterCard title="فیلتر رویدادها" description="این فیلتر فقط روی آمار رویداد، ثبت‌نام، درآمد و تنوع شرکت‌کنندگان اعمال می‌شود.">
<div className="grid gap-3 xl:grid-cols-[2fr_1.2fr]">
<div className="grid gap-3 xl:grid-cols-[2fr_1.2fr_auto]">
<div>
<DateRangeFilter
value={filters}
onChange={(next) => onFiltersChange({ ...filters, ...next })}
onReset={reset}
showReset={false}
/>
</div>
<div className="space-y-2">
@@ -1159,6 +1183,9 @@ function EventsSection({
emptyText="رویدادی پیدا نشد."
/>
</div>
<div className="flex items-end">
<FilterResetButton disabled={!filters.from && !filters.to && !filters.eventId} onClick={reset} />
</div>
</div>
</FilterCard>
{query.isLoading ? <SectionLoading /> : null}
@@ -1222,7 +1249,12 @@ function BlogSection({
return (
<div className="space-y-6">
<FilterCard title="فیلتر بلاگ" description="این فیلتر فقط روی نوشته‌ها و تعاملات بلاگ اعمال می‌شود و به رویدادها وابسته نیست.">
<DateRangeFilter value={filters} onChange={onFiltersChange} onReset={() => onFiltersChange({ from: "", to: "" })} />
<DateRangeFilter
value={filters}
onChange={onFiltersChange}
onReset={() => onFiltersChange({ from: "", to: "" })}
resetDisabled={!filters.from && !filters.to}
/>
</FilterCard>
{query.isLoading ? <SectionLoading /> : null}
{query.isError ? <SectionError error={query.error} /> : null}