feat(ui): mejorar el filtro segmentado de estado de proforma con iconos y soporte para múltiples valores

This commit is contained in:
David Arranz 2026-09-15 12:37:44 +02:00
parent 902f7806ed
commit 939577dbec

View File

@ -11,7 +11,8 @@ import {
import type { ElementType } from "react"; import type { ElementType } from "react";
import { useTranslation } from "../../../../i18n"; import { useTranslation } from "../../../../i18n";
import type { ProformaStatusCounts } from "../../../shared"; import { getProformaStatusDisplayIcon } from "../../../change-status/helpers";
import type { ProformaStatus, ProformaStatusCounts } from "../../../shared";
import type { ProformaListStatusFilter } from "../../types/proforma-list-filters"; import type { ProformaListStatusFilter } from "../../types/proforma-list-filters";
export type ProformaStatusFilter = ProformaListStatusFilter; export type ProformaStatusFilter = ProformaListStatusFilter;
@ -92,7 +93,9 @@ export const ProformaStatusSegmentedFilter = ({
}: ProformaStatusSegmentedFilterProps) => { }: ProformaStatusSegmentedFilterProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const handleValueChange = (nextValue: string) => { const handleValueChange = (nextValues: string[]) => {
const nextValue = nextValues[0];
if (!(nextValue && isProformaStatusFilter(nextValue)) || nextValue === value) { if (!(nextValue && isProformaStatusFilter(nextValue)) || nextValue === value) {
return; return;
} }
@ -103,47 +106,55 @@ export const ProformaStatusSegmentedFilter = ({
return ( return (
<ToggleGroup <ToggleGroup
aria-label={t("pages.proformas.list.filters.status.label")} aria-label={t("pages.proformas.list.filters.status.label")}
className="w-full flex-wrap justify-start gap-1" className="w-full flex-wrap justify-start gap-4"
disabled={disabled} disabled={disabled}
multiple={false}
onValueChange={handleValueChange} onValueChange={handleValueChange}
size="sm" size="sm"
spacing={1} spacing={1}
type="single" value={[value]}
value={value}
variant="outline" variant="outline"
> >
{PROFORMA_STATUS_FILTER_OPTIONS.map((option) => ( {PROFORMA_STATUS_FILTER_OPTIONS.map((option) => {
<ToggleGroupItem const normalizedStatus = option.value.toLowerCase() as ProformaStatus;
className={cn( const Icon = getProformaStatusDisplayIcon(normalizedStatus);
"group h-auto min-w-fit rounded-md border-transparent px-3 py-2 text-xs sm:text-sm shadow-none transition-colors",
"text-muted-foreground hover:border-border hover:bg-muted/60 hover:text-foreground", const disabled =
"data-[state=on]:shadow-none", "text-muted-foreground hover:border-border hover:bg-muted/60 hover:text-foreground";
option.activeClassName
)} return (
key={option.value} <ToggleGroupItem
onPointerDown={(event) => { className={cn(
if (option.value === value) { "group h-auto min-w-fit rounded-md border-none px-3 py-2 text-xs sm:text-sm shadow-none transition-colors",
event.preventDefault(); "data-[state=on]:shadow-none",
} disabled,
}} option.activeClassName
value={option.value} )}
> key={option.value}
<span className="flex items-center gap-2"> onPointerDown={(event) => {
{option.icon ? <option.icon className="size-3.5" /> : null} if (option.value === value) {
<span>{t(option.labelKey)}</span> event.preventDefault();
<RdxBadge }
className={cn( }}
"min-w-5 rounded-full px-1.5 text-[11px] font-semibold tabular-nums", value={option.value}
"bg-muted text-muted-foreground", >
"group-data-[state=on]:bg-white/20 group-data-[state=on]:text-current" <span className="flex items-center gap-2">
)} {option.icon ? <option.icon className="size-4" /> : null}
variant="secondary" <span>{t(option.labelKey)}</span>
> <RdxBadge
{counts[option.countKey]} className={cn(
</RdxBadge> "min-w-5 rounded-full px-1.5 text-[11px] font-semibold tabular-nums",
</span> "bg-muted text-muted-foreground",
</ToggleGroupItem> "group-data-[state=on]:bg-white/20 group-data-[state=on]:text-current"
))} )}
variant="secondary"
>
{counts[option.countKey]}
</RdxBadge>
</span>
</ToggleGroupItem>
);
})}
</ToggleGroup> </ToggleGroup>
); );
}; };