@@ -10,9 +10,7 @@ import Button from '@/components/UI/Button.component';
1010
1111import {
1212 getFormattedCart ,
13- getUpdatedItems ,
1413 handleQuantityChange ,
15- IProductRootObject ,
1614} from '@/utils/functions/functions' ;
1715
1816import { GET_CART } from '@/utils/gql/GQL_QUERIES' ;
@@ -23,146 +21,113 @@ const CartContents = () => {
2321 const { cart, setCart } = useCartStore ( ) ;
2422 const isCheckoutPage = router . pathname === '/kasse' ;
2523
26- const { data } = useQuery ( GET_CART , {
24+ useQuery ( GET_CART , {
2725 notifyOnNetworkStatusChange : true ,
2826 onCompleted : ( data ) => {
27+ // Only update if there's a significant difference to avoid unnecessary re-renders
2928 const updatedCart = getFormattedCart ( data ) as RootObject | undefined ;
30- setCart ( updatedCart || null ) ;
29+ if ( ! cart || cart . totalProductsCount !== updatedCart ?. totalProductsCount ) {
30+ setCart ( updatedCart || null ) ;
31+ }
3132 } ,
3233 } ) ;
3334
34- const [ updateCart ] = useMutation ( UPDATE_CART , {
35- refetchQueries : [ { query : GET_CART } ] ,
36- awaitRefetchQueries : true ,
37- } ) ;
38-
39- const handleRemoveProductClick = (
40- cartKey : string ,
41- products : IProductRootObject [ ] ,
42- ) => {
43- if ( products ?. length ) {
44- // Optimistically update local state
45- const currentCart = cart ;
46- if ( currentCart ) {
47- const updatedProducts = currentCart . products . filter ( ( p : Product ) => p . cartKey !== cartKey ) ;
48- setCart ( {
49- ...currentCart ,
50- products : updatedProducts ,
51- totalProductsCount : currentCart . totalProductsCount - 1
52- } ) ;
53- }
35+ const [ updateCart ] = useMutation ( UPDATE_CART ) ;
5436
55- // Update remote state in background
56- const updatedItems = getUpdatedItems ( products , 0 , cartKey ) ;
57- updateCart ( {
58- variables : {
59- input : {
60- clientMutationId : uuidv4 ( ) ,
61- items : updatedItems ,
62- } ,
63- } ,
37+ const handleRemoveProductClick = ( cartKey : string ) => {
38+ // Optimistically update local state
39+ if ( cart ) {
40+ const updatedProducts = cart . products . filter ( ( p : Product ) => p . cartKey !== cartKey ) ;
41+ const removedProduct = cart . products . find ( ( p : Product ) => p . cartKey === cartKey ) ;
42+ const qtyRemoved = removedProduct ?. qty || 0 ;
43+
44+ setCart ( {
45+ ...cart ,
46+ products : updatedProducts ,
47+ totalProductsCount : cart . totalProductsCount - qtyRemoved
6448 } ) ;
6549 }
66- } ;
6750
68- const cartTotal = data ?. cart ?. total || '0' ;
69-
70- const getUnitPrice = ( subtotal : string , quantity : number ) => {
71- const numericSubtotal = parseFloat ( subtotal . replace ( / [ ^ 0 - 9 . - ] + / g, '' ) ) ;
72- return isNaN ( numericSubtotal )
73- ? 'N/A'
74- : ( numericSubtotal / quantity ) . toFixed ( 2 ) ;
51+ // Update remote state in background
52+ updateCart ( {
53+ variables : {
54+ input : {
55+ clientMutationId : uuidv4 ( ) ,
56+ items : [ {
57+ key : cartKey ,
58+ quantity : 0
59+ } ] ,
60+ } ,
61+ } ,
62+ } ) ;
7563 } ;
7664
7765 return (
7866 < div className = "container mx-auto px-4 py-8" >
79- { data ?. cart ?. contents ?. nodes ?. length ? (
67+ { cart ?. products ?. length ? (
8068 < >
8169 < div className = "bg-white rounded-lg p-6 mb-8 md:w-full" >
82- { data . cart . contents . nodes . map ( ( item : IProductRootObject ) => (
70+ { cart . products . map ( ( item : Product ) => (
8371 < div
84- key = { item . key }
72+ key = { item . cartKey }
8573 className = "flex items-center border-b border-gray-200 py-4"
8674 >
8775 < div className = "flex-shrink-0 w-24 h-24 relative hidden md:block" >
8876 < Image
89- src = {
90- item . product . node . image ?. sourceUrl || '/placeholder.png'
91- }
92- alt = { item . product . node . name }
77+ src = { item . image ?. sourceUrl || '/placeholder.png' }
78+ alt = { item . name }
9379 layout = "fill"
9480 objectFit = "cover"
9581 className = "rounded"
9682 />
9783 </ div >
9884 < div className = "flex-grow ml-4" >
9985 < h2 className = "text-lg font-semibold" >
100- { item . product . node . name }
86+ { item . name }
10187 </ h2 >
10288 < p className = "text-gray-600" >
103- kr { getUnitPrice ( item . subtotal , item . quantity ) }
89+ kr { item . price }
10490 </ p >
10591 </ div >
10692 < div className = "flex items-center" >
10793 < input
10894 type = "number"
10995 min = "1"
110- value = { item . quantity }
96+ value = { item . qty }
11197 onChange = { ( event : ChangeEvent < HTMLInputElement > ) => {
11298 const newQty = parseInt ( event . target . value , 10 ) ;
11399 if ( isNaN ( newQty ) || newQty < 1 ) return ;
114100
115- // Optimistically update local state
116- if ( cart ) {
117- const oldProduct = cart . products . find ( ( p : Product ) => p . cartKey === item . key ) ;
118- const oldQty = oldProduct ?. qty || 0 ;
119- const updatedProducts = cart . products . map ( ( p : Product ) =>
120- p . cartKey === item . key ? { ...p , qty : newQty } : p
121- ) ;
122-
123- // Calculate new total count
124- const qtyDiff = newQty - oldQty ;
125- const newTotalCount = cart . totalProductsCount + qtyDiff ;
126-
127- setCart ( {
128- ...cart ,
129- products : updatedProducts ,
130- totalProductsCount : newTotalCount
131- } ) ;
132- }
101+ // Update local state
102+ useCartStore . getState ( ) . updateProductQuantity ( item . cartKey , newQty ) ;
133103
134104 // Update remote state in background
135105 handleQuantityChange (
136106 event ,
137- item . key ,
138- data . cart . contents . nodes ,
107+ item . cartKey ,
108+ newQty ,
139109 updateCart
140110 ) ;
141111 } }
142112 className = "w-16 px-2 py-1 text-center border border-gray-300 rounded mr-2"
143113 />
144114 < Button
145- handleButtonClick = { ( ) =>
146- handleRemoveProductClick (
147- item . key ,
148- data . cart . contents . nodes ,
149- )
150- }
115+ handleButtonClick = { ( ) => handleRemoveProductClick ( item . cartKey ) }
151116 variant = "secondary"
152117 >
153118 Fjern
154119 </ Button >
155120 </ div >
156121 < div className = "ml-4" >
157- < p className = "text-lg font-semibold" > { item . subtotal } </ p >
122+ < p className = "text-lg font-semibold" > { item . totalPrice } </ p >
158123 </ div >
159124 </ div >
160125 ) ) }
161126 </ div >
162127 < div className = "bg-white rounded-lg p-6 md:w-full" >
163128 < div className = "flex justify-end mb-4" >
164129 < span className = "font-semibold pr-2" > Subtotal:</ span >
165- < span > { cartTotal } </ span >
130+ < span > { cart . totalProductsPrice } </ span >
166131 </ div >
167132 { ! isCheckoutPage && (
168133 < div className = "flex justify-center mb-4" >
0 commit comments