Skip to content

Commit

Permalink
feat(curriculum): add React forms lab (#637)
Browse files Browse the repository at this point in the history
* add prototype

* improve prototype
  • Loading branch information
zairahira authored Nov 4, 2024
1 parent 38664a4 commit dc46e21
Show file tree
Hide file tree
Showing 3 changed files with 267 additions and 0 deletions.
121 changes: 121 additions & 0 deletions frontend-cert/react-projects/react-forms/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8" />
<title>Event RSVP</title>
<link rel="stylesheet" href="styles.css" />
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>

<body>
<div id="root"></div>
<script type="text/babel">
function EventRSVPForm() {
const [formData, setFormData] = React.useState({
name: '',
email: '',
attendees: '',
dietaryPreferences: '',
bringingOthers: false,
});

const [submitted, setSubmitted] = React.useState(false);

function handleChange(event) {
const { name, value, type, checked } = event.target;
setFormData({
...formData,
[name]: type === 'checkbox' ? checked : value,
});
}

function handleSubmit(event) {
event.preventDefault();
setSubmitted(true);
}

return (
<div className="form-container">
<h2>Event RSVP Form</h2>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label>Name:</label>
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
placeholder="Your Name"
required
/>
</div>
<div className="form-group">
<label>Email:</label>
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
placeholder="Your Email"
required
/>
</div>
<div className="form-group">
<label>Number of Attendees:</label>
<input
type="number"
name="attendees"
value={formData.attendees || ''}
onChange={handleChange}
min="1"
placeholder="Number of Attendees"
required
/>
</div>
<div className="form-group">
<label>Dietary Preferences:</label>
<input
type="text"
name="dietaryPreferences"
value={formData.dietaryPreferences}
onChange={handleChange}
placeholder="Dietary Preferences (Optional)"
/>
</div>
<div className="form-group">
<label>
Bringing additional guests?
</label>
<input
type="checkbox"
name="bringingOthers"
checked={formData.bringingOthers}
onChange={handleChange}
/>
</div>
<button type="submit">Submit RSVP</button>
</form>
{submitted && (
<div className="submitted-message">
<h3>RSVP Submitted!</h3>
<p><strong>Name:</strong> {formData.name}</p>
<p><strong>Email:</strong> {formData.email}</p>
<p><strong>Number of Attendees:</strong> {formData.attendees}</p>
<p><strong>Dietary Preferences:</strong> {formData.dietaryPreferences || 'None'}</p>
<p><strong>Bringing Others:</strong> {formData.bringingOthers ? 'Yes' : 'No'}</p>
</div>
)}
</div>
);
}

const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<EventRSVPForm />);
</script>
</body>

</html>
117 changes: 117 additions & 0 deletions frontend-cert/react-projects/react-forms/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
font-family: 'Helvetica Neue', Arial, sans-serif;
background-color: #e0e0e0;
}

.form-container {
background-color: #ffffff;
padding: 40px;
border-radius: 12px;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
width: 100%;
max-width: 450px;
text-align: center;
}

h2 {
margin-bottom: 20px;
font-size: 28px;
color: #333;
font-weight: bold;
}

form {
display: flex;
flex-direction: column;
}

.form-group {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
}

.form-group label {
flex: 1;
text-align: left;
margin-right: 15px;
font-size: 15px;
color: #555;
}

.form-group input[type="text"],
.form-group input[type="email"],
.form-group input[type="number"] {
flex: 2;
padding: 10px 12px;
border: 1px solid #ccc;
border-radius: 8px;
width: 100%;
font-size: 15px;
transition: border-color 0.3s ease;
}

.form-group input:focus {
border-color: #4caf4f4f;
}

.form-group input[type="checkbox"] {
margin-left: 10px;
}

button {
background-color: #5957e4;
color: white;
border: none;
padding: 12px 25px;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
margin-top: 15px;
transition: background-color 0.3s ease;
}

button:hover {
background-color: #413fb3;
}

.submitted-message {
margin-top: 30px;
text-align: left;
}

.submitted-message h3 {
color: #5957e4;
margin-bottom: 10px;
font-size: 22px;
}

@media (max-width: 500px) {
.form-container {
width: 90%;
padding: 20px;
}

.form-group {
flex-direction: column;
align-items: flex-start;
}

.form-group label {
text-align: left;
margin-bottom: 5px;
}

.form-group input[type="text"],
.form-group input[type="email"],
.form-group input[type="number"] {
width: 100%;
}
}
29 changes: 29 additions & 0 deletions frontend-cert/react-projects/react-forms/user-stories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
You should create a form with fields for name, email, number of attendees, dietary preferences, and an option to indicate if you are bringing additional guests.

You should have a text input field where you would enter your name (mandatory).

You should have an email input field where you would enter your email address (mandatory). The form should validate the format to ensure it is a proper email.

You should have a number input field where you would enter the number of attendees in the form (mandatory), and the number should not be less than one.

You should have a text input field where you would enter your dietary preferences, and this information should be optional.

You should be able to check or uncheck a checkbox to indicate whether you are bringing additional guests.

You should have a `"Submit RSVP"` button and be able to submit the form by clicking it and the form should prevent the page from reloading upon submission.

You should see a confirmation message `"RSVP Submitted!"` displayed just below the form after submitting, followed by the details you provided (name, email, number of attendees, dietary preferences, and whether you are bringing additional guests).
Here is a sample message you should see after submitting the form:

```
RSVP Submitted!
Name: John Doe
Email: [email protected]
Number of attendees: 2
Dietary preferences: None
Bringing additional guests: Yes
```

You should not be able to submit the form if the required fields (name, email, and number of attendees) are not filled out, ensuring proper validation.

You should see the default message "None" if no dietary preferences are entered after submitting the form.

0 comments on commit dc46e21

Please sign in to comment.