99 lines
3.5 KiB
TypeScript
99 lines
3.5 KiB
TypeScript
import React, { useEffect } from "react";
|
|
import { Head, usePage } from "@inertiajs/react";
|
|
import MarketingLayout from "@/layouts/mainWebsite";
|
|
import type { CheckoutPackage, GoogleProfilePrefill } from "./checkout/types";
|
|
import { CheckoutWizard } from "./checkout/CheckoutWizard";
|
|
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
|
import toast from "react-hot-toast";
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
interface CheckoutWizardPageProps {
|
|
package: CheckoutPackage;
|
|
packageOptions: CheckoutPackage[];
|
|
privacyHtml: string;
|
|
googleAuth?: {
|
|
status?: string | null;
|
|
error?: string | null;
|
|
profile?: GoogleProfilePrefill | null;
|
|
};
|
|
paddle?: {
|
|
environment?: string | null;
|
|
client_token?: string | null;
|
|
};
|
|
}
|
|
|
|
const CheckoutWizardPage: React.FC<CheckoutWizardPageProps> = ({
|
|
package: initialPackage,
|
|
packageOptions,
|
|
privacyHtml,
|
|
googleAuth,
|
|
paddle,
|
|
}) => {
|
|
const page = usePage<{ auth?: { user?: { id: number; email: string; name?: string; pending_purchase?: boolean } | null }, flash?: { verification?: { status: string; title?: string; message?: string } } }>();
|
|
const currentUser = page.props.auth?.user ?? null;
|
|
const googleProfile = googleAuth?.profile ?? null;
|
|
const { t: tAuth } = useTranslation('auth');
|
|
const verificationFlash = page.props.flash?.verification;
|
|
|
|
|
|
const dedupedOptions = React.useMemo(() => {
|
|
const ids = new Set<number>();
|
|
const list = [initialPackage, ...packageOptions];
|
|
return list.filter((pkg) => {
|
|
if (ids.has(pkg.id)) {
|
|
return false;
|
|
}
|
|
ids.add(pkg.id);
|
|
return true;
|
|
});
|
|
}, [initialPackage, packageOptions]);
|
|
|
|
useEffect(() => {
|
|
if (typeof window === 'undefined') {
|
|
return;
|
|
}
|
|
|
|
const params = new URLSearchParams(window.location.search);
|
|
if (params.get('verified') === '1') {
|
|
toast.success(tAuth('verification.toast_success', 'Email verified successfully.'));
|
|
params.delete('verified');
|
|
const next = params.toString();
|
|
const nextUrl = `${window.location.pathname}${next ? `?${next}` : ''}`;
|
|
window.history.replaceState({}, '', nextUrl);
|
|
}
|
|
}, [tAuth]);
|
|
|
|
return (
|
|
<MarketingLayout title="Checkout Wizard">
|
|
<Head title="Checkout Wizard" />
|
|
<div className="min-h-screen bg-muted/20 py-12 dark:bg-gray-950 dark:text-gray-50">
|
|
<div className="mx-auto w-full max-w-4xl px-4">
|
|
{verificationFlash && (
|
|
<Alert
|
|
className={verificationFlash.status === 'success'
|
|
? 'mb-6 border-emerald-200 bg-emerald-50 text-emerald-800'
|
|
: 'mb-6 border-rose-200 bg-rose-50 text-rose-800'}
|
|
variant={verificationFlash.status === 'success' ? 'default' : 'destructive'}
|
|
>
|
|
<AlertTitle>{verificationFlash.title}</AlertTitle>
|
|
<AlertDescription>{verificationFlash.message}</AlertDescription>
|
|
</Alert>
|
|
)}
|
|
<CheckoutWizard
|
|
initialPackage={initialPackage}
|
|
packageOptions={dedupedOptions}
|
|
privacyHtml={privacyHtml}
|
|
initialAuthUser={currentUser ? { id: currentUser.id, email: currentUser.email ?? '', name: currentUser.name ?? undefined, pending_purchase: Boolean(currentUser.pending_purchase) } : null}
|
|
googleProfile={googleProfile}
|
|
paddle={paddle ?? null}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</MarketingLayout>
|
|
);
|
|
};
|
|
|
|
CheckoutWizardPage.layout = (page: React.ReactNode) => page;
|
|
|
|
export default CheckoutWizardPage;
|