Zuma32

SignUp Page

Aug 7th, 2025
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 9.85 KB | Source Code | 0 0
  1. import { useState, useEffect } from "react";
  2. import { Link } from "react-router-dom";
  3. import { useAuth } from "./authContext";
  4. import { useNavigate } from "react-router-dom";
  5. import { Ambulance } from "lucide-react";
  6. import { womanWithAmbulane, whiteManInAmbulance } from "../assets/images/imageIdex";
  7.  
  8. const carouselData = [
  9.   {
  10.     image: womanWithAmbulane,
  11.     text: "Swift response, every time."
  12.   },
  13.   {
  14.     image: whiteManInAmbulance,
  15.     text: "Get instant Ambulance Service"
  16.   },
  17.   // Add more images and texts here as needed
  18.   // { image: anotherImage, text: "Your safety, our priority." },
  19. ];
  20.  
  21. export default function SignupPortal() {
  22.   const [firstName, setFirstName] = useState("");
  23.   const [lastName, setLastName] = useState("");
  24.   const [age, setAge] = useState("");
  25.   const [password, setPassword] = useState("");
  26.   const [phone, setPhone] = useState("");
  27.   const [email, setEmail] = useState("");
  28.   const [role, setRole] = useState("");
  29.   const [usePhone, setUsePhone] = useState(true); // toggle input mode
  30.   const [admin, setAdmin] = useState(false); // toggle admin mode
  31.   const [organizationName, setOrganizationName] = useState("");
  32.   const [organizationAddress, setOrganizationAddress] = useState("");
  33.  
  34.   const {signup, loading} = useAuth();
  35.   const navigate = useNavigate();
  36.  
  37.   // Carousel state
  38.   const [carouselIndex, setCarouselIndex] = useState(0);
  39.   useEffect(() => {
  40.     const interval = setInterval(() => {
  41.       setCarouselIndex((prev) => (prev + 1) % carouselData.length);
  42.     }, 4000);
  43.     return () => clearInterval(interval);
  44.   }, []);
  45.  
  46. const handleSubmit = async (e) => {
  47.   e.preventDefault();
  48.  
  49.   const payload = {
  50.     first_name: firstName,
  51.     last_name: lastName,
  52.     age: Number(age),
  53.     role,
  54.     password,
  55.     ...(usePhone ? { phone_number: phone.replace(/^0/, "+233") } : { email }),
  56.     ...(admin ? {
  57.       organization: {
  58.         org_name: organizationName,
  59.         address: organizationAddress
  60.       }
  61.     } : {})
  62.   };
  63.  
  64.  
  65.  
  66.     try {
  67.         await signup(payload);
  68.         navigate("/verify-token");
  69.     }
  70.     catch(error) {
  71.        
  72.     }
  73.  
  74. };
  75.  
  76.  
  77.   return (
  78.     <div className="min-h-screen w-full flex items-stretch bg-gradient-to-br from-gray-900 via-gray-800 to-gray-700 relative overflow-hidden">
  79.       {/* Fixed carousel on the left for large screens */}
  80.       <div className="hidden lg:flex flex-col justify-center items-start fixed left-0 top-0 h-full w-2/3 z-10">
  81.         <div className="relative w-full h-2/3 flex items-center justify-center">
  82.           <img
  83.             src={carouselData[carouselIndex].image}
  84.             alt="Ambulance carousel"
  85.             className="object-cover h-full w-full rounded-2xl shadow-xl opacity-60 transition-all duration-700"
  86.           />
  87.           <div className="absolute bottom-12 left-12 bg-opacity-60 px-6 py-4 rounded-xl max-w-lg">
  88.             <h2 className="text-3xl font-bold text-white drop-shadow-lg animate-fade-in-left" style={{animation: 'fadeInLeft 1.2s ease'}}>
  89.               {carouselData[carouselIndex].text}
  90.             </h2>
  91.           </div>
  92.         </div>
  93.         <style>{`
  94.           @keyframes fadeInLeft {
  95.             0% { opacity: 0; transform: translateX(-40px); }
  96.             100% { opacity: 1; transform: translateX(0); }
  97.           }
  98.           .animate-fade-in-left {
  99.             animation: fadeInLeft 1.2s ease;
  100.           }
  101.         `}</style>
  102.       </div>
  103.       {/* Signup card on the right, scrollable */}
  104.       <div className="flex-1 flex items-center justify-end ml-auto lg:pl-[66.6667%] min-h-screen">
  105.         <div className="w-full max-w-lg bg-gray-800 bg-opacity-95 rounded-2xl shadow-2xl p-8 m-12 relative z-20 flex flex-col items-center">
  106.           <Ambulance className="w-16 h-16 text-red-500 drop-shadow-lg mb-2" />
  107.           <h1 className="text-3xl font-bold text-white mb-6 tracking-wide">Sign Up</h1>
  108.           <form className="space-y-4 w-full" onSubmit={handleSubmit}>
  109.             <div>
  110.               <label className="block text-sm font-medium text-gray-300">First Name</label>
  111.               <input
  112.                 type="text"
  113.                 className="mt-1 w-full bg-gray-700 text-white border border-gray-600 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400"
  114.                 value={firstName}
  115.                 onChange={(e) => setFirstName(e.target.value)}
  116.                 required
  117.               />
  118.             </div>
  119.             <div>
  120.               <label className="block text-sm font-medium text-gray-300">Last Name</label>
  121.               <input
  122.                 type="text"
  123.                 className="mt-1 w-full bg-gray-700 text-white border border-gray-600 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400"
  124.                 value={lastName}
  125.                 onChange={(e) => setLastName(e.target.value)}
  126.                 required
  127.               />
  128.             </div>
  129.             <div>
  130.               <label className="block text-sm font-medium text-gray-300">Age</label>
  131.               <input
  132.                 type="number"
  133.                 className="mt-1 w-full bg-gray-700 text-white border border-gray-600 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400"
  134.                 value={age}
  135.                 onChange={(e) => setAge(e.target.value)}
  136.                 required
  137.               />
  138.             </div>
  139.             <div>
  140.               <label className="block text-sm font-medium text-gray-300">Role</label>
  141.               <select
  142.                 className="mt-1 w-full bg-gray-700 text-white border border-gray-600 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400"
  143.                 value={role}
  144.                 onChange={(e) => setRole(e.target.value)}
  145.                 required
  146.               >
  147.                 <option value="">Select a role</option>
  148.                 {admin && <option value="HealthAdmin">Health Admin</option> }
  149.                 {admin && <option value="DriverAdmin">Driver Admin</option> }
  150.                 {!admin && <option value="Driver">Driver</option> }
  151.                 {!admin && <option value="Individual">Individual</option>}
  152.               </select>
  153.             </div>
  154.             <div className="flex justify-between items-center">
  155.               <span className="text-sm font-medium text-gray-300">
  156.                 Use {usePhone ? "Phone" : "Email"}?
  157.               </span>
  158.               <button
  159.                 type="button"
  160.                 className="text-blue-400 text-sm"
  161.                 onClick={() => setUsePhone(!usePhone)}
  162.               >
  163.                 Switch to {usePhone ? "Email" : "Phone"}
  164.               </button>
  165.             </div>
  166.             {usePhone ? (
  167.               <div>
  168.                 <label className="block text-sm font-medium text-gray-300">Phone</label>
  169.                 <input
  170.                   type="tel"
  171.                   className="mt-1 w-full bg-gray-700 text-white border border-gray-600 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400"
  172.                   value={phone}
  173.                   onChange={(e) => setPhone(e.target.value)}
  174.                   required
  175.                 />
  176.               </div>
  177.             ) : (
  178.               <div>
  179.                 <label className="block text-sm font-medium text-gray-300">Email</label>
  180.                 <input
  181.                   type="email"
  182.                   className="mt-1 w-full bg-gray-700 text-white border border-gray-600 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400"
  183.                   value={email}
  184.                   onChange={(e) => setEmail(e.target.value)}
  185.                   required
  186.                 />
  187.               </div>
  188.             )}
  189.             <div>
  190.               <label className="block text-sm font-medium text-gray-300">Password</label>
  191.               <input
  192.                 type="password"
  193.                 className="mt-1 w-full bg-gray-700 text-white border border-gray-600 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-red-400"
  194.                 value={password}
  195.                 onChange={(e) => setPassword(e.target.value)}
  196.                 required
  197.               />
  198.             </div>
  199.             { admin &&
  200.               <div>
  201.                 <label className="block text-sm font-medium text-gray-300">Organization Name</label>
  202.                 <input
  203.                   type="text"
  204.                   className="mt-1 w-full bg-gray-700 text-white border border-gray-600 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400"
  205.                   value={organizationName}
  206.                   onChange={(e) => setOrganizationName(e.target.value)}
  207.                   required
  208.                 />
  209.                 <label className="block text-sm font-medium text-gray-300">Organization Address</label>
  210.                 <input
  211.                   type="address"
  212.                   className="mt-1 w-full bg-gray-700 text-white border border-gray-600 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400"
  213.                   value={organizationAddress}
  214.                   onChange={(e) => setOrganizationAddress(e.target.value)}
  215.                   required
  216.                 />
  217.               </div>
  218.             }
  219.             <button
  220.               type="submit"
  221.               className="w-full bg-red-500 hover:bg-red-600 text-white py-2 rounded-lg font-semibold shadow-md transition-colors"
  222.             >
  223.               {loading ?<p className="w-5 h-5 bg-white rounded-full animate-pulse"></p> : "Submit"}
  224.             </button>
  225.           </form>
  226.           <button onClick={() => {setAdmin(!admin)}} className="text-blue-400 mt-2 cursor-pointer">
  227.             {admin ? "Create an Individual Account" : "Create an Admin Account"}
  228.           </button>
  229.           <p className="text-center text-gray-400 mt-6">Already have an account? <Link to='/login' className="text-red-300 hover:underline">Login</Link></p>
  230.         </div>
  231.       </div>
  232.     </div>
  233.   );
  234. }
  235.  
Advertisement
Add Comment
Please, Sign In to add comment