Skip to content

Commit

Permalink
feat: resource page styles - shorts page (#1235)
Browse files Browse the repository at this point in the history
  • Loading branch information
annarhughes authored Dec 17, 2024
1 parent 90b4463 commit 31079c4
Show file tree
Hide file tree
Showing 15 changed files with 372 additions and 85 deletions.
40 changes: 40 additions & 0 deletions components/cards/RelatedContentCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Button, Card, CardContent, Typography } from '@mui/material';
import { useTranslations } from 'next-intl';
import { RELATED_CONTENT_CATEGORIES } from '../../constants/enums';
import Link from '../common/Link';

const cardStyle = {
mt: 0,
width: { xs: '100%', sm: 'calc(50% - 0.75rem)', md: 'calc(33% - 0.75rem)' },
mb: { xs: '1rem', sm: '1.5rem' },
} as const;

const categoryStyle = {
fontFamily: 'Montserrat, sans-serif',
fontSize: '0.875rem !important',
fontWeight: 500,
} as const;

interface RelatedContentProps {
title: string;
href: string;
category: RELATED_CONTENT_CATEGORIES;
}

export const RelatedContentCard = (props: RelatedContentProps) => {
const { title, href, category } = props;

const t = useTranslations('Shared.relatedContent');

return (
<Card sx={cardStyle}>
<CardContent>
<Typography sx={categoryStyle}>{t(category)}</Typography>
<Typography variant="h3">{title}</Typography>
<Button component={Link} href={href} variant="contained">
Open
</Button>
</CardContent>
</Card>
);
};
16 changes: 8 additions & 8 deletions components/resources/ResourceCompleteButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import {
RESOURCE_CONVERSATION_COMPLETE_ERROR,
RESOURCE_CONVERSATION_COMPLETE_REQUEST,
RESOURCE_CONVERSATION_COMPLETE_SUCCESS,
RESOURCE_SHORT_COMPLETE_ERROR,
RESOURCE_SHORT_COMPLETE_REQUEST,
RESOURCE_SHORT_COMPLETE_SUCCESS,
RESOURCE_SHORT_VIDEO_COMPLETE_ERROR,
RESOURCE_SHORT_VIDEO_COMPLETE_REQUEST,
RESOURCE_SHORT_VIDEO_COMPLETE_SUCCESS,
} from '../../constants/events';
import { useCompleteResourceMutation } from '../../store/api';
import logEvent, { EventUserData } from '../../utils/logEvent';
Expand Down Expand Up @@ -39,7 +39,7 @@ export const ResourceCompleteButton = (props: ResourceCompleteButtonProps) => {
const completeResourceAction = async () => {
logEvent(
category === RESOURCE_CATEGORIES.SHORT_VIDEO
? RESOURCE_SHORT_COMPLETE_REQUEST
? RESOURCE_SHORT_VIDEO_COMPLETE_REQUEST
: RESOURCE_CONVERSATION_COMPLETE_REQUEST,
eventData,
);
Expand All @@ -51,7 +51,7 @@ export const ResourceCompleteButton = (props: ResourceCompleteButtonProps) => {
if (completeResourceResponse.data) {
logEvent(
category === RESOURCE_CATEGORIES.SHORT_VIDEO
? RESOURCE_SHORT_COMPLETE_SUCCESS
? RESOURCE_SHORT_VIDEO_COMPLETE_SUCCESS
: RESOURCE_CONVERSATION_COMPLETE_SUCCESS,
eventData,
);
Expand All @@ -63,7 +63,7 @@ export const ResourceCompleteButton = (props: ResourceCompleteButtonProps) => {

logEvent(
category === RESOURCE_CATEGORIES.SHORT_VIDEO
? RESOURCE_SHORT_COMPLETE_ERROR
? RESOURCE_SHORT_VIDEO_COMPLETE_ERROR
: RESOURCE_CONVERSATION_COMPLETE_ERROR,
eventData,
);
Expand All @@ -77,8 +77,8 @@ export const ResourceCompleteButton = (props: ResourceCompleteButtonProps) => {
return (
<>
<Button
color="secondary"
size="large"
color="primary"
size="medium"
variant="contained"
onClick={completeResourceAction}
startIcon={<CheckCircleIcon color="error" />}
Expand Down
63 changes: 55 additions & 8 deletions components/resources/ResourceShortVideo.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { Button } from '@mui/material';
import { Link, Typography } from '@mui/material';
import { ISbRichtext } from '@storyblok/react';
import { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react';
import { PROGRESS_STATUS } from '../../constants/enums';
import {
RESOURCE_SHORT_VIDEO_COMPLETE_ERROR,
RESOURCE_SHORT_VIDEO_COMPLETE_REQUEST,
RESOURCE_SHORT_VIDEO_COMPLETE_SUCCESS,
RESOURCE_SHORT_VIDEO_STARTED_ERROR,
RESOURCE_SHORT_VIDEO_STARTED_REQUEST,
RESOURCE_SHORT_VIDEO_STARTED_SUCCESS,
RESOURCE_SHORT_VIDEO_TRANSCRIPT_CLOSED,
RESOURCE_SHORT_VIDEO_TRANSCRIPT_OPENED,
RESOURCE_SHORT_VIDEO_VIEWED,
} from '../../constants/events';
import { useStartResourceMutation } from '../../store/api';
import { useCompleteResourceMutation, useStartResourceMutation } from '../../store/api';
import logEvent, { EventUserData } from '../../utils/logEvent';
import Video from '../video/Video';
import VideoTranscriptModal from '../video/VideoTranscriptModal';
Expand All @@ -29,11 +33,16 @@ interface ResourceShortVideoProps {
video: { url: string };
video_transcript: ISbRichtext;
}

export const ResourceShortVideo = (props: ResourceShortVideoProps) => {
const { eventData, storyId, resourceProgress, name, video_transcript, video } = props;
const [videoStarted, setVideoStarted] = useState<boolean>(false);
const [videoFinished, setVideoFinished] = useState<boolean>(false);
const [openTranscriptModal, setOpenTranscriptModal] = useState<boolean | null>(null);
const [startResourceShort] = useStartResourceMutation();
const [completeResourceShort] = useCompleteResourceMutation();
const t = useTranslations('Resources');

async function callStartResourceShort() {
logEvent(RESOURCE_SHORT_VIDEO_STARTED_REQUEST, {
...eventData,
Expand All @@ -57,6 +66,31 @@ export const ResourceShortVideo = (props: ResourceShortVideoProps) => {
throw error;
}
}

async function callCompleteResourceShort() {
logEvent(RESOURCE_SHORT_VIDEO_COMPLETE_REQUEST, {
...eventData,
resource_name: name,
});

const completeResourceShortResponse = await completeResourceShort({
storyblokId: storyId,
});

if (completeResourceShortResponse.data) {
logEvent(RESOURCE_SHORT_VIDEO_COMPLETE_SUCCESS, eventData);
}

if (completeResourceShortResponse.error) {
const error = completeResourceShortResponse.error;

logEvent(RESOURCE_SHORT_VIDEO_COMPLETE_ERROR, eventData);
(window as any).Rollbar?.error('ResourceShort completed error', error);

throw error;
}
}

useEffect(() => {
if (openTranscriptModal === null) return;

Expand All @@ -73,15 +107,23 @@ export const ResourceShortVideo = (props: ResourceShortVideoProps) => {
if (openTranscriptModal && resourceProgress === PROGRESS_STATUS.NOT_STARTED) {
callStartResourceShort();
}
}, [openTranscriptModal]);
}, [openTranscriptModal, eventData, name, resourceProgress]);

useEffect(() => {
if (!videoStarted || resourceProgress !== PROGRESS_STATUS.NOT_STARTED) return;

if (videoStarted) {
callStartResourceShort();
}
}, [videoStarted]);
}, [videoStarted, resourceProgress]);

useEffect(() => {
if (!videoFinished || resourceProgress === PROGRESS_STATUS.COMPLETED) return;

if (videoFinished) {
callCompleteResourceShort();
}
}, [videoFinished, resourceProgress]);

useEffect(() => {
logEvent(RESOURCE_SHORT_VIDEO_VIEWED, eventData);
Expand All @@ -90,16 +132,21 @@ export const ResourceShortVideo = (props: ResourceShortVideoProps) => {
return (
video && (
<>
<Button variant="contained" sx={{ my: 3 }} onClick={() => setOpenTranscriptModal(true)}>
Open transcript
</Button>
<Video
url={video.url}
setVideoStarted={setVideoStarted}
setVideoFinished={setVideoFinished}
eventData={eventData}
eventPrefix="RESOURCE_SHORT"
containerStyles={{ mx: 'auto', my: 2 }}
autoplay={true}
/>
<Typography sx={{ my: '1rem !important' }}>
{t.rich('transcriptLink', {
link: (children) => (
<Link onClick={() => setOpenTranscriptModal(true)}>{children}</Link>
),
})}
</Typography>
<VideoTranscriptModal
videoName={name}
content={video_transcript}
Expand Down
2 changes: 2 additions & 0 deletions components/storyblok/StoryblokCoursePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export interface StoryblokCoursePageProps {
live_end_date: string;
live_soon_content: ISbRichtext;
live_now_content: ISbRichtext;
languages: string[]; // TODO: implement this field - currently uses FF_DISABLED_COURSES env var
component: 'Course';
}

const StoryblokCoursePage = (props: StoryblokCoursePageProps) => {
Expand Down
67 changes: 43 additions & 24 deletions components/storyblok/StoryblokRelatedContent.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { Box, Button, Card, CardContent, Typography } from '@mui/material';
import { Box } from '@mui/material';
import { ISbStoryData } from '@storyblok/react';
import { useTranslations } from 'next-intl';
import { useRouter } from 'next/router';
import { useMemo } from 'react';
import { EXERCISE_CATEGORIES, RELATED_CONTENT_CATEGORIES } from '../../constants/enums';
import { rowStyle } from '../../styles/common';
import Link from '../common/Link';
import { RelatedContentCard } from '../cards/RelatedContentCard';
import { StoryblokCoursePageProps } from './StoryblokCoursePage';
import { StoryblokResourceConversationPageProps } from './StoryblokResourceConversationPage';
import { StoryblokResourceShortPageProps } from './StoryblokResourceShortPage';
import { StoryblokSessionPageProps } from './StoryblokSessionPage';

const containerStyle = {
...rowStyle,
} as const;

export interface StoryblokRelatedContentStory extends Omit<ISbStoryData, 'content'> {
content:
| StoryblokCoursePageProps
Expand All @@ -21,42 +28,54 @@ export interface StoryblokRelatedContentProps {
relatedExercises: string[];
}

const cardStyles = { width: '32%', mb: 2 } as const;

export const StoryblokRelatedContent = (props: StoryblokRelatedContentProps) => {
const { relatedContent, relatedExercises } = props;
const tExerciseNames = useTranslations('Shared.exerciseNames');
const router = useRouter();

const relatedExercisesItems = relatedExercises.map((relatedExerciseId) => {
const pageUrl = relatedExerciseId.includes('grounding-') ? 'grounding' : 'activities';
const exerciseCategory: EXERCISE_CATEGORIES = relatedExerciseId.includes('grounding-')
? EXERCISE_CATEGORIES.GROUNDING
: EXERCISE_CATEGORIES.ACTIVITIES;

return {
id: relatedExerciseId,
name: tExerciseNames(relatedExerciseId),
href: `/${pageUrl}?openacc=${relatedExerciseId}`,
href: `/${exerciseCategory}?openacc=${relatedExerciseId}`,
category: exerciseCategory,
};
});

const disabledCoursesString = process.env.FF_DISABLED_COURSES;

const filteredRelatedContent = useMemo(() => {
return relatedContent.filter(
(story) =>
(story.content.languages
? story.content.languages.includes(router.locale || 'en')
: true) && !disabledCoursesString?.includes(`${router.locale}/${story.full_slug}`),
);
}, [relatedContent, disabledCoursesString, router.locale]);

return (
<Box sx={rowStyle}>
{relatedContent.map((relatedContentItem) => (
<Card sx={cardStyles} key={`related_content_${relatedContentItem.id}`}>
<CardContent>
<Typography variant="h3">{relatedContentItem.content.name}</Typography>
<Button component={Link} href={relatedContentItem.full_slug} variant="contained">
Open
</Button>
</CardContent>
</Card>
<Box sx={containerStyle}>
{filteredRelatedContent.map((relatedContentItem) => (
<RelatedContentCard
key={`related_content_${relatedContentItem.id}`}
title={relatedContentItem.name}
href={`/${relatedContentItem.full_slug}`}
category={
relatedContentItem.content.component.toLowerCase() as RELATED_CONTENT_CATEGORIES
}
/>
))}
{relatedExercisesItems.map((relatedExerciseItem) => (
<Card sx={cardStyles} key={`related_exercise_${relatedExerciseItem.id}`}>
<CardContent>
<Typography variant="h3">{relatedExerciseItem.name}</Typography>
<Button component={Link} href={relatedExerciseItem.href} variant="contained">
Open
</Button>
</CardContent>
</Card>
<RelatedContentCard
key={`related_exercise_${relatedExerciseItem.id}`}
title={relatedExerciseItem.name}
href={relatedExerciseItem.href}
category={relatedExerciseItem.category}
/>
))}
</Box>
);
Expand Down
7 changes: 6 additions & 1 deletion components/storyblok/StoryblokResourceConversationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '../../constants/events';
import { useTypedSelector } from '../../hooks/store';
import { Resource } from '../../store/resourcesSlice';
import theme from '../../styles/theme';
import { getEventUserData, logEvent } from '../../utils/logEvent';
import { RichTextOptions } from '../../utils/richText';
import { SignUpBanner } from '../banner/SignUpBanner';
Expand All @@ -35,6 +36,8 @@ export interface StoryblokResourceConversationPageProps {
page_sections: StoryblokPageSectionProps[];
related_content: StoryblokRelatedContentStory[];
related_exercises: string[];
languages: string[];
component: 'resource_conversation';
}

const StoryblokResourceConversationPage = (props: StoryblokResourceConversationPageProps) => {
Expand Down Expand Up @@ -133,7 +136,7 @@ const StoryblokResourceConversationPage = (props: StoryblokResourceConversationP
</>
)}
</Head>
<Container>
<Container sx={{ background: theme.palette.bloomGradient }}>
<Typography variant="h1">{name}</Typography>
<Typography variant="h3">Progress: {resourceProgress}</Typography>
{render(description, RichTextOptions)}
Expand All @@ -156,6 +159,8 @@ const StoryblokResourceConversationPage = (props: StoryblokResourceConversationP
eventData={eventData}
/>
)}
</Container>
<Container>
<Typography variant="h2">Related content</Typography>
<StoryblokRelatedContent
relatedContent={related_content}
Expand Down
Loading

0 comments on commit 31079c4

Please sign in to comment.