Files
boka-gasol247/src/lib/bookingStore.ts
2026-05-22 10:50:48 +02:00

103 lines
2.7 KiB
TypeScript

'use client';
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
// Persist booking form state across page navigations (e.g. when the user
// switches language mid-flow). sessionStorage so it's per-tab and cleared
// when the tab closes. Bumping STORE_VERSION invalidates old persisted state.
const STORE_VERSION = 1;
export type Step = 'products' | 'details' | 'pickup' | 'review';
export type BookingFormState = {
step: Step;
quantities: Record<string, number>;
contactName: string;
email: string;
phone: string;
orgName: string;
orgNumber: string;
address: string;
postalCode: string;
city: string;
country: string;
pickupSlotId: string | null;
notes: string;
confirm: boolean;
};
type BookingFormActions = {
setStep: (step: Step) => void;
setQuantity: (productId: string, qty: number) => void;
patch: (partial: Partial<BookingFormState>) => void;
reset: () => void;
};
const initial: BookingFormState = {
step: 'products',
quantities: {},
contactName: '',
email: '',
phone: '',
orgName: '',
orgNumber: '',
address: '',
postalCode: '',
city: '',
country: 'SE',
pickupSlotId: null,
notes: '',
confirm: false,
};
export const useBookingStore = create<BookingFormState & BookingFormActions>()(
persist(
(set) => ({
...initial,
setStep: (step) => set({ step }),
setQuantity: (productId, qty) =>
set((s) => {
const q = { ...s.quantities };
if (qty <= 0) delete q[productId];
else q[productId] = Math.min(999, Math.floor(qty));
return { quantities: q };
}),
patch: (partial) => set(partial as BookingFormState),
reset: () => set({ ...initial }),
}),
{
name: 'boka-gasol247:booking-form',
version: STORE_VERSION,
storage: createJSONStorage(() =>
typeof window === 'undefined'
? // SSR no-op
{
getItem: () => null,
setItem: () => {},
removeItem: () => {},
}
: window.sessionStorage,
),
// Don't persist `confirm` (re-check each session) or `step` if user
// hasn't started filling anything. Keeps the experience clean if they
// close and reopen a tab with stale state.
partialize: (s) => ({
step: s.step,
quantities: s.quantities,
contactName: s.contactName,
email: s.email,
phone: s.phone,
orgName: s.orgName,
orgNumber: s.orgNumber,
address: s.address,
postalCode: s.postalCode,
city: s.city,
country: s.country,
pickupSlotId: s.pickupSlotId,
notes: s.notes,
}),
},
),
);