Compare commits
32 Commits
apple-reje
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 60e5c0663c | |||
| 2c0198b1b7 | |||
| 573b525352 | |||
| ae0bf4dd60 | |||
| 6f9481c7c9 | |||
| bb63f7fa9a | |||
| cccb44a835 | |||
| 0f5862ce70 | |||
| 9742c1849a | |||
| 624bd49f69 | |||
| 2446e9d51a | |||
| 2265ef64cc | |||
| ab5733f336 | |||
| f5e30087ed | |||
| fbd096af9c | |||
| a93f97ed6a | |||
| 5019b00f59 | |||
| 858b441a8c | |||
| 249ada221b | |||
| 98aaa126a1 | |||
| 19814315a4 | |||
| 69452ff4e7 | |||
| 33ec892ec8 | |||
| 77ef3a055e | |||
| 8a900e9469 | |||
| aba3ad8ded | |||
| 7799c7720d | |||
| 2926b6eac1 | |||
| 637d444c5c | |||
| a614cfaac9 | |||
| 1a7ad58505 | |||
| 7612be7366 |
@@ -82,6 +82,14 @@ def enableMinifyInReleaseBuilds = (findProperty('android.enableMinifyInReleaseBu
|
|||||||
def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+'
|
def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
// @generated begin @rnmapbox/maps-libcpp - expo prebuild (DO NOT MODIFY) sync-e24830a5a3e854b398227dfe9630aabfaa1cadd1
|
||||||
|
packagingOptions {
|
||||||
|
pickFirst 'lib/x86/libc++_shared.so'
|
||||||
|
pickFirst 'lib/x86_64/libc++_shared.so'
|
||||||
|
pickFirst 'lib/arm64-v8a/libc++_shared.so'
|
||||||
|
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
|
||||||
|
}
|
||||||
|
// @generated end @rnmapbox/maps-libcpp
|
||||||
ndkVersion rootProject.ext.ndkVersion
|
ndkVersion rootProject.ext.ndkVersion
|
||||||
|
|
||||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||||
@@ -92,7 +100,7 @@ android {
|
|||||||
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'}\""
|
||||||
|
|||||||
@@ -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"/>
|
||||||
|
|||||||
BIN
android/app/src/main/res/drawable-hdpi/notification_icon.png
Normal file
BIN
android/app/src/main/res/drawable-hdpi/notification_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
BIN
android/app/src/main/res/drawable-mdpi/notification_icon.png
Normal file
BIN
android/app/src/main/res/drawable-mdpi/notification_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
android/app/src/main/res/drawable-xhdpi/notification_icon.png
Normal file
BIN
android/app/src/main/res/drawable-xhdpi/notification_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
BIN
android/app/src/main/res/drawable-xxhdpi/notification_icon.png
Normal file
BIN
android/app/src/main/res/drawable-xxhdpi/notification_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
BIN
android/app/src/main/res/drawable-xxxhdpi/notification_icon.png
Normal file
BIN
android/app/src/main/res/drawable-xxxhdpi/notification_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.6 KiB |
@@ -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>
|
||||||
@@ -23,3 +23,25 @@ allprojects {
|
|||||||
|
|
||||||
apply plugin: "expo-root-project"
|
apply plugin: "expo-root-project"
|
||||||
apply plugin: "com.facebook.react.rootproject"
|
apply plugin: "com.facebook.react.rootproject"
|
||||||
|
// @generated begin @rnmapbox/maps-v2-maven - expo prebuild (DO NOT MODIFY) sync-d4ccbfdff48fdba3138b02a8ba41b9722af001d8
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'https://api.mapbox.com/downloads/v2/releases/maven'
|
||||||
|
// Authentication is no longer required as per Mapbox's removal of download token requirement
|
||||||
|
// See: https://github.com/mapbox/mapbox-maps-flutter/issues/775
|
||||||
|
// Keeping this as optional for backward compatibility
|
||||||
|
def token = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: System.getenv('RNMAPBOX_MAPS_DOWNLOAD_TOKEN')
|
||||||
|
if (token) {
|
||||||
|
authentication { basic(BasicAuthentication) }
|
||||||
|
credentials {
|
||||||
|
username = 'mapbox'
|
||||||
|
password = token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @generated end @rnmapbox/maps-v2-maven
|
||||||
@@ -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: "8",
|
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: {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ export default function CollaborationCreate() {
|
|||||||
<TextAreaCustom
|
<TextAreaCustom
|
||||||
required
|
required
|
||||||
label="Keuntungan Proyek"
|
label="Keuntungan Proyek"
|
||||||
placeholder="Masukan keuntungan proyek"
|
placeholder="Masukan keuntungan proyek, contoh: Meningkatkan relasi bisnis , menjamin kualitas produk, meningkatkan kinerja dan lain lain"
|
||||||
showCount
|
showCount
|
||||||
maxLength={1000}
|
maxLength={1000}
|
||||||
value={data?.benefit}
|
value={data?.benefit}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
import { apiMasterEventType } from "@/service/api-client/api-master";
|
import { apiMasterEventType } from "@/service/api-client/api-master";
|
||||||
import { DateTimePickerEvent } from "@react-native-community/datetimepicker";
|
import { DateTimePickerEvent } from "@react-native-community/datetimepicker";
|
||||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function EventEdit() {
|
export default function EventEdit() {
|
||||||
@@ -55,6 +55,7 @@ export default function EventEdit() {
|
|||||||
try {
|
try {
|
||||||
setIsLoadData(true);
|
setIsLoadData(true);
|
||||||
const response = await apiEventGetOne({ id: id as string });
|
const response = await apiEventGetOne({ id: id as string });
|
||||||
|
console.log("[DATA BY ID]", JSON.stringify(response, null, 2));
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setData(response.data);
|
setData(response.data);
|
||||||
setSelectedDate(new Date(response.data.tanggal));
|
setSelectedDate(new Date(response.data.tanggal));
|
||||||
@@ -209,7 +210,7 @@ export default function EventEdit() {
|
|||||||
minimumDate={new Date(Date.now())}
|
minimumDate={new Date(Date.now())}
|
||||||
label="Tanggal & Waktu Mulai"
|
label="Tanggal & Waktu Mulai"
|
||||||
required
|
required
|
||||||
value={selectedDate as any}
|
value={selectedDate}
|
||||||
onChange={(date: any) => {
|
onChange={(date: any) => {
|
||||||
setSelectedDate(date as any);
|
setSelectedDate(date as any);
|
||||||
}}
|
}}
|
||||||
@@ -254,7 +255,6 @@ export default function EventEdit() {
|
|||||||
placeholder="Masukkan deskripsi event"
|
placeholder="Masukkan deskripsi event"
|
||||||
required
|
required
|
||||||
showCount
|
showCount
|
||||||
maxLength={100}
|
|
||||||
value={data?.deskripsi}
|
value={data?.deskripsi}
|
||||||
onChangeText={(value) => setData({ ...data, deskripsi: value })}
|
onChangeText={(value) => setData({ ...data, deskripsi: value })}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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)} />,
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ export default function EventCreate() {
|
|||||||
const response = await apiEventCreate(newData);
|
const response = await apiEventCreate(newData);
|
||||||
console.log("Response", JSON.stringify(response, null, 2));
|
console.log("Response", JSON.stringify(response, null, 2));
|
||||||
|
|
||||||
router.navigate("/event/status");
|
router.replace("/event/status");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -118,6 +118,7 @@ export default function EventCreate() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const buttonSubmit = (
|
const buttonSubmit = (
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
@@ -144,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 })
|
||||||
}
|
}
|
||||||
@@ -191,7 +192,7 @@ export default function EventCreate() {
|
|||||||
placeholder="Masukkan deskripsi event"
|
placeholder="Masukkan deskripsi event"
|
||||||
required
|
required
|
||||||
showCount
|
showCount
|
||||||
maxLength={1000}
|
value={data?.deskripsi || ""}
|
||||||
onChangeText={(value: any) =>
|
onChangeText={(value: any) =>
|
||||||
setData({ ...data, deskripsi: value })
|
setData({ ...data, deskripsi: value })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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({
|
||||||
|
|||||||
@@ -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({
|
||||||
|
|||||||
@@ -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 });
|
||||||
|
|||||||
202
app/(application)/(user)/forum/terms.tsx
Normal file
202
app/(application)/(user)/forum/terms.tsx
Normal 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",
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -11,25 +11,30 @@ 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
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
onLoadData();
|
onLoadData();
|
||||||
checkVersion();
|
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);
|
||||||
@@ -40,6 +45,13 @@ export default function Application() {
|
|||||||
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>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import Investment_ButtonInvestasiSection from "@/screens/Invesment/ButtonInvesta
|
|||||||
import Invesment_ComponentBoxOnBottomDetail from "@/screens/Invesment/ComponentBoxOnBottomDetail";
|
import Invesment_ComponentBoxOnBottomDetail from "@/screens/Invesment/ComponentBoxOnBottomDetail";
|
||||||
import Invesment_DetailDataPublishSection from "@/screens/Invesment/DetailDataPublishSection";
|
import Invesment_DetailDataPublishSection from "@/screens/Invesment/DetailDataPublishSection";
|
||||||
import { apiInvestmentGetOne } from "@/service/api-client/api-investment";
|
import { apiInvestmentGetOne } from "@/service/api-client/api-investment";
|
||||||
|
import { countDownAndCondition } from "@/utils/countDownAndCondition";
|
||||||
import { AntDesign, MaterialIcons } from "@expo/vector-icons";
|
import { AntDesign, MaterialIcons } from "@expo/vector-icons";
|
||||||
import {
|
import {
|
||||||
router,
|
router,
|
||||||
@@ -23,7 +24,7 @@ import {
|
|||||||
useLocalSearchParams,
|
useLocalSearchParams,
|
||||||
} from "expo-router";
|
} from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
export default function InvestmentDetail() {
|
export default function InvestmentDetail() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
@@ -62,6 +63,31 @@ export default function InvestmentDetail() {
|
|||||||
setOpenDrawerPublish(false);
|
setOpenDrawerPublish(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [value, setValue] = useState({
|
||||||
|
sisa: 0,
|
||||||
|
reminder: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
updateCountDown();
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
console.log("[DATA DETAIL]", JSON.stringify(data, null, 2));
|
||||||
|
|
||||||
|
const updateCountDown = () => {
|
||||||
|
const countDown = countDownAndCondition({
|
||||||
|
duration: data?.MasterPencarianInvestor.name,
|
||||||
|
publishTime: data?.countDown,
|
||||||
|
});
|
||||||
|
|
||||||
|
setValue({
|
||||||
|
sisa: countDown.durationDay,
|
||||||
|
reminder: countDown.reminder,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const bottomSection = (
|
const bottomSection = (
|
||||||
<Invesment_ComponentBoxOnBottomDetail
|
<Invesment_ComponentBoxOnBottomDetail
|
||||||
id={id as string}
|
id={id as string}
|
||||||
@@ -71,7 +97,7 @@ export default function InvestmentDetail() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const buttonSection = (
|
const buttonSection = (
|
||||||
<Investment_ButtonInvestasiSection id={id as string} isMine={user?.id === data?.author?.id} />
|
<Investment_ButtonInvestasiSection id={id as string} isMine={user?.id === data?.author?.id} reminder={value.reminder} />
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -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(
|
||||||
|
useCallback(() => {
|
||||||
onLoadMaster();
|
onLoadMaster();
|
||||||
onLoadMasterSubBidangBisnis();
|
onLoadMasterSubBidangBisnis();
|
||||||
}, []);
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
const onLoadMaster = async () => {
|
const onLoadMaster = async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -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 = {
|
||||||
|
|||||||
148
app/(application)/(user)/profile/[id]/blocked-list.tsx
Normal file
148
app/(application)/(user)/profile/[id]/blocked-list.tsx
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
import {
|
||||||
|
AvatarUsernameAndOtherComponent,
|
||||||
|
BadgeCustom,
|
||||||
|
ClickableCustom,
|
||||||
|
Divider,
|
||||||
|
SelectCustom,
|
||||||
|
TextCustom,
|
||||||
|
} from "@/components";
|
||||||
|
import ListEmptyComponent from "@/components/_ShareComponent/ListEmptyComponent";
|
||||||
|
import ListLoaderFooterComponent from "@/components/_ShareComponent/ListLoaderFooterComponent";
|
||||||
|
import ListSkeletonComponent from "@/components/_ShareComponent/ListSkeletonComponent";
|
||||||
|
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
|
||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
|
import { usePaginatedApi } from "@/hooks/use-paginated-api";
|
||||||
|
import { apiGetBlocked } from "@/service/api-client/api-blocked";
|
||||||
|
import { apiMasterAppCategory } from "@/service/api-client/api-master";
|
||||||
|
import { router, useFocusEffect } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
import { RefreshControl, View } from "react-native";
|
||||||
|
|
||||||
|
const PAGE_SIZE = 10;
|
||||||
|
export default function ProfileBlockedList() {
|
||||||
|
const { user } = useAuth();
|
||||||
|
const [masterApp, setMasterApp] = useState<any[]>([]);
|
||||||
|
const isInitialMount = useRef(true);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: listData,
|
||||||
|
loading,
|
||||||
|
refreshing,
|
||||||
|
hasMore,
|
||||||
|
search,
|
||||||
|
setSearch,
|
||||||
|
onRefresh,
|
||||||
|
loadMore,
|
||||||
|
} = usePaginatedApi({
|
||||||
|
fetcher: async (params: { page: number; search?: string }) => {
|
||||||
|
const response = await apiGetBlocked({
|
||||||
|
id: user?.id as any,
|
||||||
|
search: search,
|
||||||
|
page: String(params.page) as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
initialSearch: "",
|
||||||
|
pageSize: PAGE_SIZE,
|
||||||
|
dependencies: [user?.id],
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchMasterApp();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// 🔁 Refresh otomatis saat kembali ke halaman ini
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
if (isInitialMount.current) {
|
||||||
|
// Skip saat pertama kali mount
|
||||||
|
isInitialMount.current = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Hanya refresh saat kembali dari screen lain
|
||||||
|
onRefresh();
|
||||||
|
}, [onRefresh])
|
||||||
|
);
|
||||||
|
|
||||||
|
const fetchMasterApp = async () => {
|
||||||
|
const response = await apiMasterAppCategory();
|
||||||
|
setMasterApp(response.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderHeader = () => (
|
||||||
|
<SelectCustom
|
||||||
|
placeholder="Pilih Kategori Fitur"
|
||||||
|
data={masterApp.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}))}
|
||||||
|
value={search === "" ? undefined : search}
|
||||||
|
onChange={(value) => {
|
||||||
|
setSearch(value as any);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderItem = ({ item }: { item: any }) => (
|
||||||
|
<>
|
||||||
|
<ClickableCustom
|
||||||
|
onPress={() => {
|
||||||
|
router.push(`/profile/${item.id}/detail-blocked`);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
paddingInline: 8,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AvatarUsernameAndOtherComponent
|
||||||
|
avatarHref={`/profile/${item?.blocked?.Profile?.id}`}
|
||||||
|
avatar={item?.blocked?.Profile?.imageId}
|
||||||
|
name={item?.blocked?.username}
|
||||||
|
rightComponent={
|
||||||
|
<View style={{ flexDirection: "row", gap: 4 }}>
|
||||||
|
<BadgeCustom>
|
||||||
|
<TextCustom size={"small"} bold truncate>
|
||||||
|
{item?.menuFeature?.name}
|
||||||
|
</TextCustom>
|
||||||
|
</BadgeCustom>
|
||||||
|
</View>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Divider color="gray" />
|
||||||
|
</View>
|
||||||
|
</ClickableCustom>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<NewWrapper
|
||||||
|
// headerComponent={renderHeader()}
|
||||||
|
listData={listData}
|
||||||
|
renderItem={renderItem}
|
||||||
|
onEndReached={loadMore}
|
||||||
|
refreshControl={
|
||||||
|
<RefreshControl
|
||||||
|
progressBackgroundColor={MainColor.yellow}
|
||||||
|
refreshing={refreshing}
|
||||||
|
onRefresh={onRefresh}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
ListFooterComponent={
|
||||||
|
hasMore && !refreshing ? <ListLoaderFooterComponent /> : null
|
||||||
|
}
|
||||||
|
ListEmptyComponent={
|
||||||
|
!loading && _.isEmpty(listData) ? (
|
||||||
|
<ListSkeletonComponent />
|
||||||
|
) : (
|
||||||
|
<ListEmptyComponent />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
93
app/(application)/(user)/profile/[id]/detail-blocked.tsx
Normal file
93
app/(application)/(user)/profile/[id]/detail-blocked.tsx
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import {
|
||||||
|
AlertDefaultSystem,
|
||||||
|
AvatarUsernameAndOtherComponent,
|
||||||
|
BaseBox,
|
||||||
|
BoxButtonOnFooter,
|
||||||
|
BoxWithHeaderSection,
|
||||||
|
ButtonCustom,
|
||||||
|
NewWrapper,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
|
} from "@/components";
|
||||||
|
import AvatarAndBackground from "@/screens/Profile/AvatarAndBackground";
|
||||||
|
import {
|
||||||
|
apiGetBlockedById,
|
||||||
|
apiUnblock,
|
||||||
|
} from "@/service/api-client/api-blocked";
|
||||||
|
import { router, useLocalSearchParams } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
export default function ProfileDetailBlocked() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
const [data, setData] = useState<any>(null);
|
||||||
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchData();
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
const response = await apiGetBlockedById({ id: String(id) });
|
||||||
|
// console.log("[RESPONSE >>]", JSON.stringify(response, null, 2));
|
||||||
|
setData(response.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
await apiUnblock({ id: String(id) });
|
||||||
|
router.back();
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR >>]", JSON.stringify(error, null, 2));
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<NewWrapper
|
||||||
|
footerComponent={
|
||||||
|
<BoxButtonOnFooter>
|
||||||
|
<ButtonCustom
|
||||||
|
isLoading={isLoading}
|
||||||
|
onPress={() => {
|
||||||
|
AlertDefaultSystem({
|
||||||
|
title: "Buka Blokir",
|
||||||
|
message: "Apakah anda yakin ingin membuka blokir ini?",
|
||||||
|
textLeft: "Tidak",
|
||||||
|
textRight: "Ya",
|
||||||
|
onPressRight: () => {
|
||||||
|
handleSubmit();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Buka Blokir
|
||||||
|
</ButtonCustom>
|
||||||
|
</BoxButtonOnFooter>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<BoxWithHeaderSection>
|
||||||
|
<StackCustom>
|
||||||
|
<AvatarUsernameAndOtherComponent
|
||||||
|
avatarHref={`/profile/${data?.blocked?.Profile?.id}`}
|
||||||
|
avatar={data?.blocked?.Profile?.imageId}
|
||||||
|
name={data?.blocked?.username}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextCustom align="center">
|
||||||
|
Jika anda membuka blokir ini maka semua postingan terkait user ini
|
||||||
|
akan muncul kembali di beranda
|
||||||
|
<TextCustom bold color="red">
|
||||||
|
{" "}
|
||||||
|
{_.upperCase(data?.menuFeature?.name)}
|
||||||
|
</TextCustom>
|
||||||
|
</TextCustom>
|
||||||
|
</StackCustom>
|
||||||
|
</BoxWithHeaderSection>
|
||||||
|
</NewWrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -64,6 +64,7 @@ export default function Profile() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onLoadPortofolio = async (id: string) => {
|
const onLoadPortofolio = async (id: string) => {
|
||||||
|
try {
|
||||||
const response = await apiGetPortofolio({ id: id });
|
const response = await apiGetPortofolio({ id: id });
|
||||||
const lastTwoByDate = response.data
|
const lastTwoByDate = response.data
|
||||||
.sort(
|
.sort(
|
||||||
@@ -72,6 +73,9 @@ export default function Profile() {
|
|||||||
) // urut desc
|
) // urut desc
|
||||||
.slice(0, 2);
|
.slice(0, 2);
|
||||||
setListPortofolio(lastTwoByDate);
|
setListPortofolio(lastTwoByDate);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -33,6 +33,16 @@ export default function ProfileLayout() {
|
|||||||
name="create"
|
name="create"
|
||||||
options={{ title: "Buat Profile", headerBackVisible: false }}
|
options={{ title: "Buat Profile", headerBackVisible: false }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Stack.Screen
|
||||||
|
name="[id]/blocked-list"
|
||||||
|
options={{ title: "Blocked List", headerLeft: () => <BackButton /> }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Stack.Screen
|
||||||
|
name="[id]/detail-blocked"
|
||||||
|
options={{ title: "Detail Blokir", headerLeft: () => <BackButton /> }}
|
||||||
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import Voting_BoxPublishSection from "@/screens/Voting/BoxPublishSection";
|
import Voting_BoxPublishSection from "@/screens/Voting/BoxPublishSection";
|
||||||
import { apiVotingGetAll } from "@/service/api-client/api-voting";
|
import { apiVotingGetAll } from "@/service/api-client/api-voting";
|
||||||
import { router, useFocusEffect } from "expo-router";
|
import { router, useFocusEffect } from "expo-router";
|
||||||
@@ -13,6 +14,7 @@ import _ from "lodash";
|
|||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function VotingBeranda() {
|
export default function VotingBeranda() {
|
||||||
|
const { user } = useAuth();
|
||||||
const [listData, setListData] = useState<any>([]);
|
const [listData, setListData] = useState<any>([]);
|
||||||
const [loadingGetData, setLoadingGetData] = useState(false);
|
const [loadingGetData, setLoadingGetData] = useState(false);
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
@@ -29,6 +31,7 @@ export default function VotingBeranda() {
|
|||||||
const response = await apiVotingGetAll({
|
const response = await apiVotingGetAll({
|
||||||
search,
|
search,
|
||||||
category: "beranda",
|
category: "beranda",
|
||||||
|
userLoginId: user?.id,
|
||||||
});
|
});
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setListData(response.data);
|
setListData(response.data);
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ export default function VotingDetailStatus() {
|
|||||||
|
|
||||||
{data &&
|
{data &&
|
||||||
data?.catatan &&
|
data?.catatan &&
|
||||||
(status === "draft" || status === "rejected") && (
|
(status === "draft" || status === "reject") && (
|
||||||
<ReportBox text={data?.catatan} />
|
<ReportBox text={data?.catatan} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
ButtonCenteredOnly,
|
ButtonCenteredOnly,
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
InformationBox,
|
InformationBox,
|
||||||
|
NewWrapper,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
@@ -12,6 +13,7 @@ import { useAuth } from "@/hooks/use-auth";
|
|||||||
import { apiUser } from "@/service/api-client/api-user";
|
import { apiUser } from "@/service/api-client/api-user";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
|
import { RefreshControl } from "react-native";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function WaitingRoom() {
|
export default function WaitingRoom() {
|
||||||
@@ -33,7 +35,7 @@ export default function WaitingRoom() {
|
|||||||
} else {
|
} else {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "success",
|
type: "success",
|
||||||
text1: "Akun anda telah aktif", // text2: "Anda berhasil login",
|
text1: "Selamat ! Akun anda telah aktif", // text2: "Anda berhasil login",
|
||||||
});
|
});
|
||||||
router.replace(`/(application)/(user)/profile/create`);
|
router.replace(`/(application)/(user)/profile/create`);
|
||||||
}
|
}
|
||||||
@@ -82,10 +84,18 @@ export default function WaitingRoom() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper footerComponent={logoutButton()}>
|
<NewWrapper
|
||||||
|
footerComponent={logoutButton()}
|
||||||
|
refreshControl={
|
||||||
|
<RefreshControl refreshing={isLoading} onRefresh={handleCheck} />
|
||||||
|
}
|
||||||
|
>
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
<InformationBox text="Permohonan akses Anda sedang dalam proses verifikasi oleh admin. Harap tunggu, Anda akan menerima pemberitahuan melalui Whatsapp setelah disetujui." />
|
<InformationBox
|
||||||
<ButtonCenteredOnly
|
text="Akun Anda sedang menunggu aktivasi.
|
||||||
|
Silakan tunggu beberapa saat. Untuk memperbarui status, tarik layar ke bawah."
|
||||||
|
/>
|
||||||
|
{/* <ButtonCenteredOnly
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
handleCheck();
|
handleCheck();
|
||||||
@@ -93,9 +103,9 @@ export default function WaitingRoom() {
|
|||||||
icon="refresh-ccw"
|
icon="refresh-ccw"
|
||||||
>
|
>
|
||||||
Check
|
Check
|
||||||
</ButtonCenteredOnly>
|
</ButtonCenteredOnly> */}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</NewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,40 +1,81 @@
|
|||||||
import {
|
import {
|
||||||
|
ActionIcon,
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
|
CenterCustom,
|
||||||
|
Grid,
|
||||||
|
Spacing,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
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 { 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>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ const listPage = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "2",
|
id: "2",
|
||||||
label: "Bidang Bisnis",
|
label: "Bidang & Sub Bidang",
|
||||||
value: "business",
|
value: "business",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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}
|
|
||||||
style={{ justifyContent: "center", paddingRight: 10 }}
|
|
||||||
>
|
|
||||||
<TextCustom bold>Nama</TextCustom>
|
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col span={8} style={{ justifyContent: "center" }}>
|
<Grid.Col span={6} style={{ justifyContent: "center" }}>
|
||||||
<TextCustom>
|
<TextCustom bold>
|
||||||
{item?.User?.Profile?.name || "-"}
|
{item?.User?.username || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid>
|
</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>
|
||||||
|
|||||||
@@ -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";
|
||||||
@@ -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={
|
|
||||||
<ActionIcon
|
|
||||||
icon={
|
|
||||||
<Octicons
|
|
||||||
name="eye"
|
|
||||||
size={ICON_SIZE_BUTTON}
|
|
||||||
color="black"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
router.push(`/admin/collaboration/${item.id}/group`);
|
router.push(`/admin/collaboration/${item.id}/group`);
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
}
|
<GridSpan_NewComponent
|
||||||
value2={
|
span1={6}
|
||||||
<TextCustom truncate={1}>
|
span2={6}
|
||||||
|
text1={
|
||||||
|
<TextCustom truncate={1} align="center">
|
||||||
{item?.ProjectCollaboration_AnggotaRoomChat?.length ||
|
{item?.ProjectCollaboration_AnggotaRoomChat?.length ||
|
||||||
"-"}
|
"-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
value3={
|
text2={
|
||||||
<TextCustom truncate={2}>{item?.name || "-"}</TextCustom>
|
<TextCustom truncate={2}>
|
||||||
|
{item?.name || "-"}
|
||||||
|
</TextCustom>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</ClickableCustom>
|
||||||
</View>
|
</View>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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={
|
|
||||||
<ActionIcon
|
|
||||||
icon={
|
|
||||||
<Octicons
|
|
||||||
name="eye"
|
|
||||||
size={ICON_SIZE_BUTTON}
|
|
||||||
color="black"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
router.push(`/admin/collaboration/${item?.id}/publish`);
|
router.push(`/admin/collaboration/${item?.id}/publish`);
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
}
|
<GridSpan_NewComponent
|
||||||
value2={
|
text1={
|
||||||
<TextCustom align="center" truncate={1}>
|
<TextCustom truncate={1}>
|
||||||
{item?.Author?.username || "-"}{" "}
|
{item?.Author?.username || "-"}{" "}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
value3={
|
text2={
|
||||||
<TextCustom align="center" truncate={2}>
|
<TextCustom truncate={2}>
|
||||||
{item?.title || "-"}
|
{item?.title || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</ClickableCustom>
|
||||||
|
<Spacing height={8}/>
|
||||||
|
<Divider/>
|
||||||
</View>
|
</View>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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>}
|
||||||
|
|||||||
@@ -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>}
|
||||||
|
|||||||
@@ -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>}
|
||||||
|
|||||||
@@ -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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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
|
|
||||||
component1={
|
|
||||||
<CenterCustom>
|
|
||||||
<ActionIcon
|
|
||||||
icon={
|
|
||||||
<IconEdit size={ICON_SIZE_BUTTON} color="black" />
|
|
||||||
}
|
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
router.push(`/admin/donation/category-update?id=${index}`);
|
router.push(`/admin/donation/category-update?id=${item.id}`);
|
||||||
}}
|
}}
|
||||||
/>
|
key={index}
|
||||||
|
>
|
||||||
|
<GridSpan_4_8
|
||||||
|
label={
|
||||||
|
<CenterCustom>
|
||||||
|
<BadgeCustom
|
||||||
|
color={colorActivationForBadge({
|
||||||
|
status: item.active,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{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}
|
|
||||||
|
|
||||||
/>
|
/>
|
||||||
}
|
{/* <Grid containerStyle={{ paddingBottom: 10 }}>
|
||||||
component3={<TextCustom bold>{item.label}</TextCustom>}
|
<Grid.Col span={4} style={{ paddingLeft: 10 }}>
|
||||||
/>
|
<CenterCustom>
|
||||||
<Spacing height={10} />
|
<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",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -16,7 +16,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 } 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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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" }}>
|
||||||
|
{startDate &&
|
||||||
|
startDate.subtract(1, "hour").diff(dayjs()) < 0 ? (
|
||||||
<BadgeCustom
|
<BadgeCustom
|
||||||
style={{ alignSelf: "flex-end" }}
|
style={{ alignSelf: "flex-end" }}
|
||||||
color={item?.isPresent ? "green" : "red"}
|
color={item?.isPresent ? "green" : "red"}
|
||||||
>
|
>
|
||||||
{item?.isPresent ? "Hadir" : "Tidak Hadir"}
|
{item?.isPresent ? "Hadir" : "Tidak Hadir"}
|
||||||
</BadgeCustom>
|
</BadgeCustom>
|
||||||
|
) : (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
justifyContent: "flex-end",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BadgeCustom
|
||||||
|
style={{ alignSelf: "flex-end" }}
|
||||||
|
color="gray"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
</BadgeCustom>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid>
|
</Grid>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
|
|||||||
@@ -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={
|
|
||||||
<ActionIcon
|
|
||||||
icon={
|
|
||||||
<Octicons
|
|
||||||
name="eye"
|
|
||||||
size={ICON_SIZE_BUTTON}
|
|
||||||
color="black"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
router.push(`/admin/event/${item.id}/${status}`);
|
router.push(`/admin/event/${item.id}/${status}`);
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
}
|
<AdminTableValue
|
||||||
value2={
|
key={index}
|
||||||
|
value1={
|
||||||
<TextCustom truncate={1}>
|
<TextCustom truncate={1}>
|
||||||
{item?.Author?.username || "-"}
|
{item?.Author?.username || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
|
// <ActionIcon
|
||||||
|
// icon={
|
||||||
|
// <Octicons
|
||||||
|
// name="eye"
|
||||||
|
// size={ICON_SIZE_BUTTON}
|
||||||
|
// color="black"
|
||||||
|
// />
|
||||||
|
// }
|
||||||
|
// onPress={() => {
|
||||||
|
// router.push(`/admin/event/${item.id}/${status}`);
|
||||||
|
// }}
|
||||||
|
// />
|
||||||
}
|
}
|
||||||
value3={
|
value2={
|
||||||
<TextCustom align="center" truncate={2}>
|
<TextCustom truncate={1}>
|
||||||
{item?.title || "-"}
|
{dateTimeView({ date: item?.tanggal })}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom truncate={2}>{item?.title || "-"}</TextCustom>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
<Divider/>
|
||||||
|
</ClickableCustom>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
|
|||||||
@@ -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>}
|
||||||
|
|||||||
@@ -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,9 +126,10 @@ 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={
|
||||||
|
<CenterCustom>
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
@@ -134,23 +138,27 @@ export default function AdminForumReportComment() {
|
|||||||
id: item.id,
|
id: item.id,
|
||||||
username: item.User?.username,
|
username: item.User?.username,
|
||||||
kategori: item.ForumMaster_KategoriReport?.title,
|
kategori: item.ForumMaster_KategoriReport?.title,
|
||||||
keterangan: item.ForumMaster_KategoriReport?.deskripsi,
|
keterangan:
|
||||||
|
item.ForumMaster_KategoriReport?.deskripsi,
|
||||||
deskripsi: item.deskripsi,
|
deskripsi: item.deskripsi,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</CenterCustom>
|
||||||
}
|
}
|
||||||
value2={
|
text2={
|
||||||
<TextCustom truncate={1}>
|
<TextCustom truncate={1}>
|
||||||
{item?.User?.username || "-"}
|
{item?.User?.username || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
value3={
|
text3={
|
||||||
<TextCustom truncate={2} align="center">
|
<TextCustom truncate={2}>
|
||||||
{item?.ForumMaster_KategoriReport?.title || "-"}
|
{item?.ForumMaster_KategoriReport?.title || "-"}
|
||||||
</TextCustom>
|
</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>
|
||||||
|
|||||||
@@ -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={
|
||||||
|
<CenterCustom>
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
icon={
|
||||||
|
<IconView size={ICON_SIZE_BUTTON} color="black" />
|
||||||
|
}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setOpenDrawerAction(true);
|
setOpenDrawerAction(true);
|
||||||
setSelectedReport({
|
setSelectedReport({
|
||||||
id: item?.id,
|
id: item?.id,
|
||||||
username: item?.User?.username,
|
username: item?.User?.username,
|
||||||
kategori: item?.ForumMaster_KategoriReport?.title,
|
kategori: item?.ForumMaster_KategoriReport?.title,
|
||||||
keterangan: item?.ForumMaster_KategoriReport?.deskripsi,
|
keterangan:
|
||||||
|
item?.ForumMaster_KategoriReport?.deskripsi,
|
||||||
deskripsi: item?.deskripsi,
|
deskripsi: item?.deskripsi,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</CenterCustom>
|
||||||
}
|
}
|
||||||
value2={
|
text2={
|
||||||
<TextCustom truncate={1}>
|
<TextCustom truncate>
|
||||||
{item?.User?.username || "-"}
|
{item?.User?.username || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
value3={
|
text3={
|
||||||
<TextCustom truncate={2} align="center">
|
<TextCustom truncate={2}>
|
||||||
{item?.ForumMaster_KategoriReport?.title || "-"}
|
{item?.ForumMaster_KategoriReport?.title || "-"}
|
||||||
</TextCustom>
|
</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>
|
||||||
|
|||||||
@@ -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() {
|
||||||
@@ -38,6 +38,8 @@ export default function AdminForumPosting() {
|
|||||||
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} />
|
||||||
<StackCustom>
|
<GridSpan_NewComponent
|
||||||
<AdminTitleTable title1="Aksi" title2="Username" title3="Postingan" />
|
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 />
|
<Divider />
|
||||||
|
<Spacing />
|
||||||
|
<StackCustom>
|
||||||
{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={
|
|
||||||
<ActionIcon
|
|
||||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
router.push(`/admin/forum/${item?.id}`);
|
router.push(`/admin/forum/${item.id}`);
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
}
|
<GridSpan_NewComponent
|
||||||
value2={
|
text1={
|
||||||
<TextCustom truncate={1}>
|
<TextCustom truncate={1}>
|
||||||
{item?.Author?.username || "-"}
|
{item?.Author?.username || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
value3={
|
text2={
|
||||||
<TextCustom truncate={2}>{item?.diskusi || "-"}</TextCustom>
|
<TextCustom truncate>
|
||||||
|
{item?.diskusi || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
text3={
|
||||||
|
<TextCustom align="center" truncate={2}>
|
||||||
|
{item?.reportPosting || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
text4={
|
||||||
|
<TextCustom align="center" truncate={2}>
|
||||||
|
{item?.komentar || "-"}
|
||||||
|
</TextCustom>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
</ClickableCustom>
|
||||||
|
<Divider />
|
||||||
|
</View>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
}
|
||||||
|
text2={
|
||||||
|
<TextCustom bold truncate>
|
||||||
|
Komentar
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
text3={
|
||||||
|
<TextCustom bold truncate>
|
||||||
|
Jenis Laporan
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Divider />
|
<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={
|
|
||||||
<ActionIcon
|
|
||||||
icon={
|
|
||||||
<IconView
|
|
||||||
size={ICON_SIZE_BUTTON}
|
|
||||||
color={MainColor.black}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
router.push(
|
router.push(
|
||||||
`/admin/forum/${item?.Forum_Komentar?.id}/list-report-comment`
|
`/admin/forum/${item?.Forum_Komentar?.id}/list-report-comment`
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
}
|
<GridSpan_NewComponent
|
||||||
value2={
|
text1={
|
||||||
<TextCustom truncate={1}>
|
<TextCustom truncate={1}>
|
||||||
{item?.User?.username || "-"}
|
{item?.User?.username || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
value3={
|
text2={
|
||||||
<TextCustom truncate={2} align="center">
|
<TextCustom truncate={2}>
|
||||||
|
{item?.Forum_Komentar?.komentar || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
text3={
|
||||||
|
<TextCustom truncate={2}>
|
||||||
{item?.ForumMaster_KategoriReport?.title || "-"}
|
{item?.ForumMaster_KategoriReport?.title || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</ClickableCustom>
|
||||||
|
<Spacing />
|
||||||
|
<Divider />
|
||||||
|
</View>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
|
|||||||
@@ -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,10 +70,20 @@ export default function AdminForumReportPosting() {
|
|||||||
rightComponent={rightComponent}
|
rightComponent={rightComponent}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StackCustom gap={"sm"}>
|
<GridSpan_NewComponent
|
||||||
<AdminTitleTable title1="Aksi" title2="Pelapor" title3="Postingan" />
|
text1={
|
||||||
|
<TextCustom bold truncate>
|
||||||
|
Username
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
text2={
|
||||||
|
<TextCustom bold truncate>
|
||||||
|
Postingan
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Divider />
|
<Divider />
|
||||||
|
<StackCustom>
|
||||||
{loadList ? (
|
{loadList ? (
|
||||||
<LoaderCustom />
|
<LoaderCustom />
|
||||||
) : _.isEmpty(listData) ? (
|
) : _.isEmpty(listData) ? (
|
||||||
@@ -79,34 +92,29 @@ export default function AdminForumReportPosting() {
|
|||||||
</TextCustom>
|
</TextCustom>
|
||||||
) : (
|
) : (
|
||||||
listData?.map((item: any, index: number) => (
|
listData?.map((item: any, index: number) => (
|
||||||
<AdminTableValue
|
<View key={index}>
|
||||||
key={index}
|
<ClickableCustom
|
||||||
value1={
|
|
||||||
<ActionIcon
|
|
||||||
icon={
|
|
||||||
<IconView
|
|
||||||
size={ICON_SIZE_BUTTON}
|
|
||||||
color={MainColor.black}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
router.push(
|
router.push(
|
||||||
`/admin/forum/${item?.Forum_Posting?.id}/list-report-posting`
|
`/admin/forum/${item?.Forum_Posting?.id}/list-report-posting`
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
}
|
<GridSpan_NewComponent
|
||||||
value2={
|
text1={
|
||||||
<TextCustom truncate={1}>
|
<TextCustom truncate={1}>
|
||||||
{item?.User?.username || "-"}
|
{item?.User?.username || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
value3={
|
text2={
|
||||||
<TextCustom truncate={2} align="center">
|
<TextCustom truncate={1}>
|
||||||
{item?.Forum_Posting?.diskusi || "-"}
|
{item?.Forum_Posting?.diskusi || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</ClickableCustom>
|
||||||
|
<Divider />
|
||||||
|
</View>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export default function SuperAdmin_ListUser() {
|
|||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
component2={
|
component2={
|
||||||
<TextCustom align="center" bold>
|
<TextCustom bold>
|
||||||
Username
|
Username
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
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>}
|
||||||
|
|||||||
@@ -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>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export default function TermsAgreement() {
|
|||||||
<>
|
<>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
options={{
|
options={{
|
||||||
title: "Terms Agreement",
|
title: "Terms & Conditions",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ViewWrapper footerComponent={footerComponent}>
|
<ViewWrapper footerComponent={footerComponent}>
|
||||||
@@ -87,6 +87,7 @@ export default function TermsAgreement() {
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
marginTop: 16,
|
marginTop: 16,
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
|
paddingInline: 10,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CheckboxCustom value={term} onChange={() => setTerm(!term)} />
|
<CheckboxCustom value={term} onChange={() => setTerm(!term)} />
|
||||||
|
|||||||
16
components/Alert/AlertWarning.ts
Normal file
16
components/Alert/AlertWarning.ts
Normal 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: () => {},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -32,9 +32,10 @@ const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
fab: {
|
fab: {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
margin: 16,
|
margin: "auto",
|
||||||
right: 0,
|
right: 0,
|
||||||
bottom: 0,
|
// bottom: 10,
|
||||||
|
top: -20,
|
||||||
backgroundColor: AccentColor.softblue, // Warna Twitter biru
|
backgroundColor: AccentColor.softblue, // Warna Twitter biru
|
||||||
borderRadius: 50,
|
borderRadius: 50,
|
||||||
borderColor: AccentColor.blue,
|
borderColor: AccentColor.blue,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|
||||||
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||||
import { GStyles } from "@/styles/global-styles";
|
import { GStyles } from "@/styles/global-styles";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
@@ -6,7 +7,9 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
|
useColorScheme,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
|
import { PlaceholderColor } from "@/constants/color-palet";
|
||||||
|
|
||||||
type IconType = React.ReactNode | string;
|
type IconType = React.ReactNode | string;
|
||||||
|
|
||||||
@@ -48,7 +51,7 @@ const TextAreaCustom: React.FC<TextAreaCustomProps> = ({
|
|||||||
minRows = 4,
|
minRows = 4,
|
||||||
maxRows = 6,
|
maxRows = 6,
|
||||||
showCount = false,
|
showCount = false,
|
||||||
maxLength,
|
maxLength = 1000,
|
||||||
value,
|
value,
|
||||||
onChangeText,
|
onChangeText,
|
||||||
height = 100,
|
height = 100,
|
||||||
@@ -78,6 +81,9 @@ const TextAreaCustom: React.FC<TextAreaCustomProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const colorScheme = useColorScheme();
|
||||||
|
const theme = PlaceholderColor[colorScheme || "light"];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[GStyles.inputContainerArea]}>
|
<View style={[GStyles.inputContainerArea]}>
|
||||||
{label && (
|
{label && (
|
||||||
@@ -109,6 +115,7 @@ const TextAreaCustom: React.FC<TextAreaCustomProps> = ({
|
|||||||
GStyles.textAreaInput,
|
GStyles.textAreaInput,
|
||||||
{ color: fontColor },
|
{ color: fontColor },
|
||||||
]}
|
]}
|
||||||
|
placeholderTextColor={theme.placeholder}
|
||||||
editable={!disabled}
|
editable={!disabled}
|
||||||
value={value as string}
|
value={value as string}
|
||||||
onChangeText={onChangeText}
|
onChangeText={onChangeText}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { PlaceholderColor } from "@/constants/color-palet";
|
||||||
import { GStyles } from "@/styles/global-styles";
|
import { GStyles } from "@/styles/global-styles";
|
||||||
import Ionicons from "@expo/vector-icons/Ionicons";
|
import Ionicons from "@expo/vector-icons/Ionicons";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
@@ -8,8 +9,10 @@ import {
|
|||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
View,
|
View,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
|
useColorScheme
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
|
|
||||||
|
|
||||||
type IconType = React.ReactNode | string;
|
type IconType = React.ReactNode | string;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -74,6 +77,9 @@ const TextInputCustom = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const colorScheme = useColorScheme();
|
||||||
|
const theme = PlaceholderColor[colorScheme || "light"];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[GStyles.inputContainerArea, containerStyle]}>
|
<View style={[GStyles.inputContainerArea, containerStyle]}>
|
||||||
{label && (
|
{label && (
|
||||||
@@ -100,12 +106,14 @@ const TextInputCustom = ({
|
|||||||
{ color: fontColor },
|
{ color: fontColor },
|
||||||
disabled && GStyles.inputPlaceholderDisabled, // <-- placeholder saat disabled
|
disabled && GStyles.inputPlaceholderDisabled, // <-- placeholder saat disabled
|
||||||
]}
|
]}
|
||||||
|
placeholderTextColor={theme.placeholder}
|
||||||
editable={!disabled}
|
editable={!disabled}
|
||||||
secureTextEntry={secureTextEntry && !isPasswordVisible}
|
secureTextEntry={secureTextEntry && !isPasswordVisible}
|
||||||
keyboardType={keyboardType}
|
keyboardType={keyboardType}
|
||||||
onChangeText={handleTextChange}
|
onChangeText={handleTextChange}
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
{...rest}
|
{...rest}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
{secureTextEntry && (
|
{secureTextEntry && (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
27
components/_ShareComponent/GridSpan_4_8.tsx
Normal file
27
components/_ShareComponent/GridSpan_4_8.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
||||||
54
components/_ShareComponent/GridSpan_NewComponent.tsx
Normal file
54
components/_ShareComponent/GridSpan_NewComponent.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
||||||
20
components/_ShareComponent/ListEmptyComponent.tsx
Normal file
20
components/_ShareComponent/ListEmptyComponent.tsx
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { View } from "react-native";
|
||||||
|
import TextCustom from "../Text/TextCustom";
|
||||||
|
|
||||||
|
// Komponen Empty
|
||||||
|
const ListEmptyComponent = ({ search }: { search?: string }) => (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
padding: 20,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextCustom align="center" color="gray">
|
||||||
|
{search ? "Tidak ada hasil pencarian" : "Tidak ada data"}
|
||||||
|
</TextCustom>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default ListEmptyComponent;
|
||||||
11
components/_ShareComponent/ListLoaderFooterComponent.tsx
Normal file
11
components/_ShareComponent/ListLoaderFooterComponent.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { View } from "react-native";
|
||||||
|
import LoaderCustom from "../Loader/LoaderCustom";
|
||||||
|
|
||||||
|
const ListLoaderFooterComponent = () =>(
|
||||||
|
<View style={{ paddingVertical: 16, alignItems: "center" }}>
|
||||||
|
<LoaderCustom />
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
export default ListLoaderFooterComponent;
|
||||||
21
components/_ShareComponent/ListSkeletonComponent.tsx
Normal file
21
components/_ShareComponent/ListSkeletonComponent.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { View } from "react-native";
|
||||||
|
import StackCustom from "../Stack/StackCustom";
|
||||||
|
import SkeletonCustom from "./SkeletonCustom";
|
||||||
|
|
||||||
|
const ListSkeletonComponent = ({
|
||||||
|
length = 5,
|
||||||
|
height = 100,
|
||||||
|
}: {
|
||||||
|
length?: number;
|
||||||
|
height?: number;
|
||||||
|
}) => (
|
||||||
|
<View style={{ flex: 1 }}>
|
||||||
|
<StackCustom>
|
||||||
|
{Array.from({ length }).map((_, i) => (
|
||||||
|
<SkeletonCustom height={height} key={i} />
|
||||||
|
))}
|
||||||
|
</StackCustom>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default ListSkeletonComponent;
|
||||||
@@ -40,8 +40,8 @@ interface StaticModeProps extends BaseProps {
|
|||||||
|
|
||||||
interface ListModeProps extends BaseProps {
|
interface ListModeProps extends BaseProps {
|
||||||
children?: never;
|
children?: never;
|
||||||
listData: any[];
|
listData?: any[];
|
||||||
renderItem: FlatListProps<any>["renderItem"];
|
renderItem?: FlatListProps<any>["renderItem"];
|
||||||
onEndReached?: () => void;
|
onEndReached?: () => void;
|
||||||
// ✅ Gunakan tipe yang kompatibel dengan FlatList
|
// ✅ Gunakan tipe yang kompatibel dengan FlatList
|
||||||
ListHeaderComponent?: React.ReactElement | null;
|
ListHeaderComponent?: React.ReactElement | null;
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ import ViewWrapper from "./_ShareComponent/ViewWrapper";
|
|||||||
import SearchInput from "./_ShareComponent/SearchInput";
|
import SearchInput from "./_ShareComponent/SearchInput";
|
||||||
import DummyLandscapeImage from "./_ShareComponent/DummyLandscapeImage";
|
import DummyLandscapeImage from "./_ShareComponent/DummyLandscapeImage";
|
||||||
import GridComponentView from "./_ShareComponent/GridSectionView";
|
import GridComponentView from "./_ShareComponent/GridSectionView";
|
||||||
|
import NewWrapper from "./_ShareComponent/NewWrapper";
|
||||||
// Progress
|
// Progress
|
||||||
import ProgressCustom from "./Progress/ProgressCustom";
|
import ProgressCustom from "./Progress/ProgressCustom";
|
||||||
// Loader
|
// Loader
|
||||||
@@ -119,6 +120,7 @@ export {
|
|||||||
DummyLandscapeImage,
|
DummyLandscapeImage,
|
||||||
GridComponentView,
|
GridComponentView,
|
||||||
Spacing,
|
Spacing,
|
||||||
|
NewWrapper,
|
||||||
// Stack
|
// Stack
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TabBarBackground,
|
TabBarBackground,
|
||||||
|
|||||||
@@ -45,3 +45,23 @@ export const AdminColor = {
|
|||||||
// Warna Asli: #002e59
|
// Warna Asli: #002e59
|
||||||
// Warna Lebih Gelap: #001f3b
|
// Warna Lebih Gelap: #001f3b
|
||||||
// Warna Tergelap: #001323
|
// Warna Tergelap: #001323
|
||||||
|
|
||||||
|
|
||||||
|
export const PlaceholderColor = {
|
||||||
|
light: {
|
||||||
|
text: "#000",
|
||||||
|
placeholder: "#666",
|
||||||
|
border: "#ccc",
|
||||||
|
background: "#fff",
|
||||||
|
error: "#d00",
|
||||||
|
icon: "#555",
|
||||||
|
},
|
||||||
|
dark: {
|
||||||
|
text: "#fff",
|
||||||
|
placeholder: "#aaa",
|
||||||
|
border: "#444",
|
||||||
|
background: "#1a1a1a",
|
||||||
|
error: "#ff4d4d",
|
||||||
|
icon: "#ccc",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -72,8 +72,31 @@ 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));
|
||||||
|
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
console.log("[Keluar provider]", nomor);
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Sukses",
|
||||||
|
text2: "Kode OTP berhasil dikirim",
|
||||||
|
});
|
||||||
|
|
||||||
await AsyncStorage.setItem("kode_otp", response.kodeId);
|
await AsyncStorage.setItem("kode_otp", response.kodeId);
|
||||||
|
router.push(`/verification?nomor=${nomor}`);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
router.push(`/register?nomor=${nomor}`);
|
||||||
|
Toast.show({
|
||||||
|
type: "info",
|
||||||
|
text1: "Info",
|
||||||
|
text2: "Silahkan mendaftar",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
throw new Error(error.response?.data?.message || "Gagal kirim OTP");
|
throw new Error(error.response?.data?.message || "Gagal kirim OTP");
|
||||||
} finally {
|
} finally {
|
||||||
@@ -81,13 +104,26 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// const loginWithNomor = async (nomor: string) => {
|
||||||
|
// setIsLoading(true);
|
||||||
|
// try {
|
||||||
|
// const response = await apiLogin({ nomor: nomor });
|
||||||
|
// await AsyncStorage.setItem("kode_otp", response.kodeId);
|
||||||
|
// } catch (error: any) {
|
||||||
|
// throw new Error(error.response?.data?.message || "Gagal kirim OTP");
|
||||||
|
// } finally {
|
||||||
|
// setIsLoading(false);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
// --- 2. Validasi OTP & cek user ---
|
// --- 2. Validasi OTP & cek user ---
|
||||||
const validateOtp = async (nomor: string) => {
|
const validateOtp = async (nomor: string) => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await apiValidationCode({ nomor: nomor });
|
const response = await apiValidationCode({ nomor: nomor });
|
||||||
|
|
||||||
const { token } = response;
|
const { token } = response;
|
||||||
|
console.log("[RESPONSE VALIDASI OTP]", JSON.stringify(response, null, 2));
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setToken(token);
|
setToken(token);
|
||||||
await AsyncStorage.setItem("authToken", token);
|
await AsyncStorage.setItem("authToken", token);
|
||||||
@@ -104,20 +140,23 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
|
|
||||||
if (response.active) {
|
if (response.active) {
|
||||||
if (response.roleId === "1") {
|
if (response.roleId === "1") {
|
||||||
return "/(application)/(user)/home";
|
router.replace("/(application)/(user)/home");
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
return "/(application)/admin/dashboard";
|
router.replace("/(application)/admin/dashboard");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "/(application)/(user)/waiting-room";
|
router.replace("/(application)/(user)/waiting-room");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "info",
|
type: "info",
|
||||||
text1: "Anda belum terdaftar",
|
text1: "Terjadi kesalahan",
|
||||||
text2: "Silahkan daftar terlebih dahulu",
|
text2: "Silahkan coba lagi",
|
||||||
});
|
});
|
||||||
return `/register?nomor=${nomor}`;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log("Error validasi otp >>", (error as Error).message || error);
|
console.log("Error validasi otp >>", (error as Error).message || error);
|
||||||
@@ -132,6 +171,10 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
// --- 3. Ambil data user ---
|
// --- 3. Ambil data user ---
|
||||||
const userData = async (token: string) => {
|
const userData = async (token: string) => {
|
||||||
try {
|
try {
|
||||||
|
if (!token) {
|
||||||
|
throw new Error("Token tidak ditemukan");
|
||||||
|
}
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await apiConfig.get(`/mobile?token=${token}`, {
|
const response = await apiConfig.get(`/mobile?token=${token}`, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -145,7 +188,10 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
await AsyncStorage.setItem("userData", JSON.stringify(dataUser));
|
await AsyncStorage.setItem("userData", JSON.stringify(dataUser));
|
||||||
return dataUser;
|
return dataUser;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error.response?.data?.message + "user" || "Gagal mengambil data user");
|
console.log(
|
||||||
|
"[LOAD USER DATA]",
|
||||||
|
error.response?.data?.message + "user" || "Gagal mengambil data user"
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@@ -160,9 +206,8 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const response = await apiRegister({ data: userData });
|
const response = await apiRegister({ data: userData });
|
||||||
console.log("response", response);
|
console.log("[REGISTER FETCH]", JSON.stringify(response, null, 2));
|
||||||
|
|
||||||
const { token } = response;
|
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "info",
|
type: "info",
|
||||||
@@ -173,23 +218,63 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setToken(token);
|
|
||||||
await AsyncStorage.setItem("authToken", token);
|
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "success",
|
type: "success",
|
||||||
text1: "Sukses",
|
text1: "Sukses",
|
||||||
text2: "Anda berhasil terdaftar",
|
text2: "Anda berhasil terdaftar",
|
||||||
});
|
});
|
||||||
router.replace("/(application)/(user)/waiting-room");
|
router.replace(`/verification?nomor=${userData.nomor}`);
|
||||||
return;
|
return;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Error",
|
||||||
|
text2: error.response?.data?.message || "Gagal mendaftar",
|
||||||
|
});
|
||||||
console.log("Error register", error);
|
console.log("Error register", error);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// const registerUser = async (userData: {
|
||||||
|
// username: string;
|
||||||
|
// nomor: string;
|
||||||
|
// termsOfServiceAccepted: boolean;
|
||||||
|
// }) => {
|
||||||
|
// setIsLoading(true);
|
||||||
|
// try {
|
||||||
|
// const response = await apiRegister({ data: userData });
|
||||||
|
// console.log("response", response);
|
||||||
|
|
||||||
|
// const { token } = response;
|
||||||
|
// if (!response.success) {
|
||||||
|
// Toast.show({
|
||||||
|
// type: "info",
|
||||||
|
// text1: "Info",
|
||||||
|
// text2: response.message,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// setToken(token);
|
||||||
|
// await AsyncStorage.setItem("authToken", token);
|
||||||
|
// Toast.show({
|
||||||
|
// type: "success",
|
||||||
|
// text1: "Sukses",
|
||||||
|
// text2: "Anda berhasil terdaftar",
|
||||||
|
// });
|
||||||
|
// router.replace("/(application)/(user)/waiting-room");
|
||||||
|
// return;
|
||||||
|
// } catch (error: any) {
|
||||||
|
// console.log("Error register", error);
|
||||||
|
// } finally {
|
||||||
|
// setIsLoading(false);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
// --- 5. Logout ---
|
// --- 5. Logout ---
|
||||||
|
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|||||||
97
hooks/use-paginated-api.ts
Normal file
97
hooks/use-paginated-api.ts
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
// @/hooks/use-paginated-api.ts
|
||||||
|
import { useCallback, useState, useEffect, useRef } from "react";
|
||||||
|
|
||||||
|
interface UsePaginatedApiProps {
|
||||||
|
fetcher: (params: { page: number; search?: string }) => Promise<any[]>;
|
||||||
|
initialSearch?: string; // mengatur nilai awal dari state
|
||||||
|
pageSize?: number;
|
||||||
|
dependencies?: any[]; // untuk refresh saat deps berubah (misal: user.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const usePaginatedApi = ({
|
||||||
|
fetcher,
|
||||||
|
initialSearch = "",
|
||||||
|
pageSize = 5,
|
||||||
|
dependencies = [],
|
||||||
|
}: UsePaginatedApiProps) => {
|
||||||
|
const [data, setData] = useState<any[]>([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
|
const [hasMore, setHasMore] = useState(true);
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const [search, setSearch] = useState(initialSearch);
|
||||||
|
const refreshingRef = useRef<boolean>(false);
|
||||||
|
const loadingRef = useRef<boolean>(false);
|
||||||
|
const fetchRef = useRef(false);
|
||||||
|
|
||||||
|
const fetchData = useCallback(
|
||||||
|
async (pageNumber: number, clear: boolean) => {
|
||||||
|
const isRefresh = clear;
|
||||||
|
|
||||||
|
// 🔒 Proteksi: jangan jalankan jika sedang refreshing (untuk refresh)
|
||||||
|
if (isRefresh && refreshingRef.current) return;
|
||||||
|
// 🔒 Proteksi: jangan jalankan loadMore jika sedang loading
|
||||||
|
if (!isRefresh && loadingRef.current) return;
|
||||||
|
|
||||||
|
const setLoadingState = (isLoading: boolean) => {
|
||||||
|
if (isRefresh) {
|
||||||
|
setRefreshing(isLoading);
|
||||||
|
refreshingRef.current = isLoading;
|
||||||
|
} else {
|
||||||
|
setLoading(isLoading);
|
||||||
|
loadingRef.current = isLoading;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setLoadingState(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const newData = await fetcher({ page: pageNumber, search });
|
||||||
|
setData((prev) => {
|
||||||
|
const current = Array.isArray(prev) ? prev : [];
|
||||||
|
return clear ? newData : [...current, ...newData];
|
||||||
|
});
|
||||||
|
setHasMore(newData.length === pageSize);
|
||||||
|
setPage(pageNumber);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[usePaginatedApi] Error:", error);
|
||||||
|
setHasMore(false);
|
||||||
|
} finally {
|
||||||
|
setLoadingState(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[search, hasMore, pageSize, ...dependencies]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onRefresh = useCallback(() => {
|
||||||
|
fetchData(1, true);
|
||||||
|
}, [fetchData]);
|
||||||
|
|
||||||
|
const loadMore = useCallback(() => {
|
||||||
|
if (hasMore && !loading && !refreshing) {
|
||||||
|
fetchData(page + 1, false);
|
||||||
|
}
|
||||||
|
}, [hasMore, loading, refreshing, page, fetchData]);
|
||||||
|
|
||||||
|
// Reset & fetch ulang saat search atau deps berubah
|
||||||
|
useEffect(() => {
|
||||||
|
if (fetchRef.current) return; // hindari double initial
|
||||||
|
fetchRef.current = true;
|
||||||
|
|
||||||
|
setPage(1);
|
||||||
|
setData([]);
|
||||||
|
setHasMore(true);
|
||||||
|
fetchData(1, true);
|
||||||
|
}, [search, ...dependencies]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
loading,
|
||||||
|
refreshing,
|
||||||
|
hasMore,
|
||||||
|
search,
|
||||||
|
setSearch,
|
||||||
|
onRefresh,
|
||||||
|
loadMore,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -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,12 +416,12 @@
|
|||||||
/* 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;
|
||||||
CODE_SIGN_ENTITLEMENTS = HIPMIBadungConnect/HIPMIBadungConnect.entitlements;
|
CODE_SIGN_ENTITLEMENTS = HIPMIBadungConnect/HIPMIBadungConnect.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 2;
|
CURRENT_PROJECT_VERSION = 3;
|
||||||
DEVELOPMENT_TEAM = BMY6GT6W3D;
|
DEVELOPMENT_TEAM = BMY6GT6W3D;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
@@ -422,7 +442,7 @@
|
|||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
||||||
PRODUCT_NAME = HIPMIBadungConnect;
|
PRODUCT_NAME = "HIPMIBadungConnect";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -433,12 +453,12 @@
|
|||||||
};
|
};
|
||||||
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;
|
||||||
CODE_SIGN_ENTITLEMENTS = HIPMIBadungConnect/HIPMIBadungConnect.entitlements;
|
CODE_SIGN_ENTITLEMENTS = HIPMIBadungConnect/HIPMIBadungConnect.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 2;
|
CURRENT_PROJECT_VERSION = 3;
|
||||||
DEVELOPMENT_TEAM = BMY6GT6W3D;
|
DEVELOPMENT_TEAM = BMY6GT6W3D;
|
||||||
INFOPLIST_FILE = HIPMIBadungConnect/Info.plist;
|
INFOPLIST_FILE = HIPMIBadungConnect/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||||
@@ -454,7 +474,7 @@
|
|||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
||||||
PRODUCT_NAME = HIPMIBadungConnect;
|
PRODUCT_NAME = "HIPMIBadungConnect";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
30
ios/HIPMIBadungConnect/GoogleService-Info.plist
Normal file
30
ios/HIPMIBadungConnect/GoogleService-Info.plist
Normal 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>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>8</string>
|
<string>15</string>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
@@ -53,15 +53,18 @@
|
|||||||
<key>NSAllowsLocalNetworking</key>
|
<key>NSAllowsLocalNetworking</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
<!-- Photo Library -->
|
<string>Allow $(PRODUCT_NAME) to access your camera</string>
|
||||||
|
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||||
|
<string>Allow $(PRODUCT_NAME) to access your location</string>
|
||||||
|
<key>NSLocationAlwaysUsageDescription</key>
|
||||||
|
<string>Allow $(PRODUCT_NAME) to access your location</string>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string>Aplikasi membutuhkan akses lokasi untuk menampilkan peta.</string>
|
||||||
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
|
<string>Allow $(PRODUCT_NAME) to access your microphone</string>
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
<string>Untuk mengunggah dokumen dan media bisnis seperti foto profil, logo usaha, poster lowongan, atau bukti transaksi di berbagai fitur aplikasi: Profile, Portofolio, Job Vacancy, Investasi, dan Donasi.</string>
|
<string>Untuk mengunggah dokumen dan media bisnis seperti foto profil, logo usaha, poster lowongan, atau bukti transaksi di berbagai fitur aplikasi: Profile, Portofolio, Job Vacancy, Investasi, dan Donasi.</string>
|
||||||
|
|
||||||
<!-- Camera -->
|
|
||||||
<key>NSCameraUsageDescription</key>
|
|
||||||
<string>Untuk mengambil foto langsung saat mengunggah dokumen bisnis seperti foto profil, logo usaha, poster, atau bukti pembayaran di fitur Profile, Portofolio, Job Vacancy, Investasi, dan Donasi.</string>
|
|
||||||
|
|
||||||
<key>NSUserActivityTypes</key>
|
<key>NSUserActivityTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
36
ios/Podfile
36
ios/Podfile
@@ -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,6 +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
|
||||||
|
pre_install do |installer|
|
||||||
|
# @generated begin @rnmapbox/maps-pre_installer - expo prebuild (DO NOT MODIFY) sync-ea4905840bf9fcea0acc62e92aa2e784f9d760f8
|
||||||
|
$RNMapboxMaps.pre_install(installer)
|
||||||
|
# @generated end @rnmapbox/maps-pre_installer
|
||||||
|
end
|
||||||
|
# @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',
|
||||||
@@ -41,7 +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
|
||||||
|
$RNMapboxMaps.post_install(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],
|
||||||
@@ -49,4 +83,6 @@ target 'HIPMIBadungConnect' do
|
|||||||
:ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true',
|
:ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true',
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
# @generated end post_installer
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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) {
|
||||||
@@ -66,21 +81,13 @@ export default function LoginView() {
|
|||||||
if (!isValid) return;
|
if (!isValid) return;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
// const response = await apiLogin({ nomor: realNumber });
|
|
||||||
await loginWithNomor(realNumber);
|
await loginWithNomor(realNumber);
|
||||||
|
|
||||||
Toast.show({
|
|
||||||
type: "success",
|
|
||||||
text1: "Sukses",
|
|
||||||
text2: "Kode OTP berhasil dikirim",
|
|
||||||
});
|
|
||||||
|
|
||||||
router.navigate(`/verification?nomor=${realNumber}`);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error login", error);
|
console.log("Error login", error);
|
||||||
Toast.show({
|
Toast.show({
|
||||||
@@ -91,6 +98,30 @@ export default function LoginView() {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// setLoading(true);
|
||||||
|
// // const response = await apiLogin({ nomor: realNumber });
|
||||||
|
// const response = await loginWithNomor(realNumber);
|
||||||
|
// console.log("[RESPONSE]", response);
|
||||||
|
|
||||||
|
// Toast.show({
|
||||||
|
// type: "success",
|
||||||
|
// text1: "Sukses",
|
||||||
|
// text2: "Kode OTP berhasil dikirim",
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // router.navigate(`/verification?nomor=${realNumber}`);
|
||||||
|
// } catch (error) {
|
||||||
|
// console.log("Error login", error);
|
||||||
|
// Toast.show({
|
||||||
|
// type: "error",
|
||||||
|
// text1: "Error",
|
||||||
|
// text2: error as string,
|
||||||
|
// });
|
||||||
|
// } finally {
|
||||||
|
// setLoading(false);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token && token !== "" && !isUserActive) {
|
if (token && token !== "" && !isUserActive) {
|
||||||
@@ -110,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}>
|
||||||
@@ -154,6 +190,6 @@ export default function LoginView() {
|
|||||||
Coba
|
Coba
|
||||||
</ButtonCustom> */}
|
</ButtonCustom> */}
|
||||||
</View>
|
</View>
|
||||||
</ViewWrapper>
|
</NewWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -89,8 +91,9 @@ export default function VerificationView() {
|
|||||||
// ✅ VERIFIKASI OTOMATIS UNTUK APPLE REVIEW
|
// ✅ VERIFIKASI OTOMATIS UNTUK APPLE REVIEW
|
||||||
if (inputOtp === "1234") {
|
if (inputOtp === "1234") {
|
||||||
try {
|
try {
|
||||||
const response = await validateOtp(nomor as string);
|
await validateOtp(nomor as string);
|
||||||
router.replace(response);
|
|
||||||
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error verification", error);
|
console.log("Error verification", error);
|
||||||
Toast.show({ type: "error", text1: "Gagal verifikasi" });
|
Toast.show({ type: "error", text1: "Gagal verifikasi" });
|
||||||
@@ -103,16 +106,8 @@ export default function VerificationView() {
|
|||||||
|
|
||||||
// 🔁 VERIFIKASI NORMAL (untuk pengguna sungguhan)
|
// 🔁 VERIFIKASI NORMAL (untuk pengguna sungguhan)
|
||||||
try {
|
try {
|
||||||
const response = await validateOtp(nomor as string);
|
await validateOtp(nomor as string);
|
||||||
// registerForPushNotificationsAsync().then((token) => {
|
return
|
||||||
// if (token) {
|
|
||||||
// console.log("Expo Push Token:", token);
|
|
||||||
// // TODO: Kirim token ke backend kamu
|
|
||||||
// } else {
|
|
||||||
// console.log("Failed to get Expo Push Token");
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
router.replace(response);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error verification", error);
|
console.log("Error verification", error);
|
||||||
Toast.show({ type: "error", text1: "Gagal verifikasi" });
|
Toast.show({ type: "error", text1: "Gagal verifikasi" });
|
||||||
|
|||||||
@@ -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}}>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -203,10 +203,9 @@ export default function Forum_ViewBeranda2() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onEndReached={loadMore}
|
onEndReached={loadMore}
|
||||||
// ListHeaderComponent={ListHeaderComponent}
|
|
||||||
ListFooterComponent={ListFooterComponent}
|
ListFooterComponent={ListFooterComponent}
|
||||||
ListEmptyComponent={
|
ListEmptyComponent={
|
||||||
_.isEmpty(listData) ? <SkeletonListComponent /> : <EmptyComponent />
|
loading && _.isEmpty(listData) ? <SkeletonListComponent /> : <EmptyComponent />
|
||||||
}
|
}
|
||||||
// ------------------------
|
// ------------------------
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ export default function View_Forumku2() {
|
|||||||
ListHeaderComponent={randerHeaderComponent()}
|
ListHeaderComponent={randerHeaderComponent()}
|
||||||
ListFooterComponent={ListFooterComponent}
|
ListFooterComponent={ListFooterComponent}
|
||||||
ListEmptyComponent={
|
ListEmptyComponent={
|
||||||
_.isEmpty(listData) ? <SkeletonListComponent /> : <EmptyComponent />
|
loading && _.isEmpty(listData) ? <SkeletonListComponent /> : <EmptyComponent />
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
TextCustom,
|
TextCustom,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import API_STRORAGE from "@/constants/base-url-api-strorage";
|
import API_STRORAGE from "@/constants/base-url-api-strorage";
|
||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import DUMMY_IMAGE from "@/constants/dummy-image-value";
|
import DUMMY_IMAGE from "@/constants/dummy-image-value";
|
||||||
import { countDownAndCondition } from "@/utils/countDownAndCondition";
|
import { countDownAndCondition } from "@/utils/countDownAndCondition";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
@@ -32,6 +33,8 @@ export default function Investment_BoxBerandaSection({
|
|||||||
updateCountDown();
|
updateCountDown();
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
console.log("[DATA BERANDA]", JSON.stringify(data, null, 2));
|
||||||
|
|
||||||
const updateCountDown = () => {
|
const updateCountDown = () => {
|
||||||
const countDown = countDownAndCondition({
|
const countDown = countDownAndCondition({
|
||||||
duration: data?.pencarianInvestor,
|
duration: data?.pencarianInvestor,
|
||||||
@@ -66,8 +69,10 @@ export default function Investment_BoxBerandaSection({
|
|||||||
<TextCustom truncate={2}>{data.title}</TextCustom>
|
<TextCustom truncate={2}>{data.title}</TextCustom>
|
||||||
<ProgressCustom
|
<ProgressCustom
|
||||||
label={`${data.progress}%`}
|
label={`${data.progress}%`}
|
||||||
value={data.progress}
|
value={Number(data.progress)}
|
||||||
size="lg"
|
size="lg"
|
||||||
|
animated
|
||||||
|
color="primary"
|
||||||
/>
|
/>
|
||||||
{value.reminder ? (
|
{value.reminder ? (
|
||||||
<View
|
<View
|
||||||
@@ -79,13 +84,11 @@ export default function Investment_BoxBerandaSection({
|
|||||||
>
|
>
|
||||||
<Ionicons name="alert-circle-outline" size={16} color="red" />
|
<Ionicons name="alert-circle-outline" size={16} color="red" />
|
||||||
<TextCustom truncate color="red" size="small">
|
<TextCustom truncate color="red" size="small">
|
||||||
Periode Investasi Berakhir
|
Periode Berakhir
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<TextCustom>
|
<TextCustom>Sisa waktu: {value.sisa} hari</TextCustom>
|
||||||
Sisa waktu: {value.sisa} hari
|
|
||||||
</TextCustom>
|
|
||||||
)}
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user