From fd617aae6c55cfd6ae90863fd2d3652d83b2a970 Mon Sep 17 00:00:00 2001 From: netpoe Date: Fri, 14 Jun 2024 07:23:38 -0600 Subject: [PATCH] feat: Events page + analytics events --- app/src/hooks/useRoutes/useRoutes.tsx | 6 ++ app/src/pages/events/index.tsx | 36 ++++++++++ app/src/providers/analytics/events.ts | 14 ++++ app/src/ui/accordion/Accordion.tsx | 9 ++- app/src/ui/accordion/Accordion.types.ts | 3 + app/src/ui/button/Button.module.scss | 17 ++--- app/src/ui/footer/Footer.module.scss | 7 +- app/src/ui/footer/Footer.module.scss.d.ts | 1 + app/src/ui/footer/Footer.tsx | 70 +++++++++++++++++-- .../LarsKristoHellheads.tsx | 39 +++++++++++ .../marketplaces/Marketplaces.tsx | 16 +++++ .../ui/svpervnder/events/Events.module.scss | 15 ++++ .../svpervnder/events/Events.module.scss.d.ts | 18 +++++ app/src/ui/svpervnder/events/Events.test.tsx | 13 ++++ app/src/ui/svpervnder/events/Events.tsx | 59 ++++++++++++++++ app/src/ui/svpervnder/events/Events.types.ts | 6 ++ app/src/ui/wallet-selector/WalletSelector.tsx | 6 ++ 17 files changed, 319 insertions(+), 16 deletions(-) create mode 100644 app/src/pages/events/index.tsx create mode 100644 app/src/ui/svpervnder/events/Events.module.scss create mode 100644 app/src/ui/svpervnder/events/Events.module.scss.d.ts create mode 100644 app/src/ui/svpervnder/events/Events.test.tsx create mode 100644 app/src/ui/svpervnder/events/Events.tsx create mode 100644 app/src/ui/svpervnder/events/Events.types.ts diff --git a/app/src/hooks/useRoutes/useRoutes.tsx b/app/src/hooks/useRoutes/useRoutes.tsx index f222092..08b230e 100644 --- a/app/src/hooks/useRoutes/useRoutes.tsx +++ b/app/src/hooks/useRoutes/useRoutes.tsx @@ -11,6 +11,9 @@ export const routes = { x2y2: () => `https://x2y2.io/collection/larskristo-hellheadz/items`, looksrare: () => `https://looksrare.org/collections/0x853bdaa30Cfd5A2Ec1E1d75935eBca7A0E52626D`, }, + socials: { + discord: `https://discord.gg/y3GWNkRh`, + }, oauth: { discord: { lkhh: () => `${origin}/oauth/discord/lkhh`, @@ -20,6 +23,9 @@ export const routes = { index: () => `/artists`, larskristo: () => `/artists/larskristo`, }, + events: { + index: () => `/events`, + }, api: { discord: { verifyOwnership: () => `/api/discord/verify-ownership`, diff --git a/app/src/pages/events/index.tsx b/app/src/pages/events/index.tsx new file mode 100644 index 0000000..65d71eb --- /dev/null +++ b/app/src/pages/events/index.tsx @@ -0,0 +1,36 @@ +import { GetServerSidePropsContext, NextPage } from "next"; +import { i18n, useTranslation } from "next-i18next"; +import { serverSideTranslations } from "next-i18next/serverSideTranslations"; +import Head from "next/head"; + +import { HomeLayout } from "layouts/home-layout/HomeLayout"; +import { Events } from "ui/svpervnder/events/Events"; + +const Index: NextPage = () => { + const { t } = useTranslation("head"); + + return ( + + + {t("head.og.title")} + + + + + + + + ); +}; + +export const getServerSideProps = async ({ locale }: GetServerSidePropsContext) => { + await i18n?.reloadResources(); + + return { + props: { + ...(await serverSideTranslations(locale!, ["common", "head", "chat", "prompt-wars"])), + }, + }; +}; + +export default Index; diff --git a/app/src/providers/analytics/events.ts b/app/src/providers/analytics/events.ts index 4e9cbac..706a093 100644 --- a/app/src/providers/analytics/events.ts +++ b/app/src/providers/analytics/events.ts @@ -1,7 +1,21 @@ export const EventTracking = { click: { + events: { + discord_button: `click.events.discord_button`, + }, + navbar: { + wallet_selector: `click.navbar.wallet_selector`, + }, + footer: { + navigation: `click.footer.navigation`, + socials: `click.footer.socials`, + }, homepage: { collection_item: `click.homepage.collection_item`, + collection_discord_card_button: `click.homepage.collection_discord_card_button`, + faqs_discord_button: `click.homepage.faqs_discord_button`, + faqs_accordion_trigger: `click.homepage.faqs_accordion_trigger`, + marketplaces_button: `click.homepage.marketplaces_button`, }, }, }; diff --git a/app/src/ui/accordion/Accordion.tsx b/app/src/ui/accordion/Accordion.tsx index 8363540..139fa01 100644 --- a/app/src/ui/accordion/Accordion.tsx +++ b/app/src/ui/accordion/Accordion.tsx @@ -2,6 +2,7 @@ import clsx from "clsx"; import { useEffect, useState } from "react"; import { Icon } from "ui/icon/Icon"; +import { useAnalyticsContext } from "context/analytics/useAnalyticsContext"; import { AccordionContentProps, AccordionHeaderProps, AccordionProps } from "./Accordion.types"; import styles from "./Accordion.module.scss"; @@ -9,15 +10,21 @@ import styles from "./Accordion.module.scss"; export const Accordion: React.FC & { Header: React.FC; Content: React.FC; -} = ({ className, accordionHeader, accordionContent, isDefaultExpanded }) => { +} = ({ className, accordionHeader, accordionContent, isDefaultExpanded, analyticsEvent }) => { const [isExpanded, setIsExpanded] = useState(false); + const AnalyticsContext = useAnalyticsContext(); + useEffect(() => { setIsExpanded(!!isDefaultExpanded); }, [isDefaultExpanded]); const onClickHeaderTrigger = () => { setIsExpanded(!isExpanded); + + if (analyticsEvent?.name) { + AnalyticsContext.onClick(analyticsEvent); + } }; return ( diff --git a/app/src/ui/accordion/Accordion.types.ts b/app/src/ui/accordion/Accordion.types.ts index d1b7fab..24fc2c7 100644 --- a/app/src/ui/accordion/Accordion.types.ts +++ b/app/src/ui/accordion/Accordion.types.ts @@ -1,8 +1,11 @@ import { HTMLAttributes, ReactNode } from "react"; +import { AnalyticsEvent } from "context/analytics/AnalyticsContext.types"; + export type AccordionProps = HTMLAttributes & { accordionHeader: ReactNode; accordionContent: ReactNode; + analyticsEvent?: AnalyticsEvent; isDefaultExpanded?: boolean; className?: string; }; diff --git a/app/src/ui/button/Button.module.scss b/app/src/ui/button/Button.module.scss index b519dc1..739a594 100644 --- a/app/src/ui/button/Button.module.scss +++ b/app/src/ui/button/Button.module.scss @@ -18,6 +18,7 @@ $HALF_LOADER_SIZE: 15px; .button { @extend .button-primary; display: inline-block; + width: fit-content; min-width: auto; line-height: 0; white-space: nowrap; @@ -159,7 +160,7 @@ $HALF_LOADER_SIZE: 15px; &:hover, &:active, &:focus { - background: rgba(var(--color-status-success), 0.9); + background: rgb(var(--color-status-success) 0.9); } } @@ -174,7 +175,7 @@ $HALF_LOADER_SIZE: 15px; &:hover, &:active, &:focus { - background: rgba(var(--color-status-info), 0.9); + background: rgb(var(--color-status-info) 0.9); } } @@ -185,7 +186,7 @@ $HALF_LOADER_SIZE: 15px; &:hover, &:active, &:focus { - background: rgba(var(--color-status-critical), 0.9); + background: rgb(var(--color-status-critical) 0.9); } } @@ -208,7 +209,7 @@ $HALF_LOADER_SIZE: 15px; &:hover, &:active, &:focus { - background: rgba(var(--color-dark-5), 0.9); + background: rgb(var(--color-dark-5) 0.9); } } @@ -493,12 +494,12 @@ $HALF_LOADER_SIZE: 15px; } &--glass { - border: 1px solid rgba(48, 66, 213, 0.3); + border: 1px solid rgb(48 66 213 / 30%); border-radius: 16px; + /* From https://css.glass */ - background: rgba(83, 86, 252, 0.2); - box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); - -webkit-backdrop-filter: blur(5px); + background: rgb(83 86 252 / 20%); + box-shadow: 0 4px 30px rgb(0 0 0 / 10%); backdrop-filter: blur(5px); } diff --git a/app/src/ui/footer/Footer.module.scss b/app/src/ui/footer/Footer.module.scss index 6dbf96f..789d896 100644 --- a/app/src/ui/footer/Footer.module.scss +++ b/app/src/ui/footer/Footer.module.scss @@ -11,6 +11,10 @@ border-top: 1px solid var(--color-background-contrast); background-color: var(--color-background); + &__bottom { + margin-top: $space-default; + } + &__socials { display: flex; @@ -48,6 +52,7 @@ &__right, &__center { display: flex; + flex-wrap: wrap; &--item { @include atLargeTablet { @@ -57,7 +62,7 @@ display: flex; flex-direction: column; justify-content: center; - min-height: $footer-height-mobile; + min-height: auto; padding: $space-default 0; &-flat { diff --git a/app/src/ui/footer/Footer.module.scss.d.ts b/app/src/ui/footer/Footer.module.scss.d.ts index bf2a27c..904e476 100644 --- a/app/src/ui/footer/Footer.module.scss.d.ts +++ b/app/src/ui/footer/Footer.module.scss.d.ts @@ -1,5 +1,6 @@ export type Styles = { footer: string; + footer__bottom: string; footer__center: string; "footer__center--item": string; "footer__center--item-flat": string; diff --git a/app/src/ui/footer/Footer.tsx b/app/src/ui/footer/Footer.tsx index d91c9f6..0841157 100644 --- a/app/src/ui/footer/Footer.tsx +++ b/app/src/ui/footer/Footer.tsx @@ -9,12 +9,20 @@ import { Icon } from "ui/icon/Icon"; import { Button } from "ui/button/Button"; import evm from "providers/evm"; import { ERC721Instance } from "providers/evm/ERC721Instance"; +import { useAnalyticsContext } from "context/analytics/useAnalyticsContext"; +import analytics from "providers/analytics"; +import { AnalyticsEvent } from "context/analytics/AnalyticsContext.types"; import { FooterProps } from "./Footer.types"; import styles from "./Footer.module.scss"; export const Footer: React.FC = ({ className }) => { const routes = useRoutes(); + const AnalyticsContext = useAnalyticsContext(); + + const onClick = (event: AnalyticsEvent) => { + AnalyticsContext.onClick(event); + }; return (