Skip to content

Question 1

Design and develop a functional component called NewsletterSignup.

  • The form should include fields for full name and email address.
  • Use useState to control the form inputs.
  • On form submission, display a thank-you message using conditional rendering.
  • Style the form using an external CSS file with padding, border, and hover effects.

NewsletterSignup.jsx

jsx
import React, { useState } from 'react';
import './NewsletterSignup.css';

function NewsletterSignup(){
	// States
	const [fullName, setFullName] = useState('');
	const [email, setEmail] = useState('');
	const [submitted, setSubmitted] = useState(false);

	// Event Handlers
	function handleName(event){
	  setFullName(event.target.value);
	};
	function handleEmail(event){
	  setEmail(event.target.vale);
	};
	function handleSubmit(event) {
	  event.preventDefault();
	  setSubmitted(true);
	};
	
	// Render Thank you when Submitted
	if (submitted) {
	  return( 
	    <div 
		  className="thank-you"
		  >Thank you for signing up, {fullName}!
		  </div>
	  );
  }

	return (
		<form 
			className="newsletter-form" 
			onSubmit={handleSubmit}>
		      <h2>Sign Up for Our Newsletter</h2>
			<label>
		        Full Name:
				<input
		          type="text"
		          value={fullName}
		          onChange={handleName}
		          required/>
	        </label>
      
			<label>
		        Email Address:
		        <input
		          type="email"
		          value={email}
		          onChange={handleEmail}
		          required/>
			</label>
	      <button type="submit">Subscribe</button>
	    </form>
	);
};
export default NewsletterSignup;

NewsletterSignup.css

css
.newsletter-form {
  max-width: 400px;
  margin: 40px auto;
  padding: 20px;
  border: 2px solid #ccc;
  border-radius: 8px;
  background-color: #f9f9f9;
  font-family: Arial, sans-serif;
}

.newsletter-form h2 {
  text-align: center;
  margin-bottom: 20px;
}

.newsletter-form label {
  display: block;
  margin-bottom: 15px;
}

.newsletter-form input[type="text"],
.newsletter-form input[type="email"] {
  width: 100%;
  padding: 10px;
  margin-top: 5px;
  border: 1px solid #aaa;
  border-radius: 4px;
  box-sizing: border-box;
}

.newsletter-form button {
  width: 100%;
  padding: 10px;
  background-color: #4caf50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.newsletter-form button:hover {
  background-color: #45a049;
}

.thank-you {
  text-align: center;
  font-size: 1.5em;
  padding: 40px;
  color: #4caf50;
}

Advanced Form Component with Validation

NewsletterSignup.jsx

jsx
import React, { useState } from 'react';
import './NewsletterSignup.css';

function NewsletterSignup() {
  const [fullName, setFullName] = useState('');
  const [email, setEmail] = useState('');
  const [isSubmitted, setIsSubmitted] = useState(false);
  const [error, setError] = useState('');


  const handleFullNameChange = (event) => {
    setFullName(event.target.value);
	// Clear error when user starts typing
    if (error) setError('');     
  };

  const handleEmailChange = (event) => {
    setEmail(event.target.value);
    // Clear error when user starts typing
    if (error) setError(''); 
  };

  const validateEmail = (email) => {
    // Basic email validation regex
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  };
  
  const handleSubmit = (event) => {
    event.preventDefault(); 
    // Prevent default form submission (page reload)

    // Basic Validation to set error
    if (!fullName.trim()) {
      setError('Full name is required.');
      return;
    }
    if (!email.trim()) {
      setError('Email address is required.');
      return;
    }
    if (!validateEmail(email)) {
      setError('Please enter a valid email address.');
      return;
    }
	// If no error
    setError(''); // Clear any previous errors
    console.log('Form Submitted:', { fullName, email });
    setIsSubmitted(true);
  };
  // Thank you Once Submitted
  if (isSubmitted) {
    return (
      <div className="newsletter-form-container">
        <div className="thank-you-message">
          <h3>Thank You, {fullName}!</h3>
          <p>Successfully subscribed to our newsletter 
	          with the email: {email}.</p>
          <p>We'll be in touch soon!</p>
        </div>
      </div>
    );
  }

  return (
    <div className="newsletter-form-container">
      <h2>Subscribe to Our Newsletter</h2>
      
      {error && <p className="error-message">{error}</p>}
      
	  <form 
		  onSubmit={handleSubmit} 
		  className="newsletter-form" 
		  noValidate>
        <div className="form-group">
          <label htmlFor="fullName">Full Name:</label>
          <input
            type="text"
            id="fullName"
            name="fullName"
            value={fullName}
            onChange={handleFullNameChange}
            placeholder="Enter Full Name"
            required
          />
        </div>
        
        <div className="form-group">
          <label htmlFor="email">Email Address:</label>
          <input
            type="email"
            id="email"
            name="email"
            value={email}
            onChange={handleEmailChange}
            placeholder="e.g., jane.doe@example.com"
            required
          />
        </div>
        
        <button type="submit">Subscribe</button>
        
      </form>
    </div>
  );
}

export default NewsletterSignup;

validateEmail: A simple helper function for basic email format validation.

handleSubmit:

  • Calls event.preventDefault() to stop the browser from performing its default form submission behavior (which usually involves a page reload).
  • Performs basic validation: checks if fields are empty and if the email has a valid format.
  • If validation fails, it sets an error message using setError.
  • If validation passes, it clears any error, logs the data (you would typically send this to a server), and sets isSubmitted to true.

Conditional Rendering:

  • if (isSubmitted): If true, the component renders the "Thank You" message, personalizing it with the fullName and email.

  • Otherwise (if isSubmitted is false), it renders the form.

  • Error Display: {error && <p className="error-message">{error}</p>} conditionally renders the error message if the error state is not an empty string.

NewsletterSignup.css

css
.newsletter-form-container {
  font-family: Arial, sans-serif;
  background-color: #f9f9f9;
  padding: 25px;
  border-radius: 8px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  max-width: 400px;
  margin: 40px auto;
  border: 1px solid #ddd;
}

.newsletter-form-container h2 {
  text-align: center;
  color: #333;
  margin-bottom: 20px;
}

.newsletter-form .form-group {
  margin-bottom: 15px;
}

.newsletter-form label {
  display: block;
  margin-bottom: 5px;
  color: #555;
  font-weight: bold;
}

.newsletter-form input[type="text"],
.newsletter-form input[type="email"] {
  width: calc(100% - 22px); /* Account for padding and border */
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 16px;
  box-sizing: border-box; /* Ensures padding and border are inside the element's total width and height */
}

.newsletter-form input[type="text"]:focus,
.newsletter-form input[type="email"]:focus {
  border-color: #007bff;
  outline: none;
  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}

.newsletter-form button[type="submit"] {
  width: 100%;
  padding: 12px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  font-size: 16px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.newsletter-form button[type="submit"]:hover {
  background-color: #0056b3;
}

.thank-you-message {
  text-align: center;
  padding: 20px;
  border: 1px solid #28a745;
  background-color: #d4edda;
  color: #155724;
  border-radius: 4px;
}

.thank-you-message h3 {
  margin-top: 0;
  color: #155724;
}

.error-message {
  color: #dc3545;
  background-color: #f8d7da;
  border: 1px solid #f5c6cb;
  padding: 10px;
  border-radius: 4px;
  margin-bottom: 15px;
  text-align: center;
}

Made with ❤️ for students, by a fellow learner.