refactor module progress into user settings'

This commit is contained in:
Nathan Wang 2020-07-15 16:28:51 -07:00
parent 8aca3854a8
commit 05e6297e7d
4 changed files with 61 additions and 21 deletions

View file

@ -1,7 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import Transition from '../Transition'; import Transition from '../Transition';
import { ModuleProgressOptions } from '../../context/UserSettingsContext';
const options = ['Not Started', 'Reading', 'Practicing', 'Complete', 'Skipped'];
const MarkCompleteButton = ({ const MarkCompleteButton = ({
state, state,
@ -80,7 +79,7 @@ const MarkCompleteButton = ({
aria-orientation="vertical" aria-orientation="vertical"
aria-labelledby="options-menu" aria-labelledby="options-menu"
> >
{options.map(option => ( {ModuleProgressOptions.map(option => (
<button <button
key={option} key={option}
onClick={() => handleSelect(option)} onClick={() => handleSelect(option)}

View file

@ -244,18 +244,13 @@ export default function ModuleLayout({
module: ModuleInfo; module: ModuleInfo;
children: React.ReactNode; children: React.ReactNode;
}) { }) {
const { userProgress, setModuleProgress } = useContext(UserSettingsContext);
const [isMobileNavOpen, setIsMobileNavOpen] = useState(false); const [isMobileNavOpen, setIsMobileNavOpen] = useState(false);
const [isContactUsActive, setIsContactUsActive] = useState(false); const [isContactUsActive, setIsContactUsActive] = useState(false);
const [isConfettiActive, setIsConfettiActive] = useState(false); const [isConfettiActive, setIsConfettiActive] = useState(false);
const [moduleProgress, setModuleProgress] = useState('Not Started'); console.log(userProgress);
const moduleProgress =
React.useEffect(() => { (userProgress && userProgress[module.id]) || 'Not Started';
let progress = window.localStorage.getItem(`progress--${module.id}`);
if (progress !== null) {
console.log(progress);
setModuleProgress(progress);
}
}, []);
const data = useStaticQuery(graphql` const data = useStaticQuery(graphql`
query { query {
@ -280,8 +275,7 @@ export default function ModuleLayout({
const handleCompletionChange = progress => { const handleCompletionChange = progress => {
if (moduleProgress === progress) return; if (moduleProgress === progress) return;
setModuleProgress(progress); setModuleProgress(module.id, progress);
window.localStorage.setItem(`progress--${module.id}`, progress);
if ( if (
moduleProgress !== 'Complete' && moduleProgress !== 'Complete' &&
(progress === 'Practicing' || progress === 'Complete') (progress === 'Practicing' || progress === 'Complete')

View file

@ -33,7 +33,11 @@ export const SidebarNav = () => {
isActive={group.children.findIndex(x => x.id === module.id) !== -1} isActive={group.children.findIndex(x => x.id === module.id) !== -1}
> >
{group.children.map(link => ( {group.children.map(link => (
<ItemLink link={link} isActive={link.id === module.id} /> <ItemLink
key={link.id}
link={link}
isActive={link.id === module.id}
/>
))} ))}
</Accordion> </Accordion>
))} ))}

View file

@ -1,17 +1,42 @@
import { createContext, useRef, useState } from 'react'; import { createContext, useState } from 'react';
import * as React from 'react'; import * as React from 'react';
const UserSettingsContext = createContext({ export type ModuleProgress =
| 'Not Started'
| 'Reading'
| 'Practicing'
| 'Complete'
| 'Skipped';
export const ModuleProgressOptions: ModuleProgress[] = [
'Not Started',
'Reading',
'Practicing',
'Complete',
'Skipped',
];
export type UserProgress = { [key: string]: ModuleProgress };
export type UserLang = 'showAll' | 'cpp' | 'java' | 'py';
const UserSettingsContext = createContext<{
primaryLang: UserLang;
setPrimaryLang: (lang: string) => void;
userProgress: UserProgress;
setModuleProgress: (moduleID: string, progress: ModuleProgress) => void;
}>({
primaryLang: 'showAll', primaryLang: 'showAll',
setPrimaryLang: null, setPrimaryLang: null,
userProgress: null,
setModuleProgress: null,
}); });
export const UserSettingsProvider = ({ children }) => { export const UserSettingsProvider = ({ children }) => {
const key = 'guide:userSettings:primaryLang'; const langKey = 'guide:userSettings:primaryLang';
const progressKey = 'guide:userSettings:progress';
const [primaryLang, setPrimaryLang] = useState('showAll'); const [primaryLang, setPrimaryLang] = useState('showAll');
const [userProgress, setUserProgress] = useState({});
React.useEffect(() => { React.useEffect(() => {
const stickyValue = window.localStorage.getItem(key); let stickyValue = window.localStorage.getItem(langKey);
let v = null; let v = null;
try { try {
v = JSON.parse(stickyValue); v = JSON.parse(stickyValue);
@ -20,16 +45,34 @@ export const UserSettingsProvider = ({ children }) => {
} }
if (v === 'cpp' || v === 'java' || v === 'py') setPrimaryLang(v); if (v === 'cpp' || v === 'java' || v === 'py') setPrimaryLang(v);
else setPrimaryLang('cpp'); else setPrimaryLang('cpp');
stickyValue = window.localStorage.getItem(progressKey);
v = {};
try {
v = JSON.parse(stickyValue);
} catch (e) {
console.error("Couldn't parse user progress", e);
}
setUserProgress(v);
}, []); }, []);
return ( return (
<UserSettingsContext.Provider <UserSettingsContext.Provider
value={{ value={{
primaryLang, primaryLang: primaryLang as UserLang,
setPrimaryLang: lang => { setPrimaryLang: lang => {
window.localStorage.setItem(key, JSON.stringify(lang)); window.localStorage.setItem(langKey, JSON.stringify(lang));
setPrimaryLang(lang); setPrimaryLang(lang);
}, },
userProgress,
setModuleProgress: (moduleID: string, progress: ModuleProgress) => {
userProgress[moduleID] = progress;
window.localStorage.setItem(
progressKey,
JSON.stringify(userProgress)
);
setUserProgress(userProgress);
},
}} }}
> >
{children} {children}