Skip to content

Commit

Permalink
implement page scroller for topic pages
Browse files Browse the repository at this point in the history
  • Loading branch information
dominicarrojado committed Dec 15, 2024
1 parent 5531163 commit beb18c6
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 7 deletions.
5 changes: 3 additions & 2 deletions app/topics/cdc-appointment-slots/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Heading from "@/components/ui/heading";
import Subheading from "@/components/ui/subheading";
import Paragraph from "@/components/ui/paragraph";
import TelegramLinkButton from "@/components/telegram-link-button";
import PageScroller from "@/components/page-scroller";
import { Routes, TelegramChannel, TopicTitle } from "@/lib/enums";
import { META_OPEN_GRAPH, META_TWITTER } from "@/app/shared-metadata";
import { CdcSlotsTable } from "./cdc-slots-table";
Expand Down Expand Up @@ -88,7 +89,7 @@ export default function CdcAppointmentSlots() {
To get started, simply click either of the buttons below to join the
Telegram channel and start receiving notifications.
</Paragraph>
<div className="sticky bottom-6 z-50 mt-8 flex flex-col items-center gap-4">
<PageScroller className="mt-8 flex flex-col items-center gap-4">
<TelegramLinkButton
channel={TelegramChannel.CdcEyesightTest}
linkText="Subscribe for Eyesight Test"
Expand All @@ -99,7 +100,7 @@ export default function CdcAppointmentSlots() {
linkText="Subscribe for Counter Services"
topicTitle={TopicTitle.CdcCounterServices}
/>
</div>
</PageScroller>
</Container>
);
}
5 changes: 3 additions & 2 deletions app/topics/japan-visa-appointment-slots/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Subheading from "@/components/ui/subheading";
import Paragraph from "@/components/ui/paragraph";
import TelegramLinkButton from "@/components/telegram-link-button";
import SubscribeLinkButton from "@/components/subscribe-link-button";
import PageScroller from "@/components/page-scroller";
import { Routes, TelegramChannel, TopicTitle } from "@/lib/enums";
import { META_OPEN_GRAPH, META_TWITTER } from "@/app/shared-metadata";
import { JapanVisaSlotsTable } from "./japan-visa-slots-table";
Expand Down Expand Up @@ -82,7 +83,7 @@ export default function JapanVisa() {
notifications subscription page (for other visa applications and
services).
</Paragraph>
<div className="sticky bottom-6 z-50">
<PageScroller>
<div className="mt-8 flex flex-col justify-center gap-4 text-center sm:flex-row">
<div>
<TelegramLinkButton
Expand All @@ -105,7 +106,7 @@ export default function JapanVisa() {
topicTitle={TopicTitle.JapanVisaOthers}
/>
</div>
</div>
</PageScroller>
</Container>
);
}
5 changes: 3 additions & 2 deletions app/topics/ssdc-appointment-slots/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Subheading from "@/components/ui/subheading";
import Paragraph from "@/components/ui/paragraph";
import TelegramLinkButton from "@/components/telegram-link-button";
import SubscribeLinkButton from "@/components/subscribe-link-button";
import PageScroller from "@/components/page-scroller";
import { Routes, TelegramChannel, TopicTitle } from "@/lib/enums";
import { META_OPEN_GRAPH, META_TWITTER } from "@/app/shared-metadata";
import { SsdcSlotsTable } from "./ssdc-slots-table";
Expand Down Expand Up @@ -93,7 +94,7 @@ export default function SsdcAppointmentSlots() {
or to head over to the email notifications subscription page (for other
appointments).
</Paragraph>
<div className="sticky bottom-6 z-50">
<PageScroller>
<div className="mt-8 flex flex-col justify-center gap-4 text-center sm:flex-row">
<div>
<TelegramLinkButton
Expand All @@ -116,7 +117,7 @@ export default function SsdcAppointmentSlots() {
linkText="For Other Appointment Slots"
/>
</div>
</div>
</PageScroller>
</Container>
);
}
73 changes: 73 additions & 0 deletions components/page-scroller.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"use client";

import React, { ReactNode, useEffect, useRef, useState } from "react";
import { ArrowDownIcon } from "lucide-react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { trackEvent } from "@/lib/google-analytics";
import { GoogleAnalyticsEvent } from "@/lib/enums";

type Props = {
className?: string;
children: ReactNode;
};

export default function PageScroller({ className, children }: Props) {
const btnText = "Subscribe Now";
const subscribeElRef = useRef<HTMLDivElement>(null);
const [shouldDisplayBtn, setShouldDisplayBtn] = useState(true);
const btnOnClick = () => {
const subscribeEl = subscribeElRef.current;

if (subscribeEl) {
subscribeEl.scrollIntoView({ behavior: "smooth" });
}

trackEvent({
event: GoogleAnalyticsEvent.SCROLL_CLICK,
buttonText: btnText,
});
};

useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
setShouldDisplayBtn(!entry.isIntersecting);
},
{ threshold: 0.15 },
);
const subscribeEl = subscribeElRef.current;

if (subscribeEl) {
observer.observe(subscribeEl);
}

return () => {
if (subscribeEl) {
observer.unobserve(subscribeEl);
}
};
}, []);

return (
<>
<div ref={subscribeElRef} className={className}>
{children}
</div>
<div
className={cn(
"pointer-events-none fixed bottom-0 left-0 z-50 w-full translate-y-full text-center",
"transition-all duration-300 ease-in-out",
{
"bottom-6 translate-y-0": shouldDisplayBtn,
},
)}
>
<Button onClick={btnOnClick} className="pointer-events-auto">
<span className="align-middle">{btnText}</span>
<ArrowDownIcon className="ml-2 inline-block h-4 w-4 align-middle" />
</Button>
</div>
</>
);
}
1 change: 1 addition & 0 deletions lib/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export enum GoogleAnalyticsEvent {
TOAST_OPEN = "toast_open",
TOAST_CLOSE = "toast_close",
TOAST_CLICK = "toast_click",
SCROLL_CLICK = "scroll_click",
}

export enum FlightAirline {
Expand Down
4 changes: 3 additions & 1 deletion lib/google-analytics.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SITE_NAME } from "./constants";
import { checkIsLocalhost } from "./location";
import {
EventScrollClick,
EventSubscribeFormSubmit,
EventToastClick,
EventToastClose,
Expand All @@ -24,7 +25,8 @@ export function trackEvent(
| EventTopicPageClick
| EventToastOpen
| EventToastClose
| EventToastClick,
| EventToastClick
| EventScrollClick,
) {
if (checkIsLocalhost()) {
return;
Expand Down
5 changes: 5 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ export type EventToastClick = {
buttonText: string;
};

export type EventScrollClick = {
event: GoogleAnalyticsEvent.SCROLL_CLICK;
buttonText: string;
};

export type DepositRate = {
tenure: number;
rate: number;
Expand Down

0 comments on commit beb18c6

Please sign in to comment.