Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Fyrlex committed Sep 29, 2023
1 parent 690a218 commit 9a236e7
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 120 deletions.
23 changes: 10 additions & 13 deletions components/CheckoutForm.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { BaseSyntheticEvent, FC, useEffect, useState } from 'react';
import { BaseSyntheticEvent, FC, useState } from 'react';
import { PaymentElement, useStripe, useElements } from '@stripe/react-stripe-js';

import { FieldValues, useForm } from 'react-hook-form';
import { MoonLoader } from 'react-spinners';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { CloseIcon } from './Icons';

Expand All @@ -26,17 +25,15 @@ const CheckoutForm: FC<Props> = ({ paymentIntent }) => {
const nameSubmit = (data: FieldValues, e: BaseSyntheticEvent): void => {
e.preventDefault();

console.log(paymentIntent, 'customer');
setCustomer(prevCustomer => ({
...prevCustomer,
customer: {
name: data.fullName,
email: data.email,
payment_intent: paymentIntent,
}
},
}));

window.localStorage.setItem('customer', `{'name':'${data.fullName}','email':'${data.email}'}`);
setStep(2);
};

Expand Down Expand Up @@ -101,40 +98,40 @@ const CheckoutForm: FC<Props> = ({ paymentIntent }) => {
{step === 1 && (
<form id='address-form' onSubmit={handleSubmit((data, event) => nameSubmit(data, event!))}>
<label>
Full name
Volledige Naam
</label>
<input
className='appearance-none block w-full bg-[#F1F1F1] text-gray-700 rounded-lg py-3 px-4 mb-3 leading-tight border-[3.2px] border-white focus:border-[#F58989] focus:outline-[#FBD0D0] '
id='full-name'
type='text'
placeholder='First and last name'
placeholder='Voor- en achternaam'
minLength={1}
required
{...register('fullName', {
required: true, pattern: {
value: /^[a-zA-Z]+\s[a-zA-Z]+\s?$/,
message: 'Please submit only your first and last name',
message: 'Geef alleen je voor- en achternaam op.',
}
})}
/>
<label>
Email
E-mail
</label>
<input
className='block w-full bg-[#F1F1F1] text-gray-700 rounded-lg py-3 px-4 mb-3 leading-tight border-[3.2px] border-white focus:border-[#F58989] focus:outline-[#FBD0D0] '
type='email'
placeholder='Email'
placeholder='e-mailadres'
minLength={1}
required
{...register('email', {
required: true, pattern: {
value: /\S+@\S+\.\S+/,
message: 'Entered value does not match email format',
message: 'Voer een geldig e-mailadres in.',
}
})}
/>
<button type='submit' disabled={isLoading || !stripe || !elements} className='bottom-0 h-10 w-16 bg-[#F1F1F1] shadow-md flex items-center justify-center rounded-lg p-2 hover:bg-gray-300 transition-all duration-300 ease-in-out'>
Next
<button type='submit' disabled={isLoading || !stripe || !elements} className='bottom-0 p-2 bg-[#F1F1F1] shadow-md flex items-center justify-center rounded-lg p-2 hover:bg-gray-300 transition-all duration-300 ease-in-out'>
Volgende
</button>
</form>
)}
Expand Down
38 changes: 20 additions & 18 deletions components/PaymentStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useState, useEffect, FC } from 'react';
import { useStripe } from '@stripe/react-stripe-js';
import { useRouter } from 'next/router';
import OrderCartItem from './OrderCartItem';
import Cookies from 'js-cookie';

interface PaymentData {
amount: number,
Expand All @@ -28,6 +29,7 @@ const PaymentStatus: FC = () => {
name: '',
},
});

const [cart, setCart] = useState([]);
const [message, setMessage] = useState('');
const [redirect, setRedirect] = useState(false);
Expand All @@ -44,20 +46,20 @@ const PaymentStatus: FC = () => {

if (!clientSecret) return setRedirect(true);
if (window === undefined) return setRedirect(true);
if (!window.localStorage.getItem('cart')) return setRedirect(true);
if (!Cookies.get('cart')) return setRedirect(true);

stripe
.retrievePaymentIntent(clientSecret)
.then(({ paymentIntent }) => {
switch (paymentIntent?.status) {
case 'succeeded':
setMessage('Success! Payment received.');
setMessage('Succes! Betaling ontvangen.');
fetch('/api/stripe/payment_success', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ paymentIntent: paymentIntent.id, items: window.localStorage.getItem('cart') }),
body: JSON.stringify({ paymentIntent: paymentIntent.id, items: Cookies.get('cart') }),
}).then((req) => {
if (req.ok) window.localStorage.setItem('cart', '[]');
if (req.ok) Cookies.set('cart', '[]');
return req.json();
}).then(data => {
setData({
Expand All @@ -73,16 +75,16 @@ const PaymentStatus: FC = () => {
break;

case 'processing':
setMessage('Payment processing. We\'ll update you when payment is received.');
setMessage('Verwerking van betaling. We houden je op de hoogte wanneer de betaling is ontvangen.');
break;

case 'requires_payment_method':
setMessage('Payment failed. Please try another payment method.');
setMessage('Betaling mislukt. Probeer een andere betaalmethode.');
setRedirect(true);
break;

default:
setMessage('Something went wrong.');
setMessage('Er ging iets mis.');
setRedirect(true);
break;
}
Expand All @@ -95,12 +97,12 @@ const PaymentStatus: FC = () => {
<div className='grid place-items-center absolute inset-0 z-50 bg-black bg-opacity-80 w-full h-full rounded-lg'>
<div className='relative w-[25rem] h-11/12 right-0 left-0 z-51 bg-gray-200 rounded-lg'>
<div className='mt-2 mb-2 grid place-items-center text-center'>
<h2 className='text-xl'>{message || 'It looks like your checkout expired.'}</h2>
<h2 className='text-xl'>{message || 'Het lijkt erop dat je kassa is verlopen.'}</h2>
<div className='flex gap-3'>
<button onClick={(): void => {
router.push('/cart');
router.push('/webshop');
}} className='bottom-0 h-10 w-30 bg-red-500 shadow-md flex items-center justify-center rounded-full p-2 hover:bg-red-700 transition-all duration-300 ease-in-out'>
<p>Back to cart</p>
<p>Terug naar Webshop</p>
</button>
</div>
</div>
Expand All @@ -110,8 +112,8 @@ const PaymentStatus: FC = () => {
{!redirect && (
<div className='container flex flex-row text-black'>
<div>
<h1 className='text-2xl font-bold'>{message}</h1>
<p>Thank you for ordering, {data.customer.name}!</p>
<h1 className='text-3xl font-bold'>{message}</h1>
<p>Bedankt voor uw bestelling!</p>
<p>A confirmation email has been sent to <b>{data.customer.email}</b>.</p>
<table className='min-w-full divide-y divide-gray-200'>
<thead>
Expand All @@ -126,19 +128,19 @@ const PaymentStatus: FC = () => {
scope='col'
className='px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase '
>
Name
Product
</th>
<th
scope='col'
className='px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase '
>
Amount
Bedrag
</th>
<th
scope='col'
className='px-6 py-3 text-xs font-bold text-right text-gray-500 uppercase '
>
Price
Kosten
</th>
</tr>
</thead>
Expand All @@ -157,7 +159,7 @@ const PaymentStatus: FC = () => {
<td className='px-6 py-4 text-gray-800 whitespace-nowrap'>
</td>
<td className='px-6 py-4 text-sm text-gray-800 whitespace-nowrap'>
<p className='font-bold'>Total</p>
<p className='font-bold'>Totale</p>
</td>
<td className='px-6 py-4 text-sm font-medium text-right whitespace-nowrap'>
<p>{(data.amount / 100).toFixed(2)}</p>
Expand All @@ -167,8 +169,8 @@ const PaymentStatus: FC = () => {
</tbody>
</table>
<div>
<p className='font-bold'>Payment Details</p>
<p>Paid with {data.type}</p>
<p className='font-bold text-2xl'>Betalingsgegevens</p>
<p>Betaald met {data.type}</p>
<p>**** **** **** {data.last4}</p>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions components/ProductCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ const ProductCard: FC<Props> = ({ product, cart, setCart }) => {
<>
<div className='group bg-gray-200 p-4 rounded-lg shadow-md hover:scale-[1.04] transiton-all duration-[400ms] ease-in-out relative'>
<Image className={(product.stock === 0 ? 'grayscale ' : '') + 'w-52 rounded-lg transition-all duration-[400ms] ease-in-out group-hover:shadow-md group-hover:scale-[0.96]'} draggable={false} src={product.imageURL} alt={product.name} width='256' height='256' />
<h2 className='text-3xl font-bold m-1'>{product.name}</h2>
<h2 className='text-3xl font-bold my-1'>{product.name}</h2>
<p className='text-xl'>{product.price.toLocaleString('de')} EUR</p>
<h3>{product.stock.toLocaleString('de')} left in stock!</h3>
<p className='text-md'>Nog {product.stock.toLocaleString('de')} op voorraad!</p>
<div className='flex flex-row text-3xl items-center justify-center'>
<AiOutlinePlus className={product.stock === 0 ? 'cursor-not-allowed' : 'hover:cursor-pointer'} onClick={addItem} />
<AiOutlineMinus className={amount === 0 ? 'cursor-not-allowed' : 'hover:cursor-pointer'} onClick={removeItem} />
Expand Down
62 changes: 0 additions & 62 deletions lib/hooks/useLocalStorage.tsx

This file was deleted.

3 changes: 1 addition & 2 deletions pages/admin/evenementen/create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ const AdminCreateProducts: NextPage<{ user: { email: string, has2faEnabled: bool
const router = useRouter();

const [selected, setSelected] = useState<Date>();
console.log(selected);

const onSubmit = async (data: FieldValues, event?: BaseSyntheticEvent): Promise<void> => {
event?.preventDefault();
console.log(data);

try {
const req = await fetch('/api/events', {
method: 'POST',
Expand Down
1 change: 1 addition & 0 deletions pages/admin/sponsors/create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const AdminCreateSponsors: NextPage<{ user: { email: string, has2faEnabled: bool
url: data.url,
}),
});

if (req.ok) {
console.log('ok');
} else if (req.status === 401) {
Expand Down
2 changes: 2 additions & 0 deletions pages/api/stripe/customer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export default async function customerHandler(
case 'POST': {
const { customer } = req.body.customer;

console.log(customer);

if (!customer.payment_intent || !customer.email || !customer.name || !customer.name.match(/^[a-zA-Z]+\s[a-zA-Z]+\s?$/)) {
res.status(StatusCodes.BAD_REQUEST).json({
error: true,
Expand Down
22 changes: 12 additions & 10 deletions pages/api/stripe/payment_success.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,24 @@ import { ResponseData } from '../../../src/types';
import dbConnect from '../../../src/util/dbConnect';
import { Stripe } from 'stripe';
import { mail } from '../../../src/mail';
import { IProduct, Order, Product } from '../../../src/models';
import { Order, Product } from '../../../src/models';
import { DisplayProduct } from '../../../components/ProductCard';

const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY, {
apiVersion: '2022-11-15',
});

dbConnect();

const parseCart = async (items: string): Promise<IProduct[]> => {
const cart = [];
const parsedItems = JSON.parse(items);
const parseCart = async (items: string): Promise<DisplayProduct[]> => {
const parsedItems = JSON.parse(items) as DisplayProduct[];

for (const item of parsedItems) {
const product = await Product.findOne({ _id: item.id });
for (let i = 0; i < parsedItems.length; i++) {
const product = await Product.findOne({ _id: parsedItems[i]._id });

if (product!.stock < item.amount) item.amount = product!.stock;

cart.push(item);
if (product!.stock < parsedItems[i].amount) parsedItems[i].amount = product!.stock;
}

return parsedItems;
};

Expand All @@ -45,15 +44,18 @@ interface PaymentIntent {

export default async function paymentHandler(
req: Omit<NextApiRequest, 'body'> & { body: Body; },
res: NextApiResponse<ResponseData<PaymentIntent & { cart: IProduct[]; } | null>>,
res: NextApiResponse<ResponseData<PaymentIntent & { cart: DisplayProduct[]; } | null>>,
): Promise<void> {
switch (req.method) {
case 'POST': {
const paymentIntent = await stripe.paymentIntents.retrieve(req.body.paymentIntent);

switch (paymentIntent?.status) {
case 'succeeded': {
console.log(paymentIntent.customer);
const customer = await stripe.customers.retrieve(paymentIntent.customer as string) as Stripe.Customer;
const cart = await parseCart(req.body.items);

const paymentMethod = await stripe.paymentMethods.retrieve(paymentIntent.payment_method as string);

if (!customer) {
Expand Down
11 changes: 7 additions & 4 deletions pages/checkout.tsx → pages/kassa.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,19 @@ const Checkout: NextPage = () => {
}).catch(console.error);
}, []);


return (
<>
{useMetaData('Checkout', 'Checkout', '/checkout')}
{useMetaData('Kassa', 'Kassa', '/kassa')}
<Layout>
{clientSecret && (
{clientSecret.length ? (
<Elements options={{ clientSecret, appearance: { theme: 'flat', variables: { colorPrimary: '#EF4444' } }, loader: 'always' }} stripe={stripePromise}>
<CheckoutForm paymentIntent={paymentIntent} />
</Elements>
)}
) :
(<div className='container'>
<h1 className='text-5xl my-5'>Je winkelwagentje is leeg.</h1>
<p className='text-2xl'> Maak een selectie in de <button className='text-red-500 hover:text-red-600 duration-300' onClick={(): string => window.location.href = '/webshop'}>webshop</button>.</p>
</div>)}
</Layout>
</>
);
Expand Down
Loading

0 comments on commit 9a236e7

Please sign in to comment.