11export const useCart = ( ) => {
2- const cart = useState ( 'cart' , ( ) => [ ] ) ;
3- const addToCartButtonStatus = ref ( 'add' ) ;
4- const removeFromCartButtonStatus = ref ( 'remove' ) ;
5- const { push } = useNotivue ( ) ;
6-
7- const handleAddToCart = productId => {
8- addToCartButtonStatus . value = 'loading' ;
9-
10- $fetch ( '/api/cart/add' , {
11- method : 'POST' ,
12- body : { productId } ,
13- } )
14- . then ( res => {
15- updateCart ( [ ...cart . value , res . addToCart . cartItem ] ) ;
16- addToCartButtonStatus . value = 'added' ;
17- setTimeout ( ( ) => ( addToCartButtonStatus . value = 'add' ) , 2000 ) ;
18- } )
19- . catch ( err => {
20- addToCartButtonStatus . value = 'add' ;
21- const errorMessage = err . response . errors [ 0 ] . message
22- . replace ( / < a [ ^ > ] * > ( .* ?) < \/ a > / g, '' )
23- . replace ( / & m d a s h ; / g, '—' )
24- . trim ( ) ;
25- push . error ( errorMessage ) ;
26- } ) ;
27- } ;
28-
29- const handleRemoveFromCart = key => {
30- removeFromCartButtonStatus . value = 'loading' ;
31- $fetch ( '/api/cart/update' , {
32- method : 'POST' ,
33- body : { items : [ { key, quantity : 0 } ] } ,
34- } ) . then ( ( ) => {
35- removeFromCartButtonStatus . value = 'remove' ;
36- updateCart ( cart . value . filter ( item => item . key !== key ) ) ;
2+ const cart = useState ( 'cart' , ( ) => [ ] ) ;
3+ const itemStatus = useState ( 'itemStatus' , ( ) => ( { } ) ) ;
4+ const { push } = useNotivue ( ) ;
5+
6+ const clearStatusAfterDelay = ( key , delay = 2000 ) => {
7+ setTimeout ( ( ) => {
8+ if ( itemStatus . value [ key ] ) {
9+ itemStatus . value [ key ] = 'idle' ;
10+ }
11+ } , delay ) ;
12+ } ;
13+
14+ const updateCartCache = ( newCart ) => {
15+ cart . value = newCart ;
16+ if ( process . client ) {
17+ localStorage . setItem ( 'cart' , JSON . stringify ( newCart ) ) ;
18+ }
19+ } ;
20+
21+ const handleAddToCart = ( productId ) => {
22+ itemStatus . value [ productId ] = 'loading' ;
23+
24+ const existingItem = cart . value . find ( item => item . variation ?. node . databaseId === productId ) ;
25+ if ( existingItem ) {
26+ increaseQuantity ( existingItem ) ;
27+ return ;
28+ }
29+
30+ $fetch ( '/api/cart/add' , {
31+ method : 'POST' ,
32+ body : { productId } ,
33+ } )
34+ . then ( res => {
35+ const newItem = res . addToCart . cartItem ;
36+ updateCartCache ( [ ...( cart . value || [ ] ) , newItem ] ) ;
37+
38+ const statusKey = newItem . key ;
39+ itemStatus . value [ statusKey ] = 'added' ;
40+ clearStatusAfterDelay ( statusKey ) ;
41+
42+ if ( statusKey !== productId ) {
43+ delete itemStatus . value [ productId ] ;
44+ }
45+ } )
46+ . catch ( err => {
47+ itemStatus . value [ productId ] = 'idle' ;
48+ const errorMessage = err . response ?. errors ?. [ 0 ] ?. message ?. replace ( / < a [ ^ > ] * > ( .* ?) < \/ a > / g, '' ) . trim ( ) || 'Could not add item.' ;
49+ push . error ( { message : errorMessage } ) ;
50+ } ) ;
51+ } ;
52+
53+ const updateItemQuantity = ( item , newQuantity ) => {
54+ const statusKey = item . key ;
55+ itemStatus . value [ statusKey ] = 'loading' ;
56+
57+ if ( newQuantity <= 0 ) {
58+ handleRemoveFromCart ( item . key ) ;
59+ return ;
60+ }
61+
62+ $fetch ( '/api/cart/update' , {
63+ method : 'POST' ,
64+ body : { items : [ { key : item . key , quantity : newQuantity } ] } ,
65+ } )
66+ . then ( ( ) => {
67+ const isIncreasing = newQuantity > item . quantity ;
68+ const isDecreasing = newQuantity < item . quantity ;
69+
70+ const newCart = cart . value . map ( cartItem =>
71+ cartItem . key === item . key ? { ...cartItem , quantity : newQuantity } : cartItem
72+ ) ;
73+ updateCartCache ( newCart ) ;
74+
75+ if ( isIncreasing ) {
76+ itemStatus . value [ statusKey ] = 'increased' ;
77+ } else if ( isDecreasing ) {
78+ itemStatus . value [ statusKey ] = 'decreased' ;
79+ }
80+
81+ clearStatusAfterDelay ( statusKey ) ;
82+ } )
83+ . catch ( err => {
84+ itemStatus . value [ statusKey ] = 'idle' ;
85+ const errorMessage = err . response ?. errors ?. [ 0 ] ?. message ?. replace ( / < a [ ^ > ] * > ( .* ?) < \/ a > / g, '' ) . trim ( ) || 'Could not update quantity.' ;
86+ push . error ( { message : errorMessage } ) ;
87+ } ) ;
88+ } ;
89+
90+ const increaseQuantity = item => updateItemQuantity ( item , item . quantity + 1 ) ;
91+ const decreaseQuantity = item => updateItemQuantity ( item , item . quantity - 1 ) ;
92+
93+ const handleRemoveFromCart = key => {
94+ itemStatus . value [ key ] = 'loading' ;
95+ $fetch ( '/api/cart/update' , {
96+ method : 'POST' ,
97+ body : { items : [ { key, quantity : 0 } ] } ,
98+ } ) . then ( ( ) => {
99+ updateCartCache ( cart . value . filter ( item => item . key !== key ) ) ;
100+ delete itemStatus . value [ key ] ;
101+ } ) . catch ( ( ) => {
102+ itemStatus . value [ key ] = 'idle' ;
103+ push . error ( { message : 'Could not remove item from cart.' } ) ;
104+ } ) ;
105+ } ;
106+
107+ onMounted ( ( ) => {
108+ if ( process . client ) {
109+ const storedCart = localStorage . getItem ( 'cart' ) ;
110+ if ( storedCart ) cart . value = JSON . parse ( storedCart ) ;
111+ }
37112 } ) ;
38- } ;
39-
40- const updateCart = newCart => {
41- cart . value = newCart ;
42- localStorage . setItem ( 'cart' , JSON . stringify ( newCart ) ) ;
43- } ;
44-
45- onMounted ( ( ) => {
46- const storedCart = localStorage . getItem ( 'cart' ) ;
47- if ( storedCart ) cart . value = JSON . parse ( storedCart ) ;
48- } ) ;
49-
50- return {
51- cart,
52- handleAddToCart,
53- addToCartButtonStatus,
54- handleRemoveFromCart,
55- removeFromCartButtonStatus,
56- } ;
57- } ;
113+
114+ return {
115+ cart,
116+ itemStatus,
117+ handleAddToCart,
118+ increaseQuantity,
119+ decreaseQuantity,
120+ handleRemoveFromCart,
121+ } ;
122+ } ;
0 commit comments