72 lines
1.8 KiB
TypeScript
72 lines
1.8 KiB
TypeScript
import { toast } from 'sonner';
|
|
import type { ProductResponse } from '@/services/api/catalogService';
|
|
import {
|
|
COMPARE_LIMIT,
|
|
isSameCompareProduct,
|
|
useCartStore,
|
|
type AddToCompareResult,
|
|
} from '@/store/cartStore';
|
|
|
|
export { COMPARE_LIMIT, isSameCompareProduct };
|
|
export type { AddToCompareResult };
|
|
|
|
export function notifyCompareResult(result: AddToCompareResult): boolean {
|
|
if (!result.ok) {
|
|
if (result.reason === 'type_mismatch') {
|
|
toast.error(
|
|
`You can only compare similar products. This list is for ${result.expected}.`
|
|
);
|
|
return false;
|
|
}
|
|
toast.error(`You can compare up to ${COMPARE_LIMIT} products. Remove one to add another.`);
|
|
return false;
|
|
}
|
|
if (result.already) {
|
|
toast.message('Already in comparison');
|
|
}
|
|
return true;
|
|
}
|
|
|
|
export function waitForCartHydration(timeoutMs = 500): Promise<void> {
|
|
if (useCartStore.getState()._hasHydrated) return Promise.resolve();
|
|
try {
|
|
if (useCartStore.persist.hasHydrated()) {
|
|
useCartStore.getState().setHasHydrated(true);
|
|
return Promise.resolve();
|
|
}
|
|
} catch {
|
|
/* persist API unavailable */
|
|
}
|
|
|
|
return new Promise((resolve) => {
|
|
let settled = false;
|
|
const finish = () => {
|
|
if (settled) return;
|
|
settled = true;
|
|
resolve();
|
|
};
|
|
|
|
try {
|
|
useCartStore.persist.onFinishHydration(() => {
|
|
useCartStore.getState().setHasHydrated(true);
|
|
finish();
|
|
});
|
|
} catch {
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
window.setTimeout(finish, timeoutMs);
|
|
});
|
|
}
|
|
|
|
export async function addToCompareAndNavigate(
|
|
product: ProductResponse,
|
|
navigate: (href: string) => void
|
|
): Promise<void> {
|
|
await waitForCartHydration();
|
|
const result = useCartStore.getState().addToCompare(product);
|
|
notifyCompareResult(result);
|
|
if (!result.ok && result.reason === 'type_mismatch') return;
|
|
navigate('/compare');
|
|
}
|