Compare commits

...

27 Commits

Author SHA1 Message Date
60e5c0663c Merge pull request 'Checkpoint 2' (#28) from checkpoint-2/12-dec-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/28
2025-12-12 14:59:49 +08:00
2c0198b1b7 Checkpoint QC Done
Cooming soon: Notification feature

### No Issue
2025-12-12 14:55:30 +08:00
573b525352 Fix QC ( Keano )
Fix:
- modified:   app/(application)/(user)/home.tsx
- modified:   app/(application)/(user)/voting/create.tsx
- modified:   components/DateInput/DataTimeAndroid.tsx
- modified:   components/DateInput/DateTimePickerCustom.tsx
- modified:   screens/Event/BoxPublishSection.tsx

### No Issue
2025-12-11 14:01:05 +08:00
ae0bf4dd60 Merge pull request 'Fix QC ( Ayu )' (#27) from qc/10-dec-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/27
2025-12-10 17:39:06 +08:00
6f9481c7c9 Fix QC ( Ayu )
Fix:
- modified:   app/(application)/(user)/event/[id]/publish.tsx
- modified:   app/(application)/(user)/event/create.tsx
- modified:   app/(application)/(user)/portofolio/[id]/create.tsx
- modified:   app/(application)/(user)/portofolio/[id]/edit.tsx
- modified:   app/(application)/admin/collaboration/[id]/group.tsx
- modified:   app/(application)/admin/collaboration/group.tsx
- modified:   app/(application)/admin/collaboration/publish.tsx
- modified:   app/(application)/admin/forum/[id]/list-report-comment.tsx
- modified:   app/(application)/admin/forum/[id]/list-report-posting.tsx
- modified:   app/(application)/admin/forum/posting.tsx
- modified:   app/(application)/admin/forum/report-comment.tsx
- modified:   app/(application)/admin/forum/report-posting.tsx
- modified:   app/(application)/admin/voting/[status]/status.tsx
- modified:   app/(application)/admin/voting/history.tsx
- modified:   components/Select/SelectCustom.tsx
- modified:   components/_ShareComponent/GridSpan_4_8.tsx
- modified:   screens/Authentication/LoginView.tsx
- modified:   screens/Collaboration/BoxPublishSection.tsx
- modified:   screens/Event/BoxDetailPublishSection.tsx
- modified:   screens/Home/topFeatureSection.tsx
- modified:   screens/Portofolio/ButtonCreatePortofolio.tsx

Add:
- app/(application)/admin/app-information/business-field/[id]/bidang-update.tsx
- app/(application)/admin/app-information/business-field/[id]/sub-bidang-update.tsx

### No Issue
2025-12-10 17:35:15 +08:00
bb63f7fa9a Merge pull request 'Apple reject and QC: Ayu' (#26) from qc/9-dec-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/26
2025-12-09 17:41:55 +08:00
cccb44a835 Fix QC Ayu
Fix:
- modified:   app/(application)/(user)/event/[id]/publish.tsx
- modified:   app/(application)/(user)/event/create.tsx
- modified:   app/(application)/(user)/portofolio/[id]/create.tsx
- modified:   app/(application)/(user)/portofolio/[id]/edit.tsx
- modified:   app/(application)/admin/collaboration/[id]/group.tsx
- modified:   app/(application)/admin/collaboration/group.tsx
- modified:   app/(application)/admin/collaboration/publish.tsx
- modified:   app/(application)/admin/forum/[id]/list-report-comment.tsx
- modified:   app/(application)/admin/forum/[id]/list-report-posting.tsx
- modified:   app/(application)/admin/forum/posting.tsx
- modified:   app/(application)/admin/forum/report-comment.tsx
- modified:   app/(application)/admin/forum/report-posting.tsx
- modified:   app/(application)/admin/voting/[status]/status.tsx
- modified:   app/(application)/admin/voting/history.tsx
- modified:   components/Select/SelectCustom.tsx
- modified:   components/_ShareComponent/GridSpan_4_8.tsx
- modified:   screens/Authentication/LoginView.tsx
- modified:   screens/Collaboration/BoxPublishSection.tsx
- modified:   screens/Event/BoxDetailPublishSection.tsx
- modified:   screens/Home/topFeatureSection.tsx
- modified:   screens/Portofolio/ButtonCreatePortofolio.tsx

Add:
- components/_ShareComponent/GridSpan_NewComponent.tsx

### No Issue
2025-12-09 17:36:36 +08:00
0f5862ce70 Fix Apple Reject:
Add:
- app/(application)/(user)/forum/terms.tsx

Fix:
- app/(application)/(user)/_layout.tsx
- app/(application)/(user)/home.tsx
- screens/Home/tabsList.ts
- service/api-client/api-user.ts

### No Issue
2025-12-08 16:34:33 +08:00
9742c1849a Merge pull request 'Fix QC Admin' (#25) from qc/5-dec-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/25
2025-12-05 17:23:16 +08:00
624bd49f69 QC Admin ( Inno )
Fix:
   modified:   android/app/build.gradle
        modified:   app.config.js
        modified:   app/(application)/admin/donation/[id]/[status]/index.tsx
        modified:   app/(application)/admin/donation/[id]/[status]/transaction-detail.tsx
        modified:   app/(application)/admin/donation/[id]/detail-disbursement-of-funds.tsx
        modified:   app/(application)/admin/donation/category.tsx
        modified:   app/(application)/admin/event/[id]/[status]/index.tsx
        modified:   app/(application)/admin/event/[id]/list-of-participants.tsx
        modified:   app/(application)/admin/event/[status]/status.tsx
        modified:   app/(application)/admin/forum/[id]/index.tsx
        modified:   app/(application)/admin/forum/[id]/list-report-comment.tsx
        modified:   app/(application)/admin/forum/[id]/list-report-posting.tsx
        modified:   app/(application)/admin/investment/[id]/[status]/index.tsx
        modified:   app/(application)/admin/investment/[id]/[status]/transaction-detail.tsx
        modified:   app/(application)/admin/voting/[id]/[status]/index.tsx
        modified:   components/DateInput/DateTimeIOS.tsx
        modified:   components/_ShareComponent/Admin/ButtonReject.tsx
        deleted:    components/_ShareComponent/GridDetail_4_8.tsx

Add:/
components/_ShareComponent/GridSpan_4_8.tsx

### No Issue
2025-12-05 17:20:39 +08:00
2446e9d51a Fix apple reject EULA
Add:
components/Alert/AlertWarning.ts
        utils/badWordsIndonesia.ts

Fix:
- app.config.js
- app/(application)/(user)/forum/[id]/edit.tsx
- app/(application)/(user)/forum/[id]/index.tsx
- app/(application)/(user)/forum/create.tsx
- ios/HIPMIBadungConnect/Info.plist

### No Issue
2025-12-05 11:46:36 +08:00
2265ef64cc Merge pull request 'QC Hipmi' (#24) from qc/4-dec-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/24
2025-12-04 17:47:01 +08:00
ab5733f336 Fix redirect admin 2025-12-04 17:41:19 +08:00
f5e30087ed Fix QC Inno
Fix:
- app/(application)/admin/donation/category-create.tsx
- app/(application)/admin/donation/category-update.tsx
- app/(application)/admin/donation/category.tsx
- components/_ShareComponent/Admin/TableValue.tsx
- screens/Authentication/LoginView.tsx
- service/api-admin/api-master-admin.ts

### No Issue
2025-12-04 16:59:39 +08:00
fbd096af9c Merge pull request 'Fix rejected Apple' (#23) from qc/3-dec-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/23
2025-12-03 17:24:07 +08:00
a93f97ed6a Fix rejected Apple
Add:
-  utils/viersionBadge.ts

Fix:
- app.config.js
- context/AuthContext.tsx
- ios/HIPMIBadungConnect/Info.plist
- screens/Authentication/LoginView.tsx
- screens/Authentication/VerificationView.tsx
- service/api-config.ts

### No Issue
2025-12-03 17:23:12 +08:00
5019b00f59 Merge pull request 'Clearing apple rejected & QC' (#22) from qc/2-dec-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/22
2025-12-02 17:50:22 +08:00
249ada221b Merge pull request 'QC: Inno dan Pak Jun' (#21) from qc/1-dec-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/21
2025-12-01 17:45:26 +08:00
19814315a4 Merge pull request 'Fix loader dan prebuild' (#20) from apple-reject/28-nov-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/20
2025-11-28 17:32:49 +08:00
77ef3a055e Merge pull request 'Halaman unblock user' (#19) from apple-reject/28-nov-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/19
2025-11-28 13:58:01 +08:00
aba3ad8ded Merge pull request 'apple-rejected' (#18) from apple-rejected/26-nov-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/18
2025-11-27 05:57:04 +08:00
7799c7720d Merge pull request 'Fix map android :' (#17) from fix-map/21-nov-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/17
2025-11-21 17:45:18 +08:00
2926b6eac1 Merge pull request 'delete-account' (#16) from delete-account/20-nov-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/16
2025-11-20 15:44:03 +08:00
637d444c5c Merge pull request 'Versi 1.0.1 : Qr Code & Start notifications' (#11) from staging into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/11
2025-11-14 17:46:16 +08:00
a614cfaac9 Merge pull request 'QR Code & Notification' (#10) from qc/14-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/10
2025-11-14 17:45:29 +08:00
1a7ad58505 Merge pull request 'QR Code Scan' (#9) from qrcode-access/13-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/9
2025-11-13 17:43:08 +08:00
7612be7366 Merge pull request 'UPDATE Build' (#8) from build/12-nov-25 into main
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi-mobile/pulls/8
2025-11-12 15:03:36 +08:00
82 changed files with 2509 additions and 744 deletions

View File

@@ -100,7 +100,7 @@ packagingOptions {
applicationId 'com.bip.hipmimobileapp' applicationId 'com.bip.hipmimobileapp'
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 2 versionCode 3
versionName "1.0.1" versionName "1.0.1"
buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\"" buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""

View File

@@ -16,6 +16,10 @@
</intent> </intent>
</queries> </queries>
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true" android:enableOnBackInvokedCallback="false"> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true" android:enableOnBackInvokedCallback="false">
<meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/notification_icon_color"/>
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon"/>
<meta-data android:name="expo.modules.notifications.default_notification_color" android:resource="@color/notification_icon_color"/>
<meta-data android:name="expo.modules.notifications.default_notification_icon" android:resource="@drawable/notification_icon"/>
<meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/> <meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/> <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/> <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -3,4 +3,5 @@
<color name="iconBackground">#ffffff</color> <color name="iconBackground">#ffffff</color>
<color name="colorPrimary">#023c69</color> <color name="colorPrimary">#023c69</color>
<color name="colorPrimaryDark">#ffffff</color> <color name="colorPrimaryDark">#ffffff</color>
<color name="notification_icon_color">#ffffff</color>
</resources> </resources>

View File

@@ -14,12 +14,14 @@ export default {
ios: { ios: {
supportsTablet: true, supportsTablet: true,
bundleIdentifier: "com.anonymous.hipmi-mobile", bundleIdentifier: "com.anonymous.hipmi-mobile",
googleServicesFile: "./ios/HIPMIBadungConnect/GoogleService-Info.plist",
infoPlist: { infoPlist: {
ITSAppUsesNonExemptEncryption: false, ITSAppUsesNonExemptEncryption: false,
"NSLocationWhenInUseUsageDescription": "Aplikasi membutuhkan akses lokasi untuk menampilkan peta.", NSLocationWhenInUseUsageDescription:
"Aplikasi membutuhkan akses lokasi untuk menampilkan peta.",
}, },
associatedDomains: ["applinks:cld-dkr-staging-hipmi.wibudev.com"], associatedDomains: ["applinks:cld-dkr-staging-hipmi.wibudev.com"],
buildNumber: "10", buildNumber: "15",
}, },
android: { android: {
@@ -30,7 +32,7 @@ export default {
}, },
edgeToEdgeEnabled: true, edgeToEdgeEnabled: true,
package: "com.bip.hipmimobileapp", package: "com.bip.hipmimobileapp",
versionCode: 2, versionCode: 3,
// softwareKeyboardLayoutMode: 'resize', // option: untuk mengatur keyboard pada room chst collaboration // softwareKeyboardLayoutMode: 'resize', // option: untuk mengatur keyboard pada room chst collaboration
intentFilters: [ intentFilters: [
{ {
@@ -56,7 +58,6 @@ export default {
plugins: [ plugins: [
"expo-router", "expo-router",
"expo-notifications",
"expo-web-browser", "expo-web-browser",
[ [
"expo-splash-screen", "expo-splash-screen",
@@ -77,6 +78,15 @@ export default {
], ],
"expo-font", "expo-font",
"@rnmapbox/maps", "@rnmapbox/maps",
"@react-native-firebase/app",
[
"expo-notifications",
{
icon: "./assets/images/icon.png",
color: "#ffffff",
iosDisplayInForeground: true,
},
],
], ],
experiments: { experiments: {

View File

@@ -595,6 +595,13 @@ export default function UserLayout() {
headerLeft: () => <BackButton />, headerLeft: () => <BackButton />,
}} }}
/> />
<Stack.Screen
name="forum/terms"
options={{
title: "Syarat & Ketentuan Forum",
headerLeft: () => <BackButton />,
}}
/>
{/* ========== Maps Section ========= */} {/* ========== Maps Section ========= */}
<Stack.Screen <Stack.Screen

View File

@@ -71,8 +71,6 @@ export default function EventDetailPublish() {
} }
} }
console.log("[participans]", isParticipant);
const handlePress = (item: IMenuDrawerItem) => { const handlePress = (item: IMenuDrawerItem) => {
console.log("PATH ", item.path); console.log("PATH ", item.path);
router.navigate(item.path as any); router.navigate(item.path as any);
@@ -139,7 +137,7 @@ export default function EventDetailPublish() {
<> <>
<Stack.Screen <Stack.Screen
options={{ options={{
title: `Event publish`, title: `Event Publish`,
headerLeft: () => <LeftButtonCustom />, headerLeft: () => <LeftButtonCustom />,
headerRight: () => <DotButton onPress={() => setOpenDrawer(true)} />, headerRight: () => <DotButton onPress={() => setOpenDrawer(true)} />,
}} }}

View File

@@ -145,7 +145,7 @@ export default function EventCreate() {
label: item.name, label: item.name,
value: item.id, value: item.id,
}))} }))}
value={data?.eventMaster_TipeAcaraId || ""} value={data?.eventMaster_TipeAcaraId || null}
onChange={(value: any) => onChange={(value: any) =>
setData({ ...data, eventMaster_TipeAcaraId: value }) setData({ ...data, eventMaster_TipeAcaraId: value })
} }

View File

@@ -5,9 +5,12 @@ import {
TextAreaCustom, TextAreaCustom,
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import AlertWarning from "@/components/Alert/AlertWarning";
import { apiForumGetOne, apiForumUpdate } from "@/service/api-client/api-forum"; import { apiForumGetOne, apiForumUpdate } from "@/service/api-client/api-forum";
import { isBadContent } from "@/utils/badWordsIndonesia";
import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { Alert } from "react-native";
import Toast from "react-native-toast-message"; import Toast from "react-native-toast-message";
export default function ForumEdit() { export default function ForumEdit() {
@@ -43,6 +46,12 @@ export default function ForumEdit() {
}); });
return; return;
} }
if (isBadContent(text)) {
AlertWarning({});
return;
}
try { try {
setIsLoading(true); setIsLoading(true);
const response = await apiForumUpdate({ const response = await apiForumUpdate({

View File

@@ -7,6 +7,7 @@ import {
TextCustom, TextCustom,
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import AlertWarning from "@/components/Alert/AlertWarning";
import { useAuth } from "@/hooks/use-auth"; import { useAuth } from "@/hooks/use-auth";
import Forum_CommentarBoxSection from "@/screens/Forum/CommentarBoxSection"; import Forum_CommentarBoxSection from "@/screens/Forum/CommentarBoxSection";
import Forum_BoxDetailSection from "@/screens/Forum/DiscussionBoxSection"; import Forum_BoxDetailSection from "@/screens/Forum/DiscussionBoxSection";
@@ -18,9 +19,11 @@ import {
apiForumGetOne, apiForumGetOne,
apiForumUpdateStatus, apiForumUpdateStatus,
} from "@/service/api-client/api-forum"; } from "@/service/api-client/api-forum";
import { isBadContent } from "@/utils/badWordsIndonesia";
import { useFocusEffect, useLocalSearchParams } from "expo-router"; import { useFocusEffect, useLocalSearchParams } from "expo-router";
import _ from "lodash"; import _ from "lodash";
import { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { Alert } from "react-native";
interface CommentProps { interface CommentProps {
id: string; id: string;
@@ -110,11 +113,15 @@ export default function ForumDetail() {
// Create Commentar // Create Commentar
const handlerCreateCommentar = async () => { const handlerCreateCommentar = async () => {
if (isBadContent(text)) {
AlertWarning({});
return;
}
const newData = { const newData = {
comment: text, comment: text,
authorId: user?.id, authorId: user?.id,
}; };
try { try {
setLoadingComment(true); setLoadingComment(true);
const response = await apiForumCreateComment({ const response = await apiForumCreateComment({

View File

@@ -2,12 +2,15 @@ import {
BoxButtonOnFooter, BoxButtonOnFooter,
ButtonCustom, ButtonCustom,
TextAreaCustom, TextAreaCustom,
ViewWrapper, ViewWrapper
} from "@/components"; } from "@/components";
import AlertWarning from "@/components/Alert/AlertWarning";
import { useAuth } from "@/hooks/use-auth"; import { useAuth } from "@/hooks/use-auth";
import { apiForumCreate } from "@/service/api-client/api-forum"; import { apiForumCreate } from "@/service/api-client/api-forum";
import { isBadContent } from "@/utils/badWordsIndonesia";
import { router } from "expo-router"; import { router } from "expo-router";
import { useState } from "react"; import { useState } from "react";
import { Alert } from "react-native";
import Toast from "react-native-toast-message"; import Toast from "react-native-toast-message";
export default function ForumCreate() { export default function ForumCreate() {
@@ -16,11 +19,16 @@ export default function ForumCreate() {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const handlerSubmit = async () => { const handlerSubmit = async () => {
if (isBadContent(text)) {
AlertWarning({})
return;
}
const newData = { const newData = {
diskusi: text, diskusi: text,
authorId: user?.id, authorId: user?.id,
}; };
try { try {
setIsLoading(true); setIsLoading(true);
const response = await apiForumCreate({ data: newData }); const response = await apiForumCreate({ data: newData });

View File

@@ -0,0 +1,202 @@
import {
BaseBox,
ButtonCustom,
CheckboxCustom,
NewWrapper,
StackCustom,
TextCustom,
} from "@/components";
import { useAuth } from "@/hooks/use-auth";
import { apiAcceptForumTerms } from "@/service/api-client/api-user";
import { GStyles } from "@/styles/global-styles";
import { Ionicons } from "@expo/vector-icons";
import { router } from "expo-router";
import { useState } from "react";
import { View } from "react-native";
import { Text } from "react-native-paper";
import Toast from "react-native-toast-message";
export default function ForumSplash() {
const { user } = useAuth();
const [term, setTerm] = useState(false);
const [loading, setLoading] = useState(false);
const handleSubmit = async () => {
try {
setLoading(true);
const respone = await apiAcceptForumTerms({
category: "Forum",
userId: user?.id as any,
});
if (respone.success) {
Toast.show({
type: "success",
text1: "Berhasil",
text2: "Terima kasih telah menerima syarat & ketentuan forum ini",
});
router.replace("/(application)/forum");
return;
}
Toast.show({
type: "error",
text1: "Gagal",
text2: "Terjadi kesalahan, silahkan coba lagi",
});
} catch (error) {
console.log("[ERROR]", error);
} finally {
setLoading(false);
}
};
return (
<NewWrapper>
{/* <TextCustom bold>HIPMI Badung Connect</TextCustom> . */}
<BaseBox>
<StackCustom>
<TextCustom>
Dengan mengakses dan menggunakan Forum HIPMI Badung Connect, Anda
secara sadar menyetujui ketentuan berikut:
</TextCustom>
<TextCustom bold>
1. Dilarang keras memposting konten yang mengandung:
</TextCustom>
<View style={{ paddingInline: 10 }}>
{forumTerms1.map((term, index) => (
<View
key={index}
style={{
flexDirection: "row",
alignItems: "center",
gap: 10,
paddingBottom: 10,
}}
>
<Ionicons name="radio-button-on" color={"white"} />
<TextCustom>{term.text}</TextCustom>
</View>
))}
</View>
<TextCustom bold>
2. Setiap pengguna bertanggung jawab penuh atas konten yang
diunggah. Konten yang melanggar ketentuan ini dapat dihapus kapan
saja tanpa pemberitahuan.
</TextCustom>
<TextCustom bold>
3. Jika Anda menemukan konten tidak pantas, segera:
</TextCustom>
<View style={{ paddingInline: 10 }}>
{forumTerms2.map((term, index) => (
<View
key={index}
style={{
flexDirection: "row",
alignItems: "center",
gap: 10,
paddingBottom: 10,
}}
>
<Ionicons name="radio-button-on" color={"white"} />
<TextCustom>{term.text}</TextCustom>
</View>
))}
</View>
<TextCustom bold>
4. Gunakan fitur Blokir Pengguna di profil pengguna terkait
</TextCustom>
<View style={{ paddingInline: 10 }}>
{forumTerms3.map((term, index) => (
<View
key={index}
style={{
flexDirection: "row",
alignItems: "center",
gap: 10,
paddingBottom: 10,
}}
>
<Ionicons name="radio-button-on" color={"white"} />
<TextCustom>{term.text}</TextCustom>
</View>
))}
</View>
<TextCustom>
Pelanggaran terhadap ketentuan ini berakibat{" "}
<TextCustom bold>pencabutan akses</TextCustom> ke Forum dan/atau{" "}
<TextCustom bold>pemblokiran akun secara permanen</TextCustom> tanpa
pemberitahuan lebih lanjut.
</TextCustom>
<View
style={{
flexDirection: "row",
alignItems: "center",
marginTop: 16,
marginBottom: 16,
}}
>
<CheckboxCustom value={term} onChange={() => setTerm(!term)} />
<Text style={GStyles.textLabel}>
Saya telah membaca dan menyetujui Syarat & Ketentuan Forum ini
</Text>
</View>
<ButtonCustom
disabled={!term || loading}
onPress={() => {
handleSubmit();
}}
>
Lanjut
</ButtonCustom>
</StackCustom>
</BaseBox>
</NewWrapper>
);
}
// Data dalam format JSON (bisa juga diimpor dari file terpisah)
interface Term {
text: string;
}
const forumTerms1: Term[] = [
{
text: "Ujaran kebencian, diskriminasi, atau konten SARA (Suku, Agama, Ras, Antar-golongan)",
},
{ text: "Kata kasar, pelecehan, ancaman, atau bullying" },
{ text: "Pornografi, hoaks, spam, atau informasi menyesatkan" },
{ text: "Promosi aktivitas ilegal seperti perjudian atau narkoba" },
];
const forumTerms2: Term[] = [
{
text: "Gunakan tombol “Laporkan” di setiap postingan, atau",
},
{
text: "Gunakan fitur “Blokir Pengguna” di profil pengguna terkait.",
},
];
const forumTerms3: Term[] = [
{
text: "Meninjau setiap laporan dalam waktu 24 jam",
},
{
text: "Menghapus konten yang melanggar",
},
{
text: "Memblokir akun pelanggar sesuai tingkat pelanggaran",
},
];

View File

@@ -11,35 +11,47 @@ import Home_FeatureSection from "@/screens/Home/topFeatureSection";
import { apiUser } from "@/service/api-client/api-user"; import { apiUser } from "@/service/api-client/api-user";
import { apiVersion } from "@/service/api-config"; import { apiVersion } from "@/service/api-config";
import { Ionicons } from "@expo/vector-icons"; import { Ionicons } from "@expo/vector-icons";
import { Redirect, router, Stack } from "expo-router"; import { Redirect, router, Stack, useFocusEffect } from "expo-router";
import { useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { RefreshControl } from "react-native";
export default function Application() { export default function Application() {
const { token, user } = useAuth(); const { token, user, userData } = useAuth();
const [data, setData] = useState<any>(); const [data, setData] = useState<any>();
const [refreshing, setRefreshing] = useState(false);
console.log("[User] >>", JSON.stringify(user?.id, null, 2)); console.log("[User] >>", JSON.stringify(user?.id, null, 2));
useEffect(() => { // ‼️ Untuk cek apakah: 1. user ada, 2. user punya profile, 3. accept temrs of forum nya ada atau tidak
onLoadData(); useFocusEffect(
checkVersion(); useCallback(() => {
}, []); onLoadData();
checkVersion();
userData(token as string);
}, [user?.id, token])
);
async function onLoadData() { async function onLoadData() {
const response = await apiUser(user?.id as string); const response = await apiUser(user?.id as string);
console.log( console.log(
"[Profile ID]>>", "[Profile ID]>>",
JSON.stringify(response?.data?.Profile.id, null, 2) JSON.stringify(response?.data?.Profile?.id, null, 2)
); );
setData(response.data); setData(response.data);
} }
const checkVersion = async () => { const checkVersion = async () => {
const response = await apiVersion(); const response = await apiVersion();
console.log("[Version] >>", JSON.stringify(response.data, null, 2)); console.log("[Version] >>", JSON.stringify(response.data, null, 2));
}; };
const onRefresh = useCallback(() => {
setRefreshing(true);
onLoadData();
checkVersion();
setRefreshing(false);
}, []);
if (user && user?.termsOfServiceAccepted === false) { if (user && user?.termsOfServiceAccepted === false) {
console.log("User is not accept term service"); console.log("User is not accept term service");
return <Redirect href={`/terms-agreement`} />; return <Redirect href={`/terms-agreement`} />;
@@ -72,9 +84,10 @@ export default function Application() {
), ),
headerRight: () => ( headerRight: () => (
<Ionicons <Ionicons
disabled={true}
name="notifications" name="notifications"
size={20} size={20}
color={MainColor.yellow} color={MainColor.placeholder}
onPress={() => { onPress={() => {
router.push("/notifications"); router.push("/notifications");
}} }}
@@ -83,8 +96,16 @@ export default function Application() {
}} }}
/> />
<ViewWrapper <ViewWrapper
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}
footerComponent={ footerComponent={
<TabSection tabs={tabsHome(data?.Profile?.id as string)} /> <TabSection
tabs={tabsHome({
acceptedForumTermsAt: data?.acceptedForumTermsAt,
profileId: data?.Profile?.id,
})}
/>
} }
> >
<StackCustom> <StackCustom>

View File

@@ -31,9 +31,9 @@ import {
import pickImage from "@/utils/pickImage"; import pickImage from "@/utils/pickImage";
import { Ionicons } from "@expo/vector-icons"; import { Ionicons } from "@expo/vector-icons";
import { Image } from "expo-image"; import { Image } from "expo-image";
import { useLocalSearchParams } from "expo-router"; import { useFocusEffect, useLocalSearchParams } from "expo-router";
import _ from "lodash"; import _ from "lodash";
import { useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { Text, TouchableOpacity, View } from "react-native"; import { Text, TouchableOpacity, View } from "react-native";
import PhoneInput, { ICountry } from "react-native-international-phone-number"; import PhoneInput, { ICountry } from "react-native-international-phone-number";
import { Avatar } from "react-native-paper"; import { Avatar } from "react-native-paper";
@@ -76,7 +76,7 @@ export default function PortofolioCreate() {
function handleInputValue(phoneNumber: string) { function handleInputValue(phoneNumber: string) {
setInputValue(phoneNumber); setInputValue(phoneNumber);
const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || ""; const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || "";
const fixNumber = inputValue.replace(/\s+/g, ""); let fixNumber = inputValue.replace(/\s+/g, "").replace(/^0+/, "");
const realNumber = callingCode + fixNumber; const realNumber = callingCode + fixNumber;
setData({ ...data, tlpn: realNumber }); setData({ ...data, tlpn: realNumber });
} }
@@ -85,10 +85,12 @@ export default function PortofolioCreate() {
setSelectedCountry(country); setSelectedCountry(country);
} }
useEffect(() => { useFocusEffect(
onLoadMaster(); useCallback(() => {
onLoadMasterSubBidangBisnis(); onLoadMaster();
}, []); onLoadMasterSubBidangBisnis();
}, [])
);
const onLoadMaster = async () => { const onLoadMaster = async () => {
try { try {

View File

@@ -244,7 +244,7 @@ export default function PortofolioEdit() {
const handleSubmitUpdate = async () => { const handleSubmitUpdate = async () => {
const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || ""; const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || "";
const fixNumber = data.tlpn.replace(/\s+/g, ""); let fixNumber = data.tlpn.replace(/\s+/g, "").replace(/^0+/, "");
const realNumber = callingCode + fixNumber; const realNumber = callingCode + fixNumber;
const newData: IFormData = { const newData: IFormData = {

View File

@@ -110,7 +110,7 @@ export default function VotingCreate() {
<StackCustom gap={"xs"}> <StackCustom gap={"xs"}>
<TextInputCustom <TextInputCustom
label="Judul Voting" label="Judul Voting"
placeholder="MasukanJudul Voting" placeholder="Masukan Judul Voting"
required required
value={data.title} value={data.title}
onChangeText={(value: any) => setData({ ...data, title: value })} onChangeText={(value: any) => setData({ ...data, title: value })}

View File

@@ -0,0 +1,129 @@
/* eslint-disable react-hooks/exhaustive-deps */
import {
BoxButtonOnFooter,
ButtonCustom,
StackCustom,
TextCustom,
TextInputCustom,
ViewWrapper,
} from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { MainColor } from "@/constants/color-palet";
import {
apiAdminMasterBusinessFieldById,
apiAdminMasterBusinessFieldUpdate,
} from "@/service/api-admin/api-master-admin";
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
import { useCallback, useState } from "react";
import { Switch } from "react-native-paper";
import Toast from "react-native-toast-message";
export default function AdminAppInformation_BusinessFieldDetail() {
const { id } = useLocalSearchParams();
const [data, setData] = useState<any | null>(null);
const [isLoading, setIsLoading] = useState(false);
useFocusEffect(
useCallback(() => {
onLoadDetail();
}, [id])
);
const onLoadDetail = async () => {
try {
const response = await apiAdminMasterBusinessFieldById({
id: id as string,
category: "bidang"
});
setData(response.data);
} catch (error) {
console.log("[ERROR]", error);
setData(null);
}
};
const handlerSubmit = async () => {
if (!data.name) {
Toast.show({
type: "error",
text1: "Lengkapi Data",
});
return;
}
try {
setIsLoading(true);
const response = await apiAdminMasterBusinessFieldUpdate({
id: id as string,
data: data,
category: "bidang",
});
if (!response.success) {
Toast.show({
type: "error",
text1: "Gagal update data",
});
return;
}
Toast.show({
type: "success",
text1: "Data berhasil di update",
});
router.back();
} catch (error) {
console.log(error);
} finally {
setIsLoading(false);
}
};
const buttonSubmit = (
<BoxButtonOnFooter>
<ButtonCustom
disabled={!data?.name}
isLoading={isLoading}
onPress={() => handlerSubmit()}
>
Update
</ButtonCustom>
</BoxButtonOnFooter>
);
return (
<>
<ViewWrapper footerComponent={buttonSubmit}>
<StackCustom>
<AdminBackButtonAntTitle title="Update Bidang Bisnis" />
<TextInputCustom
label="Nama Bidang Bisnis"
placeholder="Masukan Nama Bidang Bisnis"
required
value={data?.name}
onChangeText={(value) => setData({ ...data, name: value })}
/>
<StackCustom
gap={"sm"}
style={{
alignContent: "flex-start",
}}
>
<TextCustom>Status</TextCustom>
<Switch
style={{
alignSelf: "flex-start",
}}
color={MainColor.yellow}
value={data?.active}
onValueChange={(value) => setData({ ...data, active: value })}
/>
</StackCustom>
</StackCustom>
</ViewWrapper>
</>
);
}

View File

@@ -1,22 +1,22 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
import { import {
BoxButtonOnFooter, ActionIcon,
ButtonCustom, BaseBox,
CenterCustom,
LoaderCustom,
Spacing,
StackCustom, StackCustom,
TextCustom, TextCustom,
TextInputCustom,
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import { IconEdit } from "@/components/_Icon";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { GridSpan_NewComponent } from "@/components/_ShareComponent/GridSpan_NewComponent";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { import { apiAdminMasterBusinessFieldById } from "@/service/api-admin/api-master-admin";
apiAdminMasterBusinessFieldById,
apiAdminMasterBusinessFieldUpdate,
} from "@/service/api-admin/api-master-admin";
import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { Switch } from "react-native-paper"; import { Divider } from "react-native-paper";
import Toast from "react-native-toast-message";
export default function AdminAppInformation_BusinessFieldDetail() { export default function AdminAppInformation_BusinessFieldDetail() {
const { id } = useLocalSearchParams(); const { id } = useLocalSearchParams();
@@ -33,8 +33,11 @@ export default function AdminAppInformation_BusinessFieldDetail() {
try { try {
const response = await apiAdminMasterBusinessFieldById({ const response = await apiAdminMasterBusinessFieldById({
id: id as string, id: id as string,
category: "all",
}); });
console.log("Response >>", JSON.stringify(response, null, 2));
setData(response.data); setData(response.data);
} catch (error) { } catch (error) {
console.log("[ERROR]", error); console.log("[ERROR]", error);
@@ -42,73 +45,89 @@ export default function AdminAppInformation_BusinessFieldDetail() {
} }
}; };
const handlerSubmit = async () => {
if (!data.name) {
Toast.show({
type: "error",
text1: "Lengkapi Data",
});
return;
}
try {
setIsLoading(true);
const response = await apiAdminMasterBusinessFieldUpdate({
id: id as string,
data: data,
});
if (!response.success) {
Toast.show({
type: "error",
text1: "Gagal update data",
});
return;
}
Toast.show({
type: "success",
text1: "Data berhasil di update",
});
router.back();
} catch (error) {
console.log(error);
} finally {
setIsLoading(false);
}
};
const buttonSubmit = (
<BoxButtonOnFooter>
<ButtonCustom
disabled={!data?.name}
isLoading={isLoading}
onPress={() => handlerSubmit()}
>
Update
</ButtonCustom>
</BoxButtonOnFooter>
);
return ( return (
<> <>
<ViewWrapper footerComponent={buttonSubmit}> <ViewWrapper>
<StackCustom> <StackCustom>
<AdminBackButtonAntTitle title="Update Bidang Bisnis" /> <AdminBackButtonAntTitle title="Detail Bidang & Sub Bidang" />
<TextInputCustom {!data ? (
label="Nama Bidang Bisnis" <LoaderCustom />
placeholder="Masukan Nama Bidang Bisnis" ) : (
required <StackCustom gap={"xs"}>
value={data?.name} <TextCustom bold>Nama Bidang</TextCustom>
onChangeText={(value) => setData({ ...data, name: value })} <Spacing height={5} />
/> <BaseBox>
<StackCustom gap={"xs"}>
<TextCustom bold>
Status: {data?.bidang?.active ? "Aktif" : "Tidak Aktif"}
</TextCustom>
<GridSpan_NewComponent
span1={10}
span2={2}
text1={
<TextCustom bold size={"large"}>
{data?.bidang?.name}
</TextCustom>
}
text2={
<CenterCustom>
<ActionIcon
icon={<IconEdit size={16} color={MainColor.black} />}
onPress={() =>
router.push(
`/admin/app-information/business-field/${id}/bidang-update`
)
}
/>
</CenterCustom>
}
/>
</StackCustom>
</BaseBox>
{/* <Divider /> */}
<Spacing height={5} />
<TextCustom>Status Aktivasi</TextCustom> <TextCustom bold>Sub Bidang Bisnis</TextCustom>
<Switch <Spacing height={5} />
color={MainColor.yellow}
value={data?.active} {data?.subBidang?.map((item: any, index: number) => (
onValueChange={(value) => setData({ ...data, active: value })} <BaseBox key={index}>
/> <StackCustom gap={0}>
<TextCustom bold>
Status: {item?.isActive ? "Aktif" : "Tidak Aktif"}
</TextCustom>
<GridSpan_NewComponent
span1={10}
span2={2}
text1={
<TextCustom bold size={"large"}>
{item.name}
</TextCustom>
}
text2={
<CenterCustom>
<ActionIcon
icon={
<IconEdit size={16} color={MainColor.black} />
}
onPress={() =>
router.push(
`/admin/app-information/business-field/${item?.id}/sub-bidang-update`
)
}
/>
</CenterCustom>
}
/>
</StackCustom>
</BaseBox>
))}
</StackCustom>
)}
{/* <TextCustom>{JSON.stringify(data, null, 2)}</TextCustom> */}
</StackCustom> </StackCustom>
</ViewWrapper> </ViewWrapper>
</> </>

View File

@@ -0,0 +1,135 @@
/* eslint-disable react-hooks/exhaustive-deps */
import {
BoxButtonOnFooter,
ButtonCustom,
StackCustom,
TextCustom,
TextInputCustom,
ViewWrapper,
} from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { MainColor } from "@/constants/color-palet";
import {
apiAdminMasterBusinessFieldById,
apiAdminMasterBusinessFieldUpdate,
} from "@/service/api-admin/api-master-admin";
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
import { useCallback, useState } from "react";
import { Switch } from "react-native-paper";
import Toast from "react-native-toast-message";
export default function AdminAppInformation_BusinessFieldDetail() {
const { id } = useLocalSearchParams();
const [data, setData] = useState<any | null>(null);
const [isLoading, setIsLoading] = useState(false);
useFocusEffect(
useCallback(() => {
onLoadDetail();
}, [id])
);
const onLoadDetail = async () => {
try {
const response = await apiAdminMasterBusinessFieldById({
id: id as string,
category: "sub-bidang",
subBidangId: id as string,
});
console.log("Response >>", JSON.stringify(response, null, 2));
setData(response.data);
} catch (error) {
console.log("[ERROR]", error);
setData(null);
}
};
const handlerSubmit = async () => {
if (!data.name) {
Toast.show({
type: "error",
text1: "Lengkapi Data",
});
return;
}
try {
setIsLoading(true);
const response = await apiAdminMasterBusinessFieldUpdate({
id: id as string,
data: data,
category: "sub-bidang",
});
if (!response.success) {
Toast.show({
type: "error",
text1: "Gagal update data",
});
return;
}
Toast.show({
type: "success",
text1: "Data berhasil di update",
});
router.back();
} catch (error) {
console.log(error);
} finally {
setIsLoading(false);
}
};
const buttonSubmit = (
<BoxButtonOnFooter>
<ButtonCustom
disabled={!data?.name}
isLoading={isLoading}
onPress={() => handlerSubmit()}
>
Update
</ButtonCustom>
</BoxButtonOnFooter>
);
return (
<>
<ViewWrapper footerComponent={buttonSubmit}>
<StackCustom>
<AdminBackButtonAntTitle title="Update Bidang Bisnis" />
<TextInputCustom
label="Nama Bidang Bisnis"
placeholder="Masukan Nama Bidang Bisnis"
required
value={data?.name}
onChangeText={(value) => setData({ ...data, name: value })}
/>
<StackCustom
gap={"sm"}
style={{
alignContent: "flex-start",
}}
>
<TextCustom>Status</TextCustom>
<Switch
style={{
alignSelf: "flex-start",
}}
color={MainColor.yellow}
value={data?.isActive}
onValueChange={(value) => setData({ ...data, isActive: value })}
/>
</StackCustom>
</StackCustom>
</ViewWrapper>
</>
);
}

View File

@@ -1,40 +1,81 @@
import { import {
BoxButtonOnFooter, ActionIcon,
ButtonCustom, BoxButtonOnFooter,
StackCustom, ButtonCustom,
TextInputCustom, CenterCustom,
ViewWrapper, Grid,
Spacing,
StackCustom,
TextInputCustom,
ViewWrapper,
} from "@/components"; } from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_XLARGE } from "@/constants/constans-value";
import { apiAdminMasterBusinessFieldCreate } from "@/service/api-admin/api-master-admin"; import { apiAdminMasterBusinessFieldCreate } from "@/service/api-admin/api-master-admin";
import { Ionicons } from "@expo/vector-icons";
import { router } from "expo-router"; import { router } from "expo-router";
import _ from "lodash";
import { useState } from "react"; import { useState } from "react";
import { View } from "react-native";
import { Divider } from "react-native-paper";
import Toast from "react-native-toast-message"; import Toast from "react-native-toast-message";
export default function AdminAppInformation_BusinessFieldCreate() { export default function AdminAppInformation_BusinessFieldCreate() {
const [data, setData] = useState<any>({ const [isLoading, setIsLoading] = useState(false);
const [bidang, setBidang] = useState<any>({
name: "", name: "",
}); });
const [isLoading, setIsLoading] = useState(false); const [subBidang, setSubBidang] = useState<any[]>([
{
name: "",
},
]);
const handlerSubmit = async () => { const handlerSubmit = async () => {
if (!data.name) { if (!bidang.name) {
Toast.show({ Toast.show({
type: "error", type: "error",
text1: "Lengkapi Data", text1: "Lengkapi Data",
}); });
return; return;
} }
if (subBidang[0].name === "") {
Toast.show({
type: "error",
text1: "Lengkapi Sub Bidang",
});
return;
}
try { try {
setIsLoading(true); setIsLoading(true);
const response = await apiAdminMasterBusinessFieldCreate({ data: data });
const newData = {
bidang: bidang,
subBidang: subBidang,
};
console.log("[DATA]", newData);
const response = await apiAdminMasterBusinessFieldCreate({
data: newData,
});
console.log("[RESPONSE]", response);
if (response.success) { if (response.success) {
Toast.show({ Toast.show({
type: "success", type: "success",
text1: "Data berhasil di tambah", text1: "Data berhasil di tambah",
}); });
router.back(); // router.back();
} else {
Toast.show({
type: "error",
text1: "Gagal tambah data",
});
} }
} catch (error) { } catch (error) {
console.log("[ERROR]", error); console.log("[ERROR]", error);
@@ -50,6 +91,7 @@ export default function AdminAppInformation_BusinessFieldCreate() {
const buttonSubmit = ( const buttonSubmit = (
<BoxButtonOnFooter> <BoxButtonOnFooter>
<ButtonCustom <ButtonCustom
disabled={subBidang[0].name === ""}
onPress={() => handlerSubmit()} onPress={() => handlerSubmit()}
isLoading={isLoading} isLoading={isLoading}
> >
@@ -60,16 +102,70 @@ export default function AdminAppInformation_BusinessFieldCreate() {
return ( return (
<> <>
<ViewWrapper footerComponent={buttonSubmit}> <ViewWrapper footerComponent={buttonSubmit}>
<StackCustom> <StackCustom gap={"xs"}>
<AdminBackButtonAntTitle title="Tambah Bidang Bisnis" /> <AdminBackButtonAntTitle title="Tambah Bidang Bisnis" />
<TextInputCustom <TextInputCustom
label="Nama Bidang Bisnis" label="Nama Bidang Bisnis"
placeholder="Masukan Nama Bidang Bisnis" placeholder="Masukan Nama Bidang Bisnis"
required required
value={data.name} value={bidang.name}
onChangeText={(value) => setData({ ...data, name: value })} onChangeText={(value) => setBidang({ ...bidang, name: value })}
/> />
<Divider />
<Spacing height={5} />
{subBidang.map((item, index) => (
<TextInputCustom
key={index}
label="Nama Sub Bidang"
placeholder="Masukan Nama Sub Bidang"
required
value={item.name}
onChangeText={(value) => {
const list = _.clone(subBidang);
list[index].name = value;
setSubBidang(list);
}}
/>
))}
<CenterCustom>
<View
style={{ flexDirection: "row", alignItems: "center", gap: 10 }}
>
<ActionIcon
onPress={() => {
setSubBidang([...subBidang, { name: "" }]);
}}
icon={
<Ionicons
name="add-circle-outline"
size={ICON_SIZE_XLARGE}
color={MainColor.black}
/>
}
size="xl"
/>
<ActionIcon
disabled={subBidang.length <= 1}
onPress={() => {
const list = _.clone(subBidang);
list.pop();
setSubBidang(list);
}}
icon={
<Ionicons
name="remove-circle-outline"
size={ICON_SIZE_XLARGE}
color={MainColor.black}
/>
}
size="xl"
/>
</View>
</CenterCustom>
</StackCustom> </StackCustom>
</ViewWrapper> </ViewWrapper>
</> </>

View File

@@ -75,7 +75,7 @@ const listPage = [
}, },
{ {
id: "2", id: "2",
label: "Bidang Bisnis", label: "Bidang & Sub Bidang",
value: "business", value: "business",
}, },
{ {

View File

@@ -2,11 +2,13 @@
import { import {
BaseBox, BaseBox,
Grid, Grid,
Spacing,
StackCustom, StackCustom,
TextCustom, TextCustom,
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import { apiAdminCollaborationGetById } from "@/service/api-admin/api-admin-collaboration"; import { apiAdminCollaborationGetById } from "@/service/api-admin/api-admin-collaboration";
import { useFocusEffect, useLocalSearchParams } from "expo-router"; import { useFocusEffect, useLocalSearchParams } from "expo-router";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
@@ -28,6 +30,8 @@ export default function AdminCollaborationGroup() {
category: "group", category: "group",
}); });
console.log("[DATA]", JSON.stringify(response.data, null, 2));
if (response.success) { if (response.success) {
setData(response.data); setData(response.data);
} }
@@ -59,38 +63,33 @@ export default function AdminCollaborationGroup() {
))} ))}
</StackCustom> </StackCustom>
</BaseBox> </BaseBox>
<TextCustom bold>Anggota</TextCustom>
<Spacing height={5}/>
<BaseBox> <BaseBox>
<StackCustom> <StackCustom>
<TextCustom align="center">Anggota</TextCustom>
<Grid>
<Grid.Col span={6} style={{ justifyContent: "center", paddingRight: 10 }}>
<TextCustom bold>Nomor</TextCustom>
</Grid.Col>
<Grid.Col span={6} style={{ justifyContent: "center" }}>
<TextCustom bold>Username</TextCustom>
</Grid.Col>
</Grid>
{data?.ProjectCollaboration_AnggotaRoomChat?.map( {data?.ProjectCollaboration_AnggotaRoomChat?.map(
(item: any, index: number) => ( (item: any, index: number) => (
<StackCustom key={index} gap={0}> <Grid key={index}>
<Grid> <Grid.Col span={6} style={{ justifyContent: "center", paddingRight: 10 }}>
<Grid.Col <TextCustom bold truncate>+{item?.User?.nomor || "-"}</TextCustom>
span={4} </Grid.Col>
style={{ justifyContent: "center", paddingRight: 10 }} <Grid.Col span={6} style={{ justifyContent: "center" }}>
> <TextCustom bold>
<TextCustom bold>Nama</TextCustom> {item?.User?.username || "-"}
</Grid.Col> </TextCustom>
<Grid.Col span={8} style={{ justifyContent: "center" }}> </Grid.Col>
<TextCustom> </Grid>
{item?.User?.Profile?.name || "-"}
</TextCustom>
</Grid.Col>
</Grid>
<Grid>
<Grid.Col
span={4}
style={{ justifyContent: "center", paddingRight: 10 }}
>
<TextCustom bold>Username</TextCustom>
</Grid.Col>
<Grid.Col span={8} style={{ justifyContent: "center" }}>
<TextCustom>{item?.User?.username || "-"}</TextCustom>
</Grid.Col>
</Grid>
</StackCustom>
) )
)} )}
</StackCustom> </StackCustom>

View File

@@ -1,17 +1,14 @@
import { import {
ActionIcon, ClickableCustom,
LoaderCustom, LoaderCustom,
StackCustom, StackCustom,
TextCustom, TextCustom,
ViewWrapper ViewWrapper
} from "@/components"; } from "@/components";
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { GridSpan_NewComponent } from "@/components/_ShareComponent/GridSpan_NewComponent";
import { apiAdminCollaboration } from "@/service/api-admin/api-admin-collaboration"; import { apiAdminCollaboration } from "@/service/api-admin/api-admin-collaboration";
import { Octicons } from "@expo/vector-icons";
import { router, useFocusEffect } from "expo-router"; import { router, useFocusEffect } from "expo-router";
import _ from "lodash"; import _ from "lodash";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
@@ -34,7 +31,7 @@ export default function AdminCollaborationGroup() {
const response = await apiAdminCollaboration({ const response = await apiAdminCollaboration({
category: "group", category: "group",
}); });
if (response.success) { if (response.success) {
setList(response.data); setList(response.data);
} }
@@ -51,10 +48,19 @@ export default function AdminCollaborationGroup() {
<StackCustom> <StackCustom>
<AdminComp_BoxTitle title="Group" /> <AdminComp_BoxTitle title="Group" />
<> <>
<AdminTitleTable <GridSpan_NewComponent
title1="Aksi" span1={6}
title2="Jumlah peserta" span2={6}
title3="Nama group" text1={
<TextCustom bold truncate align="center">
Jumlah Anggota
</TextCustom>
}
text2={
<TextCustom bold truncate>
Nama Group
</TextCustom>
}
/> />
<Divider /> <Divider />
@@ -67,31 +73,27 @@ export default function AdminCollaborationGroup() {
) : ( ) : (
list?.map((item: any, index: number) => ( list?.map((item: any, index: number) => (
<View key={index}> <View key={index}>
<AdminTableValue <ClickableCustom
value1={ onPress={() => {
<ActionIcon router.push(`/admin/collaboration/${item.id}/group`);
icon={ }}
<Octicons >
name="eye" <GridSpan_NewComponent
size={ICON_SIZE_BUTTON} span1={6}
color="black" span2={6}
/> text1={
} <TextCustom truncate={1} align="center">
onPress={() => { {item?.ProjectCollaboration_AnggotaRoomChat?.length ||
router.push(`/admin/collaboration/${item.id}/group`); "-"}
}} </TextCustom>
/> }
} text2={
value2={ <TextCustom truncate={2}>
<TextCustom truncate={1}> {item?.name || "-"}
{item?.ProjectCollaboration_AnggotaRoomChat?.length || </TextCustom>
"-"} }
</TextCustom> />
} </ClickableCustom>
value3={
<TextCustom truncate={2}>{item?.name || "-"}</TextCustom>
}
/>
</View> </View>
)) ))
)} )}

View File

@@ -1,6 +1,8 @@
import { import {
ActionIcon, ActionIcon,
ClickableCustom,
LoaderCustom, LoaderCustom,
Spacing,
StackCustom, StackCustom,
TextCustom, TextCustom,
ViewWrapper, ViewWrapper,
@@ -9,6 +11,7 @@ import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle"; import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue"; import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
import { GridSpan_NewComponent } from "@/components/_ShareComponent/GridSpan_NewComponent";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { apiAdminCollaboration } from "@/service/api-admin/api-admin-collaboration"; import { apiAdminCollaboration } from "@/service/api-admin/api-admin-collaboration";
import { Octicons } from "@expo/vector-icons"; import { Octicons } from "@expo/vector-icons";
@@ -51,11 +54,7 @@ export default function AdminCollaborationPublish() {
<StackCustom> <StackCustom>
<AdminComp_BoxTitle title="Publish" /> <AdminComp_BoxTitle title="Publish" />
<AdminTitleTable <GridSpan_NewComponent text1={<TextCustom bold>Username</TextCustom>} text2={<TextCustom bold>Judul Proyek</TextCustom>} />
title1="Aksi"
title2="Username"
title3="Judul Proyek"
/>
{/* <Spacing height={10} /> */} {/* <Spacing height={10} /> */}
<Divider /> <Divider />
@@ -68,32 +67,26 @@ export default function AdminCollaborationPublish() {
) : ( ) : (
list?.map((item: any, index: number) => ( list?.map((item: any, index: number) => (
<View key={index}> <View key={index}>
<AdminTableValue <ClickableCustom
value1={ onPress={() => {
<ActionIcon router.push(`/admin/collaboration/${item?.id}/publish`);
icon={ }}
<Octicons >
name="eye" <GridSpan_NewComponent
size={ICON_SIZE_BUTTON} text1={
color="black" <TextCustom truncate={1}>
/> {item?.Author?.username || "-"}{" "}
} </TextCustom>
onPress={() => { }
router.push(`/admin/collaboration/${item?.id}/publish`); text2={
}} <TextCustom truncate={2}>
/> {item?.title || "-"}
} </TextCustom>
value2={ }
<TextCustom align="center" truncate={1}> />
{item?.Author?.username || "-"}{" "} </ClickableCustom>
</TextCustom> <Spacing height={8}/>
} <Divider/>
value3={
<TextCustom align="center" truncate={2}>
{item?.title || "-"}
</TextCustom>
}
/>
</View> </View>
)) ))
)} )}

View File

@@ -18,7 +18,7 @@ import { IconDot, IconList } from "@/components/_Icon/IconComponent";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject"; import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview"; import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import ReportBox from "@/components/Box/ReportBox"; import ReportBox from "@/components/Box/ReportBox";
import { ICON_SIZE_BUTTON, TEXT_SIZE_LARGE } from "@/constants/constans-value"; import { ICON_SIZE_BUTTON, TEXT_SIZE_LARGE } from "@/constants/constans-value";
import AdminDonation_BoxOfDonationStory from "@/screens/Admin/Donation/BoxOfDonationStory"; import AdminDonation_BoxOfDonationStory from "@/screens/Admin/Donation/BoxOfDonationStory";
@@ -195,7 +195,7 @@ export default function AdminDonationDetail() {
<StackCustom gap={5}> <StackCustom gap={5}>
{listPencarianDana.map((item, i) => ( {listPencarianDana.map((item, i) => (
<GridDetail_4_8 <GridSpan_4_8
key={i} key={i}
label={<TextCustom bold>{item.label}</TextCustom>} label={<TextCustom bold>{item.label}</TextCustom>}
value={<TextCustom>{item.value}</TextCustom>} value={<TextCustom>{item.value}</TextCustom>}
@@ -236,7 +236,7 @@ export default function AdminDonationDetail() {
<Spacing /> <Spacing />
<StackCustom gap={"xs"}> <StackCustom gap={"xs"}>
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Jumlah Donatur</TextCustom>} label={<TextCustom bold>Jumlah Donatur</TextCustom>}
value={ value={
<TextCustom> <TextCustom>
@@ -244,7 +244,7 @@ export default function AdminDonationDetail() {
</TextCustom> </TextCustom>
} }
/> />
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Dana Terkumpul</TextCustom>} label={<TextCustom bold>Dana Terkumpul</TextCustom>}
value={ value={
<TextCustom> <TextCustom>
@@ -261,7 +261,7 @@ export default function AdminDonationDetail() {
<StackCustom> <StackCustom>
<DummyLandscapeImage imageId={data?.imageId || ""} /> <DummyLandscapeImage imageId={data?.imageId || ""} />
{listData.map((item, i) => ( {listData.map((item, i) => (
<GridDetail_4_8 <GridSpan_4_8
key={i} key={i}
label={<TextCustom bold>{item.label}</TextCustom>} label={<TextCustom bold>{item.label}</TextCustom>}
value={<TextCustom>{item.value}</TextCustom>} value={<TextCustom>{item.value}</TextCustom>}

View File

@@ -8,7 +8,7 @@ import {
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import { import {
apiAdminDonationInvoiceDetailById, apiAdminDonationInvoiceDetailById,
apiAdminDonationInvoiceUpdateById, apiAdminDonationInvoiceUpdateById,
@@ -177,7 +177,7 @@ export default function AdminDonasiTransactionDetail() {
<BaseBox> <BaseBox>
<StackCustom> <StackCustom>
{listData.map((item, index) => ( {listData.map((item, index) => (
<GridDetail_4_8 <GridSpan_4_8
key={index} key={index}
label={<TextCustom bold>{item.label}</TextCustom>} label={<TextCustom bold>{item.label}</TextCustom>}
value={<TextCustom>{item.value}</TextCustom>} value={<TextCustom>{item.value}</TextCustom>}

View File

@@ -7,7 +7,7 @@ import {
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import { apiAdminDonationDisbursementOfFundsListById } from "@/service/api-admin/api-admin-donation"; import { apiAdminDonationDisbursementOfFundsListById } from "@/service/api-admin/api-admin-donation";
import { dateTimeView } from "@/utils/dateTimeView"; import { dateTimeView } from "@/utils/dateTimeView";
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay"; import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
@@ -67,7 +67,7 @@ export default function AdminDonationDetailDisbursementOfFunds() {
<BaseBox> <BaseBox>
<StackCustom> <StackCustom>
{listData?.map((item, index) => ( {listData?.map((item, index) => (
<GridDetail_4_8 <GridSpan_4_8
key={index} key={index}
label={<TextCustom bold>{item.label}</TextCustom>} label={<TextCustom bold>{item.label}</TextCustom>}
value={<TextCustom>{item.value}</TextCustom>} value={<TextCustom>{item.value}</TextCustom>}

View File

@@ -1,17 +1,56 @@
import { import {
BoxButtonOnFooter, BoxButtonOnFooter,
ButtonCustom, ButtonCustom,
StackCustom,
TextCustom,
TextInputCustom, TextInputCustom,
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { MainColor } from "@/constants/color-palet";
import { apiAdminMasterDonationCategoryCreate } from "@/service/api-admin/api-master-admin";
import { useRouter } from "expo-router"; import { useRouter } from "expo-router";
import { useState } from "react";
import { Switch } from "react-native-paper";
import Toast from "react-native-toast-message";
export default function AdminDonationCategoryCreate() { export default function AdminDonationCategoryCreate() {
const router = useRouter(); const router = useRouter();
const [loading, setLoading] = useState(false);
const [data, setData] = useState({
name: "",
active: false,
});
const onSubmit = async () => {
try {
setLoading(true);
const response = await apiAdminMasterDonationCategoryCreate({ data });
if (response.success) {
Toast.show({
type: "success",
text2: "Data berhasil disimpan",
});
router.back();
return;
}
Toast.show({
type: "error",
text1: "Gagal menyimpan data",
});
} catch (error) {
console.log("[Error]", error);
} finally {
setLoading(false);
}
};
const buttonSubmit = ( const buttonSubmit = (
<BoxButtonOnFooter> <BoxButtonOnFooter>
<ButtonCustom onPress={() => router.back()}>Simpan</ButtonCustom> <ButtonCustom isLoading={loading} onPress={onSubmit}>
Simpan
</ButtonCustom>
</BoxButtonOnFooter> </BoxButtonOnFooter>
); );
return ( return (
@@ -20,7 +59,23 @@ export default function AdminDonationCategoryCreate() {
headerComponent={<AdminBackButtonAntTitle title="Tambah Kategori" />} headerComponent={<AdminBackButtonAntTitle title="Tambah Kategori" />}
footerComponent={buttonSubmit} footerComponent={buttonSubmit}
> >
<TextInputCustom placeholder="Masukkan Kategori" /> <TextInputCustom
label=""
placeholder="Masukkan Kategori"
value={data.name}
onChangeText={(text) => setData({ ...data, name: text })}
/>
<StackCustom gap={"sm"}>
<TextCustom>Status</TextCustom>
<Switch
style={{
alignSelf: "flex-start",
}}
color={MainColor.yellow}
value={data.active}
onValueChange={(value) => setData({ ...data, active: value })}
/>
</StackCustom>
</ViewWrapper> </ViewWrapper>
</> </>
); );

View File

@@ -1,21 +1,76 @@
import { import {
AlertDefaultSystem,
BoxButtonOnFooter, BoxButtonOnFooter,
ButtonCustom, ButtonCustom,
StackCustom,
TextCustom,
TextInputCustom, TextInputCustom,
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { MainColor } from "@/constants/color-palet";
import {
apiAdminMasterDonationCategoryById,
apiAdminMasterDonationCategoryUpdate,
} from "@/service/api-admin/api-master-admin";
import { useLocalSearchParams, useRouter } from "expo-router"; import { useLocalSearchParams, useRouter } from "expo-router";
import { useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { Switch } from "react-native-paper";
export default function AdminDonationCategoryUpdate() { export default function AdminDonationCategoryUpdate() {
const router = useRouter();
const { id } = useLocalSearchParams(); const { id } = useLocalSearchParams();
const [value, setValue] = useState(id); const [value, setValue] = useState(id);
const router = useRouter(); const [data, setData] = useState<any>(null);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
const response = await apiAdminMasterDonationCategoryById({
id: id as any,
});
console.log(JSON.stringify(response.data, null, 2));
setData(response.data);
};
fetchData();
}, [id]);
const handlerSubmit = async () => {
try {
setIsLoading(true);
const response = await apiAdminMasterDonationCategoryUpdate({
id: id as any,
data: data,
});
console.log(JSON.stringify(response.data, null, 2));
router.back();
} catch (error) {
console.log(error);
} finally {
setIsLoading(false);
}
};
const buttonSubmit = ( const buttonSubmit = (
<BoxButtonOnFooter> <BoxButtonOnFooter>
<ButtonCustom onPress={() => router.back()}>Update</ButtonCustom> <ButtonCustom
disabled={isLoading || data?.name === ""}
isLoading={isLoading}
onPress={() => {
AlertDefaultSystem({
title: "Update Data",
message: "Apakah anda yakin ingin mengupdate data ini?",
textLeft: "Batal",
textRight: "Ya",
onPressLeft: () => {},
onPressRight: () => handlerSubmit(),
});
}}
>
Update
</ButtonCustom>
</BoxButtonOnFooter> </BoxButtonOnFooter>
); );
return ( return (
@@ -25,10 +80,28 @@ export default function AdminDonationCategoryUpdate() {
footerComponent={buttonSubmit} footerComponent={buttonSubmit}
> >
<TextInputCustom <TextInputCustom
label="Nama Kategori"
placeholder="Masukkan Kategori" placeholder="Masukkan Kategori"
value={value as any} value={data?.name}
onChangeText={setValue} onChangeText={(value) => setData({ ...data, name: value })}
/> />
<StackCustom
gap={"sm"}
style={{
alignContent: "flex-start",
}}
>
<TextCustom>Status</TextCustom>
<Switch
style={{
alignSelf: "flex-start",
}}
color={MainColor.yellow}
value={data?.active}
onValueChange={(value) => setData({ ...data, active: value })}
/>
</StackCustom>
</ViewWrapper> </ViewWrapper>
</> </>
); );

View File

@@ -1,27 +1,65 @@
import { import {
ActionIcon, BadgeCustom,
BaseBox, CenterCustom,
CenterCustom, ClickableCustom,
Spacing, Spacing,
StackCustom, StackCustom,
TextCustom, TextCustom,
ViewWrapper, ViewWrapper
} from "@/components"; } from "@/components";
import { IconEdit } from "@/components/_Icon";
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus"; import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
import { GridView_3_3_6 } from "@/components/_ShareComponent/GridView_3_3_6"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import { MainColor } from "@/constants/color-palet"; import { apiAdminMasterDonationCategory } from "@/service/api-admin/api-master-admin";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { colorActivationForBadge } from "@/utils/colorActivationForBadge";
import { View } from "react-native"; import { router, useFocusEffect } from "expo-router";
import { Divider, Switch } from "react-native-paper"; import { useCallback, useState } from "react";
import { router } from "expo-router"; import { RefreshControl, View } from "react-native";
import { Divider } from "react-native-paper";
export default function AdminDonationCategory() { export default function AdminDonationCategory() {
const [listData, setListData] = useState<any[]>([]);
const [refreshing, setRefreshing] = useState(false);
const [loading, setLoading] = useState(false);
useFocusEffect(
useCallback(() => {
fetchMaster();
}, [])
);
const fetchMaster = async () => {
try {
setLoading(true);
const response = await apiAdminMasterDonationCategory();
if (response.success) {
console.log(JSON.stringify(response.data, null, 2));
setListData(response.data);
} else {
setListData([]);
}
} catch (error) {
console.log("[Error]", error);
} finally {
setLoading(false);
}
};
const onRefresh = async () => {
setRefreshing(true);
await fetchMaster();
setRefreshing(false);
};
return ( return (
<> <>
<ViewWrapper headerComponent={<AdminTitlePage title="Donasi" />}> <ViewWrapper
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}
headerComponent={<AdminTitlePage title="Donasi" />}
>
<AdminComp_BoxTitle <AdminComp_BoxTitle
title="Kategori" title="Kategori"
rightComponent={ rightComponent={
@@ -33,81 +71,65 @@ export default function AdminDonationCategory() {
} }
/> />
<BaseBox> <View>
<GridView_3_3_6 <GridSpan_4_8
component1={ label={<TextCustom bold>Status</TextCustom>}
<TextCustom bold align="center"> value={<TextCustom bold>Kategori</TextCustom>}
Aksi
</TextCustom>
}
component2={<TextCustom bold>Status</TextCustom>}
component3={<TextCustom bold>Kategori</TextCustom>}
/> />
{/* <Grid>
<Grid.Col style={{ paddingLeft: 10 }} span={4}>
<TextCustom bold>Status</TextCustom>
</Grid.Col>
<Grid.Col span={8}>
<TextCustom bold>Kategori</TextCustom>
</Grid.Col>
</Grid> */}
<Divider /> <Divider />
<Spacing /> <Spacing />
<StackCustom> <StackCustom>
{listData.map((item, index) => ( {listData.map((item, index) => (
<View key={index}> <ClickableCustom
<GridView_3_3_6 onPress={() => {
component1={ router.push(`/admin/donation/category-update?id=${item.id}`);
}}
key={index}
>
<GridSpan_4_8
label={
<CenterCustom> <CenterCustom>
<ActionIcon <BadgeCustom
icon={ color={colorActivationForBadge({
<IconEdit size={ICON_SIZE_BUTTON} color="black" /> status: item.active,
} })}
onPress={() => { >
router.push(`/admin/donation/category-update?id=${index}`); {item.active ? "Aktif" : "Tidak Aktif"}
}} </BadgeCustom>
/>
</CenterCustom> </CenterCustom>
} }
component2={ value={<TextCustom>{item.name}</TextCustom>}
<Switch
value={true}
onValueChange={(item) => {
console.log(item);
}}
color={MainColor.yellow}
/>
}
component3={<TextCustom bold>{item.label}</TextCustom>}
/> />
<Spacing height={10} /> {/* <Grid containerStyle={{ paddingBottom: 10 }}>
<Grid.Col span={4} style={{ paddingLeft: 10 }}>
<CenterCustom>
<BadgeCustom
color={item.active ? MainColor.green : MainColor.red}
>
{item.active ? "Aktif" : "Tidak Aktif"}
</BadgeCustom>
</CenterCustom>
</Grid.Col>
<Grid.Col span={8}>
<TextCustom bold>{item.name}</TextCustom>
</Grid.Col>
</Grid> */}
<Divider /> <Divider />
</View> </ClickableCustom>
))} ))}
</StackCustom> </StackCustom>
</BaseBox> </View>
</ViewWrapper> </ViewWrapper>
</> </>
); );
} }
const listData = [
{
label: "Kegiatan Sosial",
value: "kegiatan_sosial",
},
{
label: "Pendidikan",
value: "pendidikan",
},
{
label: "Kesehatan",
value: "kesehatan",
},
{
label: "Kebudayaan",
value: "kebudayaan",
},
{
label: "Bencana Alami",
value: "bencana_alami",
},
{
label: "Lainnya",
value: "lainnya",
},
];

View File

@@ -1,22 +1,22 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
import { import {
ActionIcon, ActionIcon,
AlertDefaultSystem, AlertDefaultSystem,
BadgeCustom, BadgeCustom,
BaseBox, BaseBox,
DrawerCustom, DrawerCustom,
LoaderCustom, LoaderCustom,
MenuDrawerDynamicGrid, MenuDrawerDynamicGrid,
Spacing, Spacing,
StackCustom, StackCustom,
TextCustom, TextCustom,
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import { IconDot, IconList } from "@/components/_Icon/IconComponent"; import { IconDot, IconList } from "@/components/_Icon/IconComponent";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject"; import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview"; import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import ReportBox from "@/components/Box/ReportBox"; import ReportBox from "@/components/Box/ReportBox";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { useAuth } from "@/hooks/use-auth"; import { useAuth } from "@/hooks/use-auth";
@@ -39,6 +39,11 @@ export default function AdminEventDetail() {
const [data, setData] = React.useState<any | null>(null); const [data, setData] = React.useState<any | null>(null);
const [loadData, setLoadData] = React.useState(false); const [loadData, setLoadData] = React.useState(false);
const deepLinkURL = `${DEEP_LINK_URL}/event/${id}/confirmation?userId=${user?.id}`; const deepLinkURL = `${DEEP_LINK_URL}/event/${id}/confirmation?userId=${user?.id}`;
const deepLinkURLDEV = `${DEEP_LINK_URL}/--/event/${id}/confirmation?userId=${user?.id}`;
const isDevLink = process.env.NODE_ENV === "development" ? deepLinkURLDEV : deepLinkURL;
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
onLoadData(); onLoadData();
@@ -156,7 +161,7 @@ export default function AdminEventDetail() {
<BaseBox> <BaseBox>
<StackCustom> <StackCustom>
{listData.map((item, i) => ( {listData.map((item, i) => (
<GridDetail_4_8 <GridSpan_4_8
key={i} key={i}
label={<TextCustom bold>{item.label}</TextCustom>} label={<TextCustom bold>{item.label}</TextCustom>}
value={<TextCustom>{item.value}</TextCustom>} value={<TextCustom>{item.value}</TextCustom>}
@@ -181,7 +186,7 @@ export default function AdminEventDetail() {
<LoaderCustom /> <LoaderCustom />
) : ( ) : (
<QRCode <QRCode
value={deepLinkURL} value={isDevLink}
size={200} size={200}
// logo={require("@/assets/images/logo-hipmi.png")} // logo={require("@/assets/images/logo-hipmi.png")}
// logoSize={70} // logoSize={70}
@@ -191,7 +196,7 @@ export default function AdminEventDetail() {
/> />
)} )}
<TextCustom align="center">{deepLinkURL}</TextCustom> <TextCustom align="center">{isDevLink}</TextCustom>
</StackCustom> </StackCustom>
</BaseBox> </BaseBox>
)} )}

View File

@@ -10,14 +10,17 @@ import {
} from "@/components"; } from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { apiAdminEventListOfParticipants } from "@/service/api-admin/api-admin-event"; import { apiAdminEventListOfParticipants } from "@/service/api-admin/api-admin-event";
import dayjs, { Dayjs } from "dayjs";
import { useFocusEffect, useLocalSearchParams } from "expo-router"; import { useFocusEffect, useLocalSearchParams } from "expo-router";
import _ from "lodash"; import _ from "lodash";
import { View } from "moti";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
export default function AdminEventListOfParticipants() { export default function AdminEventListOfParticipants() {
const { id } = useLocalSearchParams(); const { id } = useLocalSearchParams();
const [listData, setListData] = useState<any[] | null>(null); const [listData, setListData] = useState<any[] | null>(null);
const [loadData, setLoadData] = useState(false); const [loadData, setLoadData] = useState(false);
const [startDate, setStartDate] = useState<Dayjs | undefined>();
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
@@ -32,8 +35,11 @@ export default function AdminEventListOfParticipants() {
id: id as string, id: id as string,
}); });
console.log("[DATA]", JSON.stringify(response, null, 2));
if (response.success) { if (response.success) {
setListData(response.data); setListData(response.data);
setStartDate(dayjs(response.data.Event.tanggal));
} }
} catch (error) { } catch (error) {
console.log("[ERROR]", error); console.log("[ERROR]", error);
@@ -42,7 +48,6 @@ export default function AdminEventListOfParticipants() {
} }
}; };
return ( return (
<> <>
<ViewWrapper <ViewWrapper
@@ -60,17 +65,35 @@ export default function AdminEventListOfParticipants() {
<Grid> <Grid>
<Grid.Col span={6}> <Grid.Col span={6}>
<StackCustom gap={"sm"}> <StackCustom gap={"sm"}>
<TextCustom bold truncate>{item?.User?.username}</TextCustom> <TextCustom bold truncate>
{item?.User?.username}
</TextCustom>
<TextCustom>+{item?.User?.nomor}</TextCustom> <TextCustom>+{item?.User?.nomor}</TextCustom>
</StackCustom> </StackCustom>
</Grid.Col> </Grid.Col>
<Grid.Col span={6} style={{ justifyContent: "center" }}> <Grid.Col span={6} style={{ justifyContent: "center" }}>
<BadgeCustom {startDate &&
style={{ alignSelf: "flex-end" }} startDate.subtract(1, "hour").diff(dayjs()) < 0 ? (
color={item?.isPresent ? "green" : "red"} <BadgeCustom
> style={{ alignSelf: "flex-end" }}
{item?.isPresent ? "Hadir" : "Tidak Hadir"} color={item?.isPresent ? "green" : "red"}
</BadgeCustom> >
{item?.isPresent ? "Hadir" : "Tidak Hadir"}
</BadgeCustom>
) : (
<View
style={{
justifyContent: "flex-end",
}}
>
<BadgeCustom
style={{ alignSelf: "flex-end" }}
color="gray"
>
-
</BadgeCustom>
</View>
)}
</Grid.Col> </Grid.Col>
</Grid> </Grid>
</BaseBox> </BaseBox>

View File

@@ -1,11 +1,12 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
import { import {
ActionIcon, ActionIcon,
ClickableCustom,
LoaderCustom, LoaderCustom,
SearchInput, SearchInput,
StackCustom, StackCustom,
TextCustom, TextCustom,
ViewWrapper ViewWrapper,
} from "@/components"; } from "@/components";
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle"; import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
@@ -13,6 +14,7 @@ import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { apiAdminEvent } from "@/service/api-admin/api-admin-event"; import { apiAdminEvent } from "@/service/api-admin/api-admin-event";
import { dateTimeView } from "@/utils/dateTimeView";
import { Octicons } from "@expo/vector-icons"; import { Octicons } from "@expo/vector-icons";
import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
import _ from "lodash"; import _ from "lodash";
@@ -74,8 +76,8 @@ export default function AdminEventStatus() {
<StackCustom gap={"sm"}> <StackCustom gap={"sm"}>
<AdminTitleTable <AdminTitleTable
title1="Aksi" title1="Username"
title2="Username" title2="Tanggal"
title3="Judul Event" title3="Judul Event"
/> />
<Divider /> <Divider />
@@ -83,36 +85,47 @@ export default function AdminEventStatus() {
{loadData ? ( {loadData ? (
<LoaderCustom /> <LoaderCustom />
) : _.isEmpty(listData) ? ( ) : _.isEmpty(listData) ? (
<TextCustom align="center" size="small" color="gray">Belum ada data</TextCustom> <TextCustom align="center" size="small" color="gray">
Belum ada data
</TextCustom>
) : ( ) : (
listData?.map((item, index) => ( listData?.map((item, index) => (
<AdminTableValue <ClickableCustom
key={index} key={index}
value1={ onPress={() => {
<ActionIcon router.push(`/admin/event/${item.id}/${status}`);
icon={ }}
<Octicons >
name="eye" <AdminTableValue
size={ICON_SIZE_BUTTON} key={index}
color="black" value1={
/> <TextCustom truncate={1}>
} {item?.Author?.username || "-"}
onPress={() => { </TextCustom>
router.push(`/admin/event/${item.id}/${status}`); // <ActionIcon
}} // icon={
/> // <Octicons
} // name="eye"
value2={ // size={ICON_SIZE_BUTTON}
<TextCustom truncate={1}> // color="black"
{item?.Author?.username || "-"} // />
</TextCustom> // }
} // onPress={() => {
value3={ // router.push(`/admin/event/${item.id}/${status}`);
<TextCustom align="center" truncate={2}> // }}
{item?.title || "-"} // />
</TextCustom> }
} value2={
/> <TextCustom truncate={1}>
{dateTimeView({ date: item?.tanggal })}
</TextCustom>
}
value3={
<TextCustom truncate={2}>{item?.title || "-"}</TextCustom>
}
/>
<Divider/>
</ClickableCustom>
)) ))
)} )}
</StackCustom> </StackCustom>

View File

@@ -11,7 +11,7 @@ import {
} from "@/components"; } from "@/components";
import { IconDot } from "@/components/_Icon/IconComponent"; import { IconDot } from "@/components/_Icon/IconComponent";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_XLARGE } from "@/constants/constans-value"; import { ICON_SIZE_XLARGE } from "@/constants/constans-value";
import { apiAdminForumPostingById } from "@/service/api-admin/api-admin-forum"; import { apiAdminForumPostingById } from "@/service/api-admin/api-admin-forum";
@@ -103,7 +103,7 @@ export default function AdminForumDetailPosting() {
<BaseBox> <BaseBox>
<StackCustom gap={"sm"}> <StackCustom gap={"sm"}>
{listDataAction.map((item, i) => ( {listDataAction.map((item, i) => (
<GridDetail_4_8 <GridSpan_4_8
key={i} key={i}
label={<TextCustom bold>{item.label}</TextCustom>} label={<TextCustom bold>{item.label}</TextCustom>}
value={<TextCustom>{item.value}</TextCustom>} value={<TextCustom>{item.value}</TextCustom>}

View File

@@ -3,6 +3,7 @@ import {
ActionIcon, ActionIcon,
AlertDefaultSystem, AlertDefaultSystem,
BaseBox, BaseBox,
CenterCustom,
DrawerCustom, DrawerCustom,
LoaderCustom, LoaderCustom,
MenuDrawerDynamicGrid, MenuDrawerDynamicGrid,
@@ -16,7 +17,8 @@ import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButt
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle"; import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue"; import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import { GridSpan_NewComponent } from "@/components/_ShareComponent/GridSpan_NewComponent";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { import {
@@ -27,6 +29,7 @@ import {
import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
import _ from "lodash"; import _ from "lodash";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { View } from "react-native";
import { Divider } from "react-native-paper"; import { Divider } from "react-native-paper";
import Toast from "react-native-toast-message"; import Toast from "react-native-toast-message";
@@ -95,24 +98,24 @@ export default function AdminForumReportComment() {
> >
<BaseBox> <BaseBox>
<StackCustom gap={"sm"}> <StackCustom gap={"sm"}>
<GridDetail_4_8 <GridSpan_NewComponent
label={<TextCustom bold>Username</TextCustom>} text1={<TextCustom bold>Username</TextCustom>}
value={<TextCustom>{data?.Author?.username || "-"}</TextCustom>} text2={<TextCustom>{data?.Author?.username || "-"}</TextCustom>}
/> />
<GridDetail_4_8 <GridSpan_NewComponent
label={<TextCustom bold>Komentar</TextCustom>} text1={<TextCustom bold>Komentar</TextCustom>}
value={<TextCustom>{data?.komentar || "-"}</TextCustom>} text2={<TextCustom>{data?.komentar || "-"}</TextCustom>}
/> />
</StackCustom> </StackCustom>
</BaseBox> </BaseBox>
<AdminComp_BoxTitle title="Daftar Report Komentar" /> <AdminComp_BoxTitle title="Daftar Report Komentar" />
<StackCustom> <StackCustom gap={"sm"}>
<AdminTitleTable <GridSpan_NewComponent
title1="Aksi" text1={<TextCustom bold align="center">Aksi</TextCustom>}
title2="Pelapor" text2={<TextCustom bold>Pelapor</TextCustom>}
title3="Kategori Report" text3={<TextCustom bold>Kategori Report</TextCustom>}
/> />
<Divider /> <Divider />
{loadList ? ( {loadList ? (
@@ -123,34 +126,39 @@ export default function AdminForumReportComment() {
</TextCustom> </TextCustom>
) : ( ) : (
listReport?.map((item: any, index: number) => ( listReport?.map((item: any, index: number) => (
<AdminTableValue <View key={index}>
key={index} <GridSpan_NewComponent
value1={ text1={
<ActionIcon <CenterCustom>
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />} <ActionIcon
onPress={() => { icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
setOpenDrawerAction(true); onPress={() => {
setSelectedReport({ setOpenDrawerAction(true);
id: item.id, setSelectedReport({
username: item.User?.username, id: item.id,
kategori: item.ForumMaster_KategoriReport?.title, username: item.User?.username,
keterangan: item.ForumMaster_KategoriReport?.deskripsi, kategori: item.ForumMaster_KategoriReport?.title,
deskripsi: item.deskripsi, keterangan:
}); item.ForumMaster_KategoriReport?.deskripsi,
}} deskripsi: item.deskripsi,
/> });
} }}
value2={ />
<TextCustom truncate={1}> </CenterCustom>
{item?.User?.username || "-"} }
</TextCustom> text2={
} <TextCustom truncate={1}>
value3={ {item?.User?.username || "-"}
<TextCustom truncate={2} align="center"> </TextCustom>
{item?.ForumMaster_KategoriReport?.title || "-"} }
</TextCustom> text3={
} <TextCustom truncate={2}>
/> {item?.ForumMaster_KategoriReport?.title || "-"}
</TextCustom>
}
/>
<Divider />
</View>
)) ))
)} )}
</StackCustom> </StackCustom>
@@ -208,20 +216,20 @@ export default function AdminForumReportComment() {
height={"auto"} height={"auto"}
> >
<StackCustom> <StackCustom>
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Pelapor</TextCustom>} label={<TextCustom bold>Pelapor</TextCustom>}
value={<TextCustom>{selectedReport?.username || "-"}</TextCustom>} value={<TextCustom>{selectedReport?.username || "-"}</TextCustom>}
/> />
{selectedReport?.kategori && ( {selectedReport?.kategori && (
<> <>
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Kategori Report</TextCustom>} label={<TextCustom bold>Kategori Report</TextCustom>}
value={ value={
<TextCustom>{selectedReport?.kategori || "-"}</TextCustom> <TextCustom>{selectedReport?.kategori || "-"}</TextCustom>
} }
/> />
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Keterangan</TextCustom>} label={<TextCustom bold>Keterangan</TextCustom>}
value={ value={
<TextCustom>{selectedReport?.keterangan || "-"}</TextCustom> <TextCustom>{selectedReport?.keterangan || "-"}</TextCustom>
@@ -231,7 +239,7 @@ export default function AdminForumReportComment() {
)} )}
{selectedReport?.deskripsi && ( {selectedReport?.deskripsi && (
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Deskripsi</TextCustom>} label={<TextCustom bold>Deskripsi</TextCustom>}
value={ value={
<TextCustom>{selectedReport?.deskripsi || "-"}</TextCustom> <TextCustom>{selectedReport?.deskripsi || "-"}</TextCustom>

View File

@@ -4,6 +4,7 @@ import {
AlertDefaultSystem, AlertDefaultSystem,
BadgeCustom, BadgeCustom,
BaseBox, BaseBox,
CenterCustom,
DrawerCustom, DrawerCustom,
LoaderCustom, LoaderCustom,
MenuDrawerDynamicGrid, MenuDrawerDynamicGrid,
@@ -17,7 +18,8 @@ import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButt
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle"; import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue"; import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import { GridSpan_NewComponent } from "@/components/_ShareComponent/GridSpan_NewComponent";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { import {
@@ -28,6 +30,7 @@ import {
import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
import _ from "lodash"; import _ from "lodash";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { View } from "react-native";
import { Divider } from "react-native-paper"; import { Divider } from "react-native-paper";
import Toast from "react-native-toast-message"; import Toast from "react-native-toast-message";
@@ -95,14 +98,14 @@ export default function AdminForumReportPosting() {
> >
<BaseBox> <BaseBox>
<StackCustom gap={"sm"}> <StackCustom gap={"sm"}>
<GridDetail_4_8 <GridSpan_NewComponent
label={<TextCustom bold>Username</TextCustom>} text1={<TextCustom bold>Username</TextCustom>}
value={<TextCustom>{data?.Author?.username || "-"}</TextCustom>} text2={<TextCustom>{data?.Author?.username || "-"}</TextCustom>}
/> />
<GridDetail_4_8 <GridSpan_NewComponent
label={<TextCustom bold>Status</TextCustom>} text1={<TextCustom bold>Status</TextCustom>}
value={ text2={
data && data?.ForumMaster_StatusPosting?.status ? ( data && data?.ForumMaster_StatusPosting?.status ? (
<BadgeCustom <BadgeCustom
color={ color={
@@ -121,19 +124,23 @@ export default function AdminForumReportPosting() {
} }
/> />
<GridDetail_4_8 <GridSpan_NewComponent
label={<TextCustom bold>Postingan</TextCustom>} text1={<TextCustom bold>Postingan</TextCustom>}
value={<TextCustom>{data?.diskusi || "-"}</TextCustom>} text2={<TextCustom>{data?.diskusi || "-"}</TextCustom>}
/> />
</StackCustom> </StackCustom>
</BaseBox> </BaseBox>
<AdminComp_BoxTitle title="Daftar Report Posting" /> <AdminComp_BoxTitle title="Daftar Report Posting" />
<StackCustom gap={"sm"}> <StackCustom gap={"sm"}>
<AdminTitleTable <GridSpan_NewComponent
title1="Aksi" text1={
title2="Pelapor" <TextCustom bold align="center">
title3="Kategori Report" Aksi
</TextCustom>
}
text2={<TextCustom bold>Pelapor</TextCustom>}
text3={<TextCustom bold>Kategori Report</TextCustom>}
/> />
<Divider /> <Divider />
{loadListReport ? ( {loadListReport ? (
@@ -144,34 +151,41 @@ export default function AdminForumReportPosting() {
</TextCustom> </TextCustom>
) : ( ) : (
listReport?.map((item: any, index: number) => ( listReport?.map((item: any, index: number) => (
<AdminTableValue <View key={index}>
key={index} <GridSpan_NewComponent
value1={ text1={
<ActionIcon <CenterCustom>
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />} <ActionIcon
onPress={() => { icon={
setOpenDrawerAction(true); <IconView size={ICON_SIZE_BUTTON} color="black" />
setSelectedReport({ }
id: item?.id, onPress={() => {
username: item?.User?.username, setOpenDrawerAction(true);
kategori: item?.ForumMaster_KategoriReport?.title, setSelectedReport({
keterangan: item?.ForumMaster_KategoriReport?.deskripsi, id: item?.id,
deskripsi: item?.deskripsi, username: item?.User?.username,
}); kategori: item?.ForumMaster_KategoriReport?.title,
}} keterangan:
/> item?.ForumMaster_KategoriReport?.deskripsi,
} deskripsi: item?.deskripsi,
value2={ });
<TextCustom truncate={1}> }}
{item?.User?.username || "-"} />
</TextCustom> </CenterCustom>
} }
value3={ text2={
<TextCustom truncate={2} align="center"> <TextCustom truncate>
{item?.ForumMaster_KategoriReport?.title || "-"} {item?.User?.username || "-"}
</TextCustom> </TextCustom>
} }
/> text3={
<TextCustom truncate={2}>
{item?.ForumMaster_KategoriReport?.title || "-"}
</TextCustom>
}
/>
<Divider />
</View>
)) ))
)} )}
</StackCustom> </StackCustom>
@@ -229,20 +243,20 @@ export default function AdminForumReportPosting() {
height={"auto"} height={"auto"}
> >
<StackCustom> <StackCustom>
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Pelapor</TextCustom>} label={<TextCustom bold>Pelapor</TextCustom>}
value={<TextCustom>{selectedReport?.username || "-"}</TextCustom>} value={<TextCustom>{selectedReport?.username || "-"}</TextCustom>}
/> />
{selectedReport?.kategori && ( {selectedReport?.kategori && (
<> <>
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Kategori Report</TextCustom>} label={<TextCustom bold>Kategori Report</TextCustom>}
value={ value={
<TextCustom>{selectedReport?.kategori || "-"}</TextCustom> <TextCustom>{selectedReport?.kategori || "-"}</TextCustom>
} }
/> />
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Keterangan</TextCustom>} label={<TextCustom bold>Keterangan</TextCustom>}
value={ value={
<TextCustom>{selectedReport?.keterangan || "-"}</TextCustom> <TextCustom>{selectedReport?.keterangan || "-"}</TextCustom>
@@ -252,7 +266,7 @@ export default function AdminForumReportPosting() {
)} )}
{selectedReport?.deskripsi && ( {selectedReport?.deskripsi && (
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Deskripsi</TextCustom>} label={<TextCustom bold>Deskripsi</TextCustom>}
value={ value={
<TextCustom>{selectedReport?.deskripsi || "-"}</TextCustom> <TextCustom>{selectedReport?.deskripsi || "-"}</TextCustom>

View File

@@ -1,22 +1,22 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
import { import {
ActionIcon, ClickableCustom,
LoaderCustom, LoaderCustom,
SearchInput, SearchInput,
Spacing,
StackCustom, StackCustom,
TextCustom, TextCustom,
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import { IconView } from "@/components/_Icon/IconComponent";
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import { GridSpan_NewComponent } from "@/components/_ShareComponent/GridSpan_NewComponent";
import { apiAdminForum } from "@/service/api-admin/api-admin-forum"; import { apiAdminForum } from "@/service/api-admin/api-admin-forum";
import { router, useFocusEffect } from "expo-router"; import { router, useFocusEffect } from "expo-router";
import _ from "lodash"; import _ from "lodash";
import React, { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { View } from "react-native";
import { Divider } from "react-native-paper"; import { Divider } from "react-native-paper";
export default function AdminForumPosting() { export default function AdminForumPosting() {
@@ -37,7 +37,9 @@ export default function AdminForumPosting() {
category: "posting", category: "posting",
search: search, search: search,
}); });
console.log("DATA", JSON.stringify(response, null, 2));
if (response.success) { if (response.success) {
setList(response.data); setList(response.data);
} }
@@ -51,7 +53,7 @@ export default function AdminForumPosting() {
const rightComponent = ( const rightComponent = (
<SearchInput <SearchInput
containerStyle={{ width: "100%", marginBottom: 0 }} containerStyle={{ width: "100%", marginBottom: 0 }}
placeholder="Cari" placeholder="Cari postingan"
value={search} value={search}
onChangeText={setSearch} onChangeText={setSearch}
/> />
@@ -61,9 +63,15 @@ export default function AdminForumPosting() {
<> <>
<ViewWrapper headerComponent={<AdminTitlePage title="Forum" />}> <ViewWrapper headerComponent={<AdminTitlePage title="Forum" />}>
<AdminComp_BoxTitle title={"Posting"} rightComponent={rightComponent} /> <AdminComp_BoxTitle title={"Posting"} rightComponent={rightComponent} />
<GridSpan_NewComponent
text1={<TextCustom bold truncate>Username</TextCustom>}
text2={<TextCustom bold truncate> Postingan</TextCustom>}
text3={<TextCustom bold align="center" truncate> Report Posting</TextCustom>}
text4={<TextCustom bold align="center" truncate> Komentar</TextCustom>}
/>
<Divider />
<Spacing />
<StackCustom> <StackCustom>
<AdminTitleTable title1="Aksi" title2="Username" title3="Postingan" />
<Divider />
{loadList ? ( {loadList ? (
<LoaderCustom /> <LoaderCustom />
) : _.isEmpty(list) ? ( ) : _.isEmpty(list) ? (
@@ -72,25 +80,38 @@ export default function AdminForumPosting() {
</TextCustom> </TextCustom>
) : ( ) : (
list?.map((item: any, index: number) => ( list?.map((item: any, index: number) => (
<AdminTableValue <View key={index}>
key={index} <ClickableCustom
value1={ onPress={() => {
<ActionIcon router.push(`/admin/forum/${item.id}`);
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />} }}
onPress={() => { >
router.push(`/admin/forum/${item?.id}`); <GridSpan_NewComponent
}} text1={
<TextCustom truncate={1}>
{item?.Author?.username || "-"}
</TextCustom>
}
text2={
<TextCustom truncate>
{item?.diskusi || "-"}
</TextCustom>
}
text3={
<TextCustom align="center" truncate={2}>
{item?.reportPosting || "-"}
</TextCustom>
}
text4={
<TextCustom align="center" truncate={2}>
{item?.komentar || "-"}
</TextCustom>
}
/> />
}
value2={ </ClickableCustom>
<TextCustom truncate={1}> <Divider />
{item?.Author?.username || "-"} </View>
</TextCustom>
}
value3={
<TextCustom truncate={2}>{item?.diskusi || "-"}</TextCustom>
}
/>
)) ))
)} )}
</StackCustom> </StackCustom>

View File

@@ -1,8 +1,10 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
import { import {
ActionIcon, ActionIcon,
ClickableCustom,
LoaderCustom, LoaderCustom,
SearchInput, SearchInput,
Spacing,
StackCustom, StackCustom,
TextCustom, TextCustom,
ViewWrapper, ViewWrapper,
@@ -12,12 +14,14 @@ import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle"; import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue"; import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
import { GridSpan_NewComponent } from "@/components/_ShareComponent/GridSpan_NewComponent";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { apiAdminForum } from "@/service/api-admin/api-admin-forum"; import { apiAdminForum } from "@/service/api-admin/api-admin-forum";
import { router, useFocusEffect } from "expo-router"; import { router, useFocusEffect } from "expo-router";
import _ from "lodash"; import _ from "lodash";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { View } from "react-native";
import { Divider } from "react-native-paper"; import { Divider } from "react-native-paper";
export default function AdminForumReportComment() { export default function AdminForumReportComment() {
@@ -67,13 +71,26 @@ export default function AdminForumReportComment() {
rightComponent={rightComponent} rightComponent={rightComponent}
/> />
<StackCustom gap={"sm"}> <GridSpan_NewComponent
<AdminTitleTable text1={
title1="Aksi" <TextCustom bold truncate>
title2="Pelapor" Pelapor
title3="Jenis Laporan" </TextCustom>
/> }
<Divider /> text2={
<TextCustom bold truncate>
Komentar
</TextCustom>
}
text3={
<TextCustom bold truncate>
Jenis Laporan
</TextCustom>
}
/>
<Divider />
<Spacing />
<StackCustom gap={"lg"}>
{loadList ? ( {loadList ? (
<LoaderCustom /> <LoaderCustom />
) : _.isEmpty(listData) ? ( ) : _.isEmpty(listData) ? (
@@ -82,34 +99,35 @@ export default function AdminForumReportComment() {
</TextCustom> </TextCustom>
) : ( ) : (
listData?.map((item: any, index: number) => ( listData?.map((item: any, index: number) => (
<AdminTableValue <View key={index}>
key={index} <ClickableCustom
value1={ onPress={() => {
<ActionIcon router.push(
icon={ `/admin/forum/${item?.Forum_Komentar?.id}/list-report-comment`
<IconView );
size={ICON_SIZE_BUTTON} }}
color={MainColor.black} >
/> <GridSpan_NewComponent
text1={
<TextCustom truncate={1}>
{item?.User?.username || "-"}
</TextCustom>
}
text2={
<TextCustom truncate={2}>
{item?.Forum_Komentar?.komentar || "-"}
</TextCustom>
}
text3={
<TextCustom truncate={2}>
{item?.ForumMaster_KategoriReport?.title || "-"}
</TextCustom>
} }
onPress={() => {
router.push(
`/admin/forum/${item?.Forum_Komentar?.id}/list-report-comment`
);
}}
/> />
} </ClickableCustom>
value2={ <Spacing />
<TextCustom truncate={1}> <Divider />
{item?.User?.username || "-"} </View>
</TextCustom>
}
value3={
<TextCustom truncate={2} align="center">
{item?.ForumMaster_KategoriReport?.title || "-"}
</TextCustom>
}
/>
)) ))
)} )}
</StackCustom> </StackCustom>

View File

@@ -1,24 +1,27 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
import { import {
ActionIcon, ActionIcon,
ClickableCustom,
Divider, Divider,
LoaderCustom, LoaderCustom,
SearchInput, SearchInput,
StackCustom, StackCustom,
TextCustom, TextCustom,
ViewWrapper ViewWrapper,
} from "@/components"; } from "@/components";
import { IconView } from "@/components/_Icon/IconComponent"; import { IconView } from "@/components/_Icon/IconComponent";
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle"; import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue"; import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
import { GridSpan_NewComponent } from "@/components/_ShareComponent/GridSpan_NewComponent";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { apiAdminForum } from "@/service/api-admin/api-admin-forum"; import { apiAdminForum } from "@/service/api-admin/api-admin-forum";
import { router, useFocusEffect } from "expo-router"; import { router, useFocusEffect } from "expo-router";
import _ from "lodash"; import _ from "lodash";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { View } from "react-native";
export default function AdminForumReportPosting() { export default function AdminForumReportPosting() {
const [listData, setListData] = useState<any[] | null>(null); const [listData, setListData] = useState<any[] | null>(null);
@@ -67,46 +70,51 @@ export default function AdminForumReportPosting() {
rightComponent={rightComponent} rightComponent={rightComponent}
/> />
<StackCustom gap={"sm"}> <GridSpan_NewComponent
<AdminTitleTable title1="Aksi" title2="Pelapor" title3="Postingan" /> text1={
<TextCustom bold truncate>
<Divider /> Username
</TextCustom>
}
text2={
<TextCustom bold truncate>
Postingan
</TextCustom>
}
/>
<Divider />
<StackCustom>
{loadList ? ( {loadList ? (
<LoaderCustom /> <LoaderCustom />
) : _.isEmpty(listData) ? ( ) : _.isEmpty(listData) ? (
<TextCustom align="center" color="gray"> <TextCustom align="center" color="gray">
Belum ada data Belum ada data
</TextCustom> </TextCustom>
) : ( ) : (
listData?.map((item: any, index: number) => ( listData?.map((item: any, index: number) => (
<AdminTableValue <View key={index}>
key={index} <ClickableCustom
value1={ onPress={() => {
<ActionIcon router.push(
icon={ `/admin/forum/${item?.Forum_Posting?.id}/list-report-posting`
<IconView );
size={ICON_SIZE_BUTTON} }}
color={MainColor.black} >
/> <GridSpan_NewComponent
text1={
<TextCustom truncate={1}>
{item?.User?.username || "-"}
</TextCustom>
}
text2={
<TextCustom truncate={1}>
{item?.Forum_Posting?.diskusi || "-"}
</TextCustom>
} }
onPress={() => {
router.push(
`/admin/forum/${item?.Forum_Posting?.id}/list-report-posting`
);
}}
/> />
} </ClickableCustom>
value2={ <Divider />
<TextCustom truncate={1}> </View>
{item?.User?.username || "-"}
</TextCustom>
}
value3={
<TextCustom truncate={2} align="center">
{item?.Forum_Posting?.diskusi || "-"}
</TextCustom>
}
/>
)) ))
)} )}
</StackCustom> </StackCustom>

View File

@@ -19,7 +19,7 @@ import { IconDot, IconList } from "@/components/_Icon/IconComponent";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject"; import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview"; import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import ReportBox from "@/components/Box/ReportBox"; import ReportBox from "@/components/Box/ReportBox";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
@@ -183,7 +183,7 @@ export default function AdminInvestmentDetail() {
/> />
<Spacing /> <Spacing />
<StackCustom gap={"xs"}> <StackCustom gap={"xs"}>
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Sisa Saham</TextCustom>} label={<TextCustom bold>Sisa Saham</TextCustom>}
value={ value={
<TextCustom> <TextCustom>
@@ -191,7 +191,7 @@ export default function AdminInvestmentDetail() {
</TextCustom> </TextCustom>
} }
/> />
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>Validasi Transaksi</TextCustom>} label={<TextCustom bold>Validasi Transaksi</TextCustom>}
value={ value={
<TextCustom> <TextCustom>
@@ -207,7 +207,7 @@ export default function AdminInvestmentDetail() {
<StackCustom> <StackCustom>
<DummyLandscapeImage imageId={data?.imageId} /> <DummyLandscapeImage imageId={data?.imageId} />
{listData.map((item, i) => ( {listData.map((item, i) => (
<GridDetail_4_8 <GridSpan_4_8
key={i} key={i}
label={<TextCustom bold>{item.label}</TextCustom>} label={<TextCustom bold>{item.label}</TextCustom>}
value={<TextCustom>{item.value}</TextCustom>} value={<TextCustom>{item.value}</TextCustom>}
@@ -218,7 +218,7 @@ export default function AdminInvestmentDetail() {
<BaseBox> <BaseBox>
<StackCustom> <StackCustom>
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>File Prospektus</TextCustom>} label={<TextCustom bold>File Prospektus</TextCustom>}
value={ value={
<ButtonCustom <ButtonCustom
@@ -238,7 +238,7 @@ export default function AdminInvestmentDetail() {
</ButtonCustom> </ButtonCustom>
} }
/> />
<GridDetail_4_8 <GridSpan_4_8
label={<TextCustom bold>File Dokumen</TextCustom>} label={<TextCustom bold>File Dokumen</TextCustom>}
value={ value={
<StackCustom> <StackCustom>

View File

@@ -10,7 +10,7 @@ import {
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import GridTwoView from "@/components/_ShareComponent/GridTwoView"; import GridTwoView from "@/components/_ShareComponent/GridTwoView";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { import {
@@ -225,7 +225,7 @@ export default function AdminInvestmentTransactionDetail() {
<BaseBox> <BaseBox>
<StackCustom> <StackCustom>
{listData.map((item, index) => ( {listData.map((item, index) => (
<GridDetail_4_8 <GridSpan_4_8
key={index} key={index}
label={<TextCustom bold>{item.label}</TextCustom>} label={<TextCustom bold>{item.label}</TextCustom>}
value={<TextCustom>{item.value}</TextCustom>} value={<TextCustom>{item.value}</TextCustom>}

View File

@@ -76,7 +76,7 @@ export default function SuperAdmin_ListUser() {
</TextCustom> </TextCustom>
} }
component2={ component2={
<TextCustom align="center" bold> <TextCustom bold>
Username Username
</TextCustom> </TextCustom>
} }

View File

@@ -73,11 +73,7 @@ export default function AdminUserAccess() {
Aksi Aksi
</TextCustom> </TextCustom>
} }
component2={ component2={<TextCustom bold>Username</TextCustom>}
<TextCustom align="center" bold>
Username
</TextCustom>
}
component3={ component3={
<TextCustom align="center" bold> <TextCustom align="center" bold>
Status Akses Status Akses

View File

@@ -1,19 +1,19 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
import { import {
AlertDefaultSystem, AlertDefaultSystem,
BadgeCustom, BadgeCustom,
BaseBox, BaseBox,
CircleContainer, CircleContainer,
Grid, Grid,
Spacing, Spacing,
StackCustom, StackCustom,
TextCustom, TextCustom,
ViewWrapper, ViewWrapper,
} from "@/components"; } from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject"; import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview"; import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
import ReportBox from "@/components/Box/ReportBox"; import ReportBox from "@/components/Box/ReportBox";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import funUpdateStatusVoting from "@/screens/Admin/Voting/funUpdateStatus"; import funUpdateStatusVoting from "@/screens/Admin/Voting/funUpdateStatus";
@@ -169,7 +169,7 @@ export default function AdminVotingDetail() {
<BaseBox> <BaseBox>
<StackCustom> <StackCustom>
{listData.map((item, i) => ( {listData.map((item, i) => (
<GridDetail_4_8 <GridSpan_4_8
key={i} key={i}
label={<TextCustom bold>{item.label}</TextCustom>} label={<TextCustom bold>{item.label}</TextCustom>}
value={<TextCustom>{item.value}</TextCustom>} value={<TextCustom>{item.value}</TextCustom>}

View File

@@ -103,7 +103,7 @@ export default function AdminVotingStatus() {
</TextCustom> </TextCustom>
} }
value3={ value3={
<TextCustom align="center" truncate={2}> <TextCustom truncate={2}>
{item?.title || "-"} {item?.title || "-"}
</TextCustom> </TextCustom>
} }

View File

@@ -91,7 +91,7 @@ export default function AdminVotingHistory() {
} }
value2={<TextCustom truncate={1}>{item?.Author?.username || "-"}</TextCustom>} value2={<TextCustom truncate={1}>{item?.Author?.username || "-"}</TextCustom>}
value3={ value3={
<TextCustom align="center" truncate={2}> <TextCustom truncate={2}>
{item?.title || "-"} {item?.title || "-"}
</TextCustom> </TextCustom>
} }

459
bun.lock

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
import { Alert } from "react-native";
export default function AlertWarning({
title = "Peringatan Bagi Pengguna !",
description = "Konten yang Anda masukkan mengandung kata-kata yang tidak sesuai dengan pedoman komunitas kami. Mohon gunakan bahasa yang sopan dan menghargai sesama pengguna. Jika kata tersebut sebenarnya lumrah, mohon maaf—kemungkinan sistem kami belum mengenalnya sebagai wajar.",
}: {
title?: string
description?: string;
}) {
return Alert.alert(title, description, [
{
text: "Tutup",
onPress: () => {},
},
]);
}

View File

@@ -53,6 +53,8 @@ const DateTimeInput_Android: React.FC<DateTimeInputProps> = ({
const [selectedDate, setSelectedDate] = useState<Date>(value as any); const [selectedDate, setSelectedDate] = useState<Date>(value as any);
const [selectedTime, setSelectedTime] = useState<Date>(value as any); const [selectedTime, setSelectedTime] = useState<Date>(value as any);
console.log("Date Android", value)
// Fungsi untuk menggabungkan tanggal dan waktu // Fungsi untuk menggabungkan tanggal dan waktu
const combineDateAndTime = useCallback((date: Date, time: Date): Date => { const combineDateAndTime = useCallback((date: Date, time: Date): Date => {
const combined = new Date(date); const combined = new Date(date);

View File

@@ -7,7 +7,7 @@ import DateTimePicker, {
} from "@react-native-community/datetimepicker"; } from "@react-native-community/datetimepicker";
import dayjs from "dayjs"; import dayjs from "dayjs";
import React, { useState } from "react"; import React, { useState } from "react";
import { StyleProp, Text, View, ViewStyle } from "react-native"; import { Button, StyleProp, Text, View, ViewStyle } from "react-native";
import ClickableCustom from "../Clickable/ClickableCustom"; import ClickableCustom from "../Clickable/ClickableCustom";
import TextCustom from "../Text/TextCustom"; import TextCustom from "../Text/TextCustom";
@@ -129,24 +129,64 @@ const DateTimeInput_IOS: React.FC<DateTimeInputProps> = ({
borderWidth: 1, borderWidth: 1,
}} }}
> >
<View style={{ alignItems: "flex-end" }}> {/* <View style={{ alignItems: "flex-start" }}>
<Ionicons <Ionicons
name="close" name="close"
size={20} size={20}
color="black" color="black"
onPress={() => setShow(false)} onPress={() => {
setShow(false);
setSelectedDate(undefined);
}}
/> />
</View> </View> */}
<DateTimePicker <DateTimePicker
value={selectedDate || new Date()} value={selectedDate || new Date()}
mode={"datetime"} mode={"datetime"}
display="inline" display="spinner"
onChange={handleConfirm} onChange={handleConfirm}
minimumDate={minimumDate} minimumDate={minimumDate}
maximumDate={maximumDate} maximumDate={maximumDate}
themeVariant="light" themeVariant="light"
/> />
<View style={{ flexDirection: "row", gap: 10 }}>
<ClickableCustom
onPress={() => {
setShow(false)
setSelectedDate(undefined)
}}
style={{
alignItems: "center",
justifyContent: "center",
padding: 12,
borderRadius: 10,
backgroundColor: MainColor.placeholder,
marginTop: 10,
width: "48%",
}}
>
<TextCustom color="black">Batal</TextCustom>
</ClickableCustom>
<ClickableCustom
onPress={() => {
setShow(false)
onChange(selectedDate as any)
}}
style={{
alignItems: "center",
justifyContent: "center",
padding: 12,
borderRadius: 10,
backgroundColor: MainColor.darkblue,
marginTop: 10,
width: "48%",
}}
>
<TextCustom>OK</TextCustom>
</ClickableCustom>
</View>
</View> </View>
</> </>
)} )}

View File

@@ -23,6 +23,9 @@ const DateTimePickerCustom: React.FC<Props> = ({
minimumDate, minimumDate,
disabled = false, disabled = false,
}) => { }) => {
console.log("Date Android Comp", value)
return ( return (
<> <>
{Platform.OS === "ios" ? ( {Platform.OS === "ios" ? (
@@ -47,6 +50,9 @@ const DateTimePickerCustom: React.FC<Props> = ({
maximumDate={maximumDate} maximumDate={maximumDate}
minimumDate={minimumDate} minimumDate={minimumDate}
disabled={disabled} disabled={disabled}
value={value as DateTimePickerEvent | Date | null | any}
/> />
)} )}
</> </>

View File

@@ -87,7 +87,7 @@ const SelectCustom: React.FC<SelectProps> = ({
borderRadius, borderRadius,
flexDirection: "row", flexDirection: "row",
alignItems: "center", alignItems: "center",
paddingHorizontal: 10, // paddingHorizontal: 0,
height: 50, height: 50,
}, },

View File

@@ -15,7 +15,7 @@ export default function AdminButtonReject({
<> <>
<ButtonCustom <ButtonCustom
iconLeft={<IconReject size={16} />} iconLeft={<IconReject size={16} />}
backgroundColor={MainColor.red} backgroundColor={MainColor.orange}
textColor="white" textColor="white"
onPress={onReject} onPress={onReject}
isLoading={isLoading} isLoading={isLoading}

View File

@@ -1,17 +1,23 @@
import Grid from "@/components/Grid/GridCustom"; import Grid from "@/components/Grid/GridCustom";
import React from "react"; import React from "react";
import { View } from "react-native"; import { StyleProp, View, ViewStyle } from "react-native";
import { Divider } from "react-native-paper"; import { Divider } from "react-native-paper";
export default function AdminTableValue({ export default function AdminTableValue({
value1, value1,
value2, value2,
value3, value3,
style1,
style2,
style3,
bottomLine = false, bottomLine = false,
}: { }: {
value1: React.ReactNode; value1: React.ReactNode;
value2: React.ReactNode; value2: React.ReactNode;
value3: React.ReactNode; value3: React.ReactNode;
style1?: ViewStyle;
style2?: ViewStyle;
style3?: ViewStyle;
bottomLine?: boolean; bottomLine?: boolean;
}) { }) {
return ( return (
@@ -25,6 +31,7 @@ export default function AdminTableValue({
justifyContent: "center", justifyContent: "center",
paddingLeft: 10, paddingLeft: 10,
paddingRight: 10, paddingRight: 10,
...style1,
}} }}
> >
{value1} {value1}
@@ -36,6 +43,7 @@ export default function AdminTableValue({
justifyContent: "center", justifyContent: "center",
paddingLeft: 10, paddingLeft: 10,
paddingRight: 10, paddingRight: 10,
...style2,
}} }}
> >
{value2} {value2}
@@ -44,9 +52,10 @@ export default function AdminTableValue({
span={6} span={6}
style={{ style={{
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "flex-start",
paddingLeft: 10, paddingLeft: 10,
paddingRight: 10, paddingRight: 10,
...style3,
}} }}
> >
{value3} {value3}

View File

@@ -1,20 +0,0 @@
import { Grid } from "@/components";
export const GridDetail_4_8 = ({
label,
value,
}: {
label: React.ReactNode;
value: React.ReactNode;
}) => {
return (
<Grid>
<Grid.Col span={4} style={{ justifyContent: "center", paddingRight: 10 }}>
{label}
</Grid.Col>
<Grid.Col span={8} style={{ justifyContent: "center" }}>
{value}
</Grid.Col>
</Grid>
);
};

View File

@@ -0,0 +1,27 @@
import { Grid } from "@/components";
export const GridSpan_4_8 = ({
label: text1,
value: text2,
}: {
label: React.ReactNode;
value: React.ReactNode;
}) => {
return (
<Grid>
<Grid.Col
span={4}
style={{
justifyContent: "flex-start",
paddingRight: 8,
paddingLeft: 8,
}}
>
{text1}
</Grid.Col>
<Grid.Col span={8} style={{ justifyContent: "center", paddingRight: 8 }}>
{text2}
</Grid.Col>
</Grid>
);
};

View File

@@ -0,0 +1,54 @@
import { Grid } from "@/components";
export const GridSpan_NewComponent = ({
text1,
text2,
text3,
text4,
span1,
span2,
}: {
text1: React.ReactNode;
text2: React.ReactNode;
text3?: React.ReactNode;
text4?: React.ReactNode;
span1?: number;
span2?: number;
}) => {
return (
<Grid>
<Grid.Col
span={span1 ? span1 : text4 ? 3 : 4}
style={{
justifyContent: "flex-start",
paddingRight: 5,
paddingLeft: 3,
}}
>
{text1}
</Grid.Col>
<Grid.Col
span={span2 ? span2 : text4 ? 3 : text3 ? 4 : 8}
style={{ justifyContent: "flex-start", paddingRight: 5 }}
>
{text2}
</Grid.Col>
{text3 && (
<Grid.Col
span={text4 ? 3 : 4}
style={{ justifyContent: "flex-start", paddingRight: 5 }}
>
{text3}
</Grid.Col>
)}
{text4 && (
<Grid.Col
span={3}
style={{ justifyContent: "flex-start", paddingRight: 5 }}
>
{text4}
</Grid.Col>
)}
</Grid>
);
};

View File

@@ -72,10 +72,13 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
const loginWithNomor = async (nomor: string) => { const loginWithNomor = async (nomor: string) => {
setIsLoading(true); setIsLoading(true);
try { try {
console.log("[Masuk provider]", nomor);
const response = await apiLogin({ nomor: nomor }); const response = await apiLogin({ nomor: nomor });
console.log("[RESPONSE AUTH]", JSON.stringify(response)); console.log("[RESPONSE AUTH]", JSON.stringify(response));
if (response.success) { if (response.success) {
console.log("[Keluar provider]", nomor);
Toast.show({ Toast.show({
type: "success", type: "success",
text1: "Sukses", text1: "Sukses",
@@ -83,10 +86,15 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
}); });
await AsyncStorage.setItem("kode_otp", response.kodeId); await AsyncStorage.setItem("kode_otp", response.kodeId);
router.replace(`/verification?nomor=${nomor}`); router.push(`/verification?nomor=${nomor}`);
return; return;
} else { } else {
router.replace(`/register?nomor=${nomor}`); router.push(`/register?nomor=${nomor}`);
Toast.show({
type: "info",
text1: "Info",
text2: "Silahkan mendaftar",
});
return; return;
} }
} catch (error: any) { } catch (error: any) {

View File

@@ -10,7 +10,8 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
241CFEB1CBB2124E18A09822 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 51B6792712498367CD1EEA5D /* PrivacyInfo.xcprivacy */; }; 241CFEB1CBB2124E18A09822 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 51B6792712498367CD1EEA5D /* PrivacyInfo.xcprivacy */; };
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; }; 3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
7833AA2741E7B2CCBEBEB1C7 /* libPods-HIPMIBadungConnect.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B3A38F3F981E3720B61AC51 /* libPods-HIPMIBadungConnect.a */; }; 5FFACD268BA648EFA3A59CDC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E8EB1D2D7338425899CD9FA1 /* GoogleService-Info.plist */; };
74742C163A8F5202D2925B40 /* libPods-HIPMIBadungConnect.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE614D12468C9A25709B0317 /* libPods-HIPMIBadungConnect.a */; };
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; }; BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
D138B3E4BC618ADDE62DCDCC /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8F39CC335B3942749573F05 /* ExpoModulesProvider.swift */; }; D138B3E4BC618ADDE62DCDCC /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8F39CC335B3942749573F05 /* ExpoModulesProvider.swift */; };
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11748412D0307B40044C1D9 /* AppDelegate.swift */; }; F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11748412D0307B40044C1D9 /* AppDelegate.swift */; };
@@ -20,12 +21,13 @@
13B07F961A680F5B00A75B9A /* HIPMIBadungConnect.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HIPMIBadungConnect.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07F961A680F5B00A75B9A /* HIPMIBadungConnect.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HIPMIBadungConnect.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = HIPMIBadungConnect/Images.xcassets; sourceTree = "<group>"; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = HIPMIBadungConnect/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = HIPMIBadungConnect/Info.plist; sourceTree = "<group>"; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = HIPMIBadungConnect/Info.plist; sourceTree = "<group>"; };
1E94102500A8768C71C74AF6 /* Pods-HIPMIBadungConnect.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HIPMIBadungConnect.debug.xcconfig"; path = "Target Support Files/Pods-HIPMIBadungConnect/Pods-HIPMIBadungConnect.debug.xcconfig"; sourceTree = "<group>"; }; 40E847A832DE042BE51AD9E9 /* Pods-HIPMIBadungConnect.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HIPMIBadungConnect.release.xcconfig"; path = "Target Support Files/Pods-HIPMIBadungConnect/Pods-HIPMIBadungConnect.release.xcconfig"; sourceTree = "<group>"; };
51B6792712498367CD1EEA5D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = HIPMIBadungConnect/PrivacyInfo.xcprivacy; sourceTree = "<group>"; }; 51B6792712498367CD1EEA5D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = HIPMIBadungConnect/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
9B3A38F3F981E3720B61AC51 /* libPods-HIPMIBadungConnect.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HIPMIBadungConnect.a"; sourceTree = BUILT_PRODUCTS_DIR; };
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = HIPMIBadungConnect/SplashScreen.storyboard; sourceTree = "<group>"; }; AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = HIPMIBadungConnect/SplashScreen.storyboard; sourceTree = "<group>"; };
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; }; BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; };
C19B4954908DD0D4CD2965DF /* Pods-HIPMIBadungConnect.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HIPMIBadungConnect.release.xcconfig"; path = "Target Support Files/Pods-HIPMIBadungConnect/Pods-HIPMIBadungConnect.release.xcconfig"; sourceTree = "<group>"; }; BE614D12468C9A25709B0317 /* libPods-HIPMIBadungConnect.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HIPMIBadungConnect.a"; sourceTree = BUILT_PRODUCTS_DIR; };
C273E4769DE3DC0FEF6A377C /* Pods-HIPMIBadungConnect.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HIPMIBadungConnect.debug.xcconfig"; path = "Target Support Files/Pods-HIPMIBadungConnect/Pods-HIPMIBadungConnect.debug.xcconfig"; sourceTree = "<group>"; };
E8EB1D2D7338425899CD9FA1 /* GoogleService-Info.plist */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "HIPMIBadungConnect/GoogleService-Info.plist"; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
F11748412D0307B40044C1D9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = HIPMIBadungConnect/AppDelegate.swift; sourceTree = "<group>"; }; F11748412D0307B40044C1D9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = HIPMIBadungConnect/AppDelegate.swift; sourceTree = "<group>"; };
F11748442D0722820044C1D9 /* HIPMIBadungConnect-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "HIPMIBadungConnect-Bridging-Header.h"; path = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h"; sourceTree = "<group>"; }; F11748442D0722820044C1D9 /* HIPMIBadungConnect-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "HIPMIBadungConnect-Bridging-Header.h"; path = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -37,7 +39,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
7833AA2741E7B2CCBEBEB1C7 /* libPods-HIPMIBadungConnect.a in Frameworks */, 74742C163A8F5202D2925B40 /* libPods-HIPMIBadungConnect.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -54,6 +56,7 @@
13B07FB61A68108700A75B9A /* Info.plist */, 13B07FB61A68108700A75B9A /* Info.plist */,
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */, AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
51B6792712498367CD1EEA5D /* PrivacyInfo.xcprivacy */, 51B6792712498367CD1EEA5D /* PrivacyInfo.xcprivacy */,
E8EB1D2D7338425899CD9FA1 /* GoogleService-Info.plist */,
); );
name = HIPMIBadungConnect; name = HIPMIBadungConnect;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -62,7 +65,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
9B3A38F3F981E3720B61AC51 /* libPods-HIPMIBadungConnect.a */, BE614D12468C9A25709B0317 /* libPods-HIPMIBadungConnect.a */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -108,8 +111,8 @@
A30E580F1E4E26A6BD0E3B24 /* Pods */ = { A30E580F1E4E26A6BD0E3B24 /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
1E94102500A8768C71C74AF6 /* Pods-HIPMIBadungConnect.debug.xcconfig */, C273E4769DE3DC0FEF6A377C /* Pods-HIPMIBadungConnect.debug.xcconfig */,
C19B4954908DD0D4CD2965DF /* Pods-HIPMIBadungConnect.release.xcconfig */, 40E847A832DE042BE51AD9E9 /* Pods-HIPMIBadungConnect.release.xcconfig */,
); );
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -138,14 +141,14 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HIPMIBadungConnect" */; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HIPMIBadungConnect" */;
buildPhases = ( buildPhases = (
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */, AA173A81855B88A7082A949D /* [CP] Check Pods Manifest.lock */,
0B90913696EEE0E819CAF510 /* [Expo] Configure project */, 0B90913696EEE0E819CAF510 /* [Expo] Configure project */,
13B07F871A680F5B00A75B9A /* Sources */, 13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */, 13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */, 1A2B5C8B77E56B3325ADC6E7 /* [CP] Embed Pods Frameworks */,
2DA25245F64078F29C0B38E4 /* [CP] Embed Pods Frameworks */, AECA4AD2A3DFA75F552CA1F1 /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@@ -196,6 +199,7 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */, 3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */,
241CFEB1CBB2124E18A09822 /* PrivacyInfo.xcprivacy in Resources */, 241CFEB1CBB2124E18A09822 /* PrivacyInfo.xcprivacy in Resources */,
5FFACD268BA648EFA3A59CDC /* GoogleService-Info.plist in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -219,28 +223,6 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n\n"; shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n\n";
}; };
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-HIPMIBadungConnect-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
0B90913696EEE0E819CAF510 /* [Expo] Configure project */ = { 0B90913696EEE0E819CAF510 /* [Expo] Configure project */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1; alwaysOutOfDate = 1;
@@ -265,7 +247,7 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-HIPMIBadungConnect/expo-configure-project.sh\"\n"; shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-HIPMIBadungConnect/expo-configure-project.sh\"\n";
}; };
2DA25245F64078F29C0B38E4 /* [CP] Embed Pods Frameworks */ = { 1A2B5C8B77E56B3325ADC6E7 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@@ -295,7 +277,29 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HIPMIBadungConnect/Pods-HIPMIBadungConnect-frameworks.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HIPMIBadungConnect/Pods-HIPMIBadungConnect-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = { AA173A81855B88A7082A949D /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-HIPMIBadungConnect-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
AECA4AD2A3DFA75F552CA1F1 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@@ -309,6 +313,13 @@
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoDevice/ExpoDevice_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoDevice/ExpoDevice_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseMessaging/FirebaseMessaging_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf", "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf",
@@ -335,6 +346,7 @@
"${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-launcher/EXDevLauncher.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-launcher/EXDevLauncher.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-menu/EXDevMenu.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-menu/EXDevMenu.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/react-native-maps/ReactNativeMapsPrivacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/react-native-maps/ReactNativeMapsPrivacy.bundle",
); );
name = "[CP] Copy Pods Resources"; name = "[CP] Copy Pods Resources";
@@ -346,6 +358,13 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoDevice_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoDevice_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoSystemUI_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoSystemUI_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseMessaging_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf",
@@ -372,6 +391,7 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SDWebImage.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SDWebImage.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXDevLauncher.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXDevLauncher.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXDevMenu.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXDevMenu.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ReactNativeMapsPrivacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ReactNativeMapsPrivacy.bundle",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -396,7 +416,7 @@
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = { 13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 1E94102500A8768C71C74AF6 /* Pods-HIPMIBadungConnect.debug.xcconfig */; baseConfigurationReference = C273E4769DE3DC0FEF6A377C /* Pods-HIPMIBadungConnect.debug.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
@@ -433,7 +453,7 @@
}; };
13B07F951A680F5B00A75B9A /* Release */ = { 13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = C19B4954908DD0D4CD2965DF /* Pods-HIPMIBadungConnect.release.xcconfig */; baseConfigurationReference = 40E847A832DE042BE51AD9E9 /* Pods-HIPMIBadungConnect.release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;

View File

@@ -1,4 +1,5 @@
import Expo import Expo
import FirebaseCore
import React import React
import ReactAppDependencyProvider import ReactAppDependencyProvider
@@ -23,6 +24,9 @@ public class AppDelegate: ExpoAppDelegate {
#if os(iOS) || os(tvOS) #if os(iOS) || os(tvOS)
window = UIWindow(frame: UIScreen.main.bounds) window = UIWindow(frame: UIScreen.main.bounds)
// @generated begin @react-native-firebase/app-didFinishLaunchingWithOptions - expo prebuild (DO NOT MODIFY) sync-10e8520570672fd76b2403b7e1e27f5198a6349a
FirebaseApp.configure()
// @generated end @react-native-firebase/app-didFinishLaunchingWithOptions
factory.startReactNative( factory.startReactNative(
withModuleName: "main", withModuleName: "main",
in: window, in: window,

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>API_KEY</key>
<string>AIzaSyAAvM0yBp5kCXa0hLAaNFZNqwkpBGYAWYs</string>
<key>GCM_SENDER_ID</key>
<string>608461535079</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.anonymous.hipmi-mobile</string>
<key>PROJECT_ID</key>
<string>hipmi-badung-connect</string>
<key>STORAGE_BUCKET</key>
<string>hipmi-badung-connect.firebasestorage.app</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:608461535079:ios:589f31b2b6b1068b6761c2</string>
</dict>
</plist>

View File

@@ -39,7 +39,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>10</string> <string>15</string>
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
<false/> <false/>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

View File

@@ -20,6 +20,8 @@
<key>NSPrivacyAccessedAPITypeReasons</key> <key>NSPrivacyAccessedAPITypeReasons</key>
<array> <array>
<string>CA92.1</string> <string>CA92.1</string>
<string>1C8F.1</string>
<string>C56D.1</string>
</array> </array>
</dict> </dict>
<dict> <dict>

View File

@@ -1,3 +1,5 @@
use_modular_headers!
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods") require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
@@ -33,13 +35,14 @@ target 'HIPMIBadungConnect' do
use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks'] use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS'] use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']
# @generated begin pre_installer - expo prebuild (DO NOT MODIFY) sync-c8812095000d6054b846ce74840f0ffb540c2757 # @generated begin pre_installer - expo prebuild (DO NOT MODIFY) sync-c8812095000d6054b846ce74840f0ffb540c2757
pre_install do |installer| pre_install do |installer|
# @generated begin @rnmapbox/maps-pre_installer - expo prebuild (DO NOT MODIFY) sync-ea4905840bf9fcea0acc62e92aa2e784f9d760f8 # @generated begin @rnmapbox/maps-pre_installer - expo prebuild (DO NOT MODIFY) sync-ea4905840bf9fcea0acc62e92aa2e784f9d760f8
$RNMapboxMaps.pre_install(installer) $RNMapboxMaps.pre_install(installer)
# @generated end @rnmapbox/maps-pre_installer # @generated end @rnmapbox/maps-pre_installer
end end
# @generated end pre_installer # @generated end pre_installer
use_react_native!( use_react_native!(
:path => config[:reactNativePath], :path => config[:reactNativePath],
:hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes', :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
@@ -48,10 +51,31 @@ target 'HIPMIBadungConnect' do
:privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false', :privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false',
) )
pod 'Firebase/Messaging'
# @generated begin post_installer - expo prebuild (DO NOT MODIFY) sync-4092f82b887b5b9edb84642c2a56984d69b9a403
post_install do |installer| post_install do |installer|
# @generated begin @rnmapbox/maps-post_installer - expo prebuild (DO NOT MODIFY) sync-c4e8f90e96f6b6c6ea9241dd7b52ab5f57f7bf36 # @generated begin @rnmapbox/maps-post_installer - expo prebuild (DO NOT MODIFY) sync-c4e8f90e96f6b6c6ea9241dd7b52ab5f57f7bf36
$RNMapboxMaps.post_install(installer) $RNMapboxMaps.post_install(installer)
# @generated end @rnmapbox/maps-post_installer # @generated end @rnmapbox/maps-post_installer
# Fix all script phases with incorrect paths
installer.pods_project.targets.each do |target|
target.build_phases.each do |phase|
next unless phase.respond_to?(:shell_script)
# Fix duplicated path issue
if phase.shell_script.include?('with-environment.sh')
# Remove any existing path and use proper relative path
phase.shell_script = phase.shell_script.gsub(
%r{(/.*?/node_modules/react-native)+/scripts/xcode/with-environment.sh},
'${PODS_ROOT}/../../node_modules/react-native/scripts/xcode/with-environment.sh'
)
end
end
end
# Standard React Native post install
react_native_post_install( react_native_post_install(
installer, installer,
config[:reactNativePath], config[:reactNativePath],
@@ -59,4 +83,6 @@ target 'HIPMIBadungConnect' do
:ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true', :ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true',
) )
end end
end # @generated end post_installer
end

View File

@@ -239,6 +239,8 @@ PODS:
- ExpoModulesCore - ExpoModulesCore
- ExpoKeepAwake (15.0.7): - ExpoKeepAwake (15.0.7):
- ExpoModulesCore - ExpoModulesCore
- ExpoLinearGradient (15.0.7):
- ExpoModulesCore
- ExpoLinking (8.0.8): - ExpoLinking (8.0.8):
- ExpoModulesCore - ExpoModulesCore
- ExpoLocation (19.0.7): - ExpoLocation (19.0.7):
@@ -277,6 +279,58 @@ PODS:
- EXUpdatesInterface (2.0.0): - EXUpdatesInterface (2.0.0):
- ExpoModulesCore - ExpoModulesCore
- FBLazyVector (0.81.4) - FBLazyVector (0.81.4)
- Firebase/CoreOnly (12.7.0):
- FirebaseCore (~> 12.7.0)
- Firebase/Messaging (12.7.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 12.7.0)
- FirebaseCore (12.7.0):
- FirebaseCoreInternal (~> 12.7.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreInternal (12.7.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseInstallations (12.7.0):
- FirebaseCore (~> 12.7.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (12.7.0):
- FirebaseCore (~> 12.7.0)
- FirebaseInstallations (~> 12.7.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Reachability (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- nanopb (~> 3.30910.0)
- GoogleDataTransport (10.1.0):
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- GoogleUtilities/AppDelegateSwizzler (8.1.0):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Privacy
- GoogleUtilities/Environment (8.1.0):
- GoogleUtilities/Privacy
- GoogleUtilities/Logger (8.1.0):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- GoogleUtilities/Network (8.1.0):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Privacy
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (8.1.0)":
- GoogleUtilities/Privacy
- GoogleUtilities/Privacy (8.1.0)
- GoogleUtilities/Reachability (8.1.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GoogleUtilities/UserDefaults (8.1.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- hermes-engine (0.81.4): - hermes-engine (0.81.4):
- hermes-engine/Pre-built (= 0.81.4) - hermes-engine/Pre-built (= 0.81.4)
- hermes-engine/Pre-built (0.81.4) - hermes-engine/Pre-built (0.81.4)
@@ -305,6 +359,12 @@ PODS:
- MapboxCommon (= 24.15.4) - MapboxCommon (= 24.15.4)
- MapboxCoreMaps (= 11.15.4) - MapboxCoreMaps (= 11.15.4)
- Turf (= 4.0.0) - Turf (= 4.0.0)
- nanopb (3.30910.0):
- nanopb/decode (= 3.30910.0)
- nanopb/encode (= 3.30910.0)
- nanopb/decode (3.30910.0)
- nanopb/encode (3.30910.0)
- PromisesObjC (2.4.0)
- RCTDeprecation (0.81.4) - RCTDeprecation (0.81.4)
- RCTRequired (0.81.4) - RCTRequired (0.81.4)
- RCTTypeSafety (0.81.4): - RCTTypeSafety (0.81.4):
@@ -2446,10 +2506,10 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- ReactNativeDependencies - ReactNativeDependencies
- Yoga - Yoga
- SDWebImage (5.21.1): - SDWebImage (5.21.3):
- SDWebImage/Core (= 5.21.1) - SDWebImage/Core (= 5.21.3)
- SDWebImage/Core (5.21.1) - SDWebImage/Core (5.21.3)
- SDWebImageAVIFCoder (0.11.0): - SDWebImageAVIFCoder (0.11.1):
- libavif/core (>= 0.11.0) - libavif/core (>= 0.11.0)
- SDWebImage (~> 5.10) - SDWebImage (~> 5.10)
- SDWebImageSVGCoder (1.7.0): - SDWebImageSVGCoder (1.7.0):
@@ -2489,6 +2549,7 @@ DEPENDENCIES:
- ExpoImage (from `../node_modules/expo-image/ios`) - ExpoImage (from `../node_modules/expo-image/ios`)
- ExpoImagePicker (from `../node_modules/expo-image-picker/ios`) - ExpoImagePicker (from `../node_modules/expo-image-picker/ios`)
- ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`) - ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`)
- ExpoLinearGradient (from `../node_modules/expo-linear-gradient/ios`)
- ExpoLinking (from `../node_modules/expo-linking/ios`) - ExpoLinking (from `../node_modules/expo-linking/ios`)
- ExpoLocation (from `../node_modules/expo-location/ios`) - ExpoLocation (from `../node_modules/expo-location/ios`)
- ExpoModulesCore (from `../node_modules/expo-modules-core`) - ExpoModulesCore (from `../node_modules/expo-modules-core`)
@@ -2498,6 +2559,7 @@ DEPENDENCIES:
- ExpoWebBrowser (from `../node_modules/expo-web-browser/ios`) - ExpoWebBrowser (from `../node_modules/expo-web-browser/ios`)
- EXUpdatesInterface (from `../node_modules/expo-updates-interface/ios`) - EXUpdatesInterface (from `../node_modules/expo-updates-interface/ios`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- Firebase/Messaging
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
- RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`) - RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
- RCTRequired (from `../node_modules/react-native/Libraries/Required`) - RCTRequired (from `../node_modules/react-native/Libraries/Required`)
@@ -2582,12 +2644,21 @@ DEPENDENCIES:
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- Firebase
- FirebaseCore
- FirebaseCoreInternal
- FirebaseInstallations
- FirebaseMessaging
- GoogleDataTransport
- GoogleUtilities
- libavif - libavif
- libdav1d - libdav1d
- libwebp - libwebp
- MapboxCommon - MapboxCommon
- MapboxCoreMaps - MapboxCoreMaps
- MapboxMaps - MapboxMaps
- nanopb
- PromisesObjC
- SDWebImage - SDWebImage
- SDWebImageAVIFCoder - SDWebImageAVIFCoder
- SDWebImageSVGCoder - SDWebImageSVGCoder
@@ -2642,6 +2713,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/expo-image-picker/ios" :path: "../node_modules/expo-image-picker/ios"
ExpoKeepAwake: ExpoKeepAwake:
:path: "../node_modules/expo-keep-awake/ios" :path: "../node_modules/expo-keep-awake/ios"
ExpoLinearGradient:
:path: "../node_modules/expo-linear-gradient/ios"
ExpoLinking: ExpoLinking:
:path: "../node_modules/expo-linking/ios" :path: "../node_modules/expo-linking/ios"
ExpoLocation: ExpoLocation:
@@ -2846,6 +2919,7 @@ SPEC CHECKSUMS:
ExpoImage: e88f500585913969b930e13a4be47277eb7c6de8 ExpoImage: e88f500585913969b930e13a4be47277eb7c6de8
ExpoImagePicker: d251aab45a1b1857e4156fed88511b278b4eee1c ExpoImagePicker: d251aab45a1b1857e4156fed88511b278b4eee1c
ExpoKeepAwake: 1a2e820692e933c94a565ec3fbbe38ac31658ffe ExpoKeepAwake: 1a2e820692e933c94a565ec3fbbe38ac31658ffe
ExpoLinearGradient: a464898cb95153125e3b81894fd479bcb1c7dd27
ExpoLinking: f051f28e50ea9269ff539317c166adec81d9342d ExpoLinking: f051f28e50ea9269ff539317c166adec81d9342d
ExpoLocation: 93d7faa0c2adbd5a04686af0c1a61bc6ed3ee2f7 ExpoLocation: 93d7faa0c2adbd5a04686af0c1a61bc6ed3ee2f7
ExpoModulesCore: 9281d8f1cda9d0c37dbce34c26014212b22eb8c0 ExpoModulesCore: 9281d8f1cda9d0c37dbce34c26014212b22eb8c0
@@ -2855,6 +2929,13 @@ SPEC CHECKSUMS:
ExpoWebBrowser: b973e1351fdcf5fec0c400997b1851f5a8219ec3 ExpoWebBrowser: b973e1351fdcf5fec0c400997b1851f5a8219ec3
EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734 EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734
FBLazyVector: 9e0cd874afd81d9a4d36679daca991b58b260d42 FBLazyVector: 9e0cd874afd81d9a4d36679daca991b58b260d42
Firebase: 2d19a10c9a2e48ac532a4303115d3fc9b2798396
FirebaseCore: c7b57863ce0859281a66d16ca36d665c45d332b5
FirebaseCoreInternal: 571a2dd8c975410966199623351db3a3265c874d
FirebaseInstallations: 6d05424a046b68ca146b4de4376f05b4e9262fc3
FirebaseMessaging: b5f7bdc62b91b6102015991fb7bc6fa75f643908
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394 hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394
libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
@@ -2862,6 +2943,8 @@ SPEC CHECKSUMS:
MapboxCommon: 975faa94b893bb64a1d28b09d9d6d820e1030a26 MapboxCommon: 975faa94b893bb64a1d28b09d9d6d820e1030a26
MapboxCoreMaps: 105af9894d850290fbb466e9f9a133f5d175abf1 MapboxCoreMaps: 105af9894d850290fbb466e9f9a133f5d175abf1
MapboxMaps: e97e59d6ba48bb6f695a4c1dc2f174cb24743cd4 MapboxMaps: e97e59d6ba48bb6f695a4c1dc2f174cb24743cd4
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
RCTDeprecation: 7487d6dda857ccd4cb3dd6ecfccdc3170e85dcbc RCTDeprecation: 7487d6dda857ccd4cb3dd6ecfccdc3170e85dcbc
RCTRequired: 54128b7df8be566881d48c7234724a78cb9b6157 RCTRequired: 54128b7df8be566881d48c7234724a78cb9b6157
RCTTypeSafety: d2b07797a79e45d7b19e1cd2f53c79ab419fe217 RCTTypeSafety: d2b07797a79e45d7b19e1cd2f53c79ab419fe217
@@ -2940,14 +3023,14 @@ SPEC CHECKSUMS:
RNSVG: 31d6639663c249b7d5abc9728dde2041eb2a3c34 RNSVG: 31d6639663c249b7d5abc9728dde2041eb2a3c34
RNVectorIcons: 704d89d2f11886824e3bd5cbea34dd00aeade200 RNVectorIcons: 704d89d2f11886824e3bd5cbea34dd00aeade200
RNWorklets: 76fce72926e28e304afb44f0da23b2d24f2c1fa0 RNWorklets: 76fce72926e28e304afb44f0da23b2d24f2c1fa0
SDWebImage: f29024626962457f3470184232766516dee8dfea SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a
SDWebImageAVIFCoder: 00310d246aab3232ce77f1d8f0076f8c4b021d90 SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380 SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
Turf: c9eb11a65d96af58cac523460fd40fec5061b081 Turf: c9eb11a65d96af58cac523460fd40fec5061b081
Yoga: 051f086b5ccf465ff2ed38a2cf5a558ae01aaaa1 Yoga: 051f086b5ccf465ff2ed38a2cf5a558ae01aaaa1
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
PODFILE CHECKSUM: 961e5122c387eef49538723a9e3e7a469ca4144f PODFILE CHECKSUM: 61c4a9d35618e5f2a420f47e5a24c89e86706f00
COCOAPODS: 1.16.2 COCOAPODS: 1.16.2

View File

@@ -14,6 +14,8 @@
"@expo/vector-icons": "^15.0.2", "@expo/vector-icons": "^15.0.2",
"@react-native-async-storage/async-storage": "2.2.0", "@react-native-async-storage/async-storage": "2.2.0",
"@react-native-community/datetimepicker": "8.4.4", "@react-native-community/datetimepicker": "8.4.4",
"@react-native-firebase/app": "^23.7.0",
"@react-native-firebase/messaging": "^23.7.0",
"@react-navigation/bottom-tabs": "^7.3.10", "@react-navigation/bottom-tabs": "^7.3.10",
"@react-navigation/drawer": "^7.3.9", "@react-navigation/drawer": "^7.3.9",
"@react-navigation/elements": "^2.3.8", "@react-navigation/elements": "^2.3.8",
@@ -72,6 +74,7 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
"@react-native-community/cli": "^20.0.2",
"@types/react": "~19.1.10", "@types/react": "~19.1.10",
"eslint": "^9.25.0", "eslint": "^9.25.0",
"eslint-config-expo": "~10.0.0", "eslint-config-expo": "~10.0.0",

View File

@@ -1,3 +1,4 @@
import { NewWrapper } from "@/components";
import ButtonCustom from "@/components/Button/ButtonCustom"; import ButtonCustom from "@/components/Button/ButtonCustom";
import Spacing from "@/components/_ShareComponent/Spacing"; import Spacing from "@/components/_ShareComponent/Spacing";
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper"; import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
@@ -5,9 +6,11 @@ import { MainColor } from "@/constants/color-palet";
import { useAuth } from "@/hooks/use-auth"; import { useAuth } from "@/hooks/use-auth";
import { apiVersion } from "@/service/api-config"; import { apiVersion } from "@/service/api-config";
import { GStyles } from "@/styles/global-styles"; import { GStyles } from "@/styles/global-styles";
import { Redirect, router } from "expo-router"; import versionBadge from "@/utils/viersionBadge";
import VersionBadge from "@/utils/viersionBadge";
import { Redirect } from "expo-router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Text, View } from "react-native"; import { RefreshControl, Text, View } from "react-native";
import PhoneInput, { ICountry } from "react-native-international-phone-number"; import PhoneInput, { ICountry } from "react-native-international-phone-number";
import Toast from "react-native-toast-message"; import Toast from "react-native-toast-message";
@@ -16,6 +19,7 @@ export default function LoginView() {
const [selectedCountry, setSelectedCountry] = useState<null | ICountry>(null); const [selectedCountry, setSelectedCountry] = useState<null | ICountry>(null);
const [inputValue, setInputValue] = useState<string>(""); const [inputValue, setInputValue] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [refreshing, setRefreshing] = useState<boolean>(false);
const { loginWithNomor, token, isAdmin, isUserActive } = useAuth(); const { loginWithNomor, token, isAdmin, isUserActive } = useAuth();
@@ -25,7 +29,18 @@ export default function LoginView() {
async function onLoadVersion() { async function onLoadVersion() {
const res = await apiVersion(); const res = await apiVersion();
setVersion(res.data);
if (res.success) {
setVersion(versionBadge());
}
}
async function handleRefresh() {
setRefreshing(true);
await onLoadVersion();
setInputValue("");
setLoading(false);
setRefreshing(false);
} }
function handleInputValue(phoneNumber: string) { function handleInputValue(phoneNumber: string) {
@@ -65,8 +80,6 @@ export default function LoginView() {
const isValid = await validateData(); const isValid = await validateData();
if (!isValid) return; if (!isValid) return;
// const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || "";
// const fixNumber = inputValue.replace(/\s+/g, "");
const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || ""; const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || "";
let fixNumber = inputValue.replace(/\s+/g, "").replace(/^0+/, ""); let fixNumber = inputValue.replace(/\s+/g, "").replace(/^0+/, "");
@@ -74,9 +87,7 @@ export default function LoginView() {
try { try {
setLoading(true); setLoading(true);
const response = await loginWithNomor(realNumber); await loginWithNomor(realNumber);
console.log("[RESPONSE UI]", response);
} catch (error) { } catch (error) {
console.log("Error login", error); console.log("Error login", error);
Toast.show({ Toast.show({
@@ -130,7 +141,12 @@ export default function LoginView() {
} }
return ( return (
<ViewWrapper withBackground> <NewWrapper
withBackground
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />
}
>
<View style={GStyles.authContainer}> <View style={GStyles.authContainer}>
<View> <View>
<View style={GStyles.authContainerTitle}> <View style={GStyles.authContainerTitle}>
@@ -174,6 +190,6 @@ export default function LoginView() {
Coba Coba
</ButtonCustom> */} </ButtonCustom> */}
</View> </View>
</ViewWrapper> </NewWrapper>
); );
} }

View File

@@ -17,6 +17,8 @@ import Toast from "react-native-toast-message";
export default function VerificationView() { export default function VerificationView() {
const { nomor } = useLocalSearchParams<{ nomor: string }>(); const { nomor } = useLocalSearchParams<{ nomor: string }>();
console.log("[NOMOR]", nomor);
const [inputOtp, setInputOtp] = useState<string>(""); const [inputOtp, setInputOtp] = useState<string>("");
const [userNumber, setUserNumber] = useState<string>(""); const [userNumber, setUserNumber] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
@@ -52,7 +54,7 @@ export default function VerificationView() {
try { try {
const response = await apiCheckCodeOtp({ kodeId }); const response = await apiCheckCodeOtp({ kodeId });
console.log( console.log(
"Response check code otp >>", "[OTP] >>",
JSON.stringify(response.otp, null, 2) JSON.stringify(response.otp, null, 2)
); );
// Kita tidak perlu simpan codeOtp di state karena verifikasi dilakukan di backend // Kita tidak perlu simpan codeOtp di state karena verifikasi dilakukan di backend

View File

@@ -25,7 +25,7 @@ function Collaboration_BoxPublishSection({
name={data?.Author?.username || "Username"} name={data?.Author?.username || "Username"}
rightComponent={rightComponentAvatar} rightComponent={rightComponentAvatar}
avatar={data?.Author?.Profile?.imageId} avatar={data?.Author?.Profile?.imageId}
withBottomLine // withBottomLine
/> />
<StackCustom style={{paddingBlock: 10}}> <StackCustom style={{paddingBlock: 10}}>

View File

@@ -50,7 +50,7 @@ export default function Event_BoxDetailPublishSection({
<Grid.Col span={4}> <Grid.Col span={4}>
<TextCustom bold>{item.title}</TextCustom> <TextCustom bold>{item.title}</TextCustom>
</Grid.Col> </Grid.Col>
<Grid.Col span={8}> <Grid.Col span={8} style={{ paddingLeft: 10 }}>
<TextCustom>{item.value}</TextCustom> <TextCustom>{item.value}</TextCustom>
</Grid.Col> </Grid.Col>
</Grid> </Grid>

View File

@@ -28,7 +28,7 @@ export default function Event_BoxPublishSection({
<AvatarUsernameAndOtherComponent <AvatarUsernameAndOtherComponent
avatarHref={`/profile/${data?.Author?.Profile?.id}`} avatarHref={`/profile/${data?.Author?.Profile?.id}`}
name={data?.Author?.username || "-"} name={data?.Author?.username || "-"}
rightComponent={rightComponentAvatar} // rightComponent={rightComponentAvatar}
avatar={data?.Author?.Profile?.imageId || ""} avatar={data?.Author?.Profile?.imageId || ""}
/> />
<TextCustom truncate bold> <TextCustom truncate bold>

View File

@@ -1,12 +1,12 @@
import { ITabs } from "@/components/_Interface/types"; import { ITabs } from "@/components/_Interface/types";
export const tabsHome: any = (profileId: string) => [ export const tabsHome: any = ({acceptedForumTermsAt, profileId}: {acceptedForumTermsAt: Date, profileId: string}) => [
{ {
id: "forum", id: "forum",
icon: "chatbubble-ellipses-outline", icon: "chatbubble-ellipses-outline",
activeIcon: "chatbubble-ellipses", activeIcon: "chatbubble-ellipses",
label: "Forum", label: "Forum",
path: "/forum", path: acceptedForumTermsAt ? "/forum" : "/forum/terms",
isActive: true, isActive: true,
disabled: false, disabled: false,
}, },

View File

@@ -55,10 +55,6 @@ export default function Portofolio_ButtonCreate({
}; };
const handleCreatePortofolio = async () => { const handleCreatePortofolio = async () => {
console.log(
"Data sub bidang >>",
JSON.stringify(subBidangSelected, null, 2)
);
if (!validaasiData()) { if (!validaasiData()) {
Toast.show({ Toast.show({
type: "info", type: "info",

View File

@@ -60,10 +60,20 @@ export async function apiAdminMasterBusinessField() {
} }
} }
export async function apiAdminMasterBusinessFieldById({ id }: { id: string }) { export async function apiAdminMasterBusinessFieldById({
id,
subBidangId,
category,
}: {
id: string;
subBidangId?: string | null;
category: "bidang" | "sub-bidang" | "all";
}) {
const queryCategory = category ? `?category=${category}` : "";
const querySubBidang = subBidangId ? `&subBidangId=${subBidangId}` : "";
try { try {
const response = await apiConfig.get( const response = await apiConfig.get(
`/mobile/admin/master/business-field/${id}` `/mobile/admin/master/business-field/${id}${queryCategory}${querySubBidang}`
); );
return response.data; return response.data;
} catch (error) { } catch (error) {
@@ -74,13 +84,15 @@ export async function apiAdminMasterBusinessFieldById({ id }: { id: string }) {
export async function apiAdminMasterBusinessFieldUpdate({ export async function apiAdminMasterBusinessFieldUpdate({
id, id,
data, data,
category,
}: { }: {
id: string; id: string;
data: any; data: any;
category: "bidang" | "sub-bidang";
}) { }) {
try { try {
const response = await apiConfig.put( const response = await apiConfig.put(
`/mobile/admin/master/business-field/${id}`, `/mobile/admin/master/business-field/${id}?category=${category}`,
{ {
data: data, data: data,
} }
@@ -167,3 +179,64 @@ export async function apiAdminMasterTypeOfEventUpdate({
} }
// ================== END EVENT ================== // // ================== END EVENT ================== //
// ================== START DONATION ================== //
export async function apiAdminMasterDonationCategory() {
try {
const response = await apiConfig.get(`/mobile/admin/master/donation`);
return response.data;
} catch (error) {
throw error;
}
}
export async function apiAdminMasterDonationCategoryById({
id,
}: {
id: string;
}) {
try {
const response = await apiConfig.get(`/mobile/admin/master/donation/${id}`);
return response.data;
} catch (error) {
throw error;
}
}
export async function apiAdminMasterDonationCategoryUpdate({
id,
data,
}: {
id: string;
data: any;
}) {
try {
const response = await apiConfig.put(
`/mobile/admin/master/donation/${id}`,
{
data: data,
}
);
return response.data;
} catch (error) {
throw error;
}
}
export async function apiAdminMasterDonationCategoryCreate({
data,
}: {
data: any;
}) {
try {
const response = await apiConfig.post(`/mobile/admin/master/donation`, {
data: data,
});
return response.data;
} catch (error) {
throw error;
}
}
// ================== END DONATION ================== //

View File

@@ -36,3 +36,13 @@ export async function apiForumBlockUser({
throw error; throw error;
} }
} }
export async function apiAcceptForumTerms({category, userId}:{category:"Forum" | "Event", userId: string}) {
try {
const response = await apiConfig.post(`/mobile/user/${userId}/terms-of-app?category=${category}`);
return response.data;
} catch (error) {
throw error;
}
}

View File

@@ -14,6 +14,7 @@ apiConfig.interceptors.request.use(
async (config) => { async (config) => {
console.log("API_BASE_URL >>", API_BASE_URL); console.log("API_BASE_URL >>", API_BASE_URL);
const token = await AsyncStorage.getItem("authToken"); const token = await AsyncStorage.getItem("authToken");
// console.log("[TOKEN] >>", token);
if (token) { if (token) {
// config.timeout = 10000; // config.timeout = 10000;
config.headers["Content-Type"] = "application/json"; config.headers["Content-Type"] = "application/json";
@@ -33,7 +34,7 @@ export async function apiVersion() {
} }
export async function apiLogin({ nomor }: { nomor: string }) { export async function apiLogin({ nomor }: { nomor: string }) {
const response = await apiConfig.post("/mobile/auth/login", { const response = await apiConfig.post("/auth/mobile-login", {
nomor: nomor, nomor: nomor,
}); });
return response.data;; return response.data;;
@@ -45,7 +46,7 @@ export async function apiCheckCodeOtp({ kodeId }: { kodeId: string }) {
} }
export async function apiValidationCode({ nomor }: { nomor: string }) { export async function apiValidationCode({ nomor }: { nomor: string }) {
const response = await apiConfig.post(`/auth/validasi`, { const response = await apiConfig.post(`/auth/mobile-validasi`, {
nomor: nomor, nomor: nomor,
}); });
return response.data; return response.data;
@@ -56,7 +57,7 @@ export async function apiRegister({
}: { }: {
data: { nomor: string; username: string; termsOfServiceAccepted: boolean }; data: { nomor: string; username: string; termsOfServiceAccepted: boolean };
}) { }) {
const response = await apiConfig.post(`/mobile/auth/register`, { const response = await apiConfig.post(`/auth/mobile-register`, {
data: data, data: data,
}); });
return response.data; return response.data;

108
utils/badWordsIndonesia.ts Normal file
View File

@@ -0,0 +1,108 @@
// badWordsIndonesia.js (Versi Lengkap)
const badWordsIndonesia = [
// 🐶 Kata Kasar & Vulgar
'anjing', 'babi', 'bangsat', 'bodoh', 'goblok', 'idiot', 'jancok', 'jembut', 'kampret',
'kontol', 'memek', 'ngentot', 'peler', 'puki', 'sialan', 'tai', 'tolol', 'wibu',
'anjingg', 'babbii', 'bangsaat', 'gobllokk', 'jancokk', 'kontoll', 'memekk', 'ngentott',
'pelerr', 'puuki', 'sialann', 'taii', 'tololl', 'wibuu',
// 🔥 Kata Sindiran & Penghinaan
'bego', 'dungu', 'edan', 'gila', 'goblog', 'kampang', 'kampret', 'keparat', 'lonte',
'main mata', 'monyet', 'najis', 'ngeyel', 'ngibul', 'ngomong seenaknya', 'ngurangin',
'ngutang', 'ngurusin urusan orang', 'pemalas', 'pengecut', 'penipu', 'sinting',
'begoo', 'dunguu', 'goblogg', 'kampangg', 'keparatt', 'lontee', 'monyyet', 'najiss',
'ngeyell', 'ngibull', 'ngomongg seenaknya', 'nguranginn', 'ngutangg', 'pemalass',
'pengecutt', 'penipuu', 'sintting',
// ⚖️ Kata SARA & Diskriminasi
'cina', 'kafir', 'kampungan', 'kacung', 'mampus', 'menghina', 'racist', 'sara',
'setan', 'syiah', 'waria', 'wong jowo', 'wong sunda', 'wong madura',
'chinna', 'kafiir', 'kampungann', 'kacungg', 'mampuss', 'menghinna', 'racisst',
'saraa', 'setann', 'syiahh', 'wariia', 'wong jowoo', 'wong sundaa', 'wong maduraa',
// 💸 Kata Spam / Promosi Ilegal
'judi', 'togel', 'slot', 'casino', 'poker', 'qq', 'bandar', 'agen', 'link', 'wa',
'whatsapp', 'telepon', 'nomor', 'hp', 'sms', 'grup', 'join', 'daftar', 'bonus',
'deposit', 'withdraw', 'uang', 'duit', 'rp', 'ratusan', 'juta', 'milyar',
'judii', 'togell', 'slotss', 'casinoo', 'pokerr', 'qqq', 'bandarr', 'agenn', 'linkk',
'waa', 'whatsappp', 'teleponn', 'nomorr', 'hpp', 'smss', 'grupp', 'jooin', 'daftarr',
'bonuss', 'depositt', 'withdraww', 'uangs', 'duitt', 'rpp', 'ratusann', 'jutaa', 'milyarr',
// 🧩 Variasi Penulisan (Bypass Filter)
'a*njing', 'b*b*i', 'b*ngsat', 'g*blok', 'k*nt*l', 'm*m*k', 'n*g*nt*t', 'p*l*r',
't*i', 't*l*l', 'j*n*c*k', 'j*m*b*t', 'k*m*p*r*t', 's*i*l*a*n', 'w*b*u',
'a.n.j.i.n.g', 'b.a.b.i', 'b.a.n.g.s.a.t', 'g.o.b.l.o.k', 'k.o.n.t.o.l', 'm.e.m.e.k',
'n.g.e.n.t.o.t', 'p.e.l.e.r', 't.a.i', 't.o.l.o.l', 'j.a.n.c.o.k', 'j.e.m.b.u.t',
'k.a.m.p.r.e.t', 's.i.a.l.a.n', 'w.i.b.u',
// 📱 Variasi dengan Angka & Simbol
'4nj1ng', 'b4b1', 'b4ngs4t', 'g0bl0k', 'k0nt0l', 'm3m3k', 'ng3nt0t', 'p3l3r',
't4i', 't0l0l', 'j4nc0k', 'j3mbut', 'k4mpr3t', 's14l4n', 'w1bu',
'4nj1ngg', 'b4b11', 'b4ngs4tt', 'g0bl0kk', 'k0nt0ll', 'm3m3kk', 'ng3nt0tt',
'p3l3rr', 't4ii', 't0l0ll', 'j4nc0kk', 'j3mbutt', 'k4mpr3tt', 's14l4nn', 'w1buu',
// 🗣️ Kata yang Sering Digunakan dalam Konteks Negatif
'dasar', 'kamu', 'kau', 'lu', 'lo', 'gue', 'gua', 'kita', 'kami', 'mereka',
'dasarr', 'kamuu', 'kauu', 'luu', 'loo', 'guee', 'guua', 'kitaa', 'kamii', 'merekaa',
'dasar bodoh', 'dasar goblok', 'dasar bangsat', 'dasar idiot', 'dasar sialan',
'dasar bego', 'dasar dungu', 'dasar edan', 'dasar gila', 'dasar sinting',
'dasar pemalas', 'dasar pengecut', 'dasar penipu', 'dasar najis', 'dasar kampret',
// 🚫 Kata yang Mengandung Unsur Seksual
'porno', 'seks', 'mesum', 'bugil', 'telanjang', 'payudara', 'pantat', 'vagina', 'penis',
'pornoo', 'sekss', 'mesumm', 'bugill', 'telanjangg', 'payudaraa', 'pantatt', 'vaginna',
'peniss', 'pornoografi', 'pornografi', 'porno graf i', 'seksual', 'seksualitas',
'pornoograffii', 'pornografffii', 'porno graf ii', 'seksuall', 'seksualitass',
// 🤬 Kata Kasar dari Bahasa Daerah (Sunda, Jawa, dll)
'kampret', 'kacung', 'mampus', 'sialan', 'bangsat', 'goblok', 'bodoh', 'tolol',
'kamprett', 'kacungg', 'mampuss', 'sialann', 'bangsaatt', 'gobllokk', 'bodooh', 'tololl',
'kampret sunda', 'kacung jawa', 'mampus batak', 'sialan minang', 'bangsat lampung',
'goblok palembang', 'bodoh medan', 'tolol makassar',
// 📉 Kata yang Sering Digunakan untuk Menjelekkan Orang
// 'jelek', 'buruk', 'tidak pantas', 'tidak sopan', 'tidak beretika', 'tidak beradab',
// 'jelekk', 'burukk', 'tidak pantass', 'tidak sopann', 'tidak beretikaa', 'tidak beradabb',
// 'jelek banget', 'buruk banget', 'tidak pantas banget', 'tidak sopan banget',
// 'tidak beretika banget', 'tidak beradab banget',
// 🛑 Kata yang Sering Digunakan untuk Menyebarkan Hoax
// 'hoax', 'bohong', 'palsu', 'tipu', 'menipu', 'menyesatkan', 'menjerumuskan',
// 'hoaxx', 'bohongg', 'palsuu', 'tipuu', 'menipuu', 'menyesatkanng', 'menjerumuskanng',
// 'hoax besar', 'bohong besar', 'palsu besar', 'tipu besar', 'menipu besar',
// 'menyesatkan besar', 'menjerumuskan besar'
];
// Normalisasi teks
const normalizeText = (text: string) => {
return text.toLowerCase().replace(/\s+/g, ' ').trim();
};
// Cek apakah teks mengandung kata buruk
const isBadContent = (text: string) => {
const normalized = normalizeText(text);
for (let word of badWordsIndonesia) {
if (normalized.includes(word)) {
return true;
}
}
return false;
};
// Saring teks (ganti dengan asterisk)
const censorText = (text: string) => {
let result = text;
for (let word of badWordsIndonesia) {
const regex = new RegExp(word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi');
result = result.replace(regex, '*'.repeat(word.length));
}
return result;
};
export {
badWordsIndonesia,
isBadContent,
censorText,
normalizeText
};

18
utils/viersionBadge.ts Normal file
View File

@@ -0,0 +1,18 @@
// VersionBadge.tsx
import Constants from "expo-constants";
import { Platform } from "react-native";
export default function versionBadge() {
const expoConfig = Constants.expoConfig;
const version = expoConfig?.version; // "1.0.1"
const iosBuild = expoConfig?.ios?.buildNumber; // "10"
const androidBuild = expoConfig?.android?.versionCode; // 2
const build =
Platform.OS === "ios" ? iosBuild : androidBuild;
const result = `${version} ( ${build} )`;
return result
}