Skip to content

Commit

Permalink
Replaced bottom navigation within quiz with a drawer.
Browse files Browse the repository at this point in the history
  • Loading branch information
malikpiara committed Jun 9, 2024
1 parent 0ee0f9e commit edea63d
Show file tree
Hide file tree
Showing 6 changed files with 1,397 additions and 2,688 deletions.
82 changes: 58 additions & 24 deletions components/quiz/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client';
import React, { useCallback, useEffect, useRef } from 'react';
import React, { useCallback, useEffect, useState, useRef } from 'react';
import Button from '../button';
import Option from '../option';
import Prompt from '../prompt';
Expand All @@ -8,6 +8,18 @@ import { KeyboardKeys } from './keyboardKeys';
import { StartScreen } from './startScreen';
import useQuizState from './useQuizState';
import { Chapter } from '@/content';
import {
Drawer,
DrawerClose,

Check failure on line 13 in components/quiz/index.tsx

View workflow job for this annotation

GitHub Actions / test (18.x)

'DrawerClose' is defined but never used
DrawerContent,
DrawerDescription,

Check failure on line 15 in components/quiz/index.tsx

View workflow job for this annotation

GitHub Actions / test (18.x)

'DrawerDescription' is defined but never used
DrawerFooter,

Check failure on line 16 in components/quiz/index.tsx

View workflow job for this annotation

GitHub Actions / test (18.x)

'DrawerFooter' is defined but never used
DrawerHeader,
DrawerOverlay,

Check failure on line 18 in components/quiz/index.tsx

View workflow job for this annotation

GitHub Actions / test (18.x)

'DrawerOverlay' is defined but never used
DrawerTitle,

Check failure on line 19 in components/quiz/index.tsx

View workflow job for this annotation

GitHub Actions / test (18.x)

'DrawerTitle' is defined but never used
DrawerTrigger,

Check failure on line 20 in components/quiz/index.tsx

View workflow job for this annotation

GitHub Actions / test (18.x)

'DrawerTrigger' is defined but never used
} from '@/components/ui/drawer';
import { SkeletonCard } from '../ui/skeletonCard';

export interface QuizProps {
chapter: Chapter;
Expand Down Expand Up @@ -104,6 +116,8 @@ const Quiz: React.FC<QuizProps> = ({ chapter }) => {
};
}, [handleKeyDown]); // Include handleKeyDown in the dependency array to ensure it's updated when it changes

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

return (
<>
{showStartScreen ? (
Expand Down Expand Up @@ -156,29 +170,49 @@ const Quiz: React.FC<QuizProps> = ({ chapter }) => {
</div>
)}

<div className='fixed bottom-0 left-0 z-50 w-full h-16 bg-white border-t border-gray-200 flex items-center justify-between'>
<div className='ml-5'>
{!showStartScreen && !showEndScreen && <KeyboardKeys />}
</div>

<div className='flex justify-end gap-5 items-center h-full align-bottom text-gray-800 font-medium'>
{!showStartScreen && !showEndScreen && (
<div className='flex'>{questionCounter} of 10</div>
)}
<div className='flex h-max'>
{!showSolution && !showStartScreen && !showEndScreen && (
<Button
label='Check Answer'
disabled={selectedOptionId == null}
onClick={onCheckAnswer}
/>
)}
{showSolution && (
<Button label='Next Question' onClick={handleNextQuestion} />
)}
</div>
</div>
</div>
{!showStartScreen && !showEndScreen && (
<Drawer
dismissible={false}
open
modal={false}
snapPoints={['150px', '500px']}
activeSnapPoint={snap}
setActiveSnapPoint={setSnap}
>
<DrawerContent className='fixed flex flex-col bg-white border border-gray-200 border-b-none rounded-t-[10px] bottom-0 left-0 right-0 h-full max-h-[97%] mx-[-1px]'>
<DrawerHeader>
<div className='left-0 z-50 w-full h-16 bg-white flex items-center justify-between'>
<div className='ml-5'>
{!showStartScreen && !showEndScreen && <KeyboardKeys />}
</div>
<div className='flex justify-end gap-5 items-center h-full align-bottom text-gray-800 font-medium'>
{!showStartScreen && !showEndScreen && (
<div className='flex'>{questionCounter} of 10</div>
)}
<div className='flex h-max'>
{!showSolution && !showStartScreen && !showEndScreen && (
<Button
label='Check Answer'
disabled={selectedOptionId == null}
onClick={onCheckAnswer}
/>
)}
{showSolution && (
<Button
label='Next Question'
onClick={handleNextQuestion}
/>
)}
</div>
</div>
</div>
</DrawerHeader>
<div className='flex flex-col justify-center self-center gap-10'>
<SkeletonCard />
</div>
</DrawerContent>
</Drawer>
)}
</>
);
};
Expand Down
118 changes: 118 additions & 0 deletions components/ui/drawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
'use client';

import * as React from 'react';
import { Drawer as DrawerPrimitive } from 'vaul';

import { cn } from '@/lib/utils';

const Drawer = ({
shouldScaleBackground = true,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
<DrawerPrimitive.Root
shouldScaleBackground={shouldScaleBackground}
{...props}
/>
);
Drawer.displayName = 'Drawer';

const DrawerTrigger = DrawerPrimitive.Trigger;

const DrawerPortal = DrawerPrimitive.Portal;

const DrawerClose = DrawerPrimitive.Close;

const DrawerOverlay = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Overlay
ref={ref}
className={cn('fixed inset-0 z-50 bg-black/40', className)}
{...props}
/>
));
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;

const DrawerContent = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DrawerPortal>
<DrawerOverlay />
<DrawerPrimitive.Content
ref={ref}
className={cn(
'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',
className
)}
{...props}
>
<div className='mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted' />
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
));
DrawerContent.displayName = 'DrawerContent';

const DrawerHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn('grid gap-1.5 p-4 text-center sm:text-left', className)}
{...props}
/>
);
DrawerHeader.displayName = 'DrawerHeader';

const DrawerFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn('mt-auto flex flex-col gap-2 p-4', className)}
{...props}
/>
);
DrawerFooter.displayName = 'DrawerFooter';

const DrawerTitle = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Title
ref={ref}
className={cn(
'text-lg font-semibold leading-none tracking-tight',
className
)}
{...props}
/>
));
DrawerTitle.displayName = DrawerPrimitive.Title.displayName;

const DrawerDescription = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Description
ref={ref}
className={cn('text-sm text-muted-foreground', className)}
{...props}
/>
));
DrawerDescription.displayName = DrawerPrimitive.Description.displayName;

export {
Drawer,
DrawerPortal,
DrawerOverlay,
DrawerTrigger,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerFooter,
DrawerTitle,
DrawerDescription,
};
15 changes: 15 additions & 0 deletions components/ui/skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { cn } from "@/lib/utils"

function Skeleton({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn("animate-pulse rounded-md bg-muted", className)}
{...props}
/>
)
}

export { Skeleton }
13 changes: 13 additions & 0 deletions components/ui/skeletonCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Skeleton } from '@/components/ui/skeleton';

export function SkeletonCard() {
return (
<div className='flex flex-col space-y-3'>
<Skeleton className='h-[225px] w-[450px] rounded-xl' />
<div className='space-y-2'>
<Skeleton className='h-4 w-[350px]' />
<Skeleton className='h-4 w-[200px]' />
</div>
</div>
);
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
},
"dependencies": {
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-slot": "^1.0.2",
"@supabase/ssr": "^0.3.0",
"@supabase/supabase-js": "^2.43.1",
Expand All @@ -29,7 +30,8 @@
"react": "^18",
"react-dom": "^18",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7"
"tailwindcss-animate": "^1.0.7",
"vaul": "^0.9.1"
},
"devDependencies": {
"@testing-library/react": "^15.0.7",
Expand Down
Loading

0 comments on commit edea63d

Please sign in to comment.