1
- import React from 'react'
1
+ import React , { useRef } from "react" ;
2
+ import Link from "next/link" ;
3
+ import {
4
+ AiOutlineMinus ,
5
+ AiOutlinePlus ,
6
+ AiOutlineShopping ,
7
+ AiOutlineLeft ,
8
+ } from "react-icons/ai" ;
9
+ import { TiDeleteOutline } from "react-icons/ti" ;
10
+ import toast from "react-hot-toast" ;
11
+
12
+ import { useStateContext } from "../context/StateContext" ;
13
+ import { urlFor } from "../lib/client" ;
14
+ import getStripe from "../lib/getStripe" ;
2
15
3
16
const Cart = ( ) => {
17
+ const cartRef = useRef ( ) ;
18
+ const {
19
+ totalPrice,
20
+ totalQuantities,
21
+ cartItems,
22
+ setShowCart,
23
+ toggleCartItemQuantity,
24
+ onRemove,
25
+ } = useStateContext ( ) ;
26
+
27
+ const handleCheckout = async ( ) => {
28
+ const stripe = await getStripe ( ) ;
29
+
30
+ const response = await fetch ( "/api/stripe" , {
31
+ method : "POST" ,
32
+ headers : {
33
+ "Content-Type" : "application/json" ,
34
+ } ,
35
+ body : JSON . stringify ( cartItems ) ,
36
+ } ) ;
37
+
38
+ if ( response . statusCode === 500 ) return ;
39
+
40
+ const data = await response . json ( ) ;
41
+
42
+ toast . loading ( "Redirecting..." ) ;
43
+
44
+ stripe . redirectToCheckout ( { sessionId : data . id } ) ;
45
+ } ;
46
+
4
47
return (
5
- < div > Cart</ div >
6
- )
7
- }
48
+ < div className = "cart-wrapper" ref = { cartRef } >
49
+ < div className = "cart-container" >
50
+ < button
51
+ type = "button"
52
+ className = "cart-heading"
53
+ onClick = { ( ) => setShowCart ( false ) }
54
+ >
55
+ < AiOutlineLeft />
56
+ < span className = "heading" > Your Cart</ span >
57
+ < span className = "cart-num-items" > ({ totalQuantities } items)</ span >
58
+ </ button >
59
+
60
+ { cartItems . length < 1 && (
61
+ < div className = "empty-cart" >
62
+ < AiOutlineShopping size = { 150 } />
63
+ < h3 > Your shopping bag is empty.</ h3 >
64
+ < Link href = "/" >
65
+ < button
66
+ type = "button"
67
+ className = "btn"
68
+ onClick = { ( ) => setShowCart ( false ) }
69
+ >
70
+ Continue Shopping
71
+ </ button >
72
+ </ Link >
73
+ </ div >
74
+ ) }
75
+
76
+ < div className = "product-container" >
77
+ { cartItems . length >= 1 &&
78
+ cartItems . map ( ( item , index ) => (
79
+ < div className = "product" key = { item . _id } >
80
+ < img
81
+ src = { urlFor ( item ?. image [ 0 ] ) }
82
+ className = "cart-product-image"
83
+ />
84
+ < div className = "item-desc" >
85
+ < div className = "flex top" >
86
+ < h5 > { item . name } </ h5 >
87
+ < h4 > ${ item . price } </ h4 >
88
+ </ div >
89
+ < div className = "flex bottom" >
90
+ < div >
91
+ < p className = "quantity-desc" >
92
+ < span
93
+ className = "minus"
94
+ onClick = { ( ) =>
95
+ toggleCartItemQuantity ( item . _id , "dec" )
96
+ }
97
+ >
98
+ < AiOutlineMinus />
99
+ </ span >
100
+ < span className = "num" onClick = "" >
101
+ { item . quantity }
102
+ </ span >
103
+ < span
104
+ className = "plus"
105
+ onClick = { ( ) =>
106
+ toggleCartItemQuantity ( item . _id , "inc" )
107
+ }
108
+ >
109
+ < AiOutlinePlus />
110
+ </ span >
111
+ </ p >
112
+ </ div >
113
+ < button
114
+ type = "button"
115
+ className = "remove-item"
116
+ onClick = { ( ) => onRemove ( item ) }
117
+ >
118
+ < TiDeleteOutline />
119
+ </ button >
120
+ </ div >
121
+ </ div >
122
+ </ div >
123
+ ) ) }
124
+ </ div >
125
+ { cartItems . length >= 1 && (
126
+ < div className = "cart-bottom" >
127
+ < div className = "total" >
128
+ < h3 > Subtotal:</ h3 >
129
+ < h3 > ${ totalPrice . toFixed ( 2 ) } </ h3 >
130
+ </ div >
131
+ < div className = "btn-container" >
132
+ < button type = "button" className = "btn" onClick = { handleCheckout } >
133
+ Pay with Stripe
134
+ </ button >
135
+ </ div >
136
+ </ div >
137
+ ) }
138
+ </ div >
139
+ </ div >
140
+ ) ;
141
+ } ;
8
142
9
- export default Cart
143
+ export default Cart ;
0 commit comments