"use client"; import { RiArrowDownSFill, RiStore3Line } from "@remixicon/react"; import { useEffect, useMemo, useRef, useState } from "react"; import type { PurchasesByCategoryData } from "@/features/dashboard/purchases-by-category-queries"; import { EstablishmentLogo } from "@/shared/components/entity-avatar"; import MoneyValues from "@/shared/components/money-values"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/shared/components/ui/select"; import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { CATEGORY_TYPE_LABEL } from "@/shared/lib/categories/constants"; import { formatTransactionDate } from "@/shared/utils/date"; type PurchasesByCategoryWidgetProps = { data: PurchasesByCategoryData; }; const STORAGE_KEY = "purchases-by-category-selected"; export function PurchasesByCategoryWidget({ data, }: PurchasesByCategoryWidgetProps) { const firstCategoryId = data.categories[0]?.id ?? ""; const hasRestoredSelectionRef = useRef(false); const hasPersistedSelectionRef = useRef(false); const [selectedCategoryId, setSelectedCategoryId] = useState(firstCategoryId); // Agrupa categorias por tipo const categoriesByType = useMemo(() => { const grouped: Record = {}; for (const category of data.categories) { if (!grouped[category.type]) { grouped[category.type] = []; } const typeGroup = grouped[category.type]; if (typeGroup) { typeGroup.push(category); } } return grouped; // eslint-disable-next-line react-hooks/exhaustive-deps }, [data.categories]); // Restaura a categoria salva apenas depois da montagem para manter SSR e cliente consistentes. useEffect(() => { if (hasRestoredSelectionRef.current) { return; } hasRestoredSelectionRef.current = true; const saved = sessionStorage.getItem(STORAGE_KEY); if (saved && data.categories.some((cat) => cat.id === saved)) { setSelectedCategoryId(saved); return; } setSelectedCategoryId(firstCategoryId); }, [data.categories, firstCategoryId]); // Salva a categoria selecionada quando mudar, sem sobrescrever o valor salvo na primeira montagem. useEffect(() => { if (!hasPersistedSelectionRef.current) { hasPersistedSelectionRef.current = true; return; } if (selectedCategoryId) { sessionStorage.setItem(STORAGE_KEY, selectedCategoryId); return; } sessionStorage.removeItem(STORAGE_KEY); }, [selectedCategoryId]); // Atualiza a categoria selecionada se ela não existir mais na lista useEffect(() => { if (!selectedCategoryId && firstCategoryId) { setSelectedCategoryId(firstCategoryId); return; } if ( selectedCategoryId && !data.categories.some((cat) => cat.id === selectedCategoryId) ) { setSelectedCategoryId(firstCategoryId); } }, [data.categories, firstCategoryId, selectedCategoryId]); const currentTransactions = useMemo(() => { if (!selectedCategoryId) { return []; } return data.transactionsByCategory[selectedCategoryId] ?? []; }, [selectedCategoryId, data.transactionsByCategory]); const selectedCategory = useMemo(() => { return data.categories.find((cat) => cat.id === selectedCategoryId); }, [data.categories, selectedCategoryId]); if (data.categories.length === 0) { return ( } title="Nenhuma categoria encontrada" description="Crie categorias de despesas ou receitas para visualizar as compras." /> ); } return (
{currentTransactions.length === 0 ? ( } title="Nenhuma compra encontrada" description={ selectedCategory ? `Não há lançamentos na categoria "${selectedCategory.name}".` : "Selecione uma categoria para visualizar as compras." } /> ) : (
{currentTransactions.map((transaction) => { return (

{transaction.name}

{formatTransactionDate(transaction.purchaseDate)}

); })}
)}
); }