2026-01-18 02:52:30 +01:00
|
|
|
import { create } from 'zustand';
|
|
|
|
|
import { persist } from 'zustand/middleware';
|
2026-02-05 21:35:26 +01:00
|
|
|
import type { CompanyRole, CompanyWithRole } from '@/types/accounting';
|
2026-01-18 02:52:30 +01:00
|
|
|
|
|
|
|
|
interface CompanyState {
|
2026-02-05 21:35:26 +01:00
|
|
|
// Current active company (includes role from myCompanies query)
|
|
|
|
|
activeCompany: CompanyWithRole | null;
|
|
|
|
|
// List of available companies (includes role from myCompanies query)
|
|
|
|
|
companies: CompanyWithRole[];
|
2026-01-18 02:52:30 +01:00
|
|
|
// Loading state
|
|
|
|
|
isLoading: boolean;
|
|
|
|
|
|
|
|
|
|
// Actions
|
2026-02-05 21:35:26 +01:00
|
|
|
setActiveCompany: (company: CompanyWithRole) => void;
|
|
|
|
|
setCompanies: (companies: CompanyWithRole[]) => void;
|
2026-01-18 02:52:30 +01:00
|
|
|
setLoading: (loading: boolean) => void;
|
|
|
|
|
clearActiveCompany: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const useCompanyStore = create<CompanyState>()(
|
|
|
|
|
persist(
|
|
|
|
|
(set) => ({
|
|
|
|
|
activeCompany: null,
|
|
|
|
|
companies: [],
|
|
|
|
|
isLoading: false,
|
|
|
|
|
|
|
|
|
|
setActiveCompany: (company) =>
|
|
|
|
|
set({ activeCompany: company }),
|
|
|
|
|
|
|
|
|
|
setCompanies: (companies) =>
|
|
|
|
|
set({ companies }),
|
|
|
|
|
|
|
|
|
|
setLoading: (isLoading) =>
|
|
|
|
|
set({ isLoading }),
|
|
|
|
|
|
|
|
|
|
clearActiveCompany: () =>
|
|
|
|
|
set({ activeCompany: null }),
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
name: 'books-company-storage',
|
|
|
|
|
partialize: (state) => ({
|
|
|
|
|
activeCompany: state.activeCompany,
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Selector hooks for convenience
|
|
|
|
|
export const useActiveCompany = () =>
|
|
|
|
|
useCompanyStore((state) => state.activeCompany);
|
|
|
|
|
|
|
|
|
|
export const useCompanies = () =>
|
|
|
|
|
useCompanyStore((state) => state.companies);
|
2026-01-30 14:36:27 +01:00
|
|
|
|
|
|
|
|
// Get the current user's role for the active company
|
2026-02-05 21:35:26 +01:00
|
|
|
// Returns the role from the myCompanies query data stored on the active company
|
2026-01-30 14:36:27 +01:00
|
|
|
export const useActiveCompanyRole = (): CompanyRole => {
|
2026-02-05 21:35:26 +01:00
|
|
|
const activeCompany = useCompanyStore((state) => state.activeCompany);
|
|
|
|
|
// Return the actual role from the CompanyWithRole data, default to 'viewer' if not set
|
|
|
|
|
return activeCompany?.role ?? 'viewer';
|
2026-01-30 14:36:27 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Helper functions for user roles
|
|
|
|
|
export function getRoleLabel(role: CompanyRole): string {
|
|
|
|
|
switch (role) {
|
|
|
|
|
case 'owner':
|
|
|
|
|
return 'Ejer';
|
|
|
|
|
case 'accountant':
|
|
|
|
|
return 'Bogholder';
|
|
|
|
|
case 'viewer':
|
|
|
|
|
return 'Læser';
|
|
|
|
|
default:
|
|
|
|
|
return role;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRoleColor(role: CompanyRole): string {
|
|
|
|
|
switch (role) {
|
|
|
|
|
case 'owner':
|
|
|
|
|
return 'gold';
|
|
|
|
|
case 'accountant':
|
|
|
|
|
return 'blue';
|
|
|
|
|
case 'viewer':
|
|
|
|
|
return 'default';
|
|
|
|
|
default:
|
|
|
|
|
return 'default';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Hook to check if current user can administer the company
|
2026-02-05 21:35:26 +01:00
|
|
|
// Checks if the user has Owner role for the active company
|
2026-01-30 14:36:27 +01:00
|
|
|
export function useCanAdmin(): boolean {
|
2026-02-05 21:35:26 +01:00
|
|
|
const role = useActiveCompanyRole();
|
|
|
|
|
return role === 'owner';
|
2026-01-30 14:36:27 +01:00
|
|
|
}
|