Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Commit

Permalink
display chapter status
Browse files Browse the repository at this point in the history
  • Loading branch information
ceolinwill committed Jun 30, 2020
1 parent 550658b commit 24bf67e
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 34 deletions.
10 changes: 5 additions & 5 deletions src/components/ChapterList.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import { Fragment } from 'react';
import dynamic from 'next/dynamic';
import { List } from '@material-ui/core';
import { Chapter } from '@zoonk/models';
import { Chapter, UserProgress } from '@zoonk/models';
import { getChapterStatus } from '@zoonk/utils';
import ChapterListItem from './ChapterListItem';

const NoChapters = dynamic(() => import('./NoChapters'));

interface ChapterListProps {
items: Chapter.Summary[];
progress?: UserProgress.Topic;
}

/**
* Display a list of chapters.
*/
const ChapterList = ({ items }: ChapterListProps) => {
const ChapterList = ({ items, progress }: ChapterListProps) => {
if (items.length === 0) {
return <NoChapters />;
}
Expand All @@ -27,6 +26,7 @@ const ChapterList = ({ items }: ChapterListProps) => {
divider={index !== items.length - 1}
item={item}
index={index}
status={getChapterStatus(item, progress?.chapters)}
/>
))}
</List>
Expand Down
34 changes: 27 additions & 7 deletions src/components/ChapterListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,37 @@ import {
ListItem,
ListItemAvatar,
ListItemText,
makeStyles,
} from '@material-ui/core';
import NextLink from 'next/link';
import { Chapter } from '@zoonk/models';
import { theme } from '@zoonk/utils';
import { Chapter, UserProgress } from '@zoonk/models';
import useTranslation from './useTranslation';

interface ChapterListItemProps {
divider?: boolean;
index: number;
item: Chapter.Summary;
status: UserProgress.ChapterStatus;
}

/**
* Display a single chapter as a list item.
*/
const ChapterListItem = ({ divider, index, item }: ChapterListItemProps) => {
const useStyles = makeStyles((theme) => ({
notStarted: {
backgroundColor: 'white',
color: theme.palette.primary.main,
border: `1px solid ${theme.palette.primary.main}`,
},
started: { backgroundColor: theme.palette.primary.main },
completed: { backgroundColor: theme.palette.success.main },
}));

const ChapterListItem = ({
divider,
index,
item,
status,
}: ChapterListItemProps) => {
const translate = useTranslation();
const classes = useStyles();
const { description, title } = item;

return (
Expand All @@ -30,7 +46,11 @@ const ChapterListItem = ({ divider, index, item }: ChapterListItemProps) => {
disableGutters
>
<ListItemAvatar>
<Avatar style={{ backgroundColor: theme.palette.primary.main }}>
<Avatar
variant="rounded"
className={classes[status]}
title={translate(status)}
>
{index + 1}
</Avatar>
</ListItemAvatar>
Expand Down
18 changes: 15 additions & 3 deletions src/components/ChaptersCard.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
import { useEffect, useState } from 'react';
import { Card, CardContent } from '@material-ui/core';
import { Chapter, Topic } from '@zoonk/models';
import { Chapter, Topic, UserProgress } from '@zoonk/models';
import { getTopicProgress } from '@zoonk/services';
import ChaptersHeader from './ChaptersHeader';
import ChapterList from './ChapterList';
import TopicProgress from './TopicProgress';
import useAuth from './useAuth';

interface ChaptersCardProps {
chapters: Chapter.Summary[];
topic: Topic.Get;
}

const ChaptersCard = ({ chapters, topic }: ChaptersCardProps) => {
const { user } = useAuth();
const [userProgress, setProgress] = useState<UserProgress.Topic>();

useEffect(() => {
if (user) {
getTopicProgress(topic, user.uid).then(setProgress);
}
}, [topic, user]);

return (
<Card variant="outlined">
<CardContent style={{ paddingBottom: 0 }}>
<ChaptersHeader />
<TopicProgress topic={topic} />
<ChapterList items={chapters} />
<TopicProgress progress={userProgress?.progress || 0} />
<ChapterList items={chapters} progress={userProgress} />
</CardContent>
</Card>
);
Expand Down
18 changes: 2 additions & 16 deletions src/components/TopicProgress.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,16 @@
import { useEffect, useState } from 'react';
import { makeStyles } from '@material-ui/core';
import { Topic } from '@zoonk/models';
import { getTopicProgress } from '@zoonk/services';
import LinearProgressWithLabel from './LinearProgressWithLabel';
import useAuth from './useAuth';

interface TopicProgressProps {
topic: Topic.Get;
progress: number;
}

const useStyles = makeStyles((theme) => ({
root: { margin: theme.spacing(1, 0) },
}));

const TopicProgress = ({ topic }: TopicProgressProps) => {
const { user } = useAuth();
const TopicProgress = ({ progress = 0 }: TopicProgressProps) => {
const classes = useStyles();
const [progress, setProgress] = useState<number>(0);

useEffect(() => {
if (user) {
getTopicProgress(topic, user.uid).then((res) =>
setProgress(res.progress),
);
}
}, [topic, user]);

return (
<div className={classes.root}>
Expand Down
3 changes: 3 additions & 0 deletions src/locale/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const translate: TranslationFn = (key, args) => {
comment_not_found: 'Comment not found.',
comment_notification: `${args?.name} commented your post.`,
comments: 'Comments',
completed: 'Completed',
confirm: 'Confirm',
contact_us: 'Contact us',
content_changes: 'Content edits',
Expand Down Expand Up @@ -159,6 +160,7 @@ const translate: TranslationFn = (key, args) => {
no_chapters: `Chapters have lessons for teaching a topic. Help more people learn about ${args?.title}.`,
no_lessons: `Help others to learn about ${args?.title}.`,
notifications: 'Notifications',
notStarted: 'Not started',
open_page: `Open page: ${args?.title}`,
order: 'Order',
page_edits: 'Page changes',
Expand Down Expand Up @@ -297,6 +299,7 @@ const translate: TranslationFn = (key, args) => {
social_description:
'Zoonk is a social network where you can learn anything for free.',
social_media: 'Social media',
started: 'Started',
stats: 'Stats',
subtitle: 'Subtitle',
teach_article_title: 'Write an article',
Expand Down
3 changes: 3 additions & 0 deletions src/locale/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const translate: TranslationFn = (key, args) => {
comment_not_found: 'Comentário não encontrado.',
comment_notification: `${args?.name} comentou o seu post.`,
comments: 'Comentários',
completed: 'Completo',
confirm: 'Confirmar',
contact_us: 'Fale conosco',
content_changes: 'Edições de conteúdo',
Expand Down Expand Up @@ -161,6 +162,7 @@ const translate: TranslationFn = (key, args) => {
no_chapters: `Os capítulos têm aulas para ensinar um assunto. Ajude mais pessoas a aprenderem sobre ${args?.title}.`,
no_lessons: `Ajude outras pessoas a aprenderem sobre ${args?.title}.`,
notifications: 'Notificações',
notStarted: 'Não iniciado',
open_page: `Abrir página: ${args?.title}`,
order: 'Ordem',
page_edits_title: 'Alterações na página:',
Expand Down Expand Up @@ -302,6 +304,7 @@ const translate: TranslationFn = (key, args) => {
social_description:
'Zoonk é uma rede social onde você pode aprender qualquer coisa de graça online.',
social_media: 'Redes sociais',
started: 'Iniciado',
stats: 'Estatísticas',
subtitle: 'Subtítulo',
teach_article_title: 'Escrever um artigo',
Expand Down
3 changes: 3 additions & 0 deletions src/models/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export type TranslationKeys =
| 'comment_not_found'
| 'comment_notification'
| 'comments'
| 'completed'
| 'confirm'
| 'contact_us'
| 'content_changes'
Expand Down Expand Up @@ -156,6 +157,7 @@ export type TranslationKeys =
| 'no_chapters'
| 'no_lessons'
| 'notifications'
| 'notStarted'
| 'open_page'
| 'order'
| 'page_edits_title'
Expand Down Expand Up @@ -280,6 +282,7 @@ export type TranslationKeys =
| 'signup'
| 'social_description'
| 'social_media'
| 'started'
| 'stats'
| 'subtitle'
| 'teach_article_title'
Expand Down
3 changes: 3 additions & 0 deletions src/models/progress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ export interface TopicProgress {
}

export namespace UserProgress {
export type ChapterStatus = 'started' | 'completed' | 'notStarted';

export interface Topic {
chapters: TopicProgress;
progress: number;
}
}
6 changes: 3 additions & 3 deletions src/services/progress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ export const getTopicProgress = async (
const progress = await db.doc(`topics/${topic.id}/progress/${userId}`).get();
const data = progress.data() as TopicProgress | undefined;

if (!data) return { progress: 0 };
if (!data) return { chapters: {}, progress: 0 };

const userPosts: number = sum(Object.values(data), 'posts');
if (userPosts === 0) return { progress: 0 };
if (userPosts === 0) return { chapters: data, progress: 0 };

const topicPosts: number = sum(topic.chapterData, 'posts');
return { progress: (userPosts / topicPosts) * 100 };
return { chapters: data, progress: (userPosts / topicPosts) * 100 };
};

export const togglePostProgress = (
Expand Down
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './i18n';
export * from './links';
export * from './misc';
export * from './posts';
export * from './progress';
export * from './routing';
export * from './server';
export * from './settings';
Expand Down
16 changes: 16 additions & 0 deletions src/utils/progress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Chapter, TopicProgress, UserProgress } from '@zoonk/models';

export const getChapterStatus = (
chapter: Chapter.Summary,
progress?: TopicProgress,
): UserProgress.ChapterStatus => {
const chapterData = progress?.[chapter.id];
const userPosts = chapterData?.posts || 0;

if (userPosts === 0) return 'notStarted';

const chapterPosts = chapter.posts;

if (userPosts < chapterPosts) return 'started';
return 'completed';
};

0 comments on commit 24bf67e

Please sign in to comment.