ifixkart-storefront/lib/compare.ts

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');
}