diff --git a/app/(application)/(user)/home.tsx b/app/(application)/(user)/home.tsx
index 800890c..95cf893 100644
--- a/app/(application)/(user)/home.tsx
+++ b/app/(application)/(user)/home.tsx
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable react-hooks/exhaustive-deps */
-import { ButtonCustom, StackCustom, ViewWrapper } from "@/components";
+import { StackCustom, ViewWrapper } from "@/components";
import { MainColor } from "@/constants/color-palet";
import { useAuth } from "@/hooks/use-auth";
import { useNotificationStore } from "@/hooks/use-notification-store";
@@ -23,14 +23,12 @@ export default function Application() {
const [refreshing, setRefreshing] = useState(false);
const { syncUnreadCount } = useNotificationStore();
-
-
useFocusEffect(
useCallback(() => {
onLoadData();
checkVersion();
userData(token as string);
- syncUnreadCount()
+ syncUnreadCount();
}, [user?.id, token])
);
@@ -56,10 +54,10 @@ export default function Application() {
setRefreshing(false);
}, []);
- if (user && user?.termsOfServiceAccepted === false) {
- console.log("User is not accept term service");
- return ;
- }
+ // if (user && user?.termsOfServiceAccepted === false) {
+ // console.log("User is not accept term service");
+ // return ;
+ // }
if (data && data?.active === false) {
console.log("User is not active");
diff --git a/app/eula.tsx b/app/eula.tsx
new file mode 100644
index 0000000..953b70e
--- /dev/null
+++ b/app/eula.tsx
@@ -0,0 +1,9 @@
+import EULAView from "@/screens/Authentication/EULAView";
+
+export default function EULA() {
+ return (
+ <>
+
+ >
+ );
+}
diff --git a/context/AuthContext.tsx b/context/AuthContext.tsx
index 5d87fdd..416c5c7 100644
--- a/context/AuthContext.tsx
+++ b/context/AuthContext.tsx
@@ -2,6 +2,7 @@ import {
apiConfig,
apiLogin,
apiRegister,
+ apiUpdatedTermCondition,
apiValidationCode,
} from "@/service/api-config";
import { apiDeviceTokenDeleted } from "@/service/api-device-token";
@@ -29,6 +30,7 @@ type AuthContextType = {
termsOfServiceAccepted: boolean;
}) => Promise;
userData: (token: string) => Promise;
+ acceptedTerms: (nomor: string) => Promise;
};
// --- Create Context ---
@@ -74,28 +76,32 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
const loginWithNomor = async (nomor: string) => {
setIsLoading(true);
try {
- console.log("[Masuk provider]", nomor);
const response = await apiLogin({ nomor: nomor });
- console.log("[RESPONSE AUTH]", JSON.stringify(response));
+ console.log("[RESPONSE AUTH]", JSON.stringify(response, null, 2));
if (response.success) {
- console.log("[Keluar provider]", nomor);
- Toast.show({
- type: "success",
- text1: "Sukses",
- text2: "Kode OTP berhasil dikirim",
- });
+ if (response.isAcceptTerms) {
+ Toast.show({
+ type: "success",
+ text1: "Sukses",
+ text2: "Kode OTP berhasil dikirim",
+ });
- await AsyncStorage.setItem("kode_otp", response.kodeId);
- router.push(`/verification?nomor=${nomor}`);
- return;
+ await AsyncStorage.setItem("kode_otp", response.kodeId);
+ router.push(`/verification?nomor=${nomor}`);
+ return;
+ } else {
+ router.push(`/eula?nomor=${nomor}`);
+ return;
+ }
} else {
- router.push(`/register?nomor=${nomor}`);
- Toast.show({
- type: "info",
- text1: "Info",
- text2: "Silahkan mendaftar",
- });
+ router.push(`/eula?nomor=${nomor}`);
+
+ // Toast.show({
+ // type: "info",
+ // text1: "Info",
+ // text2: "Silahkan mendaftar",
+ // });
return;
}
} catch (error: any) {
@@ -226,7 +232,6 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
setIsLoading(false);
}
};
-
// --- 5. Logout ---
@@ -256,6 +261,31 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
}
};
+ const acceptedTerms = async (nomor: string) => {
+ try {
+ setIsLoading(true);
+ const response = await apiUpdatedTermCondition({ nomor: nomor });
+
+ if (response.success) {
+ router.replace(`/verification?nomor=${nomor}`);
+ } else {
+ if (response.status === 404) {
+ router.replace(`/register?nomor=${nomor}`);
+ } else {
+ Toast.show({
+ type: "error",
+ text1: "Error",
+ text2: response.message,
+ });
+ }
+ }
+ } catch (error) {
+ console.log("Error accept terms", error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
return (
<>
{
logout,
registerUser,
userData,
+ acceptedTerms,
}}
>
{children}
diff --git a/screens/Authentication/EULAView.tsx b/screens/Authentication/EULAView.tsx
new file mode 100644
index 0000000..58b7ebd
--- /dev/null
+++ b/screens/Authentication/EULAView.tsx
@@ -0,0 +1,278 @@
+// app/syarat-dan-ketentuan.tsx
+import {
+ View,
+ Text,
+ ScrollView,
+ TouchableOpacity,
+ StyleSheet,
+} from "react-native";
+import { useState, useRef } from "react";
+import { useLocalSearchParams, useRouter } from "expo-router";
+import { SafeAreaView } from "react-native-safe-area-context";
+import { AccentColor, MainColor } from "@/constants/color-palet";
+import { useAuth } from "@/hooks/use-auth";
+
+// Ganti dengan API call ke backend Anda
+// const acceptEula = async (): Promise => {
+// try {
+// const response = await fetch("/api/user/update-eula", {
+// method: "PATCH",
+// headers: { "Content-Type": "application/json" },
+// credentials: "include",
+// body: JSON.stringify({
+// eulaAcceptedAt: new Date().toISOString(),
+// eulaVersion: "2026-01-v1", // sesuaikan versi Anda
+// }),
+// });
+// return response.ok;
+// } catch (error) {
+// console.error("Gagal menyimpan persetujuan EULA:", error);
+// return false;
+// }
+// };
+
+export default function EULAView() {
+ const { acceptedTerms } = useAuth();
+ const { nomor } = useLocalSearchParams();
+ const [isLoading, setIsLoading] = useState(false);
+ const [isAtBottom, setIsAtBottom] = useState(false);
+ const scrollViewRef = useRef(null);
+
+ const handleScroll = (event: any) => {
+ const { layoutMeasurement, contentOffset, contentSize } = event.nativeEvent;
+ const paddingToBottom = 20;
+ const isCloseToBottom =
+ layoutMeasurement.height + contentOffset.y >=
+ contentSize.height - paddingToBottom;
+ setIsAtBottom(isCloseToBottom);
+ };
+
+ const handleAccept = async () => {
+ try {
+ if (!isAtBottom) return;
+
+ setIsLoading(true);
+ await acceptedTerms(nomor as string);
+ } catch (error) {
+ console.log("Error accept terms", error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return (
+
+
+ Syarat & Ketentuan Penggunaan HIPMI Badung Connect
+
+
+
+
+ Dengan menggunakan aplikasi{" "}
+ HIPMI Badung Connect (“Aplikasi”),
+ Anda setuju untuk mematuhi dan terikat oleh syarat dan ketentuan
+ berikut. Jika Anda tidak setuju dengan ketentuan ini, harap jangan
+ gunakan Aplikasi.
+
+
+ 1. Definisi
+
+ HIPMI Badung Connect adalah platform
+ digital resmi untuk anggota Himpunan Pengusaha Muda Indonesia (HIPMI)
+ Kabupaten Badung, yang bertujuan memfasilitasi jaringan, kolaborasi,
+ dan pertumbuhan bisnis para pengusaha muda.
+
+
+ 2. Larangan Konten Tidak Pantas
+
+ Anda dilarang keras memposting,
+ mengirim, membagikan, atau mengunggah konten apa pun yang mengandung:
+
+
+
+ • Ujaran kebencian, diskriminasi, atau konten SARA (Suku, Agama,
+ Ras, Antar-golongan)
+
+
+ • Pornografi, konten seksual eksplisit, atau gambar tidak senonoh
+
+
+ • Ancaman, pelecehan, bullying, atau perilaku melecehkan
+
+
+ • Informasi palsu, hoaks, spam, atau konten menyesatkan
+
+
+ • Konten ilegal, melanggar hukum, atau melanggar hak kekayaan
+ intelektual pihak lain
+
+
+ • Promosi narkoba, perjudian, atau aktivitas ilegal lainnya
+
+
+
+ 3. Tanggung Jawab Pengguna
+
+ Anda bertanggung jawab penuh atas setiap konten yang Anda unggah atau
+ bagikan melalui fitur-fitur berikut:
+
+
+ • Profil (bio, foto, portofolio)
+ • Forum diskusi
+ • Chat pribadi atau grup
+
+ • Lowongan kerja, investasi, dan donasi
+
+
+
+ Konten yang melanggar ketentuan ini dapat dihapus kapan saja tanpa
+ pemberitahuan.
+
+
+ 4. Tindakan terhadap Pelanggaran
+
+ Jika kami menerima laporan atau menemukan konten yang melanggar
+ ketentuan ini, kami akan:
+
+
+
+ • Segera menghapus konten tersebut
+
+
+ • Memberikan peringatan atau memblokir akun pengguna
+
+
+ • Dalam kasus berat, melaporkan ke pihak berwajib sesuai hukum yang
+ berlaku
+
+
+
+ Tim kami berkomitmen untuk menanggapi laporan konten tidak pantas{" "}
+ dalam waktu 24 jam.
+
+
+ 5. Mekanisme Pelaporan
+
+ Anda dapat melaporkan konten atau pengguna yang mencurigakan melalui:
+
+
+
+ • Tombol “Laporkan” di setiap
+ posting forum atau pesan chat
+
+
+ • Tombol “Blokir Pengguna” di
+ profil pengguna
+
+
+
+ Setiap laporan akan ditangani secara rahasia dan segera.
+
+
+ 6. Perubahan Ketentuan
+
+ Kami berhak memperbarui Syarat & Ketentuan ini sewaktu-waktu. Versi
+ terbaru akan dipublikasikan di halaman ini dengan tanggal revisi yang
+ diperbarui.
+
+
+ 7. Kontak
+
+ Jika Anda memiliki pertanyaan tentang ketentuan ini, silakan hubungi
+ kami di:{"\n"}
+
+ bip.baliinteraktifperkasa@gmail.com
+
+
+
+
+ © 2026 Bali Interaktif Perkasa. All rights reserved.
+
+
+
+
+
+ {isLoading ? "Menyimpan..." : "Saya Setuju"}
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: MainColor.darkblue,
+ padding: 16,
+ },
+ title: {
+ fontSize: 20,
+ fontWeight: "bold",
+ textAlign: "center",
+ marginBottom: 16,
+ color: MainColor.white,
+ },
+ scrollView: {
+ flex: 1,
+ marginBottom: 20,
+ },
+ scrollContent: {
+ paddingBottom: 30,
+ },
+ heading: {
+ fontSize: 16,
+ fontWeight: "600",
+ marginTop: 16,
+ marginBottom: 8,
+ color: MainColor.white,
+ },
+ paragraph: {
+ fontSize: 14,
+ lineHeight: 22,
+ color: MainColor.white,
+ marginBottom: 12,
+ },
+ bold: {
+ fontWeight: "600",
+ },
+ list: {
+ marginLeft: 8,
+ marginBottom: 12,
+ },
+ listItem: {
+ fontSize: 14,
+ lineHeight: 22,
+ color: MainColor.white,
+ marginBottom: 6,
+ },
+ footer: {
+ fontSize: 12,
+ color: MainColor.white,
+ textAlign: "center",
+ marginTop: 20,
+ paddingTop: 10,
+ borderTopWidth: 2,
+ borderTopColor: AccentColor.blue,
+ },
+ button: {
+ backgroundColor: MainColor.yellow,
+ paddingVertical: 14,
+ borderRadius: 8,
+ alignItems: "center",
+ },
+ buttonText: {
+ color: "#fff",
+ fontSize: 16,
+ fontWeight: "600",
+ },
+});
diff --git a/screens/Authentication/RegisterView.tsx b/screens/Authentication/RegisterView.tsx
index 214a63b..bc9fbe7 100644
--- a/screens/Authentication/RegisterView.tsx
+++ b/screens/Authentication/RegisterView.tsx
@@ -1,4 +1,3 @@
-import { CheckboxCustom } from "@/components";
import Spacing from "@/components/_ShareComponent/Spacing";
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
import ButtonCustom from "@/components/Button/ButtonCustom";
@@ -7,7 +6,6 @@ import { MainColor } from "@/constants/color-palet";
import { useAuth } from "@/hooks/use-auth";
import { BASE_URL } from "@/service/api-config";
import { GStyles } from "@/styles/global-styles";
-import { openBrowser } from "@/utils/openBrower";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { useLocalSearchParams } from "expo-router";
import { useState } from "react";
@@ -17,7 +15,7 @@ import Toast from "react-native-toast-message";
export default function RegisterView() {
const { nomor } = useLocalSearchParams();
const [username, setUsername] = useState("");
- const [term, setTerm] = useState(false);
+ // const [term, setTerm] = useState(false);
const url = BASE_URL;
const { registerUser, isLoading } = useAuth();
@@ -65,7 +63,7 @@ export default function RegisterView() {
await registerUser({
nomor: nomor as string,
username: usernameLower,
- termsOfServiceAccepted: term,
+ termsOfServiceAccepted: true,
});
}
@@ -106,12 +104,12 @@ export default function RegisterView() {
flexDirection: "row",
alignItems: "center",
marginTop: 16,
- marginBottom: 16,
+ // marginBottom: 16,
}}
>
- setTerm(!term)} />
+ {/* setTerm(!term)} /> */}
-
+ {/*
Saya setuju dengan{" "}
{" "}
yang melarang konten tidak pantas dan perilaku merugikan.
-
+ */}
diff --git a/screens/RootLayout/AppRoot.tsx b/screens/RootLayout/AppRoot.tsx
index e513fbf..203d43c 100644
--- a/screens/RootLayout/AppRoot.tsx
+++ b/screens/RootLayout/AppRoot.tsx
@@ -15,6 +15,7 @@ export default function AppRoot() {
name="index"
options={{ title: "", headerBackVisible: false }}
/>
+