import { create } from 'zustand'; import { persist } from 'zustand/middleware'; export interface LicensePayload { license_id: string; customer_email: string; tier: 'pro' | 'business'; features: string[]; issued_at: number; expires_at: number; max_activations: number; } export interface TrialState { started_at: number; } export type AppStatus = | { tag: 'Licensed'; license: LicensePayload } | { tag: 'Trial'; days_remaining: number; started_at: number } | { tag: 'Expired' }; interface LicenseState { status: AppStatus | null; isLoaded: boolean; showDialog: boolean; canEdit: boolean; } interface LicenseActions { setStatus: (status: AppStatus | null) => void; setShowDialog: (show: boolean) => void; checkStatus: () => Promise; activateLicense: (key: string) => Promise; deactivateLicense: () => Promise; hasFeature: (feature: string) => Promise; } export const useLicenseStore = create()( persist( (set) => ({ status: null, isLoaded: false, showDialog: false, canEdit: true, setStatus: (status) => { const canEdit = status?.tag === 'Licensed' || status?.tag === 'Trial'; set({ status, isLoaded: true, canEdit }); }, setShowDialog: (show) => set({ showDialog: show }), checkStatus: async () => { try { const status = await window.electronAPI?.getAppStatus(); const canEdit = status?.tag === 'Licensed' || status?.tag === 'Trial'; set({ status: status || { tag: 'Expired' }, isLoaded: true, canEdit }); } catch { set({ status: { tag: 'Expired' }, isLoaded: true, canEdit: false }); } }, activateLicense: async (key: string): Promise => { try { const license = await window.electronAPI?.activateLicense(key); if (!license) return false; set({ status: { tag: 'Licensed', license }, showDialog: false, canEdit: true }); return true; } catch { return false; } }, deactivateLicense: async () => { try { await window.electronAPI?.deactivateLicense(); const s = await window.electronAPI?.getAppStatus(); const canEdit = s?.tag === 'Licensed' || s?.tag === 'Trial'; set({ status: s || { tag: 'Expired' }, isLoaded: true, canEdit }); } catch { set({ status: { tag: 'Expired' }, isLoaded: true, canEdit: false }); } }, hasFeature: async (feature: string): Promise => { try { return await window.electronAPI?.hasLicenseFeature(feature) || false; } catch { return false; } }, }), { name: 'talkedit-license', partialize: (state) => { // Only persist Licensed status (trial is ephemeral) if (state.status?.tag === 'Licensed') { return { status: state.status }; } return {}; }, }, ), );