diff --git a/components/form/sign-up.tsx b/components/form/sign-up.tsx index 0278551..7656475 100644 --- a/components/form/sign-up.tsx +++ b/components/form/sign-up.tsx @@ -2,152 +2,103 @@ import React, { useState } from "react"; import Link from "next/link"; import Cookies from "js-cookie"; +// import { close, error, loading } from "@/config/swal"; import { useRouter } from "next/navigation"; + import withReactContent from "sweetalert2-react-content"; -import Swal from "sweetalert2"; import { Input } from "../ui/input"; import { Button } from "../ui/button"; import { Label } from "../ui/label"; + +// import { saveActivity } from "@/service/activity-log"; + +import Swal from "sweetalert2"; +import { error } from "console"; +import { EyeFilledIcon, EyeSlashFilledIcon } from "../icons"; import { RadioGroup, RadioGroupItem } from "../ui/radio-group"; -import { requestOTP, createUser } from "@/service/auth"; +import { registerTenant } from "@/service/auth"; export default function SignUp() { const router = useRouter(); + const [isVisible, setIsVisible] = useState(false); + const [isVisibleSetup, setIsVisibleSetup] = useState([false, false]); + const [oldEmail, setOldEmail] = useState(""); + const [newEmail, setNewEmail] = useState(""); + const [passwordSetup, setPasswordSetup] = useState(""); + const [confPasswordSetup, setConfPasswordSetup] = useState(""); + + const toggleVisibility = () => setIsVisible(!isVisible); + const [needOtp, setNeedOtp] = useState(false); + const [isFirstLogin, setFirstLogin] = useState(false); + const [otpValue, setOtpValue] = useState(""); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const [accessData, setAccessData] = useState(); + const [profile, setProfile] = useState(); + const [isValidEmail, setIsValidEmail] = useState(false); + const [isResetPassword, setIsResetPassword] = useState(false); + const [checkUsernameValue, setCheckUsernameValue] = useState(""); const MySwal = withReactContent(Swal); - const [step, setStep] = useState<"login" | "otp" | "form">("login"); - const [role, setRole] = useState("umum"); + + const setValUsername = (e: any) => { + const uname = e.replaceAll(/[^\w.-]/g, ""); + setUsername(uname.toLowerCase()); + }; + + const onSubmit = () => { + // Simpan userId dummy ke cookie + Cookies.set("userId", "3"); + + // (Opsional) Simpan juga data lainnya jika dibutuhkan + // Cookies.set("username", username); + + // Redirect ke halaman dashboard atau homepage + router.push("/"); // Ganti dengan path sesuai kebutuhan + }; + + const [step, setStep] = useState<"login" | "otp">("login"); const [email, setEmail] = useState(""); + const [role, setRole] = useState("umum"); const [otp, setOtp] = useState(["", "", "", "", "", ""]); - const [membershipType, setMembershipType] = useState(""); + const [membership, setMembership] = useState(""); const [certNumber, setCertNumber] = useState(""); - const [namaTenant, setNamaTenant] = useState(""); - const [namaPerusahaan, setNamaPerusahaan] = useState(""); + const [membershipType, setMembershipType] = useState(""); + const [nrp, setNrp] = useState(""); const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); - const [fullname, setFullname] = useState(""); - const [username, setUsername] = useState(""); - const [phoneNumber, setPhoneNumber] = useState(""); - const [address, setAddress] = useState(""); - const [dateOfBirth, setDateOfBirth] = useState(""); - const [genderType, setGenderType] = useState("male"); - const [password, setPassword] = useState(""); - const [workType, setWorkType] = useState(""); + const [whatsapp, setWhatsapp] = useState(""); + const [namaTenant, setNamaTenant] = useState(""); + const [tenantPassword, setTenantPassword] = useState(""); + const [confirmTenantPassword, setConfirmTenantPassword] = useState(""); + const [firstNameKontributor, setFirstNameKontributor] = useState(""); + const [lastNameKontributor, setLastNameKontributor] = useState(""); + const [whatsappKontributor, setWhatsappKontributor] = useState(""); + const [namaPerusahaan, setNamaPerusahaan] = useState(""); + const [kategoriPerusahaan, setKategoriPerusahaan] = useState(""); + const [kontributorPassword, setKontributorPassword] = useState(""); + const [confirmKontributorPassword, setConfirmKontributorPassword] = + useState(""); + const [isLoading, setIsLoading] = useState(false); + const [formErrors, setFormErrors] = useState({}); - const handleSendOtp = async (e: React.FormEvent) => { + const handleSendOtp = (e: React.FormEvent) => { e.preventDefault(); - if (!email) { - if (!email) { - MySwal.fire({ - icon: "error", - title: "Error", - text: "Email wajib diisi", - }); - return; - } + // If role is tenant, handle tenant registration directly + if (role === "tenant") { + handleTenantRegistration(e); return; } - let name = ""; - if (role === "tenant") name = namaTenant || `${firstName} ${lastName}`; - else if (role === "kontributor") - name = namaPerusahaan || `${firstName} ${lastName}`; - else if (role === "jurnalis") name = certNumber || "Jurnalis"; - else name = fullname || email; - - try { - const res = await requestOTP({ email, name }); - - if (!res?.error) { - MySwal.fire({ - icon: "success", - title: "Sukses", - text: "OTP berhasil dikirim ke email anda", - }); - setStep("otp"); - } else { - MySwal.fire({ - icon: "error", - title: "Gagal", - text: res.message || "Gagal mengirim OTP", - }); - } - } catch (err) { - console.error("Error send otp:", err); - MySwal.fire({ - icon: "error", - title: "Terjadi kesalahan server", - text: "Gagal mengirim OTP", - }); - } + // For other roles, proceed with OTP flow + setStep("otp"); }; - const handleVerifyOtp = async (e: React.FormEvent) => { + const handleVerifyOtp = (e: React.FormEvent) => { e.preventDefault(); const code = otp.join(""); - if (code.length !== 6) { - MySwal.fire({ - icon: "error", - title: "OTP harus 6 digit", - text: "error", - }); - return; - } - MySwal.fire({ - icon: "success", - title: "Sukses", - text: "OTP diverifikasi!", - }); - setStep("form"); - }; - - const handleRegister = async (e: React.FormEvent) => { - e.preventDefault(); - - const payload = { - address, - clientId: "78356d32-52fa-4dfc-b836-6cebf4e3eead", - dateOfBirth, - email, - fullName: fullname, - genderType, - identityGroup: "", - identityGroupNumber: "", - identityNumber: "", - identityType: "", - lastEducation: "", - password, - phoneNumber, - userLevelId: 1, - userRoleId: 1, - username, - workType, - }; - - try { - const res = await createUser(payload); - if (!res?.error) { - MySwal.fire({ - icon: "success", - title: "Sukses", - text: "Akun berhasil dibuat!", - }); - router.push("/auth"); - } else { - MySwal.fire({ - icon: "error", - title: "Gagal", - text: res.message || "Gagal membuat akun", - }); - } - } catch (err) { - console.error("Register error:", err); - MySwal.fire({ - icon: "error", - title: "Gagal", - text: "Terjadi kesalahan server", - }); - } + // Verifikasi kode OTP + console.log("Kode OTP:", code); }; const handleOtpChange = (index: number, value: string) => { @@ -155,215 +106,597 @@ export default function SignUp() { const newOtp = [...otp]; newOtp[index] = value; setOtp(newOtp); + // Fokus otomatis ke input selanjutnya const nextInput = document.getElementById(`otp-${index + 1}`); if (value && nextInput) nextInput.focus(); }; + // Form validation functions + const validateEmail = (email: string) => { + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return emailRegex.test(email); + }; + + const validatePhone = (phone: string) => { + const phoneRegex = /^[0-9+\-\s()]+$/; + return phoneRegex.test(phone) && phone.length >= 10; + }; + + const validatePassword = (password: string) => { + return password.length >= 8; + }; + + const validateTenantForm = () => { + const errors: any = {}; + + if (!firstName.trim()) { + errors.firstName = "First name is required"; + } + + if (!lastName.trim()) { + errors.lastName = "Last name is required"; + } + + if (!email.trim()) { + errors.email = "Email is required"; + } else if (!validateEmail(email)) { + errors.email = "Please enter a valid email address"; + } + + if (!whatsapp.trim()) { + errors.whatsapp = "WhatsApp number is required"; + } else if (!validatePhone(whatsapp)) { + errors.whatsapp = "Please enter a valid phone number"; + } + + if (!namaTenant.trim()) { + errors.namaTenant = "Tenant name is required"; + } + + if (!tenantPassword) { + errors.tenantPassword = "Password is required"; + } else if (!validatePassword(tenantPassword)) { + errors.tenantPassword = "Password must be at least 8 characters"; + } + + if (!confirmTenantPassword) { + errors.confirmTenantPassword = "Please confirm your password"; + } else if (tenantPassword !== confirmTenantPassword) { + errors.confirmTenantPassword = "Passwords do not match"; + } + + setFormErrors(errors); + return Object.keys(errors).length === 0; + }; + + const handleTenantRegistration = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!validateTenantForm()) { + return; + } + + setIsLoading(true); + setFormErrors({}); + + try { + const registrationData = { + adminUser: { + address: "Jakarta", // Default address as per API requirement + email: email, + fullname: `${firstName} ${lastName}`, + password: tenantPassword, + phoneNumber: whatsapp, + username: `${firstName}-${lastName}`, // Using firstName + lastName as username + }, + client: { + clientType: "sub_client", // Hardcoded as per API requirement + name: namaTenant, + parentClientId: "78356d32-52fa-4dfc-b836-6cebf4e3eead", // Hardcoded as per API requirement + }, + }; + + const response = await registerTenant(registrationData); + + if (response.error) { + MySwal.fire({ + title: "Registration Failed", + text: response.message || "An error occurred during registration", + icon: "error", + confirmButtonText: "OK", + }); + } else { + MySwal.fire({ + title: "Registration Successful", + text: "Your tenant account has been created successfully!", + icon: "success", + confirmButtonText: "OK", + }).then(() => { + // Redirect to login page or dashboard + router.push("/auth"); + }); + } + } catch (error) { + console.error("Registration error:", error); + MySwal.fire({ + title: "Registration Failed", + text: "An unexpected error occurred. Please try again.", + icon: "error", + confirmButtonText: "OK", + }); + } finally { + setIsLoading(false); + } + }; + return (
- {/* Left Side */} -
-
- - Logo - -

Portal NetIdhub

+ {/* Left Side - Logo Section */} +
+
+
+
+ +
+ Mikul News Logo +
+ +
+

Portal NetIdhub

+

Platform beyond classic

+
+
+ {/* Decorative elements */} +
+
- {/* Right Side */} + {/* Right Side - Login Form */}
- {/* Step 1: Pilih Role + Email */} - {step === "login" && ( -
- setRole(val)} - > -
- - -
-
- - -
-
- - -
-
- - -
-
- - {role === "jurnalis" && ( - <> - - setCertNumber(e.target.value)} - /> - - )} - - {role === "tenant" && ( - <> - setNamaTenant(e.target.value)} - /> - setFirstName(e.target.value)} - /> - setLastName(e.target.value)} - /> - - )} - - {role === "kontributor" && ( - <> - setNamaPerusahaan(e.target.value)} - /> - setFirstName(e.target.value)} - /> - setLastName(e.target.value)} - /> - - )} - - setFullname(e.target.value)} - /> - setEmail(e.target.value)} - /> - - -
- )} - - {/* Step 2: OTP */} - {step === "otp" && ( -
-

Masukkan OTP

-
- {otp.map((value, index) => ( - handleOtpChange(index, e.target.value)} - className="w-10 h-12 text-center border rounded-md" - /> - ))} +
+
+
+ netidhub Logo
- - - )} - - {/* Step 3: Form Lengkap */} - {step === "form" && ( -
- setUsername(e.target.value)} - /> - setPhoneNumber(e.target.value)} - /> - setAddress(e.target.value)} - /> - setDateOfBirth(e.target.value)} - /> - - setPassword(e.target.value)} - /> - setWorkType(e.target.value)} - /> - -
- )} + {/* Radio Buttons */} + setRole(val)} + > +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + {/* Jurnalis: Select Keanggotaan */} + {role === "jurnalis" && ( +
+ + + {/* Nomor Sertifikasi */} + setCertNumber(e.target.value)} + /> +
+ )} + + {/* Kontributor: Form Fields */} + {role === "kontributor" && ( +
+
+ + setFirstNameKontributor(e.target.value) + } + /> + setLastNameKontributor(e.target.value)} + /> +
+ + setEmail(e.target.value)} + /> + + setWhatsappKontributor(e.target.value)} + /> + + setNamaPerusahaan(e.target.value)} + /> + + + +
+ setKontributorPassword(e.target.value)} + className="pr-10" + /> + +
+ +
+ + setConfirmKontributorPassword(e.target.value) + } + className="pr-10" + /> + +
+
+ )} + + {/* Tenant: Form Fields */} + {role === "tenant" && ( +
+
+
+ setFirstName(e.target.value)} + className={ + formErrors.firstName ? "border-red-500" : "" + } + /> + {formErrors.firstName && ( +

+ {formErrors.firstName} +

+ )} +
+
+ setLastName(e.target.value)} + className={ + formErrors.lastName ? "border-red-500" : "" + } + /> + {formErrors.lastName && ( +

+ {formErrors.lastName} +

+ )} +
+
+ +
+ setEmail(e.target.value)} + className={formErrors.email ? "border-red-500" : ""} + /> + {formErrors.email && ( +

+ {formErrors.email} +

+ )} +
+ +
+ setWhatsapp(e.target.value)} + className={formErrors.whatsapp ? "border-red-500" : ""} + /> + {formErrors.whatsapp && ( +

+ {formErrors.whatsapp} +

+ )} +
+ +
+ setNamaTenant(e.target.value)} + className={ + formErrors.namaTenant ? "border-red-500" : "" + } + /> + {formErrors.namaTenant && ( +

+ {formErrors.namaTenant} +

+ )} +
+ +
+ setTenantPassword(e.target.value)} + className={`pr-10 ${ + formErrors.tenantPassword ? "border-red-500" : "" + }`} + /> + + {formErrors.tenantPassword && ( +

+ {formErrors.tenantPassword} +

+ )} +
+ +
+ + setConfirmTenantPassword(e.target.value) + } + className={`pr-10 ${ + formErrors.confirmTenantPassword + ? "border-red-500" + : "" + }`} + /> + + {formErrors.confirmTenantPassword && ( +

+ {formErrors.confirmTenantPassword} +

+ )} +
+
+ )} + + {/* Email Field (Selalu Ada, tapi posisi bergantung role) */} + {role !== "tenant" && role !== "kontributor" && ( + setEmail(e.target.value)} + /> + )} + + {/* Note */} +

+ Dengan mendaftar, saya telah menyetujui{" "} + + Syarat dan Ketentuan + {" "} + serta{" "} + + Kebijakan Privasi + +

+ + {/* Submit */} + + + {/* Link Login */} +

+ Sudah punya akun?{" "} + + Login + +

+ + ) : ( +
+

+ Masukkan Kode OTP +

+

+ Silahkan cek inbox atau kotak spam pada email Anda. +

+ +
+ {otp.map((value, index) => ( + handleOtpChange(index, e.target.value)} + className="w-10 h-12 text-center border border-gray-300 rounded-md text-lg focus:outline-none focus:ring-2 focus:ring-[#B89445]" + /> + ))} +
+ + + +

+ Kirim Ulang OTP +

+
+ )} +
diff --git a/service/auth.ts b/service/auth.ts index e6e15e7..bfe84e7 100644 --- a/service/auth.ts +++ b/service/auth.ts @@ -214,3 +214,4 @@ export async function registerTenant(data: any) { const url = "clients/with-user"; return httpPost(url, data); } +