Ask organizer modal implemented
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import { memo, useCallback, useState } from "react";
|
||||
import { useTranslation } from "../../../contexts/MessagesContext";
|
||||
import { useAnalytics } from "../../../hooks";
|
||||
import AskOrganizerInquiryModal from "../../modals/AskOrganizerInquiry";
|
||||
import AskOrganizerView from "./AskOrganizer.view";
|
||||
import type {
|
||||
AskOrganizerProps,
|
||||
@@ -45,8 +46,9 @@ const AskOrganizerContainer = memo<AskOrganizerProps>(
|
||||
const variant = variantProp;
|
||||
const t = useTranslation();
|
||||
const defaultButtonText = buttonText ?? t("askOrganizer.buttonText");
|
||||
const defaultButtonHref = buttonHref ?? t("askOrganizer.buttonHref");
|
||||
const analyticsHref = buttonHref ?? "modal";
|
||||
const { trackEvent, trackCustomEvent } = useAnalytics();
|
||||
const [inquiryOpen, setInquiryOpen] = useState(false);
|
||||
|
||||
const resolvedVariant: AskOrganizerVariant = variant ?? "centered";
|
||||
const styles = VARIANT_STYLES[resolvedVariant] ?? VARIANT_STYLES.centered;
|
||||
@@ -66,6 +68,31 @@ const AskOrganizerContainer = memo<AskOrganizerProps>(
|
||||
const handleContactClick = (
|
||||
event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>,
|
||||
) => {
|
||||
if (buttonHref) {
|
||||
// Legacy link CTA: do not intercept navigation.
|
||||
trackEvent({
|
||||
event: "contact_button_click",
|
||||
category: "engagement",
|
||||
label: "ask_organizer",
|
||||
component: "AskOrganizer",
|
||||
variant: resolvedVariant,
|
||||
});
|
||||
trackCustomEvent(
|
||||
"contact_button_click",
|
||||
{
|
||||
component: "AskOrganizer",
|
||||
variant: resolvedVariant,
|
||||
buttonText: defaultButtonText,
|
||||
buttonHref: analyticsHref,
|
||||
},
|
||||
onContactClick as
|
||||
| ((_data: Record<string, unknown>) => void)
|
||||
| undefined,
|
||||
);
|
||||
return event;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
trackEvent({
|
||||
event: "contact_button_click",
|
||||
category: "engagement",
|
||||
@@ -80,33 +107,39 @@ const AskOrganizerContainer = memo<AskOrganizerProps>(
|
||||
component: "AskOrganizer",
|
||||
variant: resolvedVariant,
|
||||
buttonText: defaultButtonText,
|
||||
buttonHref: defaultButtonHref,
|
||||
buttonHref: analyticsHref,
|
||||
},
|
||||
onContactClick as
|
||||
| ((_data: Record<string, unknown>) => void)
|
||||
| undefined,
|
||||
);
|
||||
|
||||
// Preserve existing button behavior (no preventDefault here)
|
||||
// while still tracking analytics.
|
||||
setInquiryOpen(true);
|
||||
return event;
|
||||
};
|
||||
|
||||
const closeInquiry = useCallback(() => {
|
||||
setInquiryOpen(false);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AskOrganizerView
|
||||
title={title}
|
||||
subtitle={subtitle}
|
||||
description={description}
|
||||
buttonText={defaultButtonText}
|
||||
buttonHref={defaultButtonHref}
|
||||
className={className}
|
||||
sectionPadding={sectionPadding}
|
||||
contentGap={`${contentGap} ${styles.container}`}
|
||||
buttonContainerClass={styles.buttonContainer}
|
||||
variant={resolvedVariant}
|
||||
labelledBy={labelledBy}
|
||||
onContactClick={handleContactClick}
|
||||
/>
|
||||
<>
|
||||
<AskOrganizerView
|
||||
title={title}
|
||||
subtitle={subtitle}
|
||||
description={description}
|
||||
buttonText={defaultButtonText}
|
||||
buttonHref={buttonHref}
|
||||
className={className}
|
||||
sectionPadding={sectionPadding}
|
||||
contentGap={`${contentGap} ${styles.container}`}
|
||||
buttonContainerClass={styles.buttonContainer}
|
||||
variant={resolvedVariant}
|
||||
labelledBy={labelledBy}
|
||||
onContactClick={handleContactClick}
|
||||
/>
|
||||
<AskOrganizerInquiryModal isOpen={inquiryOpen} onClose={closeInquiry} />
|
||||
</>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -11,6 +11,9 @@ export interface AskOrganizerProps {
|
||||
subtitle?: string;
|
||||
description?: string;
|
||||
buttonText?: string;
|
||||
/**
|
||||
* @deprecated Modal-only flow (CR-107). Omit; kept optional for Storybook overrides.
|
||||
*/
|
||||
buttonHref?: string;
|
||||
className?: string;
|
||||
/**
|
||||
@@ -22,7 +25,7 @@ export interface AskOrganizerProps {
|
||||
component: string;
|
||||
variant: string;
|
||||
buttonText: string;
|
||||
buttonHref: string;
|
||||
buttonHref?: string;
|
||||
timestamp: string;
|
||||
}) => void;
|
||||
}
|
||||
@@ -32,7 +35,7 @@ export interface AskOrganizerViewProps {
|
||||
subtitle?: string;
|
||||
description?: string;
|
||||
buttonText: string;
|
||||
buttonHref: string;
|
||||
buttonHref?: string;
|
||||
className: string;
|
||||
sectionPadding: string;
|
||||
contentGap: string;
|
||||
|
||||
@@ -43,13 +43,14 @@ function AskOrganizerView({
|
||||
{/* Button */}
|
||||
<div className={buttonContainerClass}>
|
||||
<Button
|
||||
href={buttonHref}
|
||||
{...(buttonHref ? { href: buttonHref } : {})}
|
||||
size="large"
|
||||
buttonType="filled"
|
||||
palette={variant === "inverse" ? "inverse" : "default"}
|
||||
className="xl:!px-[var(--spacing-scale-020)] xl:!py-[var(--spacing-scale-012)] xl:!text-[24px] xl:!leading-[28px]"
|
||||
onClick={onContactClick}
|
||||
ariaLabel={ariaLabel}
|
||||
data-testid="ask-organizer-cta"
|
||||
>
|
||||
{buttonText}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user