feat: question page ui

pull/4442/head
Kamran Ahmed 1 year ago
parent 2a7fd53c8b
commit e4c29b03ab
  1. 89
      src/components/Questions/QuestionCard.tsx
  2. 9
      src/components/Questions/QuestionLoader.tsx
  3. 37
      src/components/Questions/QuestionsList.tsx

@ -0,0 +1,89 @@
import { useEffect, useRef, useState } from 'react';
export function QuestionCard() {
const [isAnswerVisible, setIsAnswerVisible] = useState<boolean>(false);
const answerRef = useRef<HTMLDivElement>(null);
const questionRef = useRef<HTMLDivElement>(null);
useEffect(() => {
// set the height of the question width to the height of the answer
// width if the answer is visible and the question height is less than
// the answer height
if (isAnswerVisible) {
const answerHeight = answerRef.current?.clientHeight || 0;
const questionHeight = questionRef.current?.clientHeight || 0;
if (answerHeight > questionHeight) {
questionRef.current!.style.height = `${answerHeight}px`;
}
// if the user has scrolled down and the top of the answer is not
// visible, scroll to the top of the answer
const questionTop = questionRef.current?.getBoundingClientRect().top || 0;
if (questionTop < 0) {
window.scrollTo({
top: window.scrollY + questionTop - 100,
});
}
} else {
questionRef.current!.style.height = `auto`;
}
}, [isAnswerVisible]);
return (
<>
<div
ref={questionRef}
className={`flex flex-grow flex-col items-center justify-center py-8`}
>
<div className="text-gray-400">
<span>Frontend</span>
<span className="mx-3">&middot;</span>
<span className="capitalize">Easy Question</span>
</div>
<div className="mx-auto flex max-w-[550px] flex-1 items-center justify-center py-8">
<p className="text-3xl leading-normal text-black">
What do you think is the output of the following code?
</p>
</div>
<div className="text-center">
<button
onClick={() => {
setIsAnswerVisible(true);
}}
className="cursor-pointer text-gray-500 underline underline-offset-4 transition-colors hover:text-black"
>
Click to Reveal the Answer
</button>
</div>
</div>
<div
ref={answerRef}
className={`absolute left-0 right-0 flex flex-col items-center justify-center rounded-[7px] bg-neutral-100 py-8 text-xl leading-normal text-black transition-all duration-300 ${
isAnswerVisible ? 'top-0 min-h-[398px]' : 'top-full'
}`}
>
<div className="mx-auto flex max-w-[600px] flex-grow items-center py-0 px-5 text-2xl leading-normal">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam
voluptatum, quod, quas, quia, voluptates voluptate quibusdam
voluptatibus quos quae quidem. Quisqu
</p>
</div>
<div className="text-center mt-7">
<button
onClick={() => {
setIsAnswerVisible(false);
}}
className="cursor-pointer text-base text-gray-500 underline underline-offset-4 transition-colors hover:text-black"
>
Hide the Answer
</button>
</div>
</div>
</>
);
}

@ -0,0 +1,9 @@
export function QuestionLoader() {
return (
<div className="flex h-full w-full items-center justify-center">
<p className="animate-pulse text-2xl text-black duration-100">
Please wait ..
</p>
</div>
);
}

@ -1,12 +1,22 @@
import { QuestionsProgress } from './QuestionsProgress';
import { CheckCircle, SkipForward, Sparkles } from 'lucide-react';
import { useRef, useState } from 'react';
import ReactConfetti from 'react-confetti';
import { QuestionsProgress } from './QuestionsProgress';
import { CheckCircle, SkipForward, Sparkles } from 'lucide-react';
import { QuestionCard } from './QuestionCard';
import { QuestionLoader } from './QuestionLoader';
type ConfettiPosition = {
x: number;
y: number;
w: number;
h: number;
};
export function QuestionsList() {
const [confettiPos, setConfettiPos] = useState<
undefined | { x: number; y: number; w: number; h: number }
>(undefined);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [confettiPos, setConfettiPos] = useState<undefined | ConfettiPosition>(
undefined
);
const alreadyKnowRef = useRef<HTMLButtonElement>(null);
@ -16,12 +26,14 @@ export function QuestionsList() {
{confettiPos && (
<ReactConfetti
numberOfPieces={20}
height={document.body.scrollHeight}
numberOfPieces={40}
recycle={false}
onConfettiComplete={() => {
onConfettiComplete={(confettiInstance) => {
confettiInstance?.reset();
setConfettiPos(undefined);
}}
initialVelocityX={2}
initialVelocityX={4}
initialVelocityY={8}
tweenDuration={25}
confettiSource={{
@ -33,12 +45,9 @@ export function QuestionsList() {
/>
)}
<div className="relative mb-4 h-[400px] w-full overflow-hidden rounded-lg border border-gray-300 bg-white">
<div className="flex h-full w-full items-center justify-center">
<p className="animate-pulse text-2xl text-black duration-100">
Please wait ..
</p>
</div>
<div className="relative mb-4 flex min-h-[400px] w-full overflow-hidden rounded-lg border border-gray-300 bg-white">
<QuestionCard />
{isLoading && <QuestionLoader />}
</div>
<div className="flex flex-col gap-3 sm:flex-row">

Loading…
Cancel
Save