188 lines
5.1 KiB
TypeScript
188 lines
5.1 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
|
|
import { LayoutQuestion } from "@/components/layout/LayoutQuestion/LayoutQuestion";
|
|
import type { LayoutQuestionProps } from "@/components/layout/LayoutQuestion/LayoutQuestion";
|
|
import type { ActionButtonProps } from "@/components/ui/ActionButton/ActionButton";
|
|
import type { BottomActionButtonProps } from "@/components/widgets/BottomActionButton/BottomActionButton";
|
|
import { Coupon } from "@/components/widgets/Coupon/Coupon";
|
|
import Typography from "@/components/ui/Typography/Typography";
|
|
|
|
import {
|
|
buildHeaderProgress,
|
|
buildTypographyProps,
|
|
shouldShowBackButton,
|
|
shouldShowHeader,
|
|
} from "@/lib/funnel/mappers";
|
|
import type { CouponScreenDefinition } from "@/lib/funnel/types";
|
|
|
|
interface CouponTemplateProps {
|
|
screen: CouponScreenDefinition;
|
|
onContinue: () => void;
|
|
canGoBack: boolean;
|
|
onBack: () => void;
|
|
defaultTexts?: { nextButton?: string; continueButton?: string };
|
|
}
|
|
|
|
export function CouponTemplate({
|
|
screen,
|
|
onContinue,
|
|
canGoBack,
|
|
onBack,
|
|
defaultTexts,
|
|
}: CouponTemplateProps) {
|
|
const [copiedCode, setCopiedCode] = useState<string | null>(null);
|
|
|
|
const showBackButton = shouldShowBackButton(screen.header, canGoBack);
|
|
const showHeader = shouldShowHeader(screen.header);
|
|
|
|
const handleCopyPromoCode = (code: string) => {
|
|
// Copy to clipboard
|
|
navigator.clipboard.writeText(code);
|
|
setCopiedCode(code);
|
|
|
|
// Reset copied state after 2 seconds
|
|
setTimeout(() => {
|
|
setCopiedCode(null);
|
|
}, 2000);
|
|
};
|
|
|
|
const actionButtonProps: ActionButtonProps | undefined = screen.bottomActionButton
|
|
? {
|
|
children: screen.bottomActionButton.text,
|
|
cornerRadius: screen.bottomActionButton.cornerRadius,
|
|
onClick: onContinue,
|
|
}
|
|
: {
|
|
children: defaultTexts?.continueButton || "Continue",
|
|
onClick: onContinue,
|
|
};
|
|
|
|
const bottomActionButtonProps: BottomActionButtonProps = {
|
|
actionButtonProps,
|
|
};
|
|
|
|
const layoutQuestionProps: Omit<LayoutQuestionProps, "children"> = {
|
|
headerProps: showHeader ? {
|
|
progressProps: buildHeaderProgress(screen.header?.progress),
|
|
onBack: showBackButton ? onBack : undefined,
|
|
showBackButton,
|
|
} : undefined,
|
|
title:
|
|
buildTypographyProps(screen.title, {
|
|
as: "h2",
|
|
defaults: {
|
|
font: "manrope",
|
|
weight: "bold",
|
|
align: "center",
|
|
},
|
|
}) ?? {
|
|
as: "h2",
|
|
children: screen.title.text,
|
|
},
|
|
subtitle: screen.subtitle ? buildTypographyProps(screen.subtitle, {
|
|
as: "p",
|
|
defaults: {
|
|
font: "inter",
|
|
weight: "medium",
|
|
color: "muted",
|
|
align: "center",
|
|
},
|
|
}) : undefined,
|
|
bottomActionButtonProps,
|
|
};
|
|
|
|
// Build coupon props from screen definition
|
|
const couponProps = {
|
|
title: buildTypographyProps(screen.coupon.title, {
|
|
as: "h3" as const,
|
|
defaults: {
|
|
font: "manrope",
|
|
weight: "bold",
|
|
color: "primary",
|
|
},
|
|
}) ?? {
|
|
as: "h3" as const,
|
|
children: screen.coupon.title.text,
|
|
},
|
|
offer: {
|
|
title: buildTypographyProps(screen.coupon.offer.title, {
|
|
as: "h3" as const,
|
|
defaults: {
|
|
font: "manrope",
|
|
weight: "black",
|
|
color: "card",
|
|
size: "4xl",
|
|
},
|
|
}) ?? {
|
|
as: "h3" as const,
|
|
children: screen.coupon.offer.title.text,
|
|
},
|
|
description: buildTypographyProps(screen.coupon.offer.description, {
|
|
as: "p" as const,
|
|
defaults: {
|
|
font: "inter",
|
|
weight: "semiBold",
|
|
color: "card",
|
|
},
|
|
}) ?? {
|
|
as: "p" as const,
|
|
children: screen.coupon.offer.description.text,
|
|
},
|
|
},
|
|
promoCode: buildTypographyProps(screen.coupon.promoCode, {
|
|
as: "span" as const,
|
|
defaults: {
|
|
font: "inter",
|
|
weight: "semiBold",
|
|
},
|
|
}) ?? {
|
|
as: "span" as const,
|
|
children: screen.coupon.promoCode.text,
|
|
},
|
|
footer: buildTypographyProps(screen.coupon.footer, {
|
|
as: "p" as const,
|
|
defaults: {
|
|
font: "inter",
|
|
weight: "medium",
|
|
color: "muted",
|
|
size: "sm",
|
|
},
|
|
}) ?? {
|
|
as: "p" as const,
|
|
children: screen.coupon.footer.text,
|
|
},
|
|
onCopyPromoCode: handleCopyPromoCode,
|
|
};
|
|
|
|
return (
|
|
<LayoutQuestion {...layoutQuestionProps}>
|
|
<div className="w-full flex flex-col items-center justify-center mt-[30px]">
|
|
{/* Coupon Widget */}
|
|
<div className="mb-8">
|
|
<Coupon {...couponProps} />
|
|
</div>
|
|
|
|
{/* Copy Success Message */}
|
|
{copiedCode && (
|
|
<div className="mb-4 p-3 bg-green-50 border border-green-200 rounded-lg">
|
|
<Typography
|
|
as="p"
|
|
size="sm"
|
|
color="success"
|
|
weight="medium"
|
|
align="center"
|
|
>
|
|
{screen.copiedMessage
|
|
? screen.copiedMessage.replace("{code}", copiedCode || "")
|
|
: `Промокод "${copiedCode}" скопирован!`
|
|
}
|
|
</Typography>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</LayoutQuestion>
|
|
);
|
|
}
|