From de235a3da7a177fc6b6094c05a2159d8780826f4 Mon Sep 17 00:00:00 2001 From: Nicolaj Hartmann Date: Fri, 30 Jan 2026 22:47:05 +0100 Subject: [PATCH] Fix company and fiscal year sync issues - Remove duplicate sync logic from CompanySwitcher (CompanyGuard handles it) - Validate persisted activeCompany against API response in CompanyGuard - Reset fiscal year state when switching companies in FiscalYearSelector - Validate currentFiscalYear belongs to current company's data Co-Authored-By: Claude Opus 4.5 --- frontend/src/components/auth/CompanyGuard.tsx | 32 ++++++--------- .../src/components/layout/CompanySwitcher.tsx | 22 ++--------- .../components/layout/FiscalYearSelector.tsx | 39 +++++++++++++------ 3 files changed, 42 insertions(+), 51 deletions(-) diff --git a/frontend/src/components/auth/CompanyGuard.tsx b/frontend/src/components/auth/CompanyGuard.tsx index 56dc900..c5f1e29 100644 --- a/frontend/src/components/auth/CompanyGuard.tsx +++ b/frontend/src/components/auth/CompanyGuard.tsx @@ -31,30 +31,20 @@ export default function CompanyGuard({ children }: CompanyGuardProps) { // Sync companies to store when loaded useEffect(() => { - if (companies) { + if (companies && companies.length > 0) { setCompanies(companies); - // Set active company if not already set - if (companies.length > 0 && !activeCompany) { - // Try to restore from localStorage - const stored = localStorage.getItem('books-company-storage'); - if (stored) { - try { - const parsed = JSON.parse(stored); - const storedCompany = parsed.state?.activeCompany; - if (storedCompany) { - const found = companies.find((c) => c.id === storedCompany.id); - if (found) { - setActiveCompany(found); - return; - } - } - } catch { - // Ignore parse errors - } - } - // Default to first company + // Validate that activeCompany exists in API response + const validCompany = activeCompany + ? companies.find((c) => c.id === activeCompany.id) + : null; + + if (!validCompany) { + // Persisted company doesn't exist - set to first setActiveCompany(companies[0]); + } else if (JSON.stringify(validCompany) !== JSON.stringify(activeCompany)) { + // Update with fresh data from API + setActiveCompany(validCompany); } } }, [companies, activeCompany, setCompanies, setActiveCompany]); diff --git a/frontend/src/components/layout/CompanySwitcher.tsx b/frontend/src/components/layout/CompanySwitcher.tsx index 896a493..02f8a78 100644 --- a/frontend/src/components/layout/CompanySwitcher.tsx +++ b/frontend/src/components/layout/CompanySwitcher.tsx @@ -1,8 +1,6 @@ -import { useEffect } from 'react'; import { Select, Space, Typography, Tag, Skeleton } from 'antd'; import { ShopOutlined } from '@ant-design/icons'; import { useCompanyStore } from '@/stores/companyStore'; -import { useMyCompanies } from '@/api/queries/companyQueries'; import { formatCVR } from '@/lib/formatters'; import type { Company } from '@/types/accounting'; @@ -13,18 +11,8 @@ interface CompanySwitcherProps { } export default function CompanySwitcher({ compact = false }: CompanySwitcherProps) { - const { data: companies = [], isLoading } = useMyCompanies(); - const { activeCompany, setActiveCompany, setCompanies } = useCompanyStore(); - - // Sync companies with store when data changes - useEffect(() => { - if (companies.length > 0) { - setCompanies(companies); - if (!activeCompany) { - setActiveCompany(companies[0]); - } - } - }, [companies, activeCompany, setActiveCompany, setCompanies]); + const { activeCompany, setActiveCompany } = useCompanyStore(); + const companies = useCompanyStore((state) => state.companies); const handleCompanyChange = (companyId: string) => { const company = companies.find((c) => c.id === companyId); @@ -33,12 +21,8 @@ export default function CompanySwitcher({ compact = false }: CompanySwitcherProp } }; - if (isLoading) { - return ; - } - if (companies.length === 0) { - return null; + return ; } return ( diff --git a/frontend/src/components/layout/FiscalYearSelector.tsx b/frontend/src/components/layout/FiscalYearSelector.tsx index 730a80e..c78ba03 100644 --- a/frontend/src/components/layout/FiscalYearSelector.tsx +++ b/frontend/src/components/layout/FiscalYearSelector.tsx @@ -1,6 +1,6 @@ // FiscalYearSelector - Dropdown for selecting active fiscal year (regnskabsar) -import { useState, useEffect } from 'react'; +import { useState, useEffect, useRef } from 'react'; import { Select, Space, Typography, Tag, Divider, Button, Skeleton } from 'antd'; import { CalendarOutlined, @@ -62,21 +62,38 @@ export default function FiscalYearSelector({ onCreateNew, onManage }: FiscalYear const [createModalOpen, setCreateModalOpen] = useState(false); - // Sync fiscal years with store when data changes + // Track company changes + const prevCompanyIdRef = useRef(activeCompany?.id); + + // Reset fiscal year state when company changes + useEffect(() => { + if (activeCompany?.id !== prevCompanyIdRef.current) { + const isInitialMount = prevCompanyIdRef.current === undefined; + prevCompanyIdRef.current = activeCompany?.id; + + if (!isInitialMount) { + // Company changed - reset fiscal year state + setFiscalYears([]); + setCurrentFiscalYear(null); + } + } + }, [activeCompany?.id, setFiscalYears, setCurrentFiscalYear]); + + // Sync fiscal years from API to store useEffect(() => { if (fiscalYearsData.length > 0) { setFiscalYears(fiscalYearsData); - } - }, [fiscalYearsData, setFiscalYears]); - // Set default fiscal year if none selected - useEffect(() => { - if (fiscalYears.length > 0 && !currentFiscalYear) { - // Default to most recent open year, or first year - const openYear = fiscalYears.find(y => y.status === 'open'); - setCurrentFiscalYear(openYear || fiscalYears[0]); + // Validate currentFiscalYear belongs to this company's data + const isValid = currentFiscalYear && + fiscalYearsData.some(fy => fy.id === currentFiscalYear.id); + + if (!isValid) { + const openYear = fiscalYearsData.find(y => y.status === 'open'); + setCurrentFiscalYear(openYear || fiscalYearsData[0]); + } } - }, [fiscalYears, currentFiscalYear, setCurrentFiscalYear]); + }, [fiscalYearsData, currentFiscalYear, setFiscalYears, setCurrentFiscalYear]); const handleFiscalYearChange = (yearId: string) => { const year = fiscalYears.find((y) => y.id === yearId);