From ef97d7cb6205a71a60b97192756c58ce620c55c2 Mon Sep 17 00:00:00 2001 From: Spencer Spenst Date: Fri, 29 Sep 2023 22:20:57 -0700 Subject: [PATCH] wip sidebar panels --- components/level/gameWrapper.tsx | 5 +- components/level/info/formattedLevelInfo.tsx | 42 +++++++++- components/level/info/suggestedPanel.tsx | 87 ++++++++++++++++++++ components/page/didYouKnowTip.tsx | 2 +- contexts/levelContext.ts | 4 +- pages/level/[username]/[slugName].tsx | 3 + 6 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 components/level/info/suggestedPanel.tsx diff --git a/components/level/gameWrapper.tsx b/components/level/gameWrapper.tsx index 191d0827b..f5760a743 100644 --- a/components/level/gameWrapper.tsx +++ b/components/level/gameWrapper.tsx @@ -1,3 +1,4 @@ +import { LevelContext } from '@root/contexts/levelContext'; import { PageContext } from '@root/contexts/pageContext'; import React, { useContext, useEffect, useState } from 'react'; import Collection from '../../models/db/collection'; @@ -16,6 +17,7 @@ interface GameWrapperProps { } export default function GameWrapper({ chapter, collection, level, onNext, onPrev, user }: GameWrapperProps) { + const levelContext = useContext(LevelContext); const [postGameModalOpen, setShowPostGameModalOpen] = useState(false); const { setPreventKeyDownEvent } = useContext(PageContext); @@ -34,7 +36,8 @@ export default function GameWrapper({ chapter, collection, level, onNext, onPrev level={level} onNext={collection ? onNext : undefined} onPrev={collection ? onPrev : undefined} - onSolve={() => setTimeout(() => setShowPostGameModalOpen(true), 200)} + // onSolve={() => setTimeout(() => setShowPostGameModalOpen(true), 200)} + onSolve={() => levelContext && levelContext.setSidebarIndex(1)} /> } - {/* Reviews */}
- +
+ + + { + if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') { + e.preventDefault(); + } + }}> + {({ selected }) => ( +
+ Reviews +
+ )} +
+ { + if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') { + e.preventDefault(); + } + }}> + {({ selected }) => ( +
+ Suggestions +
+ )} +
+
+ + + + + + + + +
+
); } diff --git a/components/level/info/suggestedPanel.tsx b/components/level/info/suggestedPanel.tsx new file mode 100644 index 000000000..981ef0bad --- /dev/null +++ b/components/level/info/suggestedPanel.tsx @@ -0,0 +1,87 @@ +import DidYouKnowTip from '@root/components/page/didYouKnowTip'; +import useHomePageData, { HomepageDataType } from '@root/hooks/useHomePageData'; +import Collection from '@root/models/db/collection'; +import Level, { EnrichedLevel } from '@root/models/db/level'; +import User from '@root/models/db/user'; +import Link from 'next/link'; +import React, { useEffect, useState } from 'react'; +import Card from '../../cards/card'; +import ChapterSelectCard from '../../cards/chapterSelectCard'; +import RecommendedLevel from '../../homepage/recommendedLevel'; + +interface SuggestedPanelProps { + chapter?: string; + collection?: Collection; + level: Level; + reqUser: User | undefined | null; +} + +export default function SuggestedPanel({ chapter, collection, level, reqUser }: SuggestedPanelProps) { + let nextLevel: EnrichedLevel | undefined = undefined; + let lastLevelInCollection = false; + + if (collection && collection.levels) { + const levelIndex = collection.levels.findIndex((l) => l._id === level._id); + + if (levelIndex + 1 < collection.levels.length) { + nextLevel = collection.levels[levelIndex + 1] as EnrichedLevel; + } else { + lastLevelInCollection = true; + } + } + + const { data } = useHomePageData([HomepageDataType.RecommendedLevel], nextLevel !== undefined); + const recommendedLevel = data && data[HomepageDataType.RecommendedLevel]; + const [queryParams, setQueryParams] = useState({}); + + // NB: this useEffect only runs when entering the level page + // (moving between levels within a collection does not remount this component) + // this is ok for now because query params are currently never expected + // to change when going between two level pages + useEffect(() => { + setQueryParams(new URLSearchParams(window.location.search)); + }, []); + + const hrefOverride = nextLevel ? `/level/${nextLevel.slug}?${queryParams}` : undefined; + + return (<> +
+

+ Congratulations! +

+

+ You completed {level.name}! +

+
+
+ {!reqUser ? +
+ Sign up (or use a Guest Account) to save your progress and get access to more features. +
+ : + <> + {lastLevelInCollection && collection && +
+ {level.name} is the last level in {collection.name}. +
+ } + {chapter && !isNaN(Number(chapter)) ? + +
+ +
+
+ : + + } + + } + +
+ ); +} diff --git a/components/page/didYouKnowTip.tsx b/components/page/didYouKnowTip.tsx index c3da7e0b0..28818bbfc 100644 --- a/components/page/didYouKnowTip.tsx +++ b/components/page/didYouKnowTip.tsx @@ -3,7 +3,7 @@ import Link from 'next/link'; import React, { useRef } from 'react'; interface DidYouKnowTipProps { - reqUser: User | null; + reqUser: User | undefined | null; } export default function DidYouKnowTip({ reqUser }: DidYouKnowTipProps) { diff --git a/contexts/levelContext.ts b/contexts/levelContext.ts index 1e41e7816..cbc2bfb1a 100644 --- a/contexts/levelContext.ts +++ b/contexts/levelContext.ts @@ -50,9 +50,11 @@ interface LevelContextInterface { level: EnrichedLevel; mutateLevel: () => void; mutateProStatsLevel: KeyedMutator; + proStatsLevel?: ProStatsLevel; records: Record[] | undefined; reviews: Review[] | undefined; - proStatsLevel?: ProStatsLevel; + setSidebarIndex: React.Dispatch>; + sidebarIndex: number; } export const LevelContext = createContext(null); diff --git a/pages/level/[username]/[slugName].tsx b/pages/level/[username]/[slugName].tsx index 34549d482..4ae71ed84 100644 --- a/pages/level/[username]/[slugName].tsx +++ b/pages/level/[username]/[slugName].tsx @@ -59,6 +59,7 @@ export default function LevelPage({ _level, reqUser }: LevelProps) { const [level, setLevel] = useState(_level); const { mutateProStatsLevel, proStatsLevel } = useProStatsLevel(level); const router = useRouter(); + const [sidebarIndex, setSidebarIndex] = useState(0); const { chapter, cid, slugName, ts, username } = router.query as LevelUrlQueryParams; const { collection } = useCollectionById(cid); @@ -225,6 +226,8 @@ export default function LevelPage({ _level, reqUser }: LevelProps) { proStatsLevel: proStatsLevel, records: records, reviews: reviews, + setSidebarIndex: setSidebarIndex, + sidebarIndex: sidebarIndex, }}>