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 <noreply@anthropic.com>
This commit is contained in:
Nicolaj Hartmann 2026-01-30 22:47:05 +01:00
parent 7d819ace28
commit de235a3da7
3 changed files with 42 additions and 51 deletions

View file

@ -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]);

View file

@ -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 <Skeleton.Input style={{ width: 200 }} active />;
}
if (companies.length === 0) {
return null;
return <Skeleton.Input style={{ width: 200 }} active />;
}
return (

View file

@ -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<string | undefined>(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);