Skip to content

Commit

Permalink
Merge pull request #506 from audioverse-org/AV-739-Track-Actions-Sear…
Browse files Browse the repository at this point in the history
…ch-Results

added favorited on teaseplay and player
  • Loading branch information
jlaverde77 authored Jan 8, 2024
2 parents 2811ccb + b089eb2 commit be5c804
Show file tree
Hide file tree
Showing 14 changed files with 159 additions and 17 deletions.
6 changes: 3 additions & 3 deletions src/components/atoms/activeLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type ActiveLinkProps = LinkProps & {
children: ReactElement;
className?: string;
activeClassName: string;
linkLable?: string;
linkLabel?: string;
};

// SOURCE: https://zaiste.net/programming/reactjs/howtos/create-activelink-nextjs/
Expand All @@ -18,7 +18,7 @@ const ActiveLink = ({
children,
className,
activeClassName,
linkLable,
linkLabel,
...props
}: ActiveLinkProps): JSX.Element => {
const { asPath } = useRouter();
Expand All @@ -34,7 +34,7 @@ const ActiveLink = ({
className={clsx(className, isActive && activeClassName)}
aria-current={isActive ? 'page' : false}
onClick={() => {
analytics.track('menuClick', { lable: linkLable });
analytics.track('menuClick', { lable: linkLabel });
}}
>
{children}
Expand Down
31 changes: 31 additions & 0 deletions src/components/atoms/titleLogger.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// components/TitleLogger.tsx
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';

function TitleLogger() {
const router = useRouter();
const [currentTitle, setCurrentTitle] = useState<string | null>(null);

useEffect(() => {
const handleRouteChange = () => {
// Access the current title
const newTitle = document.querySelector('title')?.text;
setCurrentTitle(newTitle || null);
};

// Listen for route changes
router.events.on('routeChangeComplete', handleRouteChange);

// Initial title
handleRouteChange();

// Remove the event listener on component unmount
return () => {
router.events.off('routeChangeComplete', handleRouteChange);
};
}, [router.events]);

return { currentTitle };
}

export default TitleLogger;
22 changes: 21 additions & 1 deletion src/components/molecules/buttonFavorite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ import IconLike from '~public/img/icons/icon-like.svg';
import IconLikeActive from '~public/img/icons/icon-like-active.svg';
import IconLikeLight from '~public/img/icons/icon-like-light.svg';

import { analytics } from '../atoms/analytics';
import { isBackgroundColorDark } from './buttonPlay';
import IconButton from './iconButton';

type Props = {
favoritedType?: string;
favoritedId?: string | number;
favoritedTitle?: string;
isFavorited: boolean;
toggleFavorited: () => void;
light?: boolean;
Expand All @@ -20,7 +24,16 @@ type Props = {

const ButtonFavorite: React.VoidFunctionComponent<Props> = React.forwardRef(
function ButtonFavorite(
{ isFavorited, toggleFavorited, light, backgroundColor, className }: Props,
{
favoritedType,
favoritedId,
favoritedTitle,
isFavorited,
toggleFavorited,
light,
backgroundColor,
className,
}: Props,
ref: Ref<HTMLButtonElement>
): JSX.Element {
const intl = useIntl();
Expand Down Expand Up @@ -54,6 +67,13 @@ const ButtonFavorite: React.VoidFunctionComponent<Props> = React.forwardRef(
e.preventDefault();
e.stopPropagation();
toggleFavorited();
if (favoritedType) {
analytics.track(isFavorited ? 'Unfavorited' : 'Favorited', {
Type: favoritedType,
Id: favoritedId,
Title: favoritedTitle,
});
}
}}
color={iconColor}
{...{
Expand Down
12 changes: 12 additions & 0 deletions src/components/molecules/card/collection.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import clsx from 'clsx';
import Image from 'next/legacy/image';
import Link from 'next/link';
import router from 'next/router';
import React from 'react';
import { FormattedMessage } from 'react-intl';

Expand All @@ -15,6 +16,8 @@ import { useFormattedDuration } from '~lib/time';
import useHover from '~lib/useHover';
import SuccessIcon from '~public/img/icons/icon-success-light.svg';
import { CollectionContentType } from '~src/__generated__/graphql';
import { analytics } from '~src/components/atoms/analytics';
import TitleLogger from '~src/components/atoms/titleLogger';

import ButtonFavorite from '../buttonFavorite';
import CollectionTypeLockup from '../collectionTypeLockup';
Expand Down Expand Up @@ -64,6 +67,7 @@ export default function CardCollection({
</div>
);
const isBibleVersion = contentType === CollectionContentType.BibleVersion;
const currentTitle = TitleLogger();
return (
<Card>
<Link href={canonicalPath} legacyBehavior>
Expand All @@ -73,6 +77,14 @@ export default function CardCollection({
isBibleVersion && styles.bibleVersion,
(isHovered || isSubHovered) && styles.otherHovered
)}
onClick={() => {
analytics.track('CardClick', {
type: contentType,
path: canonicalPath,
title: currentTitle,
});
router.push(canonicalPath);
}}
>
<CollectionTypeLockup contentType={contentType} />
{heroImage}
Expand Down
14 changes: 13 additions & 1 deletion src/components/molecules/card/person.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import RoundImage from '~components/atoms/roundImage';
import Card from '~components/molecules/card';
import { useIsPersonFavorited } from '~lib/api/useIsPersonFavorited';
import { BaseColors } from '~lib/constants';
import { analytics } from '~src/components/atoms/analytics';
import TitleLogger from '~src/components/atoms/titleLogger';

import ButtonFavorite from '../buttonFavorite';
import PersonTypeLockup from '../personTypeLockup';
Expand All @@ -33,10 +35,20 @@ export default function CardPerson({
}: CardCollectionProps): JSX.Element {
const { isFavorited, toggleFavorited } = useIsPersonFavorited(person.id);
const { canonicalPath, image, name, recordings } = person;
const currentTitle = TitleLogger();
return (
<Card className={clsx(compact && styles.compact)}>
<Link href={canonicalPath} legacyBehavior>
<a className={styles.container}>
<a
className={styles.container}
onClick={() => {
analytics.track('CardClick', {
type: 'PRESENTER',
path: canonicalPath,
title: currentTitle,
});
}}
>
<div className={styles.stretch}>
{!compact && <PersonTypeLockup />}
<Heading2 unpadded sans className={styles.title}>
Expand Down
22 changes: 21 additions & 1 deletion src/components/molecules/card/sequence.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import IconClosure from '~public/img/icons/icon-closure.svg';
import IconDisclosure from '~public/img/icons/icon-disclosure.svg';
import SuccessIcon from '~public/img/icons/icon-success-light.svg';
import { SequenceContentType } from '~src/__generated__/graphql';
import { analytics } from '~src/components/atoms/analytics';
import NameMatcher from '~src/components/atoms/nameMatcher';
import TitleLogger from '~src/components/atoms/titleLogger';

import ButtonFavorite from '../buttonFavorite';
import PersonLockup from '../personLockup';
Expand Down Expand Up @@ -302,6 +304,7 @@ export default function CardSequence({
const linkUrl =
(isBibleBook && (sequence.allRecordings.nodes || [])[0].canonicalPath) ||
canonicalPath;
const currentTitle = TitleLogger();
return (
<Card>
{slim ? (
Expand All @@ -310,14 +313,31 @@ export default function CardSequence({
onClick={(e) => {
e.preventDefault();
e.stopPropagation();

analytics.track('CardClick', {
type: sequence.contentType,
path: canonicalPath,
title: currentTitle,
});
router.push(linkUrl);
}}
>
{inner}
</div>
) : (
<Link href={linkUrl} legacyBehavior>
<a className={className}>{inner}</a>
<a
className={className}
onClick={() => {
analytics.track('CardClick', {
type: sequence.contentType,
path: canonicalPath,
title: currentTitle,
});
}}
>
{inner}
</a>
</Link>
)}
</Card>
Expand Down
15 changes: 13 additions & 2 deletions src/components/molecules/card/sponsor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import Card from '~components/molecules/card';
import { useIsSponsorFavorited } from '~lib/api/useIsSponsorFavorited';
import { BaseColors } from '~lib/constants';
import UserPlusIcon from '~public/img/icons/fa-user-plus.svg';
import { analytics } from '~src/components/atoms/analytics';
import TitleLogger from '~src/components/atoms/titleLogger';

import ButtonFavorite from '../buttonFavorite';
import TypeLockup from '../typeLockup';
Expand All @@ -28,11 +30,20 @@ export default function CardSponsor({

const { canonicalPath, image, title, collections, sequences, recordings } =
sponsor;

const currentTitle = TitleLogger();
return (
<Card>
<Link href={canonicalPath} legacyBehavior>
<a className={styles.container}>
<a
className={styles.container}
onClick={() => {
analytics.track('CardClick', {
type: 'SPONSOR',
path: canonicalPath,
title: currentTitle,
});
}}
>
<TypeLockup
Icon={UserPlusIcon}
label={intl.formatMessage({
Expand Down
2 changes: 1 addition & 1 deletion src/components/molecules/navItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function NavItem({
href={href}
className={styles.navLink}
activeClassName={styles.active}
linkLable={label}
linkLabel={label}
>
{inner}
</ActiveLink>
Expand Down
1 change: 1 addition & 0 deletions src/components/molecules/player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ const Player = ({
{!disableUserFeatures && (
<RecordingButtonFavorite
id={recording.id}
title={recording.title}
backgroundColor={backgroundColor}
/>
)}
Expand Down
5 changes: 5 additions & 0 deletions src/components/molecules/recordingButtonFavorite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import ButtonFavorite from './buttonFavorite';

export default function RecordingButtonFavorite({
id,
title,
sequenceId,
...props
}: {
id: Scalars['ID']['output'];
title?: string;
sequenceId?: Scalars['ID']['output'];
backgroundColor: BaseColors;
light?: boolean;
Expand All @@ -24,6 +26,9 @@ export default function RecordingButtonFavorite({

return (
<ButtonFavorite
favoritedType="Recording"
favoritedId={id}
favoritedTitle={title}
isFavorited={!!isFavorited}
toggleFavorited={toggleFavorited}
{...props}
Expand Down
6 changes: 4 additions & 2 deletions src/components/molecules/searchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export default function SearchBar({
) {
inputRef.current?.focus();
}
setLastTerm(term);
}, [term, lastTerm, isFocused, stealFocus]);

return (
Expand All @@ -87,7 +86,10 @@ export default function SearchBar({
onChange={({ target }) => onTermChange(target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => {
setIsFocused(false), analytics.track('search', { term: term });
setIsFocused(false),
lastTerm != term && term != ''
? (analytics.track('search', { term: term }), setLastTerm(term))
: '';
}}
placeholder={
isFocused
Expand Down
23 changes: 21 additions & 2 deletions src/components/molecules/teaseRecording.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import SuccessIcon from '~public/img/icons/icon-success-light.svg';
import { RecordingContentType } from '~src/__generated__/graphql';

import { analytics } from '../atoms/analytics';
import TitleLogger from '../atoms/titleLogger';
import { TeaseRecordingFragment } from './__generated__/teaseRecording';
import ButtonFavorite from './buttonFavorite';
import { CardTheme } from './card/base/withCardTheme';
Expand Down Expand Up @@ -237,7 +238,7 @@ export default function TeaseRecording({
</div>
</>
);

const currentTitle = TitleLogger();
return (
<div className={clsx(styles.container, small && styles.small)}>
{isOptionalLink ? (
Expand All @@ -249,21 +250,39 @@ export default function TeaseRecording({
)}
onClick={(e) => {
e.stopPropagation();

analytics.track('CardClick', {
type: recording.recordingContentType,
path: recording.canonicalPath,
title: currentTitle,
});
router.push(recording.canonicalPath);
}}
>
{inner}
</div>
) : (
<Link href={recording.canonicalPath} legacyBehavior>
<a className={clsx(styles.content, unpadded && styles.unpadded)}>
<a
className={clsx(styles.content, unpadded && styles.unpadded)}
onClick={() => {
analytics.track('CardClick', {
type: recording.recordingContentType,
path: recording.canonicalPath,
title: currentTitle,
});
}}
>
{inner}
</a>
</Link>
)}

{!disableUserFeatures && (
<ButtonFavorite
favoritedType="Recording"
favoritedId={recording.id}
favoritedTitle={recording.title}
isFavorited={!!isFavorited}
toggleFavorited={toggleFavorited}
backgroundColor={backgroundColor}
Expand Down
8 changes: 8 additions & 0 deletions src/components/organisms/recording.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
SequenceContentType,
} from '~src/__generated__/graphql';

import { analytics } from '../atoms/analytics';
import { RecordingFragment } from './__generated__/recording';
import styles from './recording.module.scss';

Expand Down Expand Up @@ -214,6 +215,13 @@ export function Recording({
className={styles.attachment}
key={url}
rel="noreferrer"
onClick={() => {
analytics.track('AttachmentClicked', {
recording: recording.title,
attachment: filename,
});
}}
download
>
{filename}
<div className={styles.attachmentIcon}>
Expand Down
Loading

1 comment on commit be5c804

@vercel
Copy link

@vercel vercel bot commented on be5c804 Jan 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.