React Checkout Form

by oktaviardi pratama

HTML

<div id="root"></div>

<!-- React -->
<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>

<!-- Babel -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

<!-- Tailwind CDN -->
<script src="https://cdn.tailwindcss.com"></script>

React

const { useState } = React;

function CheckoutForm() {
  const [form, setForm] = useState({
    name: "",
    email: "",
    address: "",
    city: "",
    zip: "",
    card: "",
    cvv: ""
  });

  const [errors, setErrors] = useState({});
  const [submitted, setSubmitted] = useState(false);

  const handleChange = (e) => {
    const { name, value } = e.target;

    setForm({ ...form, [name]: value });

    setErrors({ ...errors, [name]: "" });
  };

  const validate = () => {
    let err = {};

    if (!form.name.trim() || form.name.length < 3)
      err.name = "Name must be at least 3 characters";

    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(form.email))
      err.email = "Invalid email";

    if (form.address.trim().length < 10)
      err.address = "Address too short";

    if (!form.city.trim())
      err.city = "City required";

    if (!/^[0-9]{5,6}$/.test(form.zip))
      err.zip = "ZIP must be 5–6 digits";

    if (!/^[0-9]{16}$/.test(form.card))
      err.card = "Card must be 16 digits";

    if (!/^[0-9]{3}$/.test(form.cvv))
      err.cvv = "CVV must be 3 digits";

    return err;
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    const vErrors = validate();

    if (Object.keys(vErrors).length > 0) {
      setErrors(vErrors);
      return;
    }

    setErrors({});
    setSubmitted(true);
  };

  if (submitted) {
    return (
      <div className="h-screen flex items-center justify-center bg-green-50">
        <div className="bg-white p-8 rounded-xl shadow text-center">
          <h2 className="text-2xl font-bold text-green-600">
            🎉 Payment Successful
          </h2>
          <p className="mt-2 text-gray-600">
            Thanks, {form.name}
          </p>

          <button
            onClick={() => setSubmitted(false)}
            className="mt-5 px-4 py-2 bg-black text-white rounded-lg"
          >
       ...