Skip to content

Commit

Permalink
WIP refactor to work with app router
Browse files Browse the repository at this point in the history
  • Loading branch information
tuomaskontolacr committed Sep 13, 2023
1 parent f6767e8 commit b29ad34
Show file tree
Hide file tree
Showing 63 changed files with 6,037 additions and 4,185 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@ yarn-error.log*

# typescript
*.tsbuildinfo

# packages
node_modules/

.yarn
25 changes: 25 additions & 0 deletions app/[locale]/PageContinue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use client";

import { useContext } from "react";
import { AppContext } from "../../context/AppContext";
import Link from "next/link";
import { useTranslation } from "../../utils/helpers";

type Props = {
locale: string
}
const Element = ({locale}: Props) => {
const {translation} = useTranslation(locale);
const {items} = useContext(AppContext);
return <>
{items.length > 0 &&
<div className='h-10'>
<Link className="btn" href={'/contact'} passHref>
{translation.next}
</Link>
</div>
}
</>
}

export default Element
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { NextApiRequest, NextApiResponse } from 'next'
import { fetchAPI } from '../../lib/api';
import { serverFetchAPI } from '../../lib/serverApi';
import { mappedItems, transformTranslations } from '../../utils/helpers';
import { Order, Translation } from '../../utils/models'
import paytrailService from '../../utils/paytrail';
import { NextRequest, NextResponse } from "next/server";
import { fetchAPI } from '@/lib/api';
import { serverFetchAPI } from '@/lib/serverApi';
import { mappedItems, transformTranslations } from '@/utils/helpers';
import { Order, Translation } from '@/utils/models'
import paytrailService from '@/utils/paytrail';

export const updateOrderState = async (orderId: number, status: string, transactionId?: string) => {
return serverFetchAPI<Order>(`/orders/${orderId}`, {
Expand Down Expand Up @@ -40,16 +40,16 @@ const createPayment = async (orderId: number) => {
return paytrailService.createPayment(order);
}

const handler = async (request: NextApiRequest, response: NextApiResponse) => {
if (request.method !== 'POST') return response.status(405).json({});
const { orderId } = request.body;
if (!orderId) return response.status(404).json({});
const handler = async (request: NextRequest) => {
if (request.method !== 'POST') return NextResponse.json({},{status: 405})
const { orderId } = await request.json();
if (!orderId) return NextResponse.json({},{status: 404})
try {
const result = await createPayment(orderId);
return response.status(200).json(result);
return NextResponse.json(result,{status: 200})
} catch(error) {
console.error(error);
return response.status(400).json({});
return NextResponse.json({},{status: 400})
}
};

Expand Down
24 changes: 24 additions & 0 deletions app/[locale]/api/verifyPaymenCallback/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { NextRequest, NextResponse } from "next/server";
import paytrailService from "@/utils/paytrail";
import { updateOrderState } from "../createPayment/route";

const handler = async (request: NextRequest) => {
if (request.method !== 'GET') return NextResponse.json({}, {status: 405});
const query = request.nextUrl.searchParams;
const queryObject = Object.fromEntries(query.entries())
try {
const result = paytrailService.verifyPayment(queryObject);
if (!result) return NextResponse.json({}, {status: 400});
await updateOrderState(
Number(query.get('checkout-reference')),
query.get('checkout-status') || 'fail',
query.get('checkout-transaction-id') || undefined,
);
return NextResponse.json({}, {status: 200});
} catch(error) {
console.error(error);
return NextResponse.json({}, {status: 500});
}
}

export default handler
44 changes: 44 additions & 0 deletions app/[locale]/callback/Result.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"use client";

import { useContext, useEffect, useRef } from "react";
import { AppContext } from "@/context/AppContext";
import Link from "next/link";
import { useTranslation } from "@/utils/helpers";

type Props = {
locale: string;
isValid: boolean;
paymentStatus: string;
content: any;
}

const CallbackResult = ({ locale, isValid, paymentStatus, content}: Props) => {
const {reset} = useContext(AppContext);
const {translation} = useTranslation(locale);
const handled = useRef(false);
useEffect(() => {
if(isValid && paymentStatus === 'ok' && !handled.current) {
handled.current = true;
reset();
}
},[isValid, paymentStatus, reset]);
let result = <p>{content.attributes.onSuccess}</p>
if(isValid === undefined) return <p>Loading...</p>
if (!isValid) result = <div>
{content.attributes.onError} <Link className='text-primary-900 dark:text-primary-100 underline' href="/summary">
{translation.backToOrder}
</Link>
</div>
else if (paymentStatus !== 'ok') result = <div>
{content.attributes.onCancel} <Link href="/summary">
<a className='text-primary-900 dark:text-primary-100 underline'>{translation.backToOrder}</a>
</Link>
</div>
return (
<div className='container text-primary-900 dark:text-primary-100 max-w-3xl bg-secondary-50 dark:bg-secondary-800 mx-auto rounded shadow-md p-2 pt-4 sm:p-8'>
{result}
</div>
);
}

export default CallbackResult;
37 changes: 37 additions & 0 deletions app/[locale]/callback/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import paytrailService from '@/utils/paytrail';

import { serverFetchAPI } from '@/lib/serverApi';
import { CallbackPageFields } from '@/utils/models';

import { useParams } from 'next/navigation';
import Result from './Result';

type CheckoutStatus = 'new' | 'ok' | 'fail' | 'pending' | 'delayed';

const getContent = async (locale: string) => {
const content = await serverFetchAPI<CallbackPageFields>('/callback-page',{},{
locale: locale,
});
return content;
}

type Props = {
params: {
locale: string
}
}

const CallbackPage = async ({params: {locale}}: Props) => {
const params = useParams() as Record<string,number | string>;
const isValid = paytrailService.verifyPayment(params);
const paymentStatus = params['checkout-status'] as CheckoutStatus;
const content = await getContent(locale);

return <Result
locale={locale}
isValid={isValid}
paymentStatus={paymentStatus}
content={content}/>
}

export default CallbackPage
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"use client";

import Image from 'next/image';
import {useRouter} from 'next/router';
import { useRouter } from 'next/router';
import { useEffect, useState, useCallback, useRef } from 'react';
import qs from 'qs';
import { fetchAPI } from '../../lib/api';
import { fetchAPI } from '@/lib/api';
import useSWR from 'swr';
import { Order } from '../../utils/models';
import { Order } from '@/utils/models';

interface PaymentProvider {
id: string;
Expand All @@ -24,7 +26,7 @@ const Checkout = () => {
const [paymentProviders, setProviders] = useState<PaymentProvider[]>([]);
const router = useRouter();
const {orderUid} = router.query;
const {data: order, error} = useSWR<Order>(orderUid ? `/orders/findByUid/${orderUid}` : null, fetchAPI);
const {data: order} = useSWR<Order>(orderUid ? `/orders/findByUid/${orderUid}` : null, fetchAPI);
const initializePayment = useCallback(async (orderId: number) => {
const response = await fetch('/api/createPayment', {
method: 'POST',
Expand Down
10 changes: 10 additions & 0 deletions app/[locale]/checkout/[orderUid]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Component from "./Component";


const ContactPage = () => {
return <div>
<Component></Component>
</div>
}

export default ContactPage;
27 changes: 15 additions & 12 deletions pages/contact/index.tsx → app/[locale]/contact/ContactForm.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import type { NextPage } from 'next'
"use client";

import { ChangeEvent, FormEvent, useContext, useEffect, useState } from 'react';
import { fetchAPI } from '../../lib/api';
import { AppContext } from '../../context/AppContext';
import { ContactForm} from '../../utils/models';
import { useRouter } from 'next/router';
import { fetchAPI } from '@/lib/api';
import { AppContext } from '@/context/AppContext';
import { ContactForm} from '@/utils/models';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { getContactForm, useTranslation } from '../../utils/helpers';
import GroupComponent from '../../components/Group';
import { getContactForm, useTranslation } from '@/utils/helpers';
import GroupComponent from '@/components/Group';
import useSWR from 'swr';


const Form: NextPage = () => {
const { translation } = useTranslation();
type Props = {
locale: string;
}
const Form = ({locale}: Props) => {
const { translation } = useTranslation(locale);
const router = useRouter();
const {data: contactForms} = useSWR('/contact-forms', url => fetchAPI<ContactForm[]>(url,{},{
locale: router.locale,
locale,
populate: ['contactForm','itemTypes']
}))
const {customer, refreshFields, isEmpty, items} = useContext(AppContext);
Expand All @@ -27,12 +31,11 @@ const Form: NextPage = () => {
router.push('/');
}
},[isEmpty, router]);

const contactForm = getContactForm(contactForms || [], items);
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
const updateFields: any = {...inputFields};
updateFields.locale = router.locale;
updateFields.locale = locale;
delete updateFields.createdAt;
delete updateFields.updatedAt;
delete updateFields.publishedAt;
Expand Down
13 changes: 13 additions & 0 deletions app/[locale]/contact/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Form from "./ContactForm";

type Props = {
params: {
locale: string
}
}

const ContactPage = ({params: {locale}}:Props) => {
return <Form locale={locale}/>
}

export default ContactPage;
Original file line number Diff line number Diff line change
@@ -1,49 +1,29 @@
import type {
NextPage,
GetServerSideProps,
InferGetServerSidePropsType} from 'next'
import useSWR from 'swr';
import { ChangeEvent, FormEvent, useEffect, useState } from 'react';
import { QRCodeSVG } from 'qrcode.react';
import { fetchAPI } from '../../lib/api';
import { initialCustomer } from '../../context/AppContext';
import { ContactForm,Customer, Order, StrapiBaseType } from '../../utils/models';
"use client";

import useSWR from 'swr';
import { ChangeEvent, FormEvent, useEffect, useState } from 'react';
import { fetchAPI } from '@/lib/api';
import { initialCustomer } from '@/context/AppContext';
import { ContactForm,Customer, Order, StrapiBaseType } from '@/utils/models';
import { useRouter } from 'next/router';
import Link from 'next/link';
import { getContactForm, useTranslation } from '../../utils/helpers';
import GroupComponent from '../../components/Group';
import Loader from '../../components/Loader'
import OrderComponent from '../../components/Order';
import { getContactForm, useTranslation } from '@/utils/helpers';
import GroupComponent from '@/components/Group';
import Loader from '@/components/Loader'
import OrderComponent from '@/components/Order';

type Global = StrapiBaseType<{
updateEnd: string;
}>

type ServerSidePropType = {
type Props = {
contactForms: ContactForm[];
global: Global
global: Global;
locale: string
}

export const getServerSideProps: GetServerSideProps<ServerSidePropType> = async (context) => {
const [formData, global] = await Promise.all([
fetchAPI<ContactForm[]>('/contact-forms',{},{
locale: context.locale,
populate: ['contactForm','itemTypes']
}),
fetchAPI<Global>('/global'),
]);
return {
props: {
contactForms: formData,
global
},
}
}

type PropType = InferGetServerSidePropsType<typeof getServerSideProps>

const Form: NextPage<PropType> = ({contactForms, global}) => {
const { translation } = useTranslation();
const Form = ({contactForms, global, locale}: Props) => {
const { translation } = useTranslation(locale);
const router = useRouter();
const {orderUid} = router.query;
const [isLoading, setLoading] = useState(false);
Expand Down Expand Up @@ -124,6 +104,7 @@ const Form: NextPage<PropType> = ({contactForms, global}) => {
{orders?.map(order =>
<div key={order.id} className="text-secondary-800 dark:text-secondary-100 bg-secondary-50 dark:bg-secondary-800 p-1 pt-4 sm:p-8 rounded shadow-md my-8">
<OrderComponent
locale={locale}
items={order.attributes.items.data}
/>
{order.attributes.status === 'admin-new' &&
Expand All @@ -134,18 +115,13 @@ const Form: NextPage<PropType> = ({contactForms, global}) => {
}>{translation.pay}</button></Link>}
<div className='mt-4 flex flex-wrap gap-4'>
{translation.tickets}
{ window && order.attributes.items.data
{ order.attributes.items.data
.sort((a,b) => a.id-b.id)
.map(item =>
<div
key={item.id}
className="p-4 w-fit"
>
<div className='bg-secondary-200 p-2 w-fit'>
<QRCodeSVG
level='L'
value={`https://${window.location.host}/validate/${orderUid}_${item.id}`}/>
</div>
<p className='text-center'>{translation[item.attributes.itemType.data.attributes.slug]} ID: {item.id}</p>
</div>)}
</div>
Expand Down
Loading

0 comments on commit b29ad34

Please sign in to comment.