diff --git a/app.config.js b/app.config.js index f8aba53..d782fc9 100644 --- a/app.config.js +++ b/app.config.js @@ -79,6 +79,12 @@ export default { URL_FIREBASE_DB: process.env.URL_FIREBASE_DB, PASS_ENC: process.env.PASS_ENC, WA_SERVER_TOKEN: process.env.WA_SERVER_TOKEN, + FIREBASE_API_KEY: process.env.FIREBASE_API_KEY, + FIREBASE_AUTH_DOMAIN: process.env.FIREBASE_AUTH_DOMAIN, + FIREBASE_PROJECT_ID: process.env.FIREBASE_PROJECT_ID, + FIREBASE_STORAGE_BUCKET: process.env.FIREBASE_STORAGE_BUCKET, + FIREBASE_MESSAGING_SENDER_ID: process.env.FIREBASE_MESSAGING_SENDER_ID, + FIREBASE_APP_ID: process.env.FIREBASE_APP_ID, } } }; diff --git a/app/verification.tsx b/app/verification.tsx index d0290d1..98e5769 100644 --- a/app/verification.tsx +++ b/app/verification.tsx @@ -20,10 +20,16 @@ export default function Index() { const { signIn } = useAuthSession(); const login = (): void => { - const random: string = 'contohLoginMobileDarmasaba'; - var mytexttoEncryption = "contohLoginMobileDarmasaba" - const encrypted = CryptoES.AES.encrypt(mytexttoEncryption, ConstEnv.pass_encrypt).toString(); - signIn(encrypted); + // WARNING: This is a hardcoded bypass for development purposes. + // It should be removed or secured before production release. + if (__DEV__) { + const random: string = 'contohLoginMobileDarmasaba'; + var mytexttoEncryption = "contohLoginMobileDarmasaba" + const encrypted = CryptoES.AES.encrypt(mytexttoEncryption, ConstEnv.pass_encrypt).toString(); + signIn(encrypted); + } else { + console.warn("Bypass login disabled in production."); + } } return ( diff --git a/assets/images/cogniti-dark.png b/assets/images/cogniti-dark.png new file mode 100644 index 0000000..60de6fd Binary files /dev/null and b/assets/images/cogniti-dark.png differ diff --git a/assets/images/cogniti-light.png b/assets/images/cogniti-light.png new file mode 100644 index 0000000..b2515cc Binary files /dev/null and b/assets/images/cogniti-light.png differ diff --git a/assets/images/logo-dark.png b/assets/images/logo-dark.png new file mode 100644 index 0000000..7512623 Binary files /dev/null and b/assets/images/logo-dark.png differ diff --git a/components/auth/viewLogin.tsx b/components/auth/viewLogin.tsx index 2b9e4f3..8173817 100644 --- a/components/auth/viewLogin.tsx +++ b/components/auth/viewLogin.tsx @@ -53,11 +53,10 @@ export default function ViewLogin({ onValidate }: Props) { return ( - +62} info="Kami akan mengirim kode verifikasi melalui WhatsApp, guna mengonfirmasikan nomor Anda." /> - { handleCheckPhone() }} - disabled={disableLogin} - /> + + { handleCheckPhone() }} + disabled={disableLogin} + /> + + + + + { loadingLogin && } + ) diff --git a/components/auth/viewVerification.tsx b/components/auth/viewVerification.tsx index fc921a9..0dc96bf 100644 --- a/components/auth/viewVerification.tsx +++ b/components/auth/viewVerification.tsx @@ -5,7 +5,7 @@ import { useTheme } from "@/providers/ThemeProvider"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { StatusBar } from "expo-status-bar"; import { useState } from "react"; -import { Image, Platform, View } from "react-native"; +import { Image, SafeAreaView, View } from "react-native"; import { OtpInput } from "react-native-otp-entry"; import Toast from 'react-native-toast-message'; import { ButtonForm } from "../buttonForm"; @@ -58,13 +58,12 @@ export default function ViewVerification({ phone, otp }: Props) { } return ( - <> + - - + - { onCheckOtp() }} - /> - - Tidak Menerima kode verifikasi? { resendOtp() }}>Kirim Ulang + + { onCheckOtp() }} + /> + + + Tidak Menerima kode verifikasi? { resendOtp() }} style={[{ color: colors.tint }]}>Kirim Ulang + + + + - + + ) } \ No newline at end of file diff --git a/components/buttonForm.tsx b/components/buttonForm.tsx index 551f60f..9ee7a1d 100644 --- a/components/buttonForm.tsx +++ b/components/buttonForm.tsx @@ -1,5 +1,5 @@ -import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { TouchableOpacity } from "react-native"; import Text from './Text'; @@ -10,8 +10,9 @@ type Props = { }; export function ButtonForm({ text, onPress, disabled }: Props) { + const { colors } = useTheme(); return ( - + {text} ); diff --git a/components/inputForm.tsx b/components/inputForm.tsx index ff17cdf..c12509b 100644 --- a/components/inputForm.tsx +++ b/components/inputForm.tsx @@ -74,7 +74,7 @@ export function InputForm({ label, value, placeholder, onChange, info, disable, /> {error && ({errorText})} - {info != undefined && ({info})} + {info != undefined && ({info})} ) } diff --git a/components/toastCustom.tsx b/components/toastCustom.tsx index 3004826..6385743 100644 --- a/components/toastCustom.tsx +++ b/components/toastCustom.tsx @@ -7,12 +7,19 @@ import Text from "./Text"; export default function ToastCustom({ position }: { position?: 'top' | 'bottom' }) { const { colors } = useTheme() return ( - Toast.hide()} visibilityTime={1500} position={position || 'bottom'} config={{ - small: ({ text1 }) => ( - - {text1} - - ) - }} /> + Toast.hide()} + visibilityTime={1500} + position={position || 'bottom'} + bottomOffset={80} + config={{ + small: ({ text1 }) => ( + + {text1} + + ) + }} + /> ) } \ No newline at end of file diff --git a/constants/Colors.ts b/constants/Colors.ts index 520ca2b..22215ae 100644 --- a/constants/Colors.ts +++ b/constants/Colors.ts @@ -6,7 +6,7 @@ export const Colors = { text: '#11181C', background: '#f7f7f7ff', tint: tintColorLight, - primary: '#19345E', + primary: '#1F3C88', icon: '#1F3C88', card: '#ffffff', tabIconDefault: '#687076', @@ -24,7 +24,7 @@ export const Colors = { text: '#ECEDEE', background: '#0F1B2D', tint: tintColorDark, - primary: '#19345E', + primary: '#123A6F', icon: '#9DB9E8', card: '#16233A', // slightly lighter than background #151718 tabIconDefault: '#9BA1A6', diff --git a/constants/ConstEnv.ts b/constants/ConstEnv.ts index 923221e..dc45423 100644 --- a/constants/ConstEnv.ts +++ b/constants/ConstEnv.ts @@ -2,5 +2,14 @@ import Constants from 'expo-constants'; export const ConstEnv = { url_storage: Constants?.expoConfig?.extra?.URL_STORAGE, - pass_encrypt: Constants?.expoConfig?.extra?.PASS_ENC + pass_encrypt: Constants?.expoConfig?.extra?.PASS_ENC, + firebase: { + apiKey: Constants?.expoConfig?.extra?.FIREBASE_API_KEY, + authDomain: Constants?.expoConfig?.extra?.FIREBASE_AUTH_DOMAIN, + projectId: Constants?.expoConfig?.extra?.FIREBASE_PROJECT_ID, + storageBucket: Constants?.expoConfig?.extra?.FIREBASE_STORAGE_BUCKET, + messagingSenderId: Constants?.expoConfig?.extra?.FIREBASE_MESSAGING_SENDER_ID, + appId: Constants?.expoConfig?.extra?.FIREBASE_APP_ID, + databaseURL: Constants?.expoConfig?.extra?.URL_FIREBASE_DB, + } } \ No newline at end of file diff --git a/constants/Styles.ts b/constants/Styles.ts index ca10a22..c6bc640 100644 --- a/constants/Styles.ts +++ b/constants/Styles.ts @@ -88,6 +88,9 @@ const Styles = StyleSheet.create({ mb15: { marginBottom: 15 }, + mb20: { + marginBottom: 20 + }, mb30: { marginBottom: 30 }, @@ -130,6 +133,9 @@ const Styles = StyleSheet.create({ mt15: { marginTop: 15 }, + mt30: { + marginTop: 30 + }, mr05: { marginRight: 5 }, @@ -291,9 +297,9 @@ const Styles = StyleSheet.create({ borderWidth: 1, }, btnRound: { - backgroundColor: '#19345E', + backgroundColor: '#1F3C88', borderWidth: 0, - borderColor: '#19345E', + borderColor: '#1F3C88', alignItems: 'center', borderRadius: 30, marginTop: 15, @@ -309,7 +315,7 @@ const Styles = StyleSheet.create({ }, btnLainnya: { alignSelf: 'flex-start', - backgroundColor: '#19345E', + backgroundColor: '#1F3C88', paddingVertical: 5, marginVertical: 5 }, diff --git a/lib/api.ts b/lib/api.ts index b81d90f..9ce5413 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -96,30 +96,18 @@ export const apiGetGroup = async ({ user, active, search }: { user: string, acti }; export const apiCreateGroup = async (data: { user: string, name: string }) => { - await api.post('mobile/group', data).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.post('mobile/group', data); + return response.data; }; export const apiEditGroup = async (data: { user: string, name: string }, id: string) => { - await api.put(`mobile/group/${id}`, data).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.put(`mobile/group/${id}`, data); + return response.data; }; export const apiDeleteGroup = async (data: { user: string, isActive: boolean }, id: string) => { - await api.delete(`mobile/group/${id}`, { data }).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.delete(`mobile/group/${id}`, { data }); + return response.data; }; export const apiGetPosition = async ({ user, active, search, group }: { user: string, active: string, search: string, group?: string }) => { @@ -128,22 +116,14 @@ export const apiGetPosition = async ({ user, active, search, group }: { user: st }; export const apiCreatePosition = async (data: { user: string, name: string, idGroup: string }) => { - await api.post('mobile/position', data).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.post('mobile/position', data); + return response.data; }; export const apiDeletePosition = async (data: { user: string, isActive: boolean }, id: string) => { - await api.delete(`mobile/position/${id}`, { data }).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.delete(`mobile/position/${id}`, { data }); + return response.data; }; export const apiEditPosition = async (data: { user: string, name: string, idGroup: string }, id: string) => { @@ -207,12 +187,8 @@ export const apiUpdateDiscussionGeneralCommentar = async ({ id, data }: { id: st export const apiDeleteMemberDiscussionGeneral = async (data: { user: string, idUser: string }, id: string) => { - await api.delete(`mobile/discussion-general/${id}/member`, { data }).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.delete(`mobile/discussion-general/${id}/member`, { data }); + return response.data; }; @@ -222,19 +198,10 @@ export const apiUpdateStatusDiscussionGeneral = async ({ id, data }: { id: strin }; export const apiDeleteDiscussionGeneral = async (data: { user: string, active: boolean }, id: string) => { - await api.delete(`mobile/discussion-general/${id}`, { data }).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.delete(`mobile/discussion-general/${id}`, { data }); + return response.data; }; -// export const apiEditDiscussionGeneral = async (data: { user: string, title: string, desc: string }, id: string) => { -// const response = await api.put(`/mobile/discussion-general/${id}`, data) -// return response.data; -// }; - export const apiEditDiscussionGeneral = async (data: FormData, id: string) => { const response = await api.put(`/mobile/discussion-general/${id}`, data, { headers: { diff --git a/lib/pushToPage.ts b/lib/pushToPage.ts index e510536..ed23ffc 100644 --- a/lib/pushToPage.ts +++ b/lib/pushToPage.ts @@ -23,6 +23,10 @@ export function pushToPage(category: string, idContent: string) { return router.push(`/member/${idContent}`) } else if (cat[0] == 'project') { return router.push(`/project/${idContent}`) + } else if (cat[0] == 'group') { + return router.push(`/group`) + } else if (cat[0] == 'position') { + return router.push(`/position`) } } } \ No newline at end of file diff --git a/lib/useNotification.ts b/lib/useNotification.ts index b1dd761..4af6e44 100644 --- a/lib/useNotification.ts +++ b/lib/useNotification.ts @@ -8,23 +8,28 @@ import * as Notifications from 'expo-notifications'; import { useEffect } from 'react'; import { PermissionsAndroid, Platform } from 'react-native'; -// Firebase config +import { ConstEnv } from '@/constants/ConstEnv'; + const RNfirebaseConfig = { - apiKey: "AIzaSyB2hbsW91J3oRQx4_jgrCCNY0tNt5-21e8", - authDomain: "googleapis.com", - projectId: "mobile-darmasaba", - storageBucket: "mobile-darmasaba.appspot.com", - messagingSenderId: "867439221179", - appId: "1:867439221179:android:4509f77478c8dce99b0c9e", - databaseURL: "https://mobile-darmasaba-default-rtdb.asia-southeast1.firebasedatabase.app/" + apiKey: ConstEnv.firebase.apiKey, + authDomain: ConstEnv.firebase.authDomain, + projectId: ConstEnv.firebase.projectId, + storageBucket: ConstEnv.firebase.storageBucket, + messagingSenderId: ConstEnv.firebase.messagingSenderId, + appId: ConstEnv.firebase.appId, + databaseURL: ConstEnv.firebase.databaseURL }; const initializeFirebase = async () => { try { - const app = getApps().length ? getApp() : initializeApp(RNfirebaseConfig); + let app; + const apps = getApps(); + if (apps.length) { + app = getApp() as any; + } else { + app = initializeApp(RNfirebaseConfig) as any; + } const mess = getMessaging(app); - // await registerDeviceForRemoteMessages(mess); - // `registerDeviceForRemoteMessages` tidak perlu lagi await setAutoInitEnabled(mess, true); return mess;