Skip to content

Commit

Permalink
chore: refactor session and session iba template (#1181)
Browse files Browse the repository at this point in the history
* Extracted logic for session completion,
Added SessionHeader.tsx & SessionVideo.tsx components

* feat: SessionChat.tsx & getChatAccess.ts
Added SessionChat.tsx component for more readability/reusability. Added getChatAccess.ts to extract the logic for chat access.

* fix: removed unused imports
Removed unused getChatAccess imports from StoryblokSessionIbaPage.tsx and StoryblokSessionPage.tsx

* fix messaging refactor

---------

Co-authored-by: Anna Hughes <[email protected]>
  • Loading branch information
MarosBaran and annarhughes authored Nov 5, 2024
1 parent da8da58 commit 02e75d6
Show file tree
Hide file tree
Showing 7 changed files with 381 additions and 487 deletions.
63 changes: 63 additions & 0 deletions components/session/SessionChat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import ChatBubbleOutlineIcon from '@mui/icons-material/ChatBubbleOutline';
import { Box, Button, Typography } from '@mui/material';
import { useTranslations } from 'next-intl';
import SessionContentCard from '../cards/SessionContentCard';
import { Dots } from '../common/Dots';
import Link from '../common/Link';
import Video from '../video/Video';
import { EventData } from './SessionVideo';

const chatDetailIntroStyle = { marginTop: 3, marginBottom: 1.5 } as const;

export interface SessionChatProps {
eventData: EventData;
}

export const SessionChat = (props: SessionChatProps) => {
const { eventData } = props;
const t = useTranslations('Courses');

return (
<>
<Dots />
<SessionContentCard
title={t('sessionDetail.chat.title')}
titleIcon={ChatBubbleOutlineIcon}
titleIconSize={24}
eventPrefix="SESSION_CHAT"
eventData={eventData}
>
<Typography paragraph>{t('sessionDetail.chat.description')}</Typography>
<Typography paragraph>{t('sessionDetail.chat.videoIntro')}</Typography>
<Video
eventPrefix="SESSION_CHAT_VIDEO"
eventData={eventData}
url={t('sessionDetail.chat.videoLink')}
containerStyles={{ mx: 'auto', my: 2 }}
></Video>
<Box sx={chatDetailIntroStyle}>
<Typography>{t('sessionDetail.chat.detailIntro')}</Typography>
</Box>
<Box>
<ul>
<li>{t('sessionDetail.chat.detailPrivacy')}</li>
<li>{t('sessionDetail.chat.detailTimezone')}</li>
<li>{t('sessionDetail.chat.detailLanguage')}</li>
<li>{t('sessionDetail.chat.detailLegal')}</li>
<li>{t('sessionDetail.chat.detailImmediateHelp')}</li>
</ul>
</Box>
<Box sx={{ display: 'flex', justifyContent: 'center', mt: 3 }}>
<Button
variant="contained"
href="/messaging"
component={Link}
startIcon={<ChatBubbleOutlineIcon color="error" />}
>
{t('sessionDetail.chat.startButton')}
</Button>
</Box>
</SessionContentCard>
</>
);
};
73 changes: 73 additions & 0 deletions components/session/SessionHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import Header from '../layout/Header';
import { Button, Typography } from '@mui/material';
import theme from '../../styles/theme';
import Link from '../common/Link';
import CircleIcon from '@mui/icons-material/Circle';
import illustrationPerson4Peach from '../../public/illustration_person4_peach.svg';
import { ISbRichtext, ISbStoryData } from '@storyblok/react';
import { PROGRESS_STATUS } from '../../constants/enums';
import { useTranslations } from 'next-intl';

const sessionSubtitleStyle = {
marginTop: '0.75rem !important',
} as const;
const dotStyle = {
width: { xs: 8, md: 10 },
height: { xs: 8, md: 10 },
} as const;

interface SessionHeaderProps {
description: string | ISbRichtext;
name: string;
sessionProgress: PROGRESS_STATUS;
course: ISbStoryData;
weekString: string;
subtitle?: string;
storyPosition?: number;
}
export const SessionHeader = (props: SessionHeaderProps) => {
const t = useTranslations('Courses');
const { description, name, sessionProgress, course, weekString, subtitle, storyPosition } = props;
const headerProps = {
title: name,
introduction: description,
imageSrc: illustrationPerson4Peach,
imageAlt: 'alt.personTea',
};

return (
<Header
title={headerProps.title}
introduction={headerProps.introduction}
imageSrc={headerProps.imageSrc}
imageAlt={headerProps.imageAlt}
progressStatus={sessionProgress}
>
<Button
variant="outlined"
href="/courses"
sx={{ background: theme.palette.background.default }}
size="small"
component={Link}
>
Courses
</Button>

<CircleIcon color="error" sx={{ ...dotStyle, marginX: 1 }} />

<Button
variant="outlined"
sx={{ background: theme.palette.background.default }}
href={`/${course.full_slug}`}
size="small"
component={Link}
>
{course.name}
</Button>
<Typography sx={sessionSubtitleStyle} variant="body2">
{weekString} -{' '}
{storyPosition !== undefined ? `${t('session')} ${storyPosition / 10 - 1}` : subtitle}
</Typography>
</Header>
);
};
132 changes: 132 additions & 0 deletions components/session/SessionVideo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import SessionContentCard from '../cards/SessionContentCard';
import SlowMotionVideoIcon from '@mui/icons-material/SlowMotionVideo';
import { Link as MuiLink, Typography } from '@mui/material';
import Video from '../video/Video';
import VideoTranscriptModal from '../video/VideoTranscriptModal';
import { useTranslations } from 'next-intl';
import logEvent, { EventUserData } from '../../utils/logEvent';
import { PROGRESS_STATUS } from '../../constants/enums';
import { useEffect, useState } from 'react';
import { ISbRichtext } from '@storyblok/react';
import {
SESSION_STARTED_ERROR,
SESSION_STARTED_REQUEST,
SESSION_STARTED_SUCCESS,
SESSION_VIDEO_TRANSCRIPT_CLOSED,
SESSION_VIDEO_TRANSCRIPT_OPENED,
SESSION_VIEWED,
} from '../../constants/events';
import { useStartSessionMutation } from '../../store/api';

export interface EventData extends EventUserData {
session_name: string;
session_storyblok_id: number;
session_progress: PROGRESS_STATUS;
course_name: string;
course_storyblok_id: number;
}
interface SessionVideoProps {
eventData: EventData;
sessionProgress: PROGRESS_STATUS;
name: string;
storyId: number;
video: { url: string };
video_transcript: ISbRichtext;
}
export const SessionVideo = (props: SessionVideoProps) => {
const { eventData, storyId, sessionProgress, name, video_transcript, video } = props;
const t = useTranslations('Courses');
const [videoStarted, setVideoStarted] = useState<boolean>(false);
const [openTranscriptModal, setOpenTranscriptModal] = useState<boolean | null>(null);
const [startSession] = useStartSessionMutation();
async function callStartSession() {
logEvent(SESSION_STARTED_REQUEST, {
...eventData,
session_name: name,
course_name: name,
});

const startSessionResponse = await startSession({
storyblokId: storyId,
});

if (startSessionResponse.data) {
logEvent(SESSION_STARTED_SUCCESS, eventData);
}

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

logEvent(SESSION_STARTED_ERROR, eventData);
(window as any).Rollbar?.error('Session started error', error);

throw error;
}
}
useEffect(() => {
if (openTranscriptModal === null) return;

logEvent(
openTranscriptModal ? SESSION_VIDEO_TRANSCRIPT_OPENED : SESSION_VIDEO_TRANSCRIPT_CLOSED,
{
...eventData,
session_name: name,
course_name: name,
},
);
if (openTranscriptModal && sessionProgress === PROGRESS_STATUS.NOT_STARTED) {
callStartSession();
}
}, [openTranscriptModal]);

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

if (videoStarted) {
callStartSession();
}
}, [videoStarted]);

useEffect(() => {
logEvent(SESSION_VIEWED, eventData);
}, []);

return (
video && (
<SessionContentCard
title={t('sessionDetail.videoTitle')}
titleIcon={SlowMotionVideoIcon}
eventPrefix="SESSION_VIDEO"
eventData={eventData}
initialExpanded={true}
>
<Typography mb={3}>
{t.rich('sessionDetail.videoDescription', {
transcriptLink: (children) => (
<MuiLink
component="button"
variant="body1"
onClick={() => setOpenTranscriptModal(true)}
>
{children}
</MuiLink>
),
})}
</Typography>
<Video
url={video.url}
setVideoStarted={setVideoStarted}
eventData={eventData}
eventPrefix="SESSION"
containerStyles={{ mx: 'auto', my: 2 }}
/>
<VideoTranscriptModal
videoName={name}
content={video_transcript}
setOpenTranscriptModal={setOpenTranscriptModal}
openTranscriptModal={openTranscriptModal}
/>
</SessionContentCard>
)
);
};
Loading

0 comments on commit 02e75d6

Please sign in to comment.