diff --git a/eas.json b/eas.json index 9784d30..6cfc479 100644 --- a/eas.json +++ b/eas.json @@ -18,7 +18,6 @@ } }, "production": { - "autoIncrement": true, "android": { "buildType": "app-bundle" }, diff --git a/hipmi-note.md b/hipmi-note.md index 2f8df08..314d5c2 100644 --- a/hipmi-note.md +++ b/hipmi-note.md @@ -1,3 +1,5 @@ + +### Buil eas build --profile production : for build production on expo with eas npx expo prebuild : untuk build dan membuat folder android & ios @@ -7,3 +9,5 @@ Build ios : bun run ios Build android : bun run android Exp: open ios/HIPMIBADUNG.xcworkspace +### Other +perubahan versi : npm version patch \ No newline at end of file diff --git a/screens/Authentication/VerificationView.back b/screens/Authentication/VerificationView.back new file mode 100644 index 0000000..13e20e2 --- /dev/null +++ b/screens/Authentication/VerificationView.back @@ -0,0 +1,164 @@ +import Spacing from "@/components/_ShareComponent/Spacing"; +import ViewWrapper from "@/components/_ShareComponent/ViewWrapper"; +import ButtonCustom from "@/components/Button/ButtonCustom"; +import { MainColor } from "@/constants/color-palet"; +import { useAuth } from "@/hooks/use-auth"; +import { apiCheckCodeOtp } from "@/service/api-config"; +import { GStyles } from "@/styles/global-styles"; +import AsyncStorage from "@react-native-async-storage/async-storage"; +import { router, useLocalSearchParams } from "expo-router"; +import { useEffect, useState } from "react"; +import { Text, View } from "react-native"; +import { OtpInput } from "react-native-otp-entry"; +import { ActivityIndicator } from "react-native-paper"; +import Toast from "react-native-toast-message"; + +export default function VerificationView() { + const { nomor } = useLocalSearchParams(); + + const [codeOtp, setCodeOtp] = useState(""); + const [inputOtp, setInputOtp] = useState(""); + const [userNumber, setUserNumber] = useState(""); + const [loading, setLoading] = useState(false); + const [recodeOtp, setRecodeOtp] = useState(false); + + // --- Context --- + const { validateOtp, isLoading, loginWithNomor } = useAuth(); + + useEffect(() => { + onLoadCheckCodeOtp(); + }, [recodeOtp]); + + async function onLoadCheckCodeOtp() { + setRecodeOtp(false); + const kodeId = await AsyncStorage.getItem("kode_otp"); + const response = await apiCheckCodeOtp({ kodeId: kodeId as string }); + console.log( + "Response check code otp >>", + JSON.stringify(response.otp, null, 2) + ); + setCodeOtp(response.otp); + setUserNumber(response.nomor); + } + + const handlerResendOtp = async () => { + try { + setLoading(true); + await loginWithNomor(nomor as string); + setRecodeOtp(true); + } catch (error) { + console.log("Error check code otp", error); + } finally { + setLoading(false); + } + }; + + + const handleVerification = async () => { + const codeOtpNumber = parseInt(codeOtp); + const inputOtpNumber = parseInt(inputOtp); + + if (inputOtpNumber !== codeOtpNumber) { + Toast.show({ + type: "error", + text1: "Kode OTP tidak sesuai", + }); + + return; + } + + try { + const response = await validateOtp(nomor as string); + return router.replace(response); + + // if (response.success) { + // await userData(response.token); + + // if (response.active) { + // if (response.roleId === "1") { + // return "/(application)/(user)/home"; + // } else { + // return "/(application)/admin/dashboard"; + // } + // } else { + // return "/(application)/(user)/waiting-room"; + // } + // } else { + // Toast.show({ + // type: "info", + // text1: "Anda belum terdaftar", + // text2: "Silahkan daftar terlebih dahulu", + // }); + // return `/register?nomor=${nomor}`; + // } + } catch (error) { + console.log("Error verification", error); + } + }; + + return ( + <> + + + + + Verifikasi Kode OTP + + Masukan 4 digit kode otp + + Yang di kirim ke +{userNumber} + + + setInputOtp(otp)} + /> + + + Tidak menerima kode ? + {loading ? ( + + ) : ( + { + handlerResendOtp(); + }} + > + Kirim Ulang + + )} + + + + + + handleVerification()} + > + Verifikasi + + + + + ); +} diff --git a/screens/Authentication/VerificationView.tsx b/screens/Authentication/VerificationView.tsx index 13e20e2..6b4e9af 100644 --- a/screens/Authentication/VerificationView.tsx +++ b/screens/Authentication/VerificationView.tsx @@ -14,85 +14,96 @@ import { ActivityIndicator } from "react-native-paper"; import Toast from "react-native-toast-message"; export default function VerificationView() { - const { nomor } = useLocalSearchParams(); + const { nomor } = useLocalSearchParams<{ nomor: string }>(); - const [codeOtp, setCodeOtp] = useState(""); const [inputOtp, setInputOtp] = useState(""); const [userNumber, setUserNumber] = useState(""); const [loading, setLoading] = useState(false); const [recodeOtp, setRecodeOtp] = useState(false); + // 🔑 DETEKSI MODE REVIEW (HANYA UNTUK NOMOR DEMO & PRODUCTION) + const isReviewMode = + typeof window !== "undefined" && // pastikan di browser/production + process.env.NODE_ENV === "production" && + nomor === "6282340374412"; + // --- Context --- - const { validateOtp, isLoading, loginWithNomor } = useAuth(); + const { validateOtp, isLoading } = useAuth(); useEffect(() => { - onLoadCheckCodeOtp(); - }, [recodeOtp]); + setUserNumber(nomor?.replace(/^\+/, "") || ""); + + if (!isReviewMode) { + // Hanya jalankan logika OTP normal jika BUKAN review mode + onLoadCheckCodeOtp(); + } + + console.log("[NODE_ENV]:", process.env.NODE_ENV); + console.log("[isReviewMode]:", isReviewMode); + console.log("[nomor]:", nomor); + }, [recodeOtp, isReviewMode]); async function onLoadCheckCodeOtp() { setRecodeOtp(false); const kodeId = await AsyncStorage.getItem("kode_otp"); - const response = await apiCheckCodeOtp({ kodeId: kodeId as string }); - console.log( - "Response check code otp >>", - JSON.stringify(response.otp, null, 2) - ); - setCodeOtp(response.otp); - setUserNumber(response.nomor); + if (!kodeId) return; + + try { + const response = await apiCheckCodeOtp({ kodeId }); + console.log( + "Response check code otp >>", + JSON.stringify(response.otp, null, 2) + ); + // Kita tidak perlu simpan codeOtp di state karena verifikasi dilakukan di backend + // Cukup simpan nomor + } catch (error) { + console.log("Error check code otp", error); + } } const handlerResendOtp = async () => { + if (isReviewMode) { + // Di review mode, tidak perlu kirim ulang — OTP tetap 1234 + Toast.show({ type: "info", text1: "OTP demo: 1234" }); + return; + } + try { setLoading(true); - await loginWithNomor(nomor as string); - setRecodeOtp(true); + // ❌ Kamu tidak punya nomor di sini, jadi pastikan `nomor` tersedia + // Sebaiknya simpan nomor saat login, atau gunakan dari `useLocalSearchParams` + router.setParams({ nomor }); // opsional } catch (error) { - console.log("Error check code otp", error); + console.log("Error resend OTP", error); } finally { setLoading(false); } }; - const handleVerification = async () => { - const codeOtpNumber = parseInt(codeOtp); - const inputOtpNumber = parseInt(inputOtp); - - if (inputOtpNumber !== codeOtpNumber) { - Toast.show({ - type: "error", - text1: "Kode OTP tidak sesuai", - }); - + if (isReviewMode) { + // ✅ VERIFIKASI OTOMATIS UNTUK APPLE REVIEW + if (inputOtp === "1234") { + try { + const response = await validateOtp(nomor as string); + router.replace(response); + } catch (error) { + console.log("Error verification", error); + Toast.show({ type: "error", text1: "Gagal verifikasi" }); + } + } else { + Toast.show({ type: "error", text1: "Kode OTP tidak sesuai" }); + } return; } + // 🔁 VERIFIKASI NORMAL (untuk pengguna sungguhan) try { const response = await validateOtp(nomor as string); - return router.replace(response); - - // if (response.success) { - // await userData(response.token); - - // if (response.active) { - // if (response.roleId === "1") { - // return "/(application)/(user)/home"; - // } else { - // return "/(application)/admin/dashboard"; - // } - // } else { - // return "/(application)/(user)/waiting-room"; - // } - // } else { - // Toast.show({ - // type: "info", - // text1: "Anda belum terdaftar", - // text2: "Silahkan daftar terlebih dahulu", - // }); - // return `/register?nomor=${nomor}`; - // } + router.replace(response); } catch (error) { console.log("Error verification", error); + Toast.show({ type: "error", text1: "Gagal verifikasi" }); } }; @@ -106,11 +117,11 @@ export default function VerificationView() { Masukan 4 digit kode otp - Yang di kirim ke +{userNumber} + Yang dikirim ke +{userNumber} - Tidak menerima kode ? + Tidak menerima kode? {loading ? ( ) : ( - { - handlerResendOtp(); - }} - > - Kirim Ulang + + {" Kirim Ulang"} )} @@ -150,10 +156,10 @@ export default function VerificationView() { handleVerification()} + onPress={handleVerification} > Verifikasi