Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 58 additions & 53 deletions packages/client/src/pages/Lesson/LessonHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,37 @@ import { Lesson, LessonState } from '../../containers/Lesson.container';
import { LessonProgress } from '../../components/LessonProgress/LessonProgress';
import { routes } from '../../router/routes';


// const offset: Size = 'lg';
const CloseIcon = styled(Icon)`
cursor: pointer;
`;

const StyledLogo = styled(LogoMark)`
height: 100%;
`;

const Header = styled.header<{ withProgress: boolean }>`
position: relative;
display: flex;
align-items: center;
padding: ${t.size()} ${t.size('lg')};
position: relative;
display: flex;
align - items: center;
padding: ${t.size()} ${t.size('lg')};

& > div {
flex: 1;
text-align: center;
div {
margin: auto;
margin-top: ${t.size('sm')};
max-width: 40rem;
}
flex: 1;
text - align: center;
div {
margin: auto;
margin - top: ${t.size('sm')};
max - width: 40rem;
}
}
`;

const Title = styled(Text)`
font-weight: ${t.fontWeight.bold};
color: ${t.color('grey')};
font - weight: ${t.fontWeight.bold};
color: ${t.color('grey')};
`;


const CloseConfirmModal: React.FC<{ onClose: () => void } & ModalProps> = ({
onClose,
...props
Expand All @@ -54,47 +53,53 @@ const CloseConfirmModal: React.FC<{ onClose: () => void } & ModalProps> = ({
setRedirect(true);
};

return <Modal
{...props}
onClose={onClose}
heading="Are you sure you want to quit?"
buttons={[
<Button text color="primary" onClick={onClose}>Cancel</Button>,
<Button text color="tertiary" onClick={resetLesson}>Quit lesson</Button>
]}
>
<Text>If you quit now, you will lose all your lesson progress!</Text>
</Modal>;
return (
<Modal
{...props}
onClose={onClose}
heading="Are you sure you want to quit?"
buttons={[
<Button text color="primary" onClick={onClose}>
Cancel
</Button>,
<Button text color="tertiary" onClick={resetLesson}>
Quit lesson
</Button>
]}
>
<Text>If you quit now, you will lose all your lesson progress!</Text>
</Modal>
);
};

export const LessonHeader: React.FC<{ title?: string }> = ({
title
}) => {
export const LessonHeader: React.FC<{ title?: string }> = ({ title }) => {
const [modal, setModal] = useState(false);
const { progress, lesson, lessonState } = Lesson.useContainer();


return <Header withProgress={progress !== undefined}>
<StyledLogo />

<div>
{title && <Title as="h2">{title}</Title>}
{lessonState === LessonState.lesson && <LessonProgress
current={progress!}
max={lesson!.lesson.questions.length}
/>}
</div>

<CloseIcon
icon="x"
onClick={() => setModal(true)}
size="lg"
color="grey.300"
/>

<CloseConfirmModal
onClose={() => setModal(false)}
show={modal}
/>
</Header>;
return (
<Header withProgress={progress !== undefined}>
<div>
<StyledLogo />
</div>

<div>
{title && <Title as="h2">{title}</Title>}
{lessonState === LessonState.lesson && (
<LessonProgress
current={progress!}
max={lesson!.lesson.questions.length}
/>
)}
</div>

<CloseIcon
icon="x"
onClick={() => setModal(true)}
size="lg"
color="grey.300"
/>

<CloseConfirmModal onClose={() => setModal(false)} show={modal} />
</Header>
);
};
77 changes: 43 additions & 34 deletions packages/client/src/pages/Lesson/Story/Story.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { ModuleLesson } from '@codement/api';
import { Button, centerAbsolute, NavDots, theme as t, CharacterHTML, CharacterProps } from '@codement/ui';
import {
Button,
centerAbsolute,
NavDots,
theme as t,
CharacterHTML,
CharacterProps
} from '@codement/ui';
import { Me } from '@codement/ui/lib/containers/Me.container';
import React, { useState, useMemo } from 'react';
import styled from 'styled-components';
Expand Down Expand Up @@ -27,16 +34,13 @@ const SkipButton = styled(Button)`

export const StyledCharacter = styled(CharacterHTML)`
position: absolute;
bottom: ${t.size('giant')};
bottom: ${t.size('big')};
left: 50%;
margin-left: -30rem;
transform: translateX(-100%);
`;


export const Story: React.FC<StoryProps> = ({
lesson
}) => {
export const Story: React.FC<StoryProps> = ({ lesson }) => {
const { me } = Me.useContainer();
const { setLessonState: setState } = Lesson.useContainer();
const steps = lesson.lesson.storySections;
Expand All @@ -60,34 +64,39 @@ export const Story: React.FC<StoryProps> = ({
];
const face = useMemo(() => faces[page % faces.length], [page]);

return <>
<StoryArticle>
<StoryContent text={step.content} obj={me!} key={page} />
</StoryArticle>
return (
<>
<StoryArticle>
<StoryContent text={step.content} obj={me!} key={page} />
</StoryArticle>

<StyledCharacter face={face} />
<StyledCharacter face={face} />

<LessonFooter>
<StyledNavDots
steps={new Array(steps.length).fill(true)}
value={page}
onChange={setPage}
/>
<Button
text
size="large"
icon="arrowRight"
iconPosition="right"
onClick={() => goTo(page + 1)}
>
Next
</Button>
<SkipButton
text
icon="mediaSkipForward"
onClick={() => setState(LessonState.storyCompleted)}
color="grey"
> Skip story </SkipButton>
</LessonFooter>
</>;
<LessonFooter>
<StyledNavDots
steps={new Array(steps.length).fill(true)}
value={page}
onChange={setPage}
/>
<Button
text
size="large"
icon="arrowRight"
iconPosition="right"
onClick={() => goTo(page + 1)}
>
Next
</Button>
<SkipButton
text
icon="mediaSkipForward"
onClick={() => setState(LessonState.storyCompleted)}
color="grey"
>
{' '}
Skip story{' '}
</SkipButton>
</LessonFooter>
</>
);
};
38 changes: 23 additions & 15 deletions packages/ui/components/Character/Character.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { theme as t } from '../../css/theme';

export * from './Characters';


const StyledCharacter = styled.div`
position: relative;
width: 200px;
Expand All @@ -18,26 +17,30 @@ const StyledCharacter = styled.div`
transform: translateX(-50%);
overflow: visible;

.ink { fill: ${t.color('primary.300')}; }
.background { fill: ${t.color('white')}; }
.ink {
fill: ${t.color('primary.300')};
}
.background {
fill: ${t.color('white')};
}
}

:after {
content: "";
content: '';
display: block;
padding-bottom: 150%;
padding-bottom: 130%;
}
`;

interface SvgProps {
value: string,
value: string;
obj: any;
}

const Svg: React.FC<SvgProps> = ({ value, obj, ...props }) => {
const S = obj[value];
if (!S) throw new Error(`Could not find character part '${value}'`);
return <S {...props} width="auto" height="auto" />;
return <S {...props} width="auto" height="260" />;
};

const StyledBody = styled(Svg)`
Expand All @@ -49,13 +52,13 @@ const StyledBody = styled(Svg)`
const StyledHead = styled(Svg)`
width: 50%;
left: 56%;
bottom: 52%;
bottom: 50%;
`;

const StyledFace = styled(Svg)`
width: 34%;
left: 61%;
bottom: 59%;
bottom: 48%;
`;

export interface CharacterProps {
Expand All @@ -65,9 +68,14 @@ export interface CharacterProps {
}

export const Character: React.FC<CharacterProps> = ({
body, head, face, ...props
}) => <StyledCharacter {...props}>
<StyledBody value={body} obj={svgBody} />
<StyledHead value={head} obj={svgHead} />
{face && <StyledFace value={face} obj={svgFace} />}
</StyledCharacter>;
body,
head,
face,
...props
}) => (
<StyledCharacter {...props}>
<StyledBody value={body} obj={svgBody} />
<StyledHead value={head} obj={svgHead} />
{face && <StyledFace value={face} obj={svgFace} />}
</StyledCharacter>
);
Loading