polish app

Signed-off-by: Alex Stan <alex.stan.2010@proton.me>
This commit is contained in:
Alex Stan 2024-06-01 23:42:20 +03:00
parent 328b304b6c
commit c71f5cd9a6
6 changed files with 75 additions and 29 deletions

View file

@ -17,6 +17,9 @@ const QuestionView = ({ question, setState, state }: { question: Question, setSt
const handleAnswerClick = (right: boolean) => { const handleAnswerClick = (right: boolean) => {
setState( (prevState: SessionState) => ({ setState( (prevState: SessionState) => ({
...prevState, ...prevState,
answered: prevState.answered + 1,
wrong: prevState.wrong + (right ? 0 : 1),
right: prevState.right + (right ? 1 : 0),
answer: { answer: {
...prevState.answer, ...prevState.answer,
[question.id]: right ? AnswerType.Right : AnswerType.Wrong [question.id]: right ? AnswerType.Right : AnswerType.Wrong
@ -29,30 +32,29 @@ const QuestionView = ({ question, setState, state }: { question: Question, setSt
<div className="mx-auto max-w-2xl py-32 sm:py-48 lg:py-56"> <div className="mx-auto max-w-2xl py-32 sm:py-48 lg:py-56">
<div className="text-center"> <div className="text-center">
<h1 className="text-4xl font-bold tracking-tight text-gray-50"> <h1 className="text-4xl font-bold tracking-tight text-gray-50">
{question.text} {question && question.text}
</h1> </h1>
{state.opened[ question.id ] ? ( {question && state.opened[ question.id ] ? (
<p className="mt-6 text-lg leading-8 text-gray-200"> <div><p className="mt-6 text-lg leading-8 text-gray-200">
{question.answer} {question.answer}
</p> </p>
) : null} <div className="mt-10 flex items-center justify-center gap-x-6">
<button className="text-sm font-semibold leading-6 text-gray-200" onClick={handleOpenClick}> <button
onClick={() => { handleAnswerClick( true )}}
className="rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
I knew that!
</button>
<button
onClick={() => {handleAnswerClick( false )}}
className="text-sm font-semibold leading-6 text-gray-300"
>
I didn't know that!
</button>
</div>
</div>) : (<button className="text-sm font-semibold leading-6 text-gray-200" onClick={handleOpenClick}>
Show answer Show answer
</button> </button>)}
<div className="mt-10 flex items-center justify-center gap-x-6">
<button
onClick={() => { handleAnswerClick( true )}}
className="rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
I knew that!
</button>
<button
onClick={() => {handleAnswerClick( false )}}
className="text-sm font-semibold leading-6 text-gray-300"
>
I didn't know that!
</button>
</div>
</div> </div>
</div> </div>
) )

View file

@ -7,6 +7,7 @@ import { CheckIcon } from '@heroicons/react/20/solid';
import { SessionState } from '@/app/lib/session'; import { SessionState } from '@/app/lib/session';
import { AnswerType, Question, getQuestions } from '@/app/lib/question'; import { AnswerType, Question, getQuestions } from '@/app/lib/question';
import QuestionView from '@/app/components/question_component'; import QuestionView from '@/app/components/question_component';
import ResultScreen from '@/app/results/page';
const Page = ({ params }: { params: { category: string }}) => { const Page = ({ params }: { params: { category: string }}) => {
@ -17,7 +18,8 @@ const Page = ({ params }: { params: { category: string }}) => {
right: 0, right: 0,
category: '', category: '',
opened: [], opened: [],
answer: [] answer: [],
index: 0
} ); } );
// const category = params.category; // const category = params.category;
@ -56,6 +58,12 @@ const Page = ({ params }: { params: { category: string }}) => {
console.log( "state15", state ); console.log( "state15", state );
// alternate version (show all of them at the same time):
// {/* {questions.map( (q) => (q.answered == AnswerType.Unset) ? <QuestionView key = {q.id} question={q} state={state} setState={setState}/> : <></>)} */}
const index = state.answered;
console.log( "index18", index )
return ( return (
<div> <div>
@ -75,9 +83,8 @@ const Page = ({ params }: { params: { category: string }}) => {
/> />
</div> </div>
<div style={{paddingTop: '72px'}}></div> <div style={{paddingTop: '72px'}}></div>
<Logo/>
{/* <QuestionView key = {questions[0].id} question={questions[0]} state={state} setState={setState}/> */} {questions[ index ] ? (<QuestionView question={questions[ index ]} state = {state} setState={setState}/>) : <ResultScreen state={state}/>}
{questions.map( (q) => (q.answered == AnswerType.Unset) ? <QuestionView key = {q.id} question={q} state={state} setState={setState}/> : <></>)}
<div <div
className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]" className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"

View file

@ -16,6 +16,7 @@ export type SessionState = {
category: string; category: string;
opened: boolean[]; opened: boolean[];
answer: AnswerType[]; answer: AnswerType[];
index: number;
} }
export const getSession = async (id: number): Promise<Session> => { export const getSession = async (id: number): Promise<Session> => {

View file

@ -1,6 +1,8 @@
import { CheckIcon, XMarkIcon, QuestionMarkCircleIcon, FingerPrintIcon, LockClosedIcon } from '@heroicons/react/24/outline' import { CheckIcon, XMarkIcon, QuestionMarkCircleIcon, FingerPrintIcon, LockClosedIcon } from '@heroicons/react/24/outline'
import Logo from '../components/logo'; import Logo from '../components/logo';
import { SessionState } from '../lib/session';
/*
const features = [ const features = [
{ {
name: 'Correct Questions', name: 'Correct Questions',
@ -21,8 +23,24 @@ const features = [
icon: QuestionMarkCircleIcon, icon: QuestionMarkCircleIcon,
} }
] ]
*/
export default function Example() { const Result = ({name, text1, number, text2, Icon}: {name: string, text1: string, number: number, text2: string, Icon: any}) => {
return (
<div className="relative pl-16">
<dt className="text-base font-semibold leading-7 text-gray-100">
<div className="absolute left-0 top-0 flex h-10 w-10 items-center justify-center rounded-lg bg-indigo-600">
<Icon className="h-6 w-6 text-white" aria-hidden="true"/>
</div>
{name}
</dt>
<dd className="mt-2 text-base leading-7 text-gray-300">{`${text1} ${number} ${text2}`}</dd>
</div>
// {/* <p className="relative pl-16">{`${text1} ${number} ${text2}`}</p> */}
)
}
const ResultScreen = ({state}: {state: SessionState}) => {
return ( return (
<div className="py-24 sm:py-32"> <div className="py-24 sm:py-32">
<div <div
@ -51,7 +69,7 @@ export default function Example() {
</div> </div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-4xl"> <div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-4xl">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-10 lg:max-w-none lg:grid-cols-2 lg:gap-y-16"> <dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-10 lg:max-w-none lg:grid-cols-2 lg:gap-y-16">
{features.map((feature) => ( {/* {features.map((feature) => (
<div key={feature.name} className="relative pl-16"> <div key={feature.name} className="relative pl-16">
<dt className="text-base font-semibold leading-7 text-gray-100"> <dt className="text-base font-semibold leading-7 text-gray-100">
<div className="absolute left-0 top-0 flex h-10 w-10 items-center justify-center rounded-lg bg-indigo-600"> <div className="absolute left-0 top-0 flex h-10 w-10 items-center justify-center rounded-lg bg-indigo-600">
@ -61,7 +79,10 @@ export default function Example() {
</dt> </dt>
<dd className="mt-2 text-base leading-7 text-gray-300">{feature.description}</dd> <dd className="mt-2 text-base leading-7 text-gray-300">{feature.description}</dd>
</div> </div>
))} ))} */}
<Result name="Correct Answers" key="correct" text1="Congrats for your" number={state.right} text2="correctly answered questions! Great job!" Icon={CheckIcon}/>
<Result name="Wrong Answers" key="wrong" text1="You had" number={state.wrong} text2="wrong answers... It's never too late to learn!" Icon={XMarkIcon}/>
<Result name="Total answers" key="total" text1="The" number={state.answered} text2="questions you answered surely helped you learn more." Icon={QuestionMarkCircleIcon}/>
</dl> </dl>
<br></br> <br></br>
<a <a
@ -88,3 +109,4 @@ export default function Example() {
</div> </div>
) )
} }
export default ResultScreen;

15
package-lock.json generated
View file

@ -12,7 +12,8 @@
"@heroicons/react": "^2.1.3", "@heroicons/react": "^2.1.3",
"next": "14.2.3", "next": "14.2.3",
"react": "^18", "react": "^18",
"react-dom": "^18" "react-dom": "^18",
"react-use-wizard": "^2.3.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20", "@types/node": "^20",
@ -3911,6 +3912,18 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true "dev": true
}, },
"node_modules/react-use-wizard": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/react-use-wizard/-/react-use-wizard-2.3.0.tgz",
"integrity": "sha512-z06pQNZ18FvoK+ZDW50hOf0uOySo0Hhd7H4y0MLyk/tBCwpUKGBeULosORBVhipUaWihNLpLJxwH5f+85Qt5XA==",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/read-cache": { "node_modules/read-cache": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",

View file

@ -13,7 +13,8 @@
"@heroicons/react": "^2.1.3", "@heroicons/react": "^2.1.3",
"next": "14.2.3", "next": "14.2.3",
"react": "^18", "react": "^18",
"react-dom": "^18" "react-dom": "^18",
"react-use-wizard": "^2.3.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20", "@types/node": "^20",