diff --git a/components/form/content/image/image-detail-form.tsx b/components/form/content/image/image-detail-form.tsx index 9837565..59d83dd 100644 --- a/components/form/content/image/image-detail-form.tsx +++ b/components/form/content/image/image-detail-form.tsx @@ -174,7 +174,7 @@ export default function FormImageDetail() { console.log("LALALALA", userLevelName); const [modalOpen, setModalOpen] = useState(false); const { id } = useParams() as { id: string }; - console.log(id); + console.log("IDIDIDIDI", id); const editor = useRef(null); type ImageSchema = z.infer; const [selectedFiles, setSelectedFiles] = useState([]); @@ -676,7 +676,7 @@ export default function FormImageDetail() { {`Image diff --git a/components/form/sign-up.tsx b/components/form/sign-up.tsx index e4544ed..32d7c55 100644 --- a/components/form/sign-up.tsx +++ b/components/form/sign-up.tsx @@ -2,92 +2,110 @@ 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 services +import { requestOTP, createUser } 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 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 [step, setStep] = useState<"login" | "otp" | "form">("login"); const [role, setRole] = useState("umum"); + const [email, setEmail] = useState(""); const [otp, setOtp] = useState(["", "", "", "", "", ""]); - const [membership, setMembership] = useState(""); - const [certNumber, setCertNumber] = useState(""); - const [membershipType, setMembershipType] = useState(""); - const [nrp, setNrp] = useState(""); - const [firstName, setFirstName] = useState(""); - const [lastName, setLastName] = 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 handleSendOtp = (e: React.FormEvent) => { + // data user lengkap + 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(""); + + // 🔹 Handle OTP Request + const handleSendOtp = async (e: React.FormEvent) => { e.preventDefault(); - // Kirim OTP ke email - setStep("otp"); + + if (!email) { + MySwal.fire("Error", "Email wajib diisi", "error"); + return; + } + + try { + const res = await requestOTP({ email, name: fullname || email }); + + if (!res?.error) { + MySwal.fire("Sukses", "OTP berhasil dikirim ke email anda", "success"); + setStep("otp"); + } else { + MySwal.fire("Gagal", res.message || "Gagal mengirim OTP", "error"); + } + } catch (err) { + console.error("Error send otp:", err); + MySwal.fire("Error", "Terjadi kesalahan server", "error"); + } }; - const handleVerifyOtp = (e: React.FormEvent) => { + // 🔹 Handle OTP Verification (dummy → lanjut form) + const handleVerifyOtp = async (e: React.FormEvent) => { e.preventDefault(); const code = otp.join(""); - // Verifikasi kode OTP - console.log("Kode OTP:", code); + if (code.length !== 6) { + MySwal.fire("Error", "OTP harus 6 digit", "error"); + return; + } + // TODO: ganti dengan verifyOTP API + MySwal.fire("Sukses", "OTP diverifikasi!", "success"); + setStep("form"); // lanjut ke form lengkap + }; + + // 🔹 Handle Register ke API /users + const handleRegister = async (e: React.FormEvent) => { + e.preventDefault(); + + const payload = { + address, + clientId: "web-app", // contoh default + dateOfBirth, + email, + fullName: fullname, // 🔥 fix disini (bukan 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("Sukses", "Akun berhasil dibuat!", "success"); + router.push("/login"); + } else { + MySwal.fire("Error", res.message || "Gagal membuat akun", "error"); + } + } catch (err) { + console.error("Register error:", err); + MySwal.fire("Error", "Terjadi kesalahan server", "error"); + } }; const handleOtpChange = (index: number, value: string) => { @@ -95,399 +113,133 @@ 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(); }; return (
- {/* Left Side - Logo Section */} + {/* Left Side Logo */}
-
-
- Mikul News Logo -
+ Logo -
+

Portal NetIdhub

Platform beyond classic

- {/* Decorative elements */} -
-
- {/* Right Side - Login Form */} + {/* Right Side Form */}
-
-
-
- netidhub Logo -
-

- MENYATUKAN INDONESIA -

-
- {step === "login" ? ( -
- {/* Radio Buttons */} - setRole(val)} - > -
- - -
-
- - -
-
- - -
-
- - -
-
+ {/* Step 1: Kirim OTP */} + {step === "login" && ( + + setFullname(e.target.value)} + /> + setEmail(e.target.value)} + /> + +
+ )} - {/* 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)} - /> - setLastName(e.target.value)} - /> -
- - setEmail(e.target.value)} - /> - - setWhatsapp(e.target.value)} - /> - - setNamaTenant(e.target.value)} - /> - -
- setTenantPassword(e.target.value)} - className="pr-10" - /> - -
- -
- setConfirmTenantPassword(e.target.value)} - className="pr-10" - /> - -
-
- )} - - {/* Email Field (Selalu Ada, tapi posisi bergantung role) */} - {role !== "tenant" && role !== "kontributor" && ( - setEmail(e.target.value)} + {/* Step 2: Verifikasi OTP */} + {step === "otp" && ( +
+

Masukkan OTP

+
+ {otp.map((value, index) => ( + handleOtpChange(index, e.target.value)} + className="w-10 h-12 text-center border rounded-md" /> - )} + ))} +
+ +
+ )} - {/* Note */} -

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

- - {/* Submit */} - - - {/* Link Login */} -

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

- - ) : ( -
+ setFullname(e.target.value)} + /> + setUsername(e.target.value)} + /> + setPhoneNumber(e.target.value)} + /> + setAddress(e.target.value)} + /> + setDateOfBirth(e.target.value)} + /> + 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 -

- - )} -
+ + + + setPassword(e.target.value)} + /> + setWorkType(e.target.value)} + /> + + + )}
diff --git a/next.config.mjs b/next.config.mjs index 9b9d832..9ce7634 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -98,6 +98,7 @@ const nextConfig = { { protocol: "https", hostname: "i.pravatar.cc" }, { protocol: "https", hostname: "dev.mikulnews.com" }, { protocol: "https", hostname: "netidhub.com" }, + { protocol: "https", hostname: "kontenhumas.com" }, ], }, }; diff --git a/service/auth.ts b/service/auth.ts index 0492ddf..31bdbf9 100644 --- a/service/auth.ts +++ b/service/auth.ts @@ -7,6 +7,31 @@ import { postAPIWithJson, } from "./http-config/http-interceptor-service"; +export interface CreateUserPayload { + address: string; + clientId: string; + dateOfBirth: string; + email: string; + fullName: string; + genderType: string; + identityGroup: string; + identityGroupNumber: string; + identityNumber: string; + identityType: string; + lastEducation: string; + password: string; + phoneNumber: string; + userLevelId: number; + userRoleId: number; + username: string; + workType: string; +} + +export interface RequestOtpPayload { + email: string; + name: string; +} + export async function login(data: any) { const pathUrl = "signin"; return httpPost(pathUrl, data); @@ -119,10 +144,10 @@ export async function postRegistration(data: any) { return httpPost(url, data); } -export async function requestOTP(data: any) { - const url = "public/users/otp-request"; - return httpPostInterceptor(url, data); -} +// export async function requestOTP(data: any) { +// const url = "public/users/otp-request"; +// return httpPostInterceptor(url, data); +// } export async function verifyOTP(email: any, otp: any) { const url = `public/users/verify-otp?email=${email}&otp=${otp}`; @@ -173,3 +198,13 @@ export async function getDataPersonil(nrp: any) { const url = `public/users/search-personil?nrp=${nrp}`; return httpGetInterceptor(url); } + +export async function createUser(data: CreateUserPayload) { + const url = "users"; + return httpPost(url, data); +} + +export async function requestOTP(data: { email: string; name: string }) { + const url = "users/otp-request"; + return httpPostInterceptor(url, data); +} diff --git a/service/content/content.ts b/service/content/content.ts index 1699654..703ed3d 100644 --- a/service/content/content.ts +++ b/service/content/content.ts @@ -286,7 +286,7 @@ export async function convertSPIT(data: any) { } export async function submitApproval(data: any) { - const url = "media/approval"; + const url = "article-approval-flows/1/multi-branch-approve"; return httpPostInterceptor(url, data); }