Skip to content

Commit

Permalink
Removed npm legacy files. Fixed drawer behavior.
Browse files Browse the repository at this point in the history
  • Loading branch information
malikpiara committed Jan 11, 2025
1 parent e96d2c6 commit 4f2c4b5
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 8,136 deletions.
2 changes: 1 addition & 1 deletion components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getAllSubSets } from '@/utils/getAllSubsets';

const Navbar = () => {
const allSets: Set[] = Object.values(sets);
console.log(allSets);

const allSubSets = getAllSubSets(allSets); // Flattened array of sub-sets

const [isDropdownVisible, setDropdownVisible] = useState(false);
Expand Down
149 changes: 88 additions & 61 deletions components/quiz/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import React, { useCallback, useEffect, useState, useRef } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import Button from '../button';
import Option from '../option';
import Prompt from '../prompt';
Expand All @@ -13,7 +13,7 @@ import { SubSet } from '@/content/types';
import { Drawer, DrawerContent, DrawerHeader } from '@/components/ui/drawer';

export interface QuizProps {
subSet: SubSet; // Replaces QuizProps { chapter: Chapter }
subSet: SubSet;
}

const Quiz: React.FC<QuizProps> = ({ subSet }) => {
Expand All @@ -30,11 +30,32 @@ const Quiz: React.FC<QuizProps> = ({ subSet }) => {
selectNextOption,
selectPreviousOption,
selectOption,
// onShowSolution: not used in this snippet, but you can keep/remove if your hook returns it
onShowStartScreen,
previousGuesses,
} = useQuizState(subSet);

// Drawer snap state initialized to the smallest snap point
const [snap, setSnap] = useState<number | string | null>('180px');

// Ref to track if the drawer has been expanded before
const hasExpanded = useRef(false);

/**
* When users click "Check Answer," we want to:
* - run onCheckAnswer() (quiz logic)
* - snap to "460px" only if it's the first time
*/
function handleCheckAnswerAndExpandDrawer() {

Check warning on line 48 in components/quiz/index.tsx

View workflow job for this annotation

GitHub Actions / test (18.x)

The 'handleCheckAnswerAndExpandDrawer' function makes the dependencies of useCallback Hook (at line 110) change on every render. To fix this, wrap the definition of 'handleCheckAnswerAndExpandDrawer' in its own useCallback() Hook
onCheckAnswer();

if (!hasExpanded.current) {
setSnap('460px'); // Snap to the largest point on first click
hasExpanded.current = true; // Mark that the drawer has been expanded
} else {
setSnap('180px'); // Keep it at the smallest point on subsequent clicks
}
}

// Creating ref to make each option focusable with keyboard shortcuts
const activeOptionRef = useRef<HTMLButtonElement>(null);

Expand All @@ -43,6 +64,9 @@ const Quiz: React.FC<QuizProps> = ({ subSet }) => {
activeOptionRef.current?.focus();
}, [selectedOptionId]);

/**
* Keyboard handling
*/
const handleKeyDown = useCallback(
(event: KeyboardEvent) => {
if (!currentQuestion) return;
Expand All @@ -63,11 +87,10 @@ const Quiz: React.FC<QuizProps> = ({ subSet }) => {
break;
}
if (!showStartScreen && !showSolution && selectedOptionId != null) {
onCheckAnswer();
handleCheckAnswerAndExpandDrawer();
break;
}
if (showSolution) {
// Remove focus from the active option
activeOptionRef.current?.blur();
handleNextQuestion();
}
Expand All @@ -90,11 +113,11 @@ const Quiz: React.FC<QuizProps> = ({ subSet }) => {
showSolution,
selectedOptionId,
onShowStartScreen,
onCheckAnswer,
handleNextQuestion,
selectNextOption,
selectPreviousOption,
selectOption,
handleCheckAnswerAndExpandDrawer,
handleNextQuestion,
]
);

Expand All @@ -105,8 +128,6 @@ const Quiz: React.FC<QuizProps> = ({ subSet }) => {
};
}, [handleKeyDown]);

const [snap, setSnap] = useState<number | string | null>('180px');

return (
<>
{showStartScreen ? (
Expand Down Expand Up @@ -157,10 +178,16 @@ const Quiz: React.FC<QuizProps> = ({ subSet }) => {
</div>
)}

{/** If we're not on start/end screen, show the Drawer */}
{!showStartScreen && !showEndScreen && (
<Drawer
dismissible={false}
/**
* We keep the drawer always open by setting `open` to true.
* "modal={false}" so it won't be over the entire screen as a modal.
*/
open
onOpenChange={() => {}} // No action needed since it's always open
dismissible={false}
modal={false}
snapPoints={['180px', '460px', 1]}
activeSnapPoint={snap}
Expand All @@ -181,7 +208,7 @@ const Quiz: React.FC<QuizProps> = ({ subSet }) => {
<Button
label='Check Answer'
disabled={selectedOptionId == null}
onClick={onCheckAnswer}
onClick={handleCheckAnswerAndExpandDrawer}
/>
)}
{showSolution && (
Expand All @@ -196,13 +223,12 @@ const Quiz: React.FC<QuizProps> = ({ subSet }) => {
</DrawerHeader>

<div className='flex flex-col justify-center gap-10 mx-4 md:mx-8 text-gray-500'>
{(subSet.id === 1 && (
{subSet.id === 1 && (
<>
<div>
<h3 className='text-xl md:text-2xl font-semibold text-gray-800'>
What makes a well-formed formula (wff)?
</h3>

<p>{`A wff must have one of these eight forms (where other capitals can replace "A" and "B" and other small letters "c" and "d"):`}</p>
</div>

Expand All @@ -217,54 +243,55 @@ const Quiz: React.FC<QuizProps> = ({ subSet }) => {
<div>c is not D</div>
</div>
</>
)) ||
(subSet.id === 6 && (
<>
<h3 className='text-xl md:text-2xl font-semibold text-gray-800'>
What makes a well-formed formula (wff)?
</h3>
<p>
Use a pair of parentheses for each &quot;
<KatexSpan className='inline' text={'$ \\cdot $'} />
&quot; (AND), &quot;
<KatexSpan className='inline' text={'$ \\vee $'} />
&quot; (OR), &quot;
<KatexSpan className='inline' text={'$ \\rightarrow $'} />
&quot; (IF-THEN) and &quot;
<KatexSpan className='inline' text={'$ \\equiv $'} />
&quot; (IFF).{' '}
</p>
<p>Do not use any other parentheses.</p>
</>
)) ||
(subSet.id === 3 && (
<>
<h3 className='text-xl md:text-2xl font-semibold text-gray-800'>
What is a definition?
</h3>
<p>
A definition is a rule of paraphrase designed to explain
meaning. More precisely, a definition of a word or phrase
is a rule saying how to eliminate this word or phrase in
any sentence using it and produce a second sentence that
means the same thing – the purpose of this being to
explain or clarify the meaning of the word or phrase.
</p>
<p>
Definitions may be stipulative (specifying your own usage)
or lexical (explaining current usage). A good lexical
definition should allow us to &quot;paraphrase out&quot; a
term – to produce a second sentence that means the same
thing but doesn&apos;t use the defined term. A good
lexical definition should: be neither too broad nor too
narrow, avoid circularity and poorly understood terms,
match in vagueness the term defined, match, as far as
possible, the emotional tone (positive or negative or
neutral) of the term defined, and include only properties
essential to the term.
</p>
</>
))}
)}

{subSet.id === 6 && (
<>
<h3 className='text-xl md:text-2xl font-semibold text-gray-800'>
What makes a well-formed formula (wff)?
</h3>
<p>
Use a pair of parentheses for each &quot;
<KatexSpan className='inline' text={'$ \\cdot $'} />
&quot; (AND), &quot;
<KatexSpan className='inline' text={'$ \\vee $'} />
&quot; (OR), &quot;
<KatexSpan className='inline' text={'$ \\rightarrow $'} />
&quot; (IF-THEN) and &quot;
<KatexSpan className='inline' text={'$ \\equiv $'} />
&quot; (IFF).{' '}
</p>
<p>Do not use any other parentheses.</p>
</>
)}

{subSet.id === 3 && (
<>
<h3 className='text-xl md:text-2xl font-semibold text-gray-800'>
What is a definition?
</h3>
<p>
A definition is a rule of paraphrase designed to explain
meaning. More precisely, a definition of a word or phrase is
a rule saying how to eliminate this word or phrase in any
sentence using it and produce a second sentence that means
the same thing – the purpose of this being to explain or
clarify the meaning of the word or phrase.
</p>
<p>
Definitions may be stipulative (specifying your own usage)
or lexical (explaining current usage). A good lexical
definition should allow us to &quot;paraphrase out&quot; a
term – to produce a second sentence that means the same
thing but doesn&apos;t use the defined term. A good lexical
definition should: be neither too broad nor too narrow,
avoid circularity and poorly understood terms, match in
vagueness the term defined, match, as far as possible, the
emotional tone (positive or negative or neutral) of the term
defined, and include only properties essential to the term.
</p>
</>
)}
</div>
</DrawerContent>
</Drawer>
Expand Down
4 changes: 3 additions & 1 deletion components/quiz/useQuizState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ export default function useQuizState(subSet: SubSet) {
setPreviousGuesses([]);
setShowSolution(false);
setQuestionCounter(questionCounter + 1);
} else {
}
if (questionCounter > 9) {
// If the user does more than 10 questions, exit the program.
onShowEndScreen();
}
}
Expand Down
Loading

1 comment on commit 4f2c4b5

@vercel
Copy link

@vercel vercel bot commented on 4f2c4b5 Jan 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.