infoalloggi-monorepo/apps/infoalloggi/src/pages/servizio/pagamento-status.tsx

186 lines
4.9 KiB
TypeScript
Raw Normal View History

import { ArrowLeft } from "lucide-react";
import type { GetServerSideProps } from "next";
import Link from "next/link";
import { useRouter } from "next/router";
import PaymentStatus from "~/components/payment_status";
import { ProgressRedirect } from "~/components/progress_redirect";
import { Button, buttonVariants } from "~/components/ui/button";
import stripe from "~/lib/stripe";
import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
enum AcquistoStatusEnum {
success = "success",
processing = "processing",
failed = "failed",
internal_error = "internal_error",
not_found = "not_found",
}
type AcquistoProcessingProps = {
status: AcquistoStatusEnum;
};
export const getServerSideProps = (async (context) => {
const paymentIntentId = context.query?.payment_intent;
if (!paymentIntentId || typeof paymentIntentId !== "string") {
return {
redirect: {
destination: "/500",
permanent: false,
},
};
}
const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId);
if (!paymentIntent) {
return {
props: {
status: AcquistoStatusEnum.internal_error,
},
};
}
const access_token = context.req.cookies.access_token;
const helper = await TrpcAuthedFetchingIstance({ access_token });
if (helper) {
const payment = await helper.trpc.pagamenti.getPaymentFromIntent.fetch({
pIntentId: paymentIntent.id,
});
if (!payment) {
return {
props: {
status: AcquistoStatusEnum.not_found,
},
};
}
let resultStatus: AcquistoStatusEnum;
if (paymentIntent.status === "succeeded") {
if (payment.paymentstatus !== PaymentStatusEnum.success) {
resultStatus = AcquistoStatusEnum.internal_error;
}
resultStatus = AcquistoStatusEnum.success;
} else if (paymentIntent.status === "processing") {
if (payment.paymentstatus !== PaymentStatusEnum.processing) {
resultStatus = AcquistoStatusEnum.internal_error;
}
resultStatus = AcquistoStatusEnum.processing;
} else {
resultStatus = AcquistoStatusEnum.failed;
}
return {
props: {
status: resultStatus,
},
};
}
return {
redirect: {
destination: "/500",
permanent: false,
},
};
}) satisfies GetServerSideProps<AcquistoProcessingProps>;
export default function AcquistoProcessing({
status,
}: AcquistoProcessingProps) {
const { t } = useTranslation();
const router = useRouter();
return (
<div className="mx-auto my-5 w-full max-w-lg space-y-8">
<h3 className="my-8 text-center font-bold text-neutral-700 text-xl uppercase tracking-wide dark:text-white">
{t.acquisto_elaborazione.titolo}
</h3>
<div className="space-y-4 p-4">
{status === AcquistoStatusEnum.success && (
<>
<PaymentStatus
message={t.acquisto_elaborazione.success_desc}
status="success"
title={t.acquisto_elaborazione.success_title}
/>
<ProgressRedirect href="/area-riservata/dashboard" />
</>
)}
{status === AcquistoStatusEnum.processing && (
<>
<PaymentStatus
message={t.acquisto_elaborazione.processing_desc}
status="processing"
title={t.acquisto_elaborazione.processing_title}
/>
<Link
className={cn("w-full", buttonVariants({ variant: "info" }))}
href="/area-riservata/dashboard"
>
{t.acquisto_elaborazione.to_dashboard}
</Link>
</>
)}
{status === AcquistoStatusEnum.failed && (
<>
<PaymentStatus
message={t.acquisto_elaborazione.failed_desc}
status="error"
title={t.acquisto_elaborazione.failed_title}
/>
<Link
className={cn("w-full", buttonVariants({ variant: "default" }))}
href="/area-riservata/chat"
>
{t.acquisto_elaborazione.to_chat}
</Link>
</>
)}
{status === AcquistoStatusEnum.internal_error && (
<>
<PaymentStatus
message={t.acquisto_elaborazione.internal_error_desc}
status="error"
title={t.acquisto_elaborazione.internal_error_title}
/>
<Link
className={cn("w-full", buttonVariants({ variant: "default" }))}
href="/area-riservata/chat"
>
{t.acquisto_elaborazione.to_chat}
</Link>
</>
)}
{status === AcquistoStatusEnum.not_found && (
<>
<PaymentStatus
message={t.acquisto_elaborazione.not_found_desc}
status="error"
title={t.acquisto_elaborazione.not_found_title}
/>
<Button
className="w-full"
onClick={() => router.back()}
variant="secondary"
>
<ArrowLeft />
{t.indietro}
</Button>
<Link
className={cn("w-full", buttonVariants({ variant: "default" }))}
href="/area-riservata/chat"
>
{t.acquisto_elaborazione.to_chat}
</Link>
</>
)}
</div>
</div>
);
}