diff --git a/webapp/src/components/obiz/LayoutOrderStatus.tsx b/webapp/src/components/obiz/LayoutOrderStatus.tsx index 8260f515..b339096b 100644 --- a/webapp/src/components/obiz/LayoutOrderStatus.tsx +++ b/webapp/src/components/obiz/LayoutOrderStatus.tsx @@ -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 = ({ @@ -19,20 +30,34 @@ const LayoutOrderStatusIcon = ({ return ; case "info": return ; + case "success": + return ; + case "error": + return ; } }; const LayoutOrderStatus = (props: LayoutOrderStatusProps) => { - const { status, title, subtitle, children } = props; + const { status, title, subtitle, children, onClose } = props; + const router = useRouter(); return ( - - Logo de carte "jeune engagé" + +
+ {onClose && ( + } + onClick={onClose} + /> + )} + Logo de carte "jeune engagé" +
diff --git a/webapp/src/pages/dashboard/order/[id]/error.tsx b/webapp/src/pages/dashboard/order/[id]/error.tsx new file mode 100644 index 00000000..6df7c2cc --- /dev/null +++ b/webapp/src/pages/dashboard/order/[id]/error.tsx @@ -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 ( + router.push(`/dashboard/order/${order_id}`)} + > + + + ); +}; + +export const getServerSideProps: GetServerSideProps = async ({ query }) => { + const order_id = query.id; + return { + props: { order_id }, + }; +}; + +export default OrderError; diff --git a/webapp/src/pages/dashboard/order/[id].tsx b/webapp/src/pages/dashboard/order/[id]/index.tsx similarity index 100% rename from webapp/src/pages/dashboard/order/[id].tsx rename to webapp/src/pages/dashboard/order/[id]/index.tsx diff --git a/webapp/src/pages/dashboard/order/[id]/success.tsx b/webapp/src/pages/dashboard/order/[id]/success.tsx new file mode 100644 index 00000000..c733641e --- /dev/null +++ b/webapp/src/pages/dashboard/order/[id]/success.tsx @@ -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(); + const [currentStep, setCurrentStep] = useState({ + 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[] = [ + { + 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 ; +}; + +export const getServerSideProps: GetServerSideProps = async ({ query }) => { + const order_id = query.id; + return { + props: { order_id }, + }; +}; + +export default OrderSuccess; diff --git a/webapp/src/server/api/routers/order.ts b/webapp/src/server/api/routers/order.ts index e2f8a695..1e681cec 100644 --- a/webapp/src/server/api/routers/order.ts +++ b/webapp/src/server/api/routers/order.ts @@ -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", diff --git a/webapp/src/utils/obiz.ts b/webapp/src/utils/obiz.ts index dc75afce..6603a196 100644 --- a/webapp/src/utils/obiz.ts +++ b/webapp/src/utils/obiz.ts @@ -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"); @@ -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 "", "", "",