Implementing a React Quiz Application with User Authentication
The folllowing demonstrates a React appilcation featuring user authentication on the left panel and a quiz interface on the right.
First, create a new React project:
npx create-react-app quiz-app
Layout Structure
Create a flex container with two child elements:
<div className='container'>
<div className='auth-panel'></div>
<div className='quiz-panel'></div>
</div>
Add corresponding styles:
.container {
display: flex;
height: 100vh;
}
.auth-panel {
flex: 1;
}
.quiz-panel {
flex: 2;
background-color: #000;
}
Authentication Componetn
Initialize state and handlers:
state = {
username: '',
errorMessage: '',
isLoggedIn: false,
buttonText: 'Login'
}
handleInputChange = (e) => {
this.setState({ username: e.target.value });
}
handleLogin = () => {
const { username, buttonText } = this.state;
if (buttonText === 'Login') {
if (!username) {
alert('Username required');
} else if (username.length < 6 || username.length > 18) {
this.setState({ errorMessage: 'Username must be 6-18 characters' });
} else {
this.setState({
errorMessage: '',
isLoggedIn: true,
buttonText: 'Logout'
});
}
} else {
this.setState({
isLoggedIn: false,
buttonText: 'Login'
});
}
}
Quiz Component
Define quiz questions and state:
state = {
questions: [
{
text: 'What does the br tag do?',
options: ['Line break', 'Display images', 'Create buttons', 'Paragraph'],
answer: 0
},
// Additional questions...
],
currentIndex: 0,
correct: 0,
incorrect: 0,
selectedOption: null
}
handleNext = () => {
const { currentIndex, selectedOption, questions } = this.state;
if (selectedOption === null) {
alert('Please select an answer');
return;
}
if (currentIndex < questions.length - 1) {
this.setState(prevState => ({
correct: selectedOption === questions[currentIndex].answer
? prevState.correct + 1
: prevState.correct,
incorrect: selectedOption !== questions[currentIndex].answer
? prevState.incorrect + 1
: prevState.incorrect,
currentIndex: prevState.currentIndex + 1,
selectedOption: null
}));
} else {
this.setState({
currentIndex: 0,
correct: 0,
incorrect: 0
});
}
}
Combined Implementation
const {
username,
errorMessage,
isLoggedIn,
buttonText,
questions,
currentIndex,
correct,
incorrect,
selectedOption
} = this.state;
return (
<div className='container'>
<div className='auth-panel'>
<input
onChange={this.handleInputChange}
placeholder='Enter username'
/>
<span style={{color: 'red'}}>{errorMessage}</span>
<br />
<button onClick={this.handleLogin}>{buttonText}</button>
</div>
{isLoggedIn && (
<div className='quiz-panel'>
<h3>{questions[currentIndex].text}</h3>
{questions[currentIndex].options.map((option, index) => (
<div key={index} className='option'>
<input
type='radio'
name='quiz'
onChange={() => this.setState({ selectedOption: index })}
checked={index === selectedOption}
/>
{option}
</div>
))}
<button onClick={this.handleNext}>
{currentIndex < questions.length - 1 ? 'Next' : 'Restart'}
</button>
<br />
{currentIndex + 1}/{questions.length}
Correct: {correct} Incorrect: {incorrect}
</div>
)}
</div>
);