created confirmation page
This commit is contained in:
parent
e170c9223a
commit
bb4d1adf73
6 changed files with 78 additions and 5 deletions
BIN
donutshop_ecommerce/public/check.png
Normal file
BIN
donutshop_ecommerce/public/check.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
BIN
donutshop_ecommerce/public/empty.png
Normal file
BIN
donutshop_ecommerce/public/empty.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -56,9 +56,12 @@ export async function POST(req){
|
||||||
line_items: stripeLineItems,
|
line_items: stripeLineItems,
|
||||||
mode: 'payment',
|
mode: 'payment',
|
||||||
customer_email: userEmail,
|
customer_email: userEmail,
|
||||||
success_url: process.env.NEXTAUTH_URL + 'cart?success=1',
|
success_url: process.env.NEXTAUTH_URL + 'orders/' + orderDoc._id.toString() + '?clear-cart=1',
|
||||||
cancel_url: process.env.NEXTAUTH_URL + 'cart?canceled=1',
|
cancel_url: process.env.NEXTAUTH_URL + 'cart?canceled=1',
|
||||||
metadata: {orderId: orderDoc._id.toString()},
|
metadata: {orderId: orderDoc._id.toString()},
|
||||||
|
payment_intent_data: {
|
||||||
|
metadata:{orderId:orderDoc._id.toString()},
|
||||||
|
},
|
||||||
shipping_options: [
|
shipping_options: [
|
||||||
{
|
{
|
||||||
shipping_rate_data: {
|
shipping_rate_data: {
|
||||||
|
|
|
@ -6,8 +6,20 @@ export async function POST(req){
|
||||||
let event;
|
let event;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const reqBuffer = await req.text();
|
||||||
|
const signSecret = process.env.STRIPE_SIGN_SECRET
|
||||||
|
event = stripe.webhooks.constructEvent(reqBuffer, sig, signSecret);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
return Response.json(error, {status: 400});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(event.type === 'checkout.session.completed'){
|
||||||
|
const orderId = event?.data?.object?.metadata?.orderId;
|
||||||
|
const isPaid = event?.data?.object?.payment_status === 'paid';
|
||||||
|
if (isPaid) {
|
||||||
|
await Order.updateOne({_id:orderId}, {paid:true});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.json('ok', {status: 200})
|
||||||
}
|
}
|
|
@ -5,12 +5,24 @@ import Image from 'next/image';
|
||||||
import { IoMdCloseCircleOutline } from "react-icons/io";
|
import { IoMdCloseCircleOutline } from "react-icons/io";
|
||||||
import AddressInfo from '../../components/layout/AddressInfo';
|
import AddressInfo from '../../components/layout/AddressInfo';
|
||||||
import useProfile from '../../components/UseProfile';
|
import useProfile from '../../components/UseProfile';
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
const CartPage = () => {
|
const CartPage = () => {
|
||||||
const {cartProducts, removeCartProduct} = useContext(CartContext);
|
const {cartProducts, removeCartProduct} = useContext(CartContext);
|
||||||
const [address, setAddress] = useState({})
|
const [address, setAddress] = useState({})
|
||||||
const {data:profileCheckoutData} = useProfile()
|
const {data:profileCheckoutData} = useProfile()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(typeof window !== 'undefined'){
|
||||||
|
if(window.location.href.includes('canceled=1')){
|
||||||
|
toast.error('Fail to make a payment!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if(profileCheckoutData?.city){
|
if(profileCheckoutData?.city){
|
||||||
const {phoneNumber, streetAddress, city, stateProvince, zipCode, country} = profileCheckoutData;
|
const {phoneNumber, streetAddress, city, stateProvince, zipCode, country} = profileCheckoutData;
|
||||||
|
@ -44,7 +56,21 @@ const CartPage = () => {
|
||||||
console.log({cartProducts})
|
console.log({cartProducts})
|
||||||
|
|
||||||
|
|
||||||
|
if(cartProducts?.length === 0){
|
||||||
|
return(
|
||||||
|
<div className='px-5 md:px-10 py-5 sm:py-10'>
|
||||||
|
<p className='text-center text-2xl sm:text-3xl md:text-4xl text-pink-500 uppercase font-bold drop-shadow-[0_2px_2px_rgba(105,105,105,1)] mb-10'>My cart</p>
|
||||||
|
<div className='flex flex-col gap-4 items-center justify-center text-center mb-10'>
|
||||||
|
<Image src='/empty.png' width={100} height={100} alt='empty-cart'/>
|
||||||
|
</div>
|
||||||
|
<p className='text-center mb-5 text-xl text-gray-700 font-semibold'>Empty Menu</p>
|
||||||
|
<p className='text-center mb-5 text-gray-500'>Look like you have not made your choice yet...</p>
|
||||||
|
<Link href='/menu' className='flex justify-center items-center text-center'>
|
||||||
|
<button type='botton' className='rounded-md bg-pink-500 text-white hover:opacity-80 duration-300 p-2 block'>Back to menu</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='pb-20 md:pb-40'>
|
<div className='pb-20 md:pb-40'>
|
||||||
|
@ -53,7 +79,7 @@ const CartPage = () => {
|
||||||
<div className='grid grid-cols-1 md:grid-cols-2 gap-10 mt-5 md:mt-10'>
|
<div className='grid grid-cols-1 md:grid-cols-2 gap-10 mt-5 md:mt-10'>
|
||||||
<div className='border-t'>
|
<div className='border-t'>
|
||||||
{cartProducts?.length === 0 && (
|
{cartProducts?.length === 0 && (
|
||||||
<div>Your cart is empty</div>
|
<p className='text-center mt-10'>Your cart is empty</p>
|
||||||
)}
|
)}
|
||||||
{cartProducts?.length > 0 && cartProducts.map((product, index) => (
|
{cartProducts?.length > 0 && cartProducts.map((product, index) => (
|
||||||
<div className='flex gap-2 justify-between items-center border-b'>
|
<div className='flex gap-2 justify-between items-center border-b'>
|
||||||
|
|
32
donutshop_ecommerce/src/app/orders/[id]/page.js
Normal file
32
donutshop_ecommerce/src/app/orders/[id]/page.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
"use client"
|
||||||
|
import Image from 'next/image'
|
||||||
|
import React, { useContext, useEffect } from 'react'
|
||||||
|
import { CartContext } from '../../../components/AppContext'
|
||||||
|
|
||||||
|
const OrdersPage = () => {
|
||||||
|
const {clearCart} = useContext(CartContext);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(typeof window !== 'undefined'){
|
||||||
|
if(window.location.href.includes('clear-cart=1')){
|
||||||
|
clearCart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='pb-20 md:pb-40'>
|
||||||
|
<div className='px-5 md:px-10 py-5 sm:py-10'>
|
||||||
|
<div className='flex flex-col gap-4 items-center justify-center text-center'>
|
||||||
|
<Image src='/check.png' width={100} height={100} alt='checked' className='mb-10'/>
|
||||||
|
<p className='uppercase'>Thank you</p>
|
||||||
|
<p className='uppercase text-xl'>Your order is confirmed</p>
|
||||||
|
<p className='text-sm'>We will be sending you an email confirmation to your email shortly</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OrdersPage
|
Loading…
Add table
Reference in a new issue