Skip to content

Commit

Permalink
wip sidebar panels
Browse files Browse the repository at this point in the history
  • Loading branch information
sspenst committed Sep 30, 2023
1 parent 1e224fc commit ef97d7c
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 5 deletions.
5 changes: 4 additions & 1 deletion components/level/gameWrapper.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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);

Expand All @@ -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)}
/>
<PostGameModal
chapter={chapter}
Expand Down
42 changes: 40 additions & 2 deletions components/level/info/formattedLevelInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Tab } from '@headlessui/react';
import FormattedDate from '@root/components/formatted/formattedDate';
import FormattedLevelReviews from '@root/components/formatted/formattedLevelReviews';
import Solved from '@root/components/level/info/solved';
import classNames from 'classnames';
import Image from 'next/image';
import React, { useContext, useState } from 'react';
import toast from 'react-hot-toast';
Expand All @@ -21,6 +22,7 @@ import UnpublishLevelModal from '../../modal/unpublishLevelModal';
import LevelInfoCompletions from './levelInfoCompletions';
import LevelInfoPlayTime from './levelInfoPlayTime';
import LevelInfoRecords from './levelInfoRecords';
import SuggestedPanel from './suggestedPanel';

interface FormattedLevelInfoProps {
level: EnrichedLevel;
Expand Down Expand Up @@ -226,11 +228,47 @@ export default function FormattedLevelInfo({ level }: FormattedLevelInfoProps) {
level={level}
/>
</>}
{/* Reviews */}
<div className='m-3' style={{
backgroundColor: 'var(--bg-color-4)',
height: 1,
}} />
<FormattedLevelReviews />
<div className='flex flex-col gap-2'>
<Tab.Group selectedIndex={levelContext?.sidebarIndex} onChange={levelContext?.setSidebarIndex}>
<Tab.List className='flex flex-wrap gap-x-1 items-start rounded-[10px] p-1 border w-fit' style={{
borderColor: 'var(--bg-color-4)',
}}>
<Tab id='leastStepsTab' className='focus:outline-none' onKeyDown={(e: React.KeyboardEvent) => {
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
e.preventDefault();
}
}}>
{({ selected }) => (
<div className={classNames('py-1 px-2 rounded-md', selected ? 'tab-active' : 'tab')}>
Reviews
</div>
)}
</Tab>
<Tab id='completionsTab' className='focus:outline-none' onKeyDown={(e: React.KeyboardEvent) => {
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
e.preventDefault();
}
}}>
{({ selected }) => (
<div className={classNames('py-1 px-2 rounded-md', selected ? 'tab-active' : 'tab')}>
Suggestions
</div>
)}
</Tab>
</Tab.List>
<Tab.Panels>
<Tab.Panel tabIndex={-1}>
<FormattedLevelReviews />
</Tab.Panel>
<Tab.Panel tabIndex={-1}>
<SuggestedPanel level={level} reqUser={user} />
</Tab.Panel>
</Tab.Panels>
</Tab.Group>
</div>
</>);
}
87 changes: 87 additions & 0 deletions components/level/info/suggestedPanel.tsx
Original file line number Diff line number Diff line change
@@ -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 (<>
<div className='flex flex-col gap-1'>
<h3 className='text-center text-2xl p-1'>
Congratulations!
</h3>
<h4 className='text-md'>
You completed {level.name}!
</h4>
</div>
<div className='flex flex-col gap-4 justify-center items-center'>
{!reqUser ?
<div className='text-center'>
<Link href='/signup' className='underline font-bold'>Sign up</Link> (or use a <Link href='/play-as-guest' className='underline font-bold'>Guest Account</Link>) to save your progress and get access to more features.
</div>
:
<>
{lastLevelInCollection && collection &&
<div>
{level.name} is the last level in <Link className='font-bold hover:underline' href={`/collection/${collection.slug}`}>{collection.name}</Link>.
</div>
}
{chapter && !isNaN(Number(chapter)) ?
<Card id='campaign' title='Head back to the campaign!'>
<div className='p-3'>
<ChapterSelectCard chapter={Number(chapter)} />
</div>
</Card>
:
<RecommendedLevel
hrefOverride={hrefOverride}
id='next-level'
level={nextLevel ?? recommendedLevel}
title={nextLevel ? 'Next Level' : 'Try this next!'}
/>
}
</>
}
<DidYouKnowTip reqUser={reqUser} />
</div>
</>);
}
2 changes: 1 addition & 1 deletion components/page/didYouKnowTip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 3 additions & 1 deletion contexts/levelContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ interface LevelContextInterface {
level: EnrichedLevel;
mutateLevel: () => void;
mutateProStatsLevel: KeyedMutator<ProStatsLevel>;
proStatsLevel?: ProStatsLevel;
records: Record[] | undefined;
reviews: Review[] | undefined;
proStatsLevel?: ProStatsLevel;
setSidebarIndex: React.Dispatch<React.SetStateAction<number>>;
sidebarIndex: number;
}

export const LevelContext = createContext<LevelContextInterface | null>(null);
3 changes: 3 additions & 0 deletions pages/level/[username]/[slugName].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -225,6 +226,8 @@ export default function LevelPage({ _level, reqUser }: LevelProps) {
proStatsLevel: proStatsLevel,
records: records,
reviews: reviews,
setSidebarIndex: setSidebarIndex,
sidebarIndex: sidebarIndex,
}}>
<Page
folders={folders}
Expand Down

0 comments on commit ef97d7c

Please sign in to comment.