added error boundary, fixed selection and layout

This commit is contained in:
2023-06-03 19:52:15 +02:00
parent 4114ccb678
commit bd49129273
8 changed files with 157 additions and 86 deletions
+39
View File
@@ -0,0 +1,39 @@
import React from 'react';
import { Capitalize } from '../Utils';
type Props = {
difficulty: string;
category: string | undefined;
questionNumber: number;
totalQuestions: number;
score: number;
gameOver:boolean;
};
const DetailsCard: React.FC<Props> = ({
difficulty,
category,
questionNumber,
totalQuestions,
score,
gameOver
}) => {
return (
<div className="question-card-wrapper">
<div className="details">
<div>Difficulty: {Capitalize(difficulty)}</div>
<div>
Question: {!gameOver && questionNumber + 1+'\/'}{totalQuestions}
</div>
<div>Score: {score}</div>
{category && (
<div>
Category: {category.replace(/Entertainment: |Science: /g, '')}
</div>
)}
</div>
</div>
);
};
export default DetailsCard;
+34
View File
@@ -0,0 +1,34 @@
import React, { Component, ErrorInfo, ReactNode } from "react";
interface Props {
children?: ReactNode;
}
interface State {
hasError: boolean;
}
class ErrorBoundary extends Component<Props, State> {
public state: State = {
hasError: false
};
public static getDerivedStateFromError(_: Error): State {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error("Uncaught error:", error, errorInfo);
}
public render() {
if (this.state.hasError) {
return <h1>Sorry.. there was an error</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;
+16 -44
View File
@@ -1,64 +1,36 @@
import React from 'react';
import { ButtonWrapper } from '../App.style';
import { AnswerObject } from '../Types';
import { Capitalize } from '../Utils';
import { unEscape } from '../Utils';
type Props = {
answers: string[];
callback: (e: React.MouseEvent<HTMLButtonElement>) => void;
difficulty: string;
question: string;
category: string;
questionNr: number;
score: number;
totalQuestions: number;
userAnswer: AnswerObject | undefined;
userAnswers: AnswerObject | undefined;
};
const QuestionCard: React.FC<Props> = ({
answers,
callback,
difficulty,
question,
category,
questionNr,
score,
totalQuestions,
userAnswer
userAnswers
}) => (
<div className="question-card-wrapper">
<div className="details">
<div>Difficulty: {Capitalize(difficulty)}</div>
<div>{category}</div>
<p className="question">{unEscape(question)}</p>
<div>
{answers.map((answer) => (
<ButtonWrapper
correct={userAnswers?.correctAnswer === answer}
userClicked={userAnswers?.answer === answer}
key={answer}
>
<button disabled={!!userAnswers} onClick={callback} value={answer}>
<span>{unEscape(answer)}</span>
</button>
</ButtonWrapper>
))}
</div>
<div className="details">
<div>
Question: {questionNr}/{totalQuestions}
</div>
<div>Score: {score}</div>
</div>
{!(questionNr === totalQuestions) && (
<>
<p
className="question"
dangerouslySetInnerHTML={{ __html: question }}
/>
<div>
{answers.map((answer) => (
<ButtonWrapper
correct={userAnswer?.correctAnswer === answer}
userClicked={userAnswer?.answer === answer}
key={answer}
>
<button disabled={!!userAnswer} onClick={callback} value={answer}>
<span dangerouslySetInnerHTML={{ __html: answer }} />
</button>
</ButtonWrapper>
))}
</div>
</>
)}
</div>
);
+9 -9
View File
@@ -4,24 +4,24 @@ import { SelectWrapper } from '../App.style';
import { Category } from '../Types';
type Props = {
category: number;
categoryID: number;
categoryList: Array<Category>;
setCategory: (category: number) => void;
setCategoryID: (categoryID: number) => void;
};
const SelectCategory = ({ category, categoryList, setCategory }: Props) => {
const SelectCategory = ({ categoryID, categoryList, setCategoryID }: Props) => {
return (
<SelectWrapper
value={category}
value={categoryID}
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
e.preventDefault();
setCategory(e.target.value as number);
setCategoryID(e.target.value as number);
}}
>
<option value={1}>Any Category</option>
{categoryList.map((cat) => (
<option value={cat.id} key={cat.id}>
{cat.name}
<option value={1}>Random Category</option>
{categoryList.map((category) => (
<option value={category.id} key={category.id}>
{category.name.replace(/Entertainment: |Science: /g, '')}
</option>
))}
</SelectWrapper>