Skip to content

Commit

Permalink
feat: add success and error page for order after payment success or e…
Browse files Browse the repository at this point in the history
…rror
  • Loading branch information
HoreKk committed Nov 7, 2024
1 parent 159f91d commit 622ed5d
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 14 deletions.
47 changes: 36 additions & 11 deletions webapp/src/components/obiz/LayoutOrderStatus.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import { Box, CircularProgress, Flex, Icon, Text } from "@chakra-ui/react";
import { HiCheckCircle } from "react-icons/hi2";
import {
Box,
Center,
CircularProgress,
Flex,
Icon,
IconButton,
Text,
} from "@chakra-ui/react";
import { HiCheckCircle, HiXMark } from "react-icons/hi2";
import Image from "../ui/Image";
import { HiExclamationCircle } from "react-icons/hi";
import { useRouter } from "next/router";

type LayoutOrderStatusProps = {
export type LayoutOrderStatusProps = {
status: "loading" | "success" | "error" | "info";
title: string;
subtitle?: string;
children?: React.ReactNode;
onClose?: () => void;
};

const LayoutOrderStatusIcon = ({
Expand All @@ -19,20 +30,34 @@ const LayoutOrderStatusIcon = ({
return <CircularProgress color="blackLight" isIndeterminate />;
case "info":
return <Icon as={HiCheckCircle} color="primary" fontSize="4xl" />;
case "success":
return <Icon as={HiCheckCircle} color="success" w={8} h={8} />;
case "error":
return <Icon as={HiExclamationCircle} color="error" w={8} h={8} />;
}
};

const LayoutOrderStatus = (props: LayoutOrderStatusProps) => {
const { status, title, subtitle, children } = props;
const { status, title, subtitle, children, onClose } = props;
const router = useRouter();

return (
<Flex alignItems={"center"} flexDir="column" py={14} px={4} minH="full">
<Image
src="/images/cje-logo.png"
alt='Logo de carte "jeune engagé"'
height={32}
width={60}
/>
<Flex alignItems="center" flexDir="column" py={14} px={4} minH="full">
<Center>
{onClose && (
<IconButton
aria-label="Close"
icon={<Icon as={HiXMark} w={8} h={8} />}
onClick={onClose}
/>
)}
<Image
src="/images/cje-logo.png"
alt='Logo de carte "jeune engagé"'
height={32}
width={60}
/>
</Center>
<Box mt={18}>
<LayoutOrderStatusIcon status={status} />
</Box>
Expand Down
38 changes: 38 additions & 0 deletions webapp/src/pages/dashboard/order/[id]/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Button } from "@chakra-ui/react";
import { GetServerSideProps } from "next";
import { useRouter } from "next/router";
import LayoutOrderStatus from "~/components/obiz/LayoutOrderStatus";

type OrderSuccessProps = {
order_id: string;
};

export const OrderError = ({ order_id }: OrderSuccessProps) => {
const router = useRouter();

return (
<LayoutOrderStatus
title="Erreur lors de la livraison de la commande"
subtitle="Quelque chose n'a pas fonctionné"
status="error"
onClose={() => router.push(`/dashboard/order/${order_id}`)}
>
<Button
mt="auto"
colorScheme="blackBtn"
onClick={() => router.push(`/dashboard/order/${order_id}`)}
>
Retourner à la commande
</Button>
</LayoutOrderStatus>
);
};

export const getServerSideProps: GetServerSideProps = async ({ query }) => {
const order_id = query.id;
return {
props: { order_id },
};
};

export default OrderError;
File renamed without changes.
92 changes: 92 additions & 0 deletions webapp/src/pages/dashboard/order/[id]/success.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import _ from "lodash";
import { GetServerSideProps } from "next";
import { useRouter } from "next/router";
import { useEffect, useMemo, useState } from "react";
import LayoutOrderStatus, {
LayoutOrderStatusProps,
} from "~/components/obiz/LayoutOrderStatus";
import { useAuth } from "~/providers/Auth";
import { api } from "~/utils/api";

type OrderSuccessProps = {
order_id: string;
};

type Step = {
status: LayoutOrderStatusProps["status"];
title: string;
subtitle: string;
};

export const OrderSuccess = ({ order_id }: OrderSuccessProps) => {
const utils = api.useUtils();
const { user } = useAuth();
const router = useRouter();

const [stepInterval, setStepInterval] = useState<NodeJS.Timeout>();
const [currentStep, setCurrentStep] = useState<Step>({
title: `Nous générons vos bons d'achat ${_.capitalize(user?.firstName ?? "")}...`,
subtitle: "Validation du paiement...",
status: "loading",
});

const { mutate } = api.order.synchronizeOrder.useMutation({
onSuccess: ({ data }) => {
if (data.ticket) {
clearInterval(stepInterval);
utils.order.getById.invalidate({ id: parseInt(order_id) });
setCurrentStep({
status: "success",
title: "C'est prêt !",
subtitle: "Tout est bon",
});
setTimeout(() => router.push(`/dashboard/order/${order_id}`), 1000);
}
},
onError: (error) => {
switch (error.data?.code) {
case "FORBIDDEN":
case "INTERNAL_SERVER_ERROR":
router.push(`/dashboard/order/${order_id}/error`);
break;
}
},
});

useEffect(() => {
mutate({ order_id: parseInt(order_id) });

const steps: Partial<Step>[] = [
{
subtitle: "Créations des bons d'achat...",
},
];

let currentStepIndex = 0;
let interval = setInterval(() => {
const step = steps[currentStepIndex];
setCurrentStep((prev) => ({ ...prev, ...step }));
if (currentStepIndex < steps.length - 1) {
currentStepIndex++;
} else {
clearInterval(interval);
router.push(`/dashboard/order/${order_id}`);
}
}, 2000);

setStepInterval(interval);

return () => clearInterval(interval);
}, []);

return <LayoutOrderStatus {...currentStep} />;
};

export const getServerSideProps: GetServerSideProps = async ({ query }) => {
const order_id = query.id;
return {
props: { order_id },
};
};

export default OrderSuccess;
4 changes: 4 additions & 0 deletions webapp/src/server/api/routers/order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ export const orderRouter = createTRPCRouter({
};
} else {
// Erreur dans la réponse SOAP
console.error(
"Error from obiz SOAP web service:",
JSON.stringify(resultItemObject)
);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "An error occurred from obiz SOAP web service",
Expand Down
10 changes: 7 additions & 3 deletions webapp/src/utils/obiz.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { User } from "~/payload/payload-types";
import { extractAddressInformations, getTodayFrenchDate } from "./tools";
import {
extractAddressInformations,
getBaseUrl,
getTodayFrenchDate,
} from "./tools";
import { OfferArticle } from "~/server/types";

var crypto = require("crypto");
Expand Down Expand Up @@ -81,8 +85,8 @@ export const createOrderPayload = (
city,
"FRANCE",
"",
"", // url_retour_ok
"", // url_retour_ko
"/dashboard/order/success", // url_retour_ok
"/dashboard/order/error", // url_retour_ko
"",
"",
"",
Expand Down

0 comments on commit 622ed5d

Please sign in to comment.