113 lines
2.8 KiB
TypeScript
113 lines
2.8 KiB
TypeScript
'use client';
|
|
|
|
import React, { createContext, useContext, useReducer, useEffect, ReactNode } from 'react';
|
|
import { toast } from 'sonner';
|
|
import {
|
|
wishlistReducer,
|
|
isInWishlist,
|
|
getWishlistCount,
|
|
} from '@/domain/wishlist/wishlist-domain';
|
|
import type { WishlistItem, NewWishlistItem } from '@/domain/wishlist/entities';
|
|
import { container } from '@/infrastructure/di/container';
|
|
|
|
export type { WishlistItem };
|
|
|
|
interface WishlistContextType {
|
|
items: WishlistItem[];
|
|
isOpen: boolean;
|
|
totalItems: number;
|
|
toggleWishlist: (item: NewWishlistItem) => void;
|
|
removeFromWishlist: (id: string) => void;
|
|
clearWishlist: () => void;
|
|
isWishlisted: (id: string) => boolean;
|
|
toggleDrawer: () => void;
|
|
openWishlist: () => void;
|
|
closeWishlist: () => void;
|
|
}
|
|
|
|
const WishlistContext = createContext<WishlistContextType | undefined>(undefined);
|
|
|
|
export function WishlistProvider({ children }: { children: ReactNode }) {
|
|
const [state, dispatch] = useReducer(wishlistReducer, {
|
|
items: [],
|
|
isOpen: false,
|
|
});
|
|
|
|
useEffect(() => {
|
|
const savedItems = container.wishlistRepository.load();
|
|
if (savedItems.length > 0) {
|
|
dispatch({ type: 'RESTORE_ITEMS', payload: savedItems });
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
container.wishlistRepository.save(state.items);
|
|
}, [state.items]);
|
|
|
|
const totalItems = getWishlistCount(state.items);
|
|
|
|
const toggleWishlist = (item: NewWishlistItem) => {
|
|
const wasInList = isInWishlist(state.items, item.id);
|
|
dispatch({ type: 'TOGGLE_ITEM', payload: item });
|
|
|
|
if (wasInList) {
|
|
toast.info(`Removed ${item.name} from wishlist`);
|
|
} else {
|
|
toast.success(`Saved ${item.name} to wishlist`, {
|
|
action: {
|
|
label: 'View',
|
|
onClick: () => dispatch({ type: 'OPEN_DRAWER' }),
|
|
},
|
|
});
|
|
}
|
|
};
|
|
|
|
const removeFromWishlist = (id: string) => {
|
|
dispatch({ type: 'REMOVE_ITEM', payload: id });
|
|
};
|
|
|
|
const clearWishlist = () => {
|
|
dispatch({ type: 'CLEAR_WISHLIST' });
|
|
};
|
|
|
|
const isWishlisted = (id: string) => isInWishlist(state.items, id);
|
|
|
|
const toggleDrawer = () => {
|
|
dispatch({ type: 'TOGGLE_DRAWER' });
|
|
};
|
|
|
|
const openWishlist = () => {
|
|
dispatch({ type: 'OPEN_DRAWER' });
|
|
};
|
|
|
|
const closeWishlist = () => {
|
|
dispatch({ type: 'CLOSE_DRAWER' });
|
|
};
|
|
|
|
return (
|
|
<WishlistContext.Provider
|
|
value={{
|
|
items: state.items,
|
|
isOpen: state.isOpen,
|
|
totalItems,
|
|
toggleWishlist,
|
|
removeFromWishlist,
|
|
clearWishlist,
|
|
isWishlisted,
|
|
toggleDrawer,
|
|
openWishlist,
|
|
closeWishlist,
|
|
}}
|
|
>
|
|
{children}
|
|
</WishlistContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useWishlist() {
|
|
const context = useContext(WishlistContext);
|
|
if (context === undefined) {
|
|
throw new Error('useWishlist must be used within a WishlistProvider');
|
|
}
|
|
return context;
|
|
} |