Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(curriculum): add React forms lab #637

Merged
merged 2 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.