Compare commits
36 Commits
api-admin/
...
apple-reje
| Author | SHA1 | Date | |
|---|---|---|---|
| d471682ae7 | |||
| 00eea71248 | |||
| 41e648d8f3 | |||
| 0c4deac6e2 | |||
| 676b8a38be | |||
| 0a2aa71013 | |||
| 868e96a54a | |||
| 059b4d053a | |||
| 76debfd6a6 | |||
| 8c3aec8e57 | |||
| 1ade69ff2f | |||
| 97ea6ab799 | |||
| 4e9ce07759 | |||
| 8f659c2b7e | |||
| 61bca7cfe1 | |||
| 5af85c3a8b | |||
| a8807d88ad | |||
| 5d36429aa4 | |||
| ec49999f99 | |||
| 867e82c6fa | |||
| f9f996f195 | |||
| 98394309e6 | |||
| 4625831377 | |||
| ebd6107c36 | |||
| f23cfe1107 | |||
| f9d9b5fbaa | |||
| b3209dc7ee | |||
| 31c1b35173 | |||
| 1e1b18f860 | |||
| de0280367f | |||
| 5d4328a139 | |||
| c8b14b816f | |||
| 125bf16605 | |||
| 73a803f2e8 | |||
| 1bcd1a044f | |||
| 1e0b72de22 |
@@ -92,8 +92,8 @@ android {
|
||||
applicationId 'com.bip.hipmimobileapp'
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0.0"
|
||||
versionCode 2
|
||||
versionName "1.0.1"
|
||||
|
||||
buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
|
||||
}
|
||||
@@ -180,3 +180,5 @@ dependencies {
|
||||
implementation jscFlavor
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
29
android/app/google-services.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "608461535079",
|
||||
"project_id": "hipmi-badung-connect",
|
||||
"storage_bucket": "hipmi-badung-connect.firebasestorage.app"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:608461535079:android:4ff12ddc283fb3746761c2",
|
||||
"android_client_info": {
|
||||
"package_name": "com.bip.hipmimobileapp"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyBiDtIk3Q9zffFwIdJ5cjqY7e4390JGSkM"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
@@ -29,6 +31,12 @@
|
||||
<data android:scheme="hipmimobile"/>
|
||||
<data android:scheme="exp+hipmi-mobile"/>
|
||||
</intent-filter>
|
||||
<intent-filter android:autoVerify="true" data-generated="true">
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<data android:scheme="https" android:host="cld-dkr-staging-hipmi.wibudev.com" android:pathPrefix="/"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 30 KiB |
@@ -1,5 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">HIPMI BADUNG</string>
|
||||
<string name="app_name">HIPMI Badung Connect</string>
|
||||
<string name="expo_system_ui_user_interface_style" translatable="false">automatic</string>
|
||||
<string name="expo_splash_screen_resize_mode" translatable="false">contain</string>
|
||||
<string name="expo_splash_screen_status_bar_translucent" translatable="false">false</string>
|
||||
|
||||
@@ -6,6 +6,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.google.gms:google-services:4.4.1'
|
||||
classpath('com.android.tools.build:gradle')
|
||||
classpath('com.facebook.react:react-native-gradle-plugin')
|
||||
classpath('org.jetbrains.kotlin:kotlin-gradle-plugin')
|
||||
|
||||
@@ -31,7 +31,7 @@ extensions.configure(com.facebook.react.ReactSettingsExtension) { ex ->
|
||||
}
|
||||
expoAutolinking.useExpoModules()
|
||||
|
||||
rootProject.name = 'HIPMI BADUNG'
|
||||
rootProject.name = 'HIPMI Badung Connect'
|
||||
|
||||
expoAutolinking.useExpoVersionCatalog()
|
||||
|
||||
|
||||
@@ -1,61 +1,82 @@
|
||||
// app.config.js
|
||||
require('dotenv').config();
|
||||
require("dotenv").config();
|
||||
|
||||
export default {
|
||||
name: 'HIPMI BADUNG',
|
||||
slug: 'hipmi-mobile',
|
||||
version: '1.0.0',
|
||||
orientation: 'portrait',
|
||||
icon: './assets/images/icon.png',
|
||||
scheme: 'hipmimobile',
|
||||
userInterfaceStyle: 'automatic',
|
||||
name: "HIPMI Badung Connect",
|
||||
slug: "hipmi-mobile",
|
||||
version: "1.0.1",
|
||||
orientation: "portrait",
|
||||
icon: "./assets/images/icon.png",
|
||||
scheme: "hipmimobile",
|
||||
userInterfaceStyle: "automatic",
|
||||
newArchEnabled: true,
|
||||
|
||||
ios: {
|
||||
supportsTablet: true,
|
||||
bundleIdentifier: 'com.anonymous.hipmi-mobile',
|
||||
bundleIdentifier: "com.anonymous.hipmi-mobile",
|
||||
infoPlist: {
|
||||
ITSAppUsesNonExemptEncryption: false,
|
||||
"NSLocationWhenInUseUsageDescription": "Aplikasi membutuhkan akses lokasi untuk menampilkan peta.",
|
||||
},
|
||||
associatedDomains: ["applinks:cld-dkr-staging-hipmi.wibudev.com"],
|
||||
buildNumber: "8",
|
||||
},
|
||||
|
||||
android: {
|
||||
googleServicesFile: "./google-services.json",
|
||||
adaptiveIcon: {
|
||||
foregroundImage: './assets/images/splash-icon.png',
|
||||
backgroundColor: '#ffffff',
|
||||
foregroundImage: "./assets/images/splash-icon.png",
|
||||
backgroundColor: "#ffffff",
|
||||
},
|
||||
edgeToEdgeEnabled: true,
|
||||
package: 'com.bip.hipmimobileapp',
|
||||
package: "com.bip.hipmimobileapp",
|
||||
versionCode: 2,
|
||||
// softwareKeyboardLayoutMode: 'resize', // option: untuk mengatur keyboard pada room chst collaboration
|
||||
intentFilters: [
|
||||
{
|
||||
action: "VIEW",
|
||||
autoVerify: true, // wajib untuk App Links
|
||||
data: [
|
||||
{
|
||||
scheme: "https",
|
||||
host: "cld-dkr-staging-hipmi.wibudev.com",
|
||||
pathPrefix: "/",
|
||||
},
|
||||
],
|
||||
category: ["BROWSABLE", "DEFAULT"],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
web: {
|
||||
bundler: 'metro',
|
||||
output: 'static',
|
||||
favicon: './assets/images/favicon.png',
|
||||
bundler: "metro",
|
||||
output: "static",
|
||||
favicon: "./assets/images/favicon.png",
|
||||
},
|
||||
|
||||
plugins: [
|
||||
'expo-router',
|
||||
'expo-web-browser',
|
||||
"expo-router",
|
||||
"expo-notifications",
|
||||
"expo-web-browser",
|
||||
[
|
||||
'expo-splash-screen',
|
||||
"expo-splash-screen",
|
||||
{
|
||||
image: './assets/images/splash-icon.png',
|
||||
image: "./assets/images/splash-icon.png",
|
||||
imageWidth: 200,
|
||||
resizeMode: 'contain',
|
||||
backgroundColor: '#ffffff',
|
||||
resizeMode: "contain",
|
||||
backgroundColor: "#ffffff",
|
||||
},
|
||||
],
|
||||
[
|
||||
'expo-camera',
|
||||
"expo-camera",
|
||||
{
|
||||
cameraPermission: 'Allow $(PRODUCT_NAME) to access your camera',
|
||||
microphonePermission: 'Allow $(PRODUCT_NAME) to access your microphone',
|
||||
cameraPermission: "Allow $(PRODUCT_NAME) to access your camera",
|
||||
microphonePermission: "Allow $(PRODUCT_NAME) to access your microphone",
|
||||
recordAudioAndroid: true,
|
||||
},
|
||||
],
|
||||
'expo-font',
|
||||
"expo-font",
|
||||
"@rnmapbox/maps",
|
||||
],
|
||||
|
||||
experiments: {
|
||||
@@ -65,11 +86,11 @@ export default {
|
||||
extra: {
|
||||
router: {},
|
||||
eas: {
|
||||
projectId: '5cf15964-4889-4755-b8ed-b99c61d614d1',
|
||||
projectId: "5cf15964-4889-4755-b8ed-b99c61d614d1",
|
||||
},
|
||||
// Tambahkan environment variables ke sini
|
||||
API_BASE_URL: process.env.API_BASE_URL,
|
||||
BASE_URL: process.env.BASE_URL,
|
||||
DEEP_LINK_URL: process.env.DEEP_LINK_URL,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -10,6 +10,13 @@ export default function UserLayout() {
|
||||
return (
|
||||
<>
|
||||
<Stack screenOptions={HeaderStyles}>
|
||||
<Stack.Screen
|
||||
name="delete-account"
|
||||
options={{
|
||||
title: "Hapus Akun",
|
||||
headerLeft: () => <BackButton />,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="waiting-room"
|
||||
options={{
|
||||
|
||||
111
app/(application)/(user)/delete-account.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BaseBox,
|
||||
ButtonCustom,
|
||||
CenterCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { apiDeleteUser } from "@/service/api-client/api-user";
|
||||
import { Image } from "expo-image";
|
||||
import { useLocalSearchParams } from "expo-router/build/hooks";
|
||||
import { useState } from "react";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function DeleteAccount() {
|
||||
const { token, logout, user } = useAuth();
|
||||
const { phone } = useLocalSearchParams();
|
||||
const [text, setText] = useState("");
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
const deleteAccount = async () => {
|
||||
if (text !== "Delete Account") {
|
||||
return Toast.show({
|
||||
type: "error",
|
||||
text1: "Ketik 'Delete Account' untuk menghapus akun",
|
||||
});
|
||||
}
|
||||
|
||||
AlertDefaultSystem({
|
||||
title: "Anda yakin akan menghapus akun ini?",
|
||||
message:
|
||||
"Semua data yang pernah anda buat akan terhapus secara permanen !",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressRight: async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await apiDeleteUser({ id: user?.id as string });
|
||||
|
||||
if (response.success) {
|
||||
console.log("RESPONSE >> ", response);
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Akun berhasil dihapus",
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
logout();
|
||||
setLoading(false);
|
||||
}, 2000);
|
||||
} else {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Gagal menghapus akun",
|
||||
});
|
||||
setLoading(false);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("ERROR >> ", error);
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
<StackCustom>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
<CenterCustom>
|
||||
<Image
|
||||
source={require("@/assets/images/constants/logo-hipmi.png")}
|
||||
style={{
|
||||
width: 150,
|
||||
height: 150,
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
<TextCustom align="center">
|
||||
Anda akan menghapus akun dengan nomor +{phone}
|
||||
</TextCustom>
|
||||
<TextCustom align="center">
|
||||
Ketik 'Delete Account' untuk menghapus akun
|
||||
</TextCustom>
|
||||
<TextInputCustom
|
||||
value={text}
|
||||
onChangeText={setText}
|
||||
placeholder="Ketik 'Delete Account'"
|
||||
/>
|
||||
|
||||
<ButtonCustom
|
||||
backgroundColor="red"
|
||||
textColor="white"
|
||||
onPress={deleteAccount}
|
||||
isLoading={isLoading}
|
||||
disabled={isLoading}
|
||||
>
|
||||
Submit
|
||||
</ButtonCustom>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BaseBox,
|
||||
Grid,
|
||||
@@ -7,11 +8,60 @@ import {
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { apiDonationGetInvoiceById } from "@/service/api-client/api-donation";
|
||||
import { GStyles } from "@/styles/global-styles";
|
||||
import { dateTimeView } from "@/utils/dateTimeView";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { FontAwesome6 } from "@expo/vector-icons";
|
||||
import dayjs from "dayjs";
|
||||
import { useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
export default function DonasiFailed() {
|
||||
const { id, invoiceId } = useLocalSearchParams();
|
||||
const [data, setData] = useState<any>(null);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id, invoiceId])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiDonationGetInvoiceById({
|
||||
id: invoiceId as string,
|
||||
});
|
||||
|
||||
console.log("[DATA]", JSON.stringify(response.data, null, 2));
|
||||
setData(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Bank",
|
||||
value: (data && data?.MasterBank?.namaBank) || "-",
|
||||
},
|
||||
{
|
||||
label: "Rekening Penerima",
|
||||
value: (data && data?.MasterBank?.namaAkun) || "-",
|
||||
},
|
||||
{
|
||||
label: "No Rekening",
|
||||
value: (data && data?.MasterBank?.norek) || "-",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Donasi",
|
||||
value: (data && formatCurrencyDisplay(data?.nominal)) || "-",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: (data && dateTimeView({ date: data?.createdAt })) || "-",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ViewWrapper>
|
||||
<StackCustom>
|
||||
@@ -58,26 +108,3 @@ export default function DonasiFailed() {
|
||||
</ViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Bank",
|
||||
value: " BCA",
|
||||
},
|
||||
{
|
||||
label: "Rekening Penerima",
|
||||
value: "Himpunan Pengusaha Muda Indonesia",
|
||||
},
|
||||
{
|
||||
label: "No Rekening",
|
||||
value: "2304235678854332",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Donasi",
|
||||
value: "Rp. 750.000",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: `${dayjs(new Date()).format("DD/MM/YYYY")}`,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -122,7 +122,7 @@ export default function DonationInvoice() {
|
||||
}}
|
||||
>
|
||||
<TextCustom size="xlarge" bold color="yellow">
|
||||
{data?.DonasiMaster_Bank?.norek}
|
||||
{data?.MasterBank?.norek}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col
|
||||
@@ -131,7 +131,7 @@ export default function DonationInvoice() {
|
||||
alignItems: "flex-end",
|
||||
}}
|
||||
>
|
||||
<CopyButton textToCopy={data?.DonasiMaster_Bank?.norek} />
|
||||
<CopyButton textToCopy={data?.MasterBank?.norek} />
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BaseBox,
|
||||
Grid,
|
||||
@@ -7,11 +8,60 @@ import {
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { apiDonationGetInvoiceById } from "@/service/api-client/api-donation";
|
||||
import { GStyles } from "@/styles/global-styles";
|
||||
import { dateTimeView } from "@/utils/dateTimeView";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { FontAwesome6 } from "@expo/vector-icons";
|
||||
import dayjs from "dayjs";
|
||||
import { useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
export default function DonationSuccess() {
|
||||
const { id, invoiceId } = useLocalSearchParams();
|
||||
const [data, setData] = useState<any>(null);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id, invoiceId])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiDonationGetInvoiceById({
|
||||
id: invoiceId as string,
|
||||
});
|
||||
|
||||
console.log("[DATA]", JSON.stringify(response.data, null, 2));
|
||||
setData(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Bank",
|
||||
value: (data && data?.MasterBank?.namaBank) || "-",
|
||||
},
|
||||
{
|
||||
label: "Rekening Penerima",
|
||||
value: (data && data?.MasterBank?.namaAkun) || "-",
|
||||
},
|
||||
{
|
||||
label: "No Rekening",
|
||||
value: (data && data?.MasterBank?.norek) || "-",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Donasi",
|
||||
value: (data && formatCurrencyDisplay(data?.nominal)) || "-",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: (data && dateTimeView({ date: data?.createdAt })) || "-",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ViewWrapper>
|
||||
<StackCustom>
|
||||
@@ -59,25 +109,4 @@ export default function DonationSuccess() {
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Bank",
|
||||
value: " BCA",
|
||||
},
|
||||
{
|
||||
label: "Rekening Penerima",
|
||||
value: "Himpunan Pengusaha Muda Indonesia",
|
||||
},
|
||||
{
|
||||
label: "No Rekening",
|
||||
value: "2304235678854332",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Donasi",
|
||||
value: "Rp. 750.000",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: `${dayjs(new Date()).format("DD/MM/YYYY")}`,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -1,17 +1,71 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BaseBox,
|
||||
ButtonCenteredOnly,
|
||||
Grid,
|
||||
InformationBox,
|
||||
LoaderCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import {
|
||||
apiDonationDisbursementOfFundsListById,
|
||||
apiDonationGetOne,
|
||||
} from "@/service/api-client/api-donation";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React, { useState } from "react";
|
||||
|
||||
export default function DonationFundDisbursement() {
|
||||
const { id } = useLocalSearchParams();
|
||||
|
||||
const [data, setData] = useState({
|
||||
totalPencairan: 0,
|
||||
akumulasiPencairan: 0,
|
||||
});
|
||||
|
||||
const [listData, setListData] = React.useState<any[] | null>(null);
|
||||
const [loadData, setLoadData] = React.useState(false);
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadData(true);
|
||||
|
||||
const responseData = await apiDonationGetOne({
|
||||
id: id as string,
|
||||
category: "permanent",
|
||||
});
|
||||
|
||||
if (responseData.success) {
|
||||
setData({
|
||||
totalPencairan: responseData.data.totalPencairan,
|
||||
akumulasiPencairan: responseData.data.akumulasiPencairan,
|
||||
});
|
||||
}
|
||||
|
||||
const responseList = await apiDonationDisbursementOfFundsListById({
|
||||
id: id as string,
|
||||
});
|
||||
|
||||
if (responseList.success) {
|
||||
setListData(responseList.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
@@ -20,47 +74,50 @@ export default function DonationFundDisbursement() {
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<TextCustom bold color="yellow">
|
||||
Rp. 0
|
||||
Rp. {formatCurrencyDisplay(data?.totalPencairan)}
|
||||
</TextCustom>
|
||||
<TextCustom size="small">Total Pencairan Dana</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<TextCustom bold color="yellow">
|
||||
0 kali
|
||||
{data?.akumulasiPencairan} kali
|
||||
</TextCustom>
|
||||
<TextCustom size="small">Akumulasi Pencairan</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<BaseBox key={index}>
|
||||
<StackCustom>
|
||||
<Grid>
|
||||
<Grid.Col span={8}>
|
||||
<TextCustom bold>Pencairan ke - {index + 1}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4} style={{ alignItems: "flex-end" }}>
|
||||
<TextCustom>{dayjs().format("DD MMM YYYY")}</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<TextCustom>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Nesciunt dolor ad sit? Eaque rem nihil natus, id, esse possimus
|
||||
perferendis provident velit illo consectetur distinctio ab
|
||||
accusantium quis earum omnis!
|
||||
</TextCustom>
|
||||
<ButtonCenteredOnly
|
||||
onPress={() => {
|
||||
router.navigate(`/(application)/(file)/${id}`);
|
||||
}}
|
||||
icon="file-text"
|
||||
>
|
||||
Bukti Transaksi
|
||||
</ButtonCenteredOnly>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
))}
|
||||
{loadData ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(listData) ? (
|
||||
<TextCustom align="center" color="gray">
|
||||
Belum ada data
|
||||
</TextCustom>
|
||||
) : (
|
||||
listData?.map((item, index) => (
|
||||
<BaseBox key={index}>
|
||||
<StackCustom>
|
||||
<Grid>
|
||||
<Grid.Col span={8}>
|
||||
<TextCustom bold>{item?.title}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4} style={{ alignItems: "flex-end" }}>
|
||||
<TextCustom>{dayjs(item?.createdAt).format("DD MMM YYYY")}</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<TextCustom>{item?.deskripsi}</TextCustom>
|
||||
<ButtonCenteredOnly
|
||||
onPress={() => {
|
||||
router.navigate(`/(application)/(image)/preview-image/${item?.imageId}`);
|
||||
}}
|
||||
icon="file-text"
|
||||
>
|
||||
Bukti Transaksi
|
||||
</ButtonCenteredOnly>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
))
|
||||
)}
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -16,20 +16,19 @@ import Donation_ComponentInfoFundrising from "@/screens/Donation/ComponentInfoFu
|
||||
import Donation_ComponentStoryFunrising from "@/screens/Donation/ComponentStoryFunrising";
|
||||
import Donation_ProgressSection from "@/screens/Donation/ProgressSection";
|
||||
import { apiDonationGetOne } from "@/service/api-client/api-donation";
|
||||
import { countDownAndCondition } from "@/utils/countDownAndCondition";
|
||||
import {
|
||||
router,
|
||||
Stack,
|
||||
useFocusEffect,
|
||||
useLocalSearchParams,
|
||||
} from "expo-router";
|
||||
import { useCallback, useState } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
export default function DonasiDetailBeranda() {
|
||||
const { user } = useAuth();
|
||||
const { id } = useLocalSearchParams();
|
||||
console.log("ID ", id);
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
|
||||
const [data, setData] = useState<any>();
|
||||
|
||||
useFocusEffect(
|
||||
@@ -45,21 +44,41 @@ export default function DonasiDetailBeranda() {
|
||||
category: "permanent",
|
||||
});
|
||||
|
||||
console.log("[RES GET ONE]", JSON.stringify(response.data, null, 2));
|
||||
|
||||
setData(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
};
|
||||
|
||||
const [value, setValue] = useState({
|
||||
sisa: 0,
|
||||
reminder: false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
updateCountDown();
|
||||
}, [data]);
|
||||
|
||||
const updateCountDown = () => {
|
||||
const countDown = countDownAndCondition({
|
||||
duration: data?.DonasiMaster_Durasi?.name,
|
||||
publishTime: data?.publishTime,
|
||||
});
|
||||
|
||||
setValue({
|
||||
sisa: countDown.durationDay,
|
||||
reminder: countDown.reminder,
|
||||
});
|
||||
};
|
||||
|
||||
const buttonSection = (
|
||||
<>
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
disabled={value?.reminder}
|
||||
onPress={() => router.navigate(`/donation/${id}/(transaction-flow)`)}
|
||||
>
|
||||
Donasi
|
||||
{value?.reminder ? "Waktu berakhir" : "Donasi"}
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
</>
|
||||
@@ -80,8 +99,10 @@ export default function DonasiDetailBeranda() {
|
||||
<ViewWrapper footerComponent={buttonSection}>
|
||||
<StackCustom>
|
||||
<Donation_ComponentBoxDetailData
|
||||
sisaHari={value.sisa}
|
||||
reminder={value.reminder}
|
||||
data={data}
|
||||
bottomSection={<Donation_ProgressSection id={id as string} />}
|
||||
bottomSection={<Donation_ProgressSection id={id as string} progres={Number(data?.progres) || 0} />}
|
||||
/>
|
||||
<Donation_ComponentInfoFundrising dataAuthor={data?.Author} />
|
||||
<Donation_ComponentStoryFunrising
|
||||
|
||||
@@ -1,46 +1,93 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BaseBox,
|
||||
Grid,
|
||||
LoaderCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { apiAdminDonationListOfDonaturById } from "@/service/api-admin/api-admin-donation";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { FontAwesome6 } from "@expo/vector-icons";
|
||||
import dayjs from "dayjs";
|
||||
import { useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
export default function Donation_ListOfDonatur() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [listData, setListData] = useState<any[] | null>(null);
|
||||
const [loadData, setLoadData] = useState(false);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadData(true);
|
||||
const response = await apiAdminDonationListOfDonaturById({
|
||||
id: id as string,
|
||||
});
|
||||
|
||||
|
||||
if (response.success) {
|
||||
setListData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<BaseBox key={index}>
|
||||
<Grid>
|
||||
<Grid.Col
|
||||
span={3}
|
||||
style={{ alignItems: "center", justifyContent: "center" }}
|
||||
>
|
||||
<FontAwesome6
|
||||
name="face-smile-wink"
|
||||
size={50}
|
||||
style={{ color: MainColor.yellow }}
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={9}>
|
||||
<StackCustom gap={"xs"}>
|
||||
{loadData ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(listData) ? (
|
||||
<TextCustom bold align="center">
|
||||
Belum ada donatur
|
||||
</TextCustom>
|
||||
) : (
|
||||
listData?.map((item: any, index: number) => (
|
||||
<BaseBox key={index}>
|
||||
<Grid>
|
||||
<Grid.Col
|
||||
span={3}
|
||||
style={{ alignItems: "center", justifyContent: "center" }}
|
||||
>
|
||||
<FontAwesome6
|
||||
name="face-smile-wink"
|
||||
size={50}
|
||||
style={{ color: MainColor.yellow }}
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={9}>
|
||||
<TextCustom bold size="large">
|
||||
Username
|
||||
{item?.Author?.username || "-"}
|
||||
</TextCustom>
|
||||
<TextCustom>Berdonas sebesar </TextCustom>
|
||||
<TextCustom bold size="large" color="yellow">
|
||||
Rp. 100.000
|
||||
</TextCustom>
|
||||
<TextCustom>{dayjs().format("DD MMM YYYY")}</TextCustom>
|
||||
</StackCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
))}
|
||||
<Spacing/>
|
||||
<StackCustom gap={"xs"}>
|
||||
<TextCustom size={"small"}>Berdonas sebesar </TextCustom>
|
||||
<TextCustom bold size="large" color="yellow">
|
||||
Rp. {formatCurrencyDisplay(item?.nominal)}
|
||||
</TextCustom>
|
||||
<TextCustom>
|
||||
{dayjs(item?.createdAt).format("DD MMM YYYY, HH:mm")}
|
||||
</TextCustom>
|
||||
</StackCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
))
|
||||
)}
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -74,8 +74,6 @@ export default function UserEventConfirmation() {
|
||||
userId: user?.id as string,
|
||||
});
|
||||
|
||||
console.log("[RES CONFIRMATION]", JSON.stringify(response, null, 2));
|
||||
|
||||
if (response.success) {
|
||||
setData(response.data?.dataEvent);
|
||||
setPeserta(response.data?.peserta);
|
||||
@@ -142,11 +140,11 @@ export default function UserEventConfirmation() {
|
||||
return (
|
||||
<TamplateBox data={data}>
|
||||
<TamplateText
|
||||
text={`Event telah selesai, anda terdaftar sebagai peserta dan${
|
||||
text={`Event telah selesai, anda terdaftar sebagai peserta dan ${
|
||||
konfirmasi
|
||||
? "Anda telah mengonfirmasi kehadiran."
|
||||
: "Anda tidak mengonfirmasi kehadiran."
|
||||
}. Terima kasih atas perhatian dan minat Anda. Kami berharap dapat bertemu di acara kami berikutnya.`}
|
||||
} Terima kasih atas perhatian dan minat Anda. Kami berharap dapat bertemu di acara kami berikutnya.`}
|
||||
/>
|
||||
<BackToOtherPath
|
||||
path="event"
|
||||
@@ -173,14 +171,16 @@ export default function UserEventConfirmation() {
|
||||
if (isWithinConfirmationWindow && peserta === true) {
|
||||
if (konfirmasi === false) {
|
||||
return (
|
||||
<TamplateBox data={data}>
|
||||
<TamplateText text="Konfirmasi Kehadiran" />
|
||||
</TamplateBox>
|
||||
<UserParticipan_And_DuringEvent
|
||||
id={data.id}
|
||||
userId={user?.id as string}
|
||||
data={data}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<TamplateBox data={data}>
|
||||
<TamplateText text="Anda telah mengonfirmasi kehadiran." />
|
||||
<TamplateText text="Terimakasih telah mengonfirmasi kehadiran. Silahkan lihat peserta lain pada halaman event atau kembali ke halaman home. Selamat menikmati acara dan selamat berpartisipasi." />
|
||||
<BackToOtherPath
|
||||
path="event"
|
||||
id={data.id}
|
||||
@@ -192,7 +192,7 @@ export default function UserEventConfirmation() {
|
||||
|
||||
return (
|
||||
<TamplateBox data={data}>
|
||||
<TamplateText text="Anda terdaftar sebagai peserta. Konfirmasi kehadiran dibuka 1 jam sebelum acara dimulai." />
|
||||
<TamplateText text="Anda telah terdaftar sebagai peserta pada Event ini. Konfirmasi kehadiran dibuka 1 jam sebelum acara dimulai." />
|
||||
<BackToOtherPath
|
||||
path="event"
|
||||
id={data.id}
|
||||
@@ -261,17 +261,17 @@ export default function UserEventConfirmation() {
|
||||
<Stack.Screen
|
||||
options={{
|
||||
title: "Konfirmasi Event",
|
||||
headerLeft: () => (
|
||||
<Ionicons
|
||||
name="arrow-back"
|
||||
size={20}
|
||||
color={MainColor.yellow}
|
||||
onPress={() =>
|
||||
router.navigate("/(application)/(user)/event/create")
|
||||
}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
// headerLeft: () => (
|
||||
// <Ionicons
|
||||
// name="arrow-back"
|
||||
// size={20}
|
||||
// color={MainColor.yellow}
|
||||
// onPress={() =>
|
||||
// router.navigate("/(application)/(user)/event/create")
|
||||
// }
|
||||
// />
|
||||
// ),
|
||||
}}
|
||||
/>
|
||||
<ViewWrapper>{handlerReturn()}</ViewWrapper>
|
||||
</>
|
||||
@@ -326,7 +326,7 @@ const TamplateBox = ({
|
||||
);
|
||||
};
|
||||
|
||||
const TamplateText = ({ text }: { text: string }) => {
|
||||
const TamplateText = ({ text }: { text: React.ReactNode }) => {
|
||||
return (
|
||||
<>
|
||||
<TextCustom align="center">{text}</TextCustom>
|
||||
@@ -442,7 +442,7 @@ const NotStarted_And_UserNotParticipan = ({
|
||||
};
|
||||
|
||||
// 🟡 ZONA ACARA BERLANGSUNG
|
||||
// Acara sedang berlangsung & belum terdaftar
|
||||
// Acara sedang berlangsung & belum terdaftar & user harus join dan konfirmasi
|
||||
const UserNotParticipan_And_DuringEvent = ({
|
||||
id,
|
||||
userId,
|
||||
@@ -464,8 +464,6 @@ const UserNotParticipan_And_DuringEvent = ({
|
||||
category: "join_and_confirm",
|
||||
});
|
||||
|
||||
// console.log("[RES JOIN & CONFIRMATION EVENT]", response);
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
@@ -498,3 +496,59 @@ const UserNotParticipan_And_DuringEvent = ({
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// 🟡 ZONA ACARA BERLANGSUN
|
||||
// User sudah terdaftar & Event sedang berlangsung & user harus konfirmasi
|
||||
const UserParticipan_And_DuringEvent = ({
|
||||
id,
|
||||
userId,
|
||||
data,
|
||||
}: {
|
||||
id: string;
|
||||
userId: string;
|
||||
data: DataEvent;
|
||||
}) => {
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const handlerSubmit = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const response = await apiEventConfirmationAction({
|
||||
id: id as string,
|
||||
userId: userId as string,
|
||||
category: "confirmation",
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Anda gagal konfirmasi",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Anda berhasil konfirmasi",
|
||||
});
|
||||
router.navigate(`/(application)/(user)/event/${id}/publish`);
|
||||
} catch (error) {
|
||||
console.log("[ERROR JOIN & CONFIRMATION EVENT]", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<TamplateBox data={data}>
|
||||
<TamplateText text="Anda sudah terdaftar sebagai peserta & Event sedang berlangsung. Silahkan konfirmasi kehadiran" />
|
||||
|
||||
<ButtonCustom onPress={() => handlerSubmit()} isLoading={isLoading}>
|
||||
Konfirmasi
|
||||
</ButtonCustom>
|
||||
</TamplateBox>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -11,29 +11,30 @@ import {
|
||||
apiEventGetOne,
|
||||
apiEventListOfParticipants,
|
||||
} from "@/service/api-client/api-event";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useEffect, useState } from "react";
|
||||
import dayjs, { Dayjs } from "dayjs";
|
||||
import { useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function EventListOfParticipants() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [startDate, setStartDate] = useState();
|
||||
const [listData, setListData] = useState([]);
|
||||
const [isLoadData, setIsLoadData] = useState(false);
|
||||
const [startDate, setStartDate] = useState<Dayjs | undefined>();
|
||||
const [listData, setListData] = useState<any[] | null>(null);
|
||||
const [loadtData, setLoadData] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
handlerLoadData();
|
||||
}, [id]);
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
handlerLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const handlerLoadData = () => {
|
||||
try {
|
||||
setIsLoadData(true);
|
||||
onLoadData();
|
||||
onLoadList();
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setIsLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -41,7 +42,8 @@ export default function EventListOfParticipants() {
|
||||
try {
|
||||
const response = await apiEventGetOne({ id: id as string });
|
||||
if (response.success) {
|
||||
setStartDate(response.data.tanggal);
|
||||
const date = dayjs(response.data.tanggal);
|
||||
setStartDate(date);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
@@ -50,30 +52,36 @@ export default function EventListOfParticipants() {
|
||||
|
||||
const onLoadList = async () => {
|
||||
try {
|
||||
setLoadData(true);
|
||||
const response = await apiEventListOfParticipants({ id: id as string });
|
||||
|
||||
if (response.success) {
|
||||
setListData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ViewWrapper>
|
||||
{isLoadData ? (
|
||||
{loadtData && !listData ? (
|
||||
<LoaderCustom />
|
||||
) : listData.length === 0 ? (
|
||||
<TextCustom align="center">Belum ada peserta</TextCustom>
|
||||
) : _.isEmpty(listData) ? (
|
||||
<TextCustom align="center" color="gray">
|
||||
Belum ada peserta
|
||||
</TextCustom>
|
||||
) : (
|
||||
listData.map((item: any, index: number) => (
|
||||
listData?.map((item: any, index: number) => (
|
||||
<BaseBox key={index}>
|
||||
<AvatarUsernameAndOtherComponent
|
||||
avatar={item?.User?.Profile?.imageId}
|
||||
name={item?.User?.username}
|
||||
avatarHref={`/profile/${item?.User?.Profile?.id}`}
|
||||
rightComponent={
|
||||
new Date().getTime() > new Date(startDate as any).getTime() ? (
|
||||
startDate && startDate.subtract(1, "hour").diff(dayjs()) < 0 ? (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "flex-end",
|
||||
|
||||
@@ -1,142 +1,12 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
AvatarComp,
|
||||
ButtonCustom,
|
||||
CenterCustom,
|
||||
DrawerCustom,
|
||||
FloatingButton,
|
||||
Grid,
|
||||
LoaderCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import Forum_BoxDetailSection from "@/screens/Forum/DiscussionBoxSection";
|
||||
import Forum_MenuDrawerBerandaSection from "@/screens/Forum/MenuDrawerSection.tsx/MenuBeranda";
|
||||
import { apiForumGetAll } from "@/service/api-client/api-forum";
|
||||
import { apiUser } from "@/service/api-client/api-user";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
import View_Forumku from "@/screens/Forum/ViewForumku";
|
||||
import View_Forumku2 from "@/screens/Forum/ViewForumku2";
|
||||
|
||||
export default function Forumku() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const { user } = useAuth();
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
const [status, setStatus] = useState("");
|
||||
const [listData, setListData] = useState<any | null>(null);
|
||||
const [dataUser, setDataUser] = useState<any | null>(null);
|
||||
const [loadingGetList, setLoadingGetList] = useState(false);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
onLoadDataProfile(id as string);
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadDataProfile = async (id: string) => {
|
||||
try {
|
||||
const response = await apiUser(id);
|
||||
|
||||
setDataUser(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
}
|
||||
};
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadingGetList(true);
|
||||
const response = await apiForumGetAll({
|
||||
search: "",
|
||||
authorId: id as string,
|
||||
});
|
||||
|
||||
setListData(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadingGetList(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
floatingButton={
|
||||
user?.id === id && (
|
||||
<FloatingButton
|
||||
onPress={() =>
|
||||
router.navigate("/(application)/(user)/forum/create")
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
>
|
||||
<StackCustom>
|
||||
<CenterCustom>
|
||||
<AvatarComp
|
||||
fileId={dataUser?.Profile?.imageId}
|
||||
href={`/(application)/(image)/preview-image/${dataUser?.Profile?.imageId}`}
|
||||
size="xl"
|
||||
/>
|
||||
</CenterCustom>
|
||||
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<TextCustom bold truncate>
|
||||
@{dataUser?.username || "-"}
|
||||
</TextCustom>
|
||||
<TextCustom>{listData?.length || "0"} postingan</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6} style={{ alignItems: "flex-end" }}>
|
||||
<ButtonCustom href={`/profile/${dataUser?.Profile?.id}`}>
|
||||
Kunjungi Profile
|
||||
</ButtonCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
{loadingGetList ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(listData) ? (
|
||||
<TextCustom> Tidak ada diskusi</TextCustom>
|
||||
) : (
|
||||
<>
|
||||
{listData?.map((item: any, index: number) => (
|
||||
<Forum_BoxDetailSection
|
||||
isRightComponent={false}
|
||||
key={index}
|
||||
data={item}
|
||||
isTruncate={true}
|
||||
href={`/forum/${item.id}`}
|
||||
onSetData={(value) => {
|
||||
setOpenDrawer(value.setOpenDrawer);
|
||||
setStatus(value.setStatus);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
|
||||
{/* Drawer Komponen Eksternal */}
|
||||
<DrawerCustom
|
||||
height={"auto"}
|
||||
isVisible={openDrawer}
|
||||
closeDrawer={() => setOpenDrawer(false)}
|
||||
>
|
||||
<Forum_MenuDrawerBerandaSection
|
||||
id={id as string}
|
||||
status={status}
|
||||
setIsDrawerOpen={() => {
|
||||
setOpenDrawer(false);
|
||||
}}
|
||||
authorId={id as string}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
{/* <View_Forumku /> */}
|
||||
<View_Forumku2 />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -223,6 +223,7 @@ export default function ForumDetail() {
|
||||
>
|
||||
<Forum_MenuDrawerBerandaSection
|
||||
id={dataId}
|
||||
authorUsername={data?.Author?.username as string}
|
||||
status={status}
|
||||
setIsDrawerOpen={() => {
|
||||
setOpenDrawer(false);
|
||||
|
||||
@@ -1,129 +1,12 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
AvatarComp,
|
||||
BackButton,
|
||||
DrawerCustom,
|
||||
LoaderCustom,
|
||||
SearchInput,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import FloatingButton from "@/components/Button/FloatingButton";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import Forum_BoxDetailSection from "@/screens/Forum/DiscussionBoxSection";
|
||||
import Forum_MenuDrawerBerandaSection from "@/screens/Forum/MenuDrawerSection.tsx/MenuBeranda";
|
||||
import { apiForumGetAll } from "@/service/api-client/api-forum";
|
||||
import { apiUser } from "@/service/api-client/api-user";
|
||||
import { router, Stack, useFocusEffect } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
import Forum_ViewBeranda from "@/screens/Forum/ViewBeranda";
|
||||
import Forum_ViewBeranda2 from "@/screens/Forum/ViewBeranda2";
|
||||
|
||||
export default function Forum() {
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
const [status, setStatus] = useState("");
|
||||
const { user } = useAuth();
|
||||
const [dataUser, setDataUser] = useState<any>();
|
||||
const [listData, setListData] = useState<any[]>();
|
||||
const [loadingGetList, setLoadingGetList] = useState(false);
|
||||
const [search, setSearch] = useState("");
|
||||
const [dataId, setDataId] = useState("");
|
||||
const [authorId, setAuthorId] = useState("");
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
onLoadDataProfile(user?.id as string);
|
||||
}, [user?.id, search])
|
||||
);
|
||||
|
||||
const onLoadDataProfile = async (id: string) => {
|
||||
const response = await apiUser(id);
|
||||
setDataUser(response.data);
|
||||
};
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadingGetList(true);
|
||||
const response = await apiForumGetAll({ search: search });
|
||||
|
||||
setListData(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadingGetList(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack.Screen
|
||||
options={{
|
||||
title: "Forum",
|
||||
headerLeft: () => <BackButton />,
|
||||
headerRight: () => (
|
||||
<AvatarComp
|
||||
fileId={dataUser?.Profile?.imageId}
|
||||
size="base"
|
||||
href={`/forum/${user?.id}/forumku`}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<SearchInput
|
||||
placeholder="Cari topik diskusi"
|
||||
onChangeText={(e) => setSearch(e)}
|
||||
/>
|
||||
}
|
||||
floatingButton={
|
||||
<FloatingButton
|
||||
onPress={() =>
|
||||
router.navigate("/(application)/(user)/forum/create")
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{loadingGetList ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(listData) ? (
|
||||
<TextCustom align="center" color="gray">
|
||||
Tidak ada diskusi
|
||||
</TextCustom>
|
||||
) : (
|
||||
listData?.map((e: any, i: number) => (
|
||||
<Forum_BoxDetailSection
|
||||
key={i}
|
||||
data={e}
|
||||
onSetData={() => {
|
||||
setDataId(e.id);
|
||||
setOpenDrawer(true);
|
||||
setStatus(e.ForumMaster_StatusPosting?.status);
|
||||
setAuthorId(e.Author?.id);
|
||||
}}
|
||||
isTruncate={true}
|
||||
href={`/forum/${e.id}`}
|
||||
isRightComponent={false}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</ViewWrapper>
|
||||
|
||||
<DrawerCustom
|
||||
height={"auto"}
|
||||
isVisible={openDrawer}
|
||||
closeDrawer={() => setOpenDrawer(false)}
|
||||
>
|
||||
<Forum_MenuDrawerBerandaSection
|
||||
id={dataId}
|
||||
authorId={authorId}
|
||||
status={status}
|
||||
setIsDrawerOpen={() => {
|
||||
setOpenDrawer(false);
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
{/* <Forum_ViewBeranda /> */}
|
||||
<Forum_ViewBeranda2 />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,25 +16,34 @@ import { useEffect, useState } from "react";
|
||||
|
||||
export default function Application() {
|
||||
const { token, user } = useAuth();
|
||||
|
||||
const [data, setData] = useState<any>();
|
||||
|
||||
console.log("[User] >>", JSON.stringify(user?.id, null, 2));
|
||||
|
||||
useEffect(() => {
|
||||
onLoadData();
|
||||
checkVersion();
|
||||
}, []);
|
||||
|
||||
|
||||
async function onLoadData() {
|
||||
const response = await apiUser(user?.id as string);
|
||||
console.log("Response profile >>", JSON.stringify(response?.data?.Profile, null, 2));
|
||||
|
||||
console.log(
|
||||
"[Profile ID]>>",
|
||||
JSON.stringify(response?.data?.Profile.id, null, 2)
|
||||
);
|
||||
|
||||
setData(response.data);
|
||||
}
|
||||
|
||||
|
||||
const checkVersion = async () => {
|
||||
const response = await apiVersion();
|
||||
console.log("Version >>", JSON.stringify(response.data, null, 2));
|
||||
console.log("[Version] >>", JSON.stringify(response.data, null, 2));
|
||||
};
|
||||
|
||||
if (user && user?.termsOfServiceAccepted === false) {
|
||||
console.log("User is not accept term service");
|
||||
return <Redirect href={`/terms-agreement`} />;
|
||||
}
|
||||
|
||||
if (data && data?.active === false) {
|
||||
console.log("User is not active");
|
||||
|
||||
@@ -1,23 +1,14 @@
|
||||
import {
|
||||
BaseBox,
|
||||
FloatingButton,
|
||||
Grid,
|
||||
LoaderCustom,
|
||||
ProgressCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import API_STRORAGE from "@/constants/base-url-api-strorage";
|
||||
import DUMMY_IMAGE from "@/constants/dummy-image-value";
|
||||
import NoDataText from "@/components/_ShareComponent/NoDataText";
|
||||
import Investment_BoxBerandaSection from "@/screens/Invesment/BoxBerandaSection";
|
||||
import { apiInvestmentGetAll } from "@/service/api-client/api-investment";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import dayjs from "dayjs";
|
||||
import { Image } from "expo-image";
|
||||
import { router, useFocusEffect } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function InvestmentBursa() {
|
||||
const [list, setList] = useState<any[] | null>(null);
|
||||
@@ -32,8 +23,10 @@ export default function InvestmentBursa() {
|
||||
const onLoadList = async () => {
|
||||
try {
|
||||
setLoadingList(true);
|
||||
const response = await apiInvestmentGetAll();
|
||||
console.log("[DATA LIST]", JSON.stringify(response.data, null, 2));
|
||||
const response = await apiInvestmentGetAll({
|
||||
category: "bursa"
|
||||
});
|
||||
// console.log("[DATA LIST]", JSON.stringify(response.data, null, 2));
|
||||
setList(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
@@ -52,95 +45,12 @@ export default function InvestmentBursa() {
|
||||
{loadingList ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(list) ? (
|
||||
<TextCustom>Belum ada data</TextCustom>
|
||||
<NoDataText />
|
||||
) : (
|
||||
list?.map((item: any, index: number) => (
|
||||
<BaseBox
|
||||
key={index}
|
||||
paddingTop={7}
|
||||
paddingBottom={7}
|
||||
href={`/investment/${item.id}`}
|
||||
>
|
||||
<Grid>
|
||||
<Grid.Col span={5}>
|
||||
<Image
|
||||
source={
|
||||
item && item.imageId
|
||||
? API_STRORAGE.GET({ fileId: item.imageId })
|
||||
: DUMMY_IMAGE.background
|
||||
}
|
||||
style={{ width: "auto", height: 100, borderRadius: 10 }}
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}>
|
||||
<View />
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<StackCustom>
|
||||
<TextCustom truncate={2}>{item.title}</TextCustom>
|
||||
<ProgressCustom
|
||||
label={`${item.progress}%`}
|
||||
value={item.progress}
|
||||
size="lg"
|
||||
/>
|
||||
{Number(item?.pencarianInvestor) -
|
||||
dayjs().diff(dayjs(item.countDown), "days") <=
|
||||
0 ? (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: 5,
|
||||
}}
|
||||
>
|
||||
<Ionicons
|
||||
name="alert-circle-outline"
|
||||
size={16}
|
||||
color="red"
|
||||
/>
|
||||
<TextCustom color="red" size="small">
|
||||
Periode Investasi Selesai
|
||||
</TextCustom>
|
||||
</View>
|
||||
) : (
|
||||
<TextCustom>
|
||||
Sisa waktu:{" "}
|
||||
{Number(item?.pencarianInvestor) -
|
||||
dayjs().diff(dayjs(item.countDown), "days")}{" "}
|
||||
hari
|
||||
</TextCustom>
|
||||
)}
|
||||
</StackCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
<Investment_BoxBerandaSection id={item.id} data={item} key={index} />
|
||||
))
|
||||
)}
|
||||
</ViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
// <View style={{ padding: 20, gap: 16 }}>
|
||||
// <TextCustom>Progress 70%</TextCustom>
|
||||
// <ProgressCustom value={70} color="primary" size="md" />
|
||||
|
||||
// <TextCustom>Success Progress</TextCustom>
|
||||
// <ProgressCustom value={40} color="success" size="lg" />
|
||||
|
||||
// <TextCustom>Warning Progress (small)</TextCustom>
|
||||
// <ProgressCustom value={90} color="warning" size="sm" />
|
||||
|
||||
// <TextCustom>Error Indeterminate</TextCustom>
|
||||
// <ProgressCustom value={null} color="error" size="md" />
|
||||
|
||||
// <TextCustom>Custom Radius</TextCustom>
|
||||
// <ProgressCustom value={60} color="info" size="xl" radius={4} />
|
||||
|
||||
// <ProgressCustom value={70} color="primary" size="lg" />
|
||||
|
||||
// <ProgressCustom value={45} color="success" size="md" label="Halfway!" />
|
||||
|
||||
// <ProgressCustom value={90} color="warning" size="lg" showLabel={false} />
|
||||
|
||||
// <ProgressCustom value={null} color="error" size="sm" label="Loading..." />
|
||||
// </View>;
|
||||
|
||||
@@ -1,50 +1,102 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BaseBox,
|
||||
Grid,
|
||||
LoaderCustom,
|
||||
ProgressCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { router } from "expo-router";
|
||||
import NoDataText from "@/components/_ShareComponent/NoDataText";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import {
|
||||
apiInvestmentGetAll
|
||||
} from "@/service/api-client/api-investment";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { router, useFocusEffect } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React, { useCallback, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function InvestmentMyHolding() {
|
||||
const { user } = useAuth();
|
||||
const [list, setList] = useState<any[] | null>(null);
|
||||
const [loadingList, setLoadingList] = useState(false);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadList();
|
||||
}, [user?.id])
|
||||
);
|
||||
|
||||
const onLoadList = async () => {
|
||||
try {
|
||||
setLoadingList(true);
|
||||
const response = await apiInvestmentGetAll({
|
||||
category: "my-holding",
|
||||
authorId: user?.id,
|
||||
});
|
||||
console.log("[DATA LIST]", JSON.stringify(response.data, null, 2));
|
||||
setList(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadingList(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ViewWrapper hideFooter>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<BaseBox key={index} paddingTop={7} paddingBottom={7} onPress={() => router.push(`/investment/${index}/(my-holding)/holding-${index}`)}>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<StackCustom gap={"xs"}>
|
||||
<TextCustom truncate={2}>
|
||||
Title here : Lorem ipsum dolor sit amet consectetur
|
||||
adipisicing elit. Omnis, exercitationem, sequi enim quod
|
||||
distinctio maiores laudantium amet, quidem atque repellat sit
|
||||
vitae qui aliquam est veritatis laborum eum voluptatum totam!
|
||||
</TextCustom>
|
||||
{loadingList ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(list) ? (
|
||||
<NoDataText />
|
||||
) : (
|
||||
list?.map((item, index) => (
|
||||
<BaseBox
|
||||
key={index}
|
||||
paddingTop={7}
|
||||
paddingBottom={7}
|
||||
onPress={() =>
|
||||
router.push(`/investment/${item?.id}/(my-holding)/${item?.id}`)
|
||||
}
|
||||
>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<StackCustom gap={"xs"}>
|
||||
<TextCustom truncate={2}>{item?.title}</TextCustom>
|
||||
|
||||
<Spacing height={5} />
|
||||
<TextCustom size="small">Rp. 7.500.000</TextCustom>
|
||||
<TextCustom size="small">300 Lembar</TextCustom>
|
||||
</StackCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}>
|
||||
<View />
|
||||
</Grid.Col>
|
||||
<Grid.Col
|
||||
span={5}
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<ProgressCustom value={(index % 5) * 20} size="lg" />
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
))}
|
||||
<Spacing height={5} />
|
||||
<TextCustom size="small">
|
||||
Rp. {formatCurrencyDisplay(item?.nominal)}
|
||||
</TextCustom>
|
||||
<TextCustom size="small">
|
||||
{item?.lembarTerbeli} Lembar
|
||||
</TextCustom>
|
||||
</StackCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}>
|
||||
<View />
|
||||
</Grid.Col>
|
||||
<Grid.Col
|
||||
span={5}
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<ProgressCustom
|
||||
value={item?.progress}
|
||||
label={`${item?.progress}%`}
|
||||
size="lg"
|
||||
/>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
))
|
||||
)}
|
||||
</ViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import NoDataText from "@/components/_ShareComponent/NoDataText";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { apiInvestmentGetInvoice } from "@/service/api-client/api-investment";
|
||||
import { GStyles } from "@/styles/global-styles";
|
||||
@@ -74,7 +75,7 @@ export default function InvestmentTransaction() {
|
||||
{loadList ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(list) ? (
|
||||
<TextCustom>Tidak ada data</TextCustom>
|
||||
<NoDataText/>
|
||||
) : (
|
||||
list.map((item: any, i: number) => (
|
||||
<BaseBox
|
||||
|
||||
@@ -1,29 +1,56 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BackButton,
|
||||
BaseBox,
|
||||
DotButton,
|
||||
DrawerCustom,
|
||||
Grid,
|
||||
MenuDrawerDynamicGrid,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
BackButton,
|
||||
BaseBox,
|
||||
DotButton,
|
||||
DrawerCustom,
|
||||
Grid,
|
||||
MenuDrawerDynamicGrid,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconDocument, IconEdit, IconNews } from "@/components/_Icon";
|
||||
import { IMenuDrawerItem } from "@/components/_Interface/types";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_MEDIUM } from "@/constants/constans-value";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import Invesment_ComponentBoxOnBottomDetail from "@/screens/Invesment/ComponentBoxOnBottomDetail";
|
||||
import Invesment_DetailDataPublishSection from "@/screens/Invesment/DetailDataPublishSection";
|
||||
import { apiInvestmentGetInvoice } from "@/service/api-client/api-investment";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { AntDesign, MaterialIcons } from "@expo/vector-icons";
|
||||
import { router, Stack, useLocalSearchParams } from "expo-router";
|
||||
import { router, Stack, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useState } from "react";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
export default function InvestmentDetailHolding() {
|
||||
const { user } = useAuth();
|
||||
const { id, status } = useLocalSearchParams();
|
||||
const [openDrawerDraft, setOpenDrawerDraft] = useState(false);
|
||||
const [openDrawerPublish, setOpenDrawerPublish] = useState(false);
|
||||
const [data, setData] = useState<any>(null);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id, status])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiInvestmentGetInvoice({
|
||||
id: id as string,
|
||||
authorId: user?.id,
|
||||
category: "invoice",
|
||||
});
|
||||
|
||||
console.log("[DATA]", JSON.stringify(response.data, null, 2));
|
||||
setData(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePressDraft = (item: IMenuDrawerItem) => {
|
||||
console.log("PATH >> ", item.path);
|
||||
@@ -39,7 +66,8 @@ export default function InvestmentDetailHolding() {
|
||||
|
||||
const bottomSection = (
|
||||
<Invesment_ComponentBoxOnBottomDetail
|
||||
id={id as string}
|
||||
prospectusId={id as string}
|
||||
id={data?.Investasi?.id as string}
|
||||
status={"publish"}
|
||||
/>
|
||||
);
|
||||
@@ -64,10 +92,12 @@ export default function InvestmentDetailHolding() {
|
||||
<StackCustom gap={"xs"}>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<TextCustom bold>Nila Transaksi</TextCustom>
|
||||
<TextCustom bold>Nilai Transaksi</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<TextCustom bold>Rp. 7.500.000</TextCustom>
|
||||
<TextCustom bold>
|
||||
Rp. {data ? formatCurrencyDisplay(data?.nominal) : ""}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Grid>
|
||||
@@ -75,12 +105,16 @@ export default function InvestmentDetailHolding() {
|
||||
<TextCustom bold>Saham Terbeli</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<TextCustom bold>300 Lembar</TextCustom>
|
||||
<TextCustom bold>
|
||||
{data ? data?.lembarTerbeli : ""} Lembar
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
<Invesment_DetailDataPublishSection
|
||||
data={data && data?.Investasi}
|
||||
status={"publish"}
|
||||
bottomSection={bottomSection}
|
||||
/>
|
||||
|
||||
@@ -1,9 +1,73 @@
|
||||
import { BaseBox, Grid, Spacing, StackCustom, TextCustom, ViewWrapper } from "@/components";
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BaseBox,
|
||||
Grid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { apiInvestmentGetInvoice } from "@/service/api-client/api-investment";
|
||||
import { GStyles } from "@/styles/global-styles";
|
||||
import { dateTimeView } from "@/utils/dateTimeView";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { FontAwesome6 } from "@expo/vector-icons";
|
||||
import { useLocalSearchParams, useFocusEffect } from "expo-router";
|
||||
import React from "react";
|
||||
|
||||
export default function InvestmentFailed() {
|
||||
const { id } = useLocalSearchParams();
|
||||
console.log("[ID]", id);
|
||||
|
||||
const [data, setData] = React.useState<any | null>(null);
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiInvestmentGetInvoice({
|
||||
id: id as string,
|
||||
category: "invoice",
|
||||
});
|
||||
|
||||
console.log("[RES INVOICE]", JSON.stringify(response.data, null, 2));
|
||||
setData(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Bank",
|
||||
value: (data && data?.MasterBank?.namaBank) || "-",
|
||||
},
|
||||
{
|
||||
label: "Rekening Penerima",
|
||||
value: (data && data?.MasterBank?.namaAkun) || "-",
|
||||
},
|
||||
{
|
||||
label: "No Rekening",
|
||||
value: (data && data?.MasterBank?.norek) || "-",
|
||||
},
|
||||
{
|
||||
label: "Jumlah",
|
||||
value: `Rp ${data && formatCurrencyDisplay(data?.nominal)}` || "-",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: (data && dateTimeView({ date: data?.createdAt })) || "-",
|
||||
},
|
||||
{
|
||||
label: "Lembar Terbeli",
|
||||
value: (data && formatCurrencyDisplay(data?.lembarTerbeli)) || "-",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ViewWrapper>
|
||||
<StackCustom>
|
||||
@@ -11,8 +75,7 @@ export default function InvestmentFailed() {
|
||||
<StackCustom>
|
||||
<TextCustom bold align="center">
|
||||
Transaksi anda gagal karena bukti transfer tidak sesuai dengan
|
||||
data kami. Jika ini masalah khusus silahkan hubungi pada kontak
|
||||
whatsapp kami.
|
||||
data kami. Hubungi admin untuk memperbaiki masalah ini.
|
||||
</TextCustom>
|
||||
|
||||
<FontAwesome6
|
||||
@@ -50,30 +113,3 @@ export default function InvestmentFailed() {
|
||||
</ViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Bank",
|
||||
value: " BCA",
|
||||
},
|
||||
{
|
||||
label: "Rekening Penerima",
|
||||
value: "Himpunan Pengusaha Muda Indonesia",
|
||||
},
|
||||
{
|
||||
label: "No Rekening",
|
||||
value: "2304235678854332",
|
||||
},
|
||||
{
|
||||
label: "Jumlah",
|
||||
value: "Rp. 1.000.000",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: "2022-01-01",
|
||||
},
|
||||
{
|
||||
label: "Lembar Terbeli",
|
||||
value: "100",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -108,7 +108,9 @@ export default function InvestmentInvest() {
|
||||
<TextCustom>Sisa Lembar Saham</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6} style={{ alignItems: "flex-end" }}>
|
||||
<TextCustom>{data?.sisaLembar || "-"}</TextCustom>
|
||||
<TextCustom>
|
||||
{data && formatCurrencyDisplay(data?.sisaLembar) || "-"}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Grid>
|
||||
@@ -116,7 +118,9 @@ export default function InvestmentInvest() {
|
||||
<TextCustom>Harga Per Lembar</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6} style={{ alignItems: "flex-end" }}>
|
||||
<TextCustom>{data?.hargaLembar || "-"}</TextCustom>
|
||||
<TextCustom>
|
||||
{data && formatCurrencyDisplay(data?.hargaLembar) || "-"}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Grid>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BaseBox,
|
||||
Grid,
|
||||
@@ -7,10 +8,66 @@ import {
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { apiInvestmentGetInvoice } from "@/service/api-client/api-investment";
|
||||
import { GStyles } from "@/styles/global-styles";
|
||||
import { dateTimeView } from "@/utils/dateTimeView";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { FontAwesome6 } from "@expo/vector-icons";
|
||||
import { useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import React from "react";
|
||||
|
||||
export default function InvestmentSuccess() {
|
||||
const { id } = useLocalSearchParams();
|
||||
console.log("[ID]", id);
|
||||
|
||||
const [data, setData] = React.useState<any | null>(null);
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiInvestmentGetInvoice({
|
||||
id: id as string,
|
||||
category: "invoice",
|
||||
});
|
||||
|
||||
console.log("[RES INVOICE]", JSON.stringify(response.data, null, 2));
|
||||
setData(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Bank",
|
||||
value: (data && data?.MasterBank?.namaBank) || "-",
|
||||
},
|
||||
{
|
||||
label: "Rekening Penerima",
|
||||
value: (data && data?.MasterBank?.namaAkun) || "-",
|
||||
},
|
||||
{
|
||||
label: "No Rekening",
|
||||
value: (data && data?.MasterBank?.norek) || "-",
|
||||
},
|
||||
{
|
||||
label: "Jumlah",
|
||||
value: `Rp ${data && formatCurrencyDisplay(data?.nominal)}` || "-",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: (data && dateTimeView({ date: data?.createdAt })) || "-",
|
||||
},
|
||||
{
|
||||
label: "Lembar Terbeli",
|
||||
value: (data && formatCurrencyDisplay(data?.lembarTerbeli)) || "-",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ViewWrapper>
|
||||
<StackCustom>
|
||||
@@ -35,8 +92,7 @@ export default function InvestmentSuccess() {
|
||||
Detail Transaksi
|
||||
</TextCustom>
|
||||
|
||||
<Spacing/>
|
||||
|
||||
<Spacing />
|
||||
|
||||
<StackCustom>
|
||||
{listData.map((item, i) => (
|
||||
@@ -45,7 +101,9 @@ export default function InvestmentSuccess() {
|
||||
<TextCustom bold>{item.label}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={7}>
|
||||
<TextCustom style={{paddingLeft: 10}}>{item.value}</TextCustom>
|
||||
<TextCustom style={{ paddingLeft: 10 }}>
|
||||
{item.value}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
))}
|
||||
@@ -55,30 +113,3 @@ export default function InvestmentSuccess() {
|
||||
</ViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Bank",
|
||||
value: " BCA",
|
||||
},
|
||||
{
|
||||
label: "Rekening Penerima",
|
||||
value: "Himpunan Pengusaha Muda Indonesia",
|
||||
},
|
||||
{
|
||||
label: "No Rekening",
|
||||
value: "2304235678854332",
|
||||
},
|
||||
{
|
||||
label: "Jumlah",
|
||||
value: "Rp. 1.000.000",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: "2022-01-01",
|
||||
},
|
||||
{
|
||||
label: "Lembar Terbeli",
|
||||
value: "100",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,20 +1,66 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
AvatarUsernameAndOtherComponent,
|
||||
BoxWithHeaderSection,
|
||||
LoaderCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import NoDataText from "@/components/_ShareComponent/NoDataText";
|
||||
import { apiInvestmentGetInvestorById } from "@/service/api-client/api-investment";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
export default function InvestmentInvestor() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [list, setList] = useState<any[] | null>(null);
|
||||
const [loadingList, setLoadingList] = useState(false);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadList();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadList = async () => {
|
||||
try {
|
||||
setLoadingList(true);
|
||||
const response = await apiInvestmentGetInvestorById({
|
||||
id: id as string,
|
||||
})
|
||||
console.log("[DATA LIST]", JSON.stringify(response.data, null, 2));
|
||||
setList(response.data);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadingList(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<BoxWithHeaderSection key={index}>
|
||||
<AvatarUsernameAndOtherComponent />
|
||||
<TextCustom bold>Rp. 7.000.000</TextCustom>
|
||||
</BoxWithHeaderSection>
|
||||
))}
|
||||
{loadingList ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(list) ? (
|
||||
<NoDataText />
|
||||
) : (
|
||||
list?.map((item: any, index: number) => (
|
||||
<BoxWithHeaderSection key={index}>
|
||||
<AvatarUsernameAndOtherComponent
|
||||
avatar={item?.Author?.Profile?.imageId}
|
||||
name={item?.Author?.username}
|
||||
avatarHref={`/profile/${item?.Author?.Profile?.id}`}
|
||||
/>
|
||||
<TextCustom bold>
|
||||
Rp. {formatCurrencyDisplay(item?.nominal)}
|
||||
</TextCustom>
|
||||
</BoxWithHeaderSection>
|
||||
))
|
||||
)}
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,32 +1,6 @@
|
||||
import {
|
||||
ButtonCustom,
|
||||
DrawerCustom,
|
||||
DummyLandscapeImage,
|
||||
Grid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import GridTwoView from "@/components/_ShareComponent/GridTwoView";
|
||||
import API_IMAGE from "@/constants/api-storage";
|
||||
import { ICON_SIZE_SMALL } from "@/constants/constans-value";
|
||||
import { apiMapsGetAll } from "@/service/api-client/api-maps";
|
||||
import { openInDeviceMaps } from "@/utils/openInDeviceMaps";
|
||||
import { FontAwesome, Ionicons } from "@expo/vector-icons";
|
||||
import { Image } from "expo-image";
|
||||
import { router, useFocusEffect } from "expo-router";
|
||||
import { useCallback, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import MapView, { Marker } from "react-native-maps";
|
||||
|
||||
const defaultRegion = {
|
||||
latitude: -8.737109,
|
||||
longitude: 115.1756897,
|
||||
latitudeDelta: 0.1,
|
||||
longitudeDelta: 0.1,
|
||||
height: 300,
|
||||
};
|
||||
import MapsView from "@/screens/Maps/MapsView";
|
||||
import MapsView2 from "@/screens/Maps/MapsView2";
|
||||
import { Text, View } from "react-native";
|
||||
|
||||
export interface LocationItem {
|
||||
id: string | number;
|
||||
@@ -37,198 +11,11 @@ export interface LocationItem {
|
||||
}
|
||||
|
||||
export default function Maps() {
|
||||
const [list, setList] = useState<any[] | null>(null);
|
||||
const [loadList, setLoadList] = useState(false);
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
const [selected, setSelected] = useState({
|
||||
id: "",
|
||||
bidangBisnis: "",
|
||||
nomorTelepon: "",
|
||||
alamatBisnis: "",
|
||||
namePin: "",
|
||||
imageId: "",
|
||||
portofolioId: "",
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
});
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
handlerLoadList();
|
||||
}, [])
|
||||
);
|
||||
|
||||
const handlerLoadList = async () => {
|
||||
try {
|
||||
setLoadList(true);
|
||||
const response = await apiMapsGetAll();
|
||||
|
||||
if (response.success) {
|
||||
setList(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadList(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper style={{ paddingInline: 0, paddingBlock: 0 }}>
|
||||
{/* <MapCustom height={"100%"} /> */}
|
||||
<View style={{ flex: 1 }}>
|
||||
{loadList ? (
|
||||
<MapView
|
||||
initialRegion={defaultRegion}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<MapView
|
||||
initialRegion={defaultRegion}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
{list?.map((item: any, index: number) => {
|
||||
return (
|
||||
<Marker
|
||||
key={item?.id}
|
||||
coordinate={{
|
||||
latitude: item?.latitude,
|
||||
longitude: item?.longitude,
|
||||
}}
|
||||
title={item?.namePin}
|
||||
onPress={() => {
|
||||
setOpenDrawer(true);
|
||||
setSelected({
|
||||
id: item?.id,
|
||||
bidangBisnis:
|
||||
item?.Portofolio?.MasterBidangBisnis?.name,
|
||||
nomorTelepon: item?.Portofolio?.tlpn,
|
||||
alamatBisnis: item?.Portofolio?.alamatKantor,
|
||||
namePin: item?.namePin,
|
||||
imageId: item?.imageId,
|
||||
portofolioId: item?.Portofolio?.id,
|
||||
latitude: item?.latitude,
|
||||
longitude: item?.longitude,
|
||||
});
|
||||
}}
|
||||
// Gunakan gambar kustom jika tersedia
|
||||
>
|
||||
<View style={{}}>
|
||||
<Image
|
||||
source={{
|
||||
uri: API_IMAGE.GET({
|
||||
fileId: item?.Portofolio?.logoId,
|
||||
}),
|
||||
}}
|
||||
style={{
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 100,
|
||||
borderWidth: 1,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</Marker>
|
||||
);
|
||||
})}
|
||||
</MapView>
|
||||
)}
|
||||
</View>
|
||||
</ViewWrapper>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawer}
|
||||
closeDrawer={() => setOpenDrawer(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<DummyLandscapeImage height={200} imageId={selected.imageId} />
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
<GridTwoView
|
||||
spanLeft={2}
|
||||
spanRight={10}
|
||||
leftIcon={
|
||||
<FontAwesome
|
||||
name="building-o"
|
||||
size={ICON_SIZE_SMALL}
|
||||
color="white"
|
||||
/>
|
||||
}
|
||||
rightIcon={<TextCustom>{selected.namePin}</TextCustom>}
|
||||
/>
|
||||
|
||||
<GridTwoView
|
||||
spanLeft={2}
|
||||
spanRight={10}
|
||||
leftIcon={
|
||||
<Ionicons
|
||||
name="list-outline"
|
||||
size={ICON_SIZE_SMALL}
|
||||
color="white"
|
||||
/>
|
||||
}
|
||||
rightIcon={<TextCustom>{selected.bidangBisnis}</TextCustom>}
|
||||
/>
|
||||
|
||||
<GridTwoView
|
||||
spanLeft={2}
|
||||
spanRight={10}
|
||||
leftIcon={
|
||||
<Ionicons
|
||||
name="call-outline"
|
||||
size={ICON_SIZE_SMALL}
|
||||
color="white"
|
||||
/>
|
||||
}
|
||||
rightIcon={<TextCustom>{selected.nomorTelepon}</TextCustom>}
|
||||
/>
|
||||
<GridTwoView
|
||||
spanLeft={2}
|
||||
spanRight={10}
|
||||
leftIcon={
|
||||
<Ionicons
|
||||
name="location-outline"
|
||||
size={ICON_SIZE_SMALL}
|
||||
color="white"
|
||||
/>
|
||||
}
|
||||
rightIcon={<TextCustom>{selected.alamatBisnis}</TextCustom>}
|
||||
/>
|
||||
|
||||
<Grid>
|
||||
<Grid.Col span={6} style={{ paddingRight: 10 }}>
|
||||
<ButtonCustom
|
||||
onPress={() => {
|
||||
setOpenDrawer(false);
|
||||
router.push(`/portofolio/${selected.portofolioId}`);
|
||||
}}
|
||||
>
|
||||
Detail
|
||||
</ButtonCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6} style={{ paddingLeft: 10 }}>
|
||||
<ButtonCustom
|
||||
onPress={() => {
|
||||
openInDeviceMaps({
|
||||
latitude: selected.latitude,
|
||||
longitude: selected.longitude,
|
||||
title: selected.namePin,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Buka Maps
|
||||
</ButtonCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</StackCustom>
|
||||
</DrawerCustom>
|
||||
<MapsView />
|
||||
{/* <MapsView2 />, */}
|
||||
{/* <View style={{ flex: 1, backgroundColor: "gray" }}><Text style={{ color: "white" }}>Map disabled</Text></View> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ export default function ApplicationLayout() {
|
||||
<Stack.Screen name="(user)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="admin" options={{ headerShown: false }} />
|
||||
|
||||
|
||||
|
||||
{/* Take Picture */}
|
||||
<Stack.Screen
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
ActionIcon,
|
||||
AlertDefaultSystem,
|
||||
@@ -18,97 +19,153 @@ import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButt
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import ReportBox from "@/components/Box/ReportBox";
|
||||
import { ICON_SIZE_BUTTON, TEXT_SIZE_LARGE } from "@/constants/constans-value";
|
||||
import AdminDonation_BoxOfDonationStory from "@/screens/Admin/Donation/BoxOfDonationStory";
|
||||
import { funUpdateStatusDonation } from "@/screens/Admin/Donation/funDonationUpdateStatus";
|
||||
import { apiAdminDonationDetailById } from "@/service/api-admin/api-admin-donation";
|
||||
import { colorBadgeStatus } from "@/utils/colorBadge";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminDonationDetail() {
|
||||
const { id, status } = useLocalSearchParams();
|
||||
const [openDrawer, setOpenDrawer] = React.useState(false);
|
||||
|
||||
const colorBadge = () => {
|
||||
if (status === "publish") {
|
||||
return MainColor.green;
|
||||
} else if (status === "review") {
|
||||
return MainColor.orange;
|
||||
} else if (status === "reject") {
|
||||
return MainColor.red;
|
||||
} else {
|
||||
return MainColor.placeholder;
|
||||
const [data, setData] = React.useState<any | null>(null);
|
||||
const [countDonatur, setCountDonatur] = React.useState(0);
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiAdminDonationDetailById({
|
||||
id: id as string,
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
setData(response.data.donasi);
|
||||
setCountDonatur(response.data.donatur);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
setData(null);
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Penggalang Dana",
|
||||
value: `Bagas Banuna ${id}`,
|
||||
value: (data && data?.Author?.username) || "-",
|
||||
},
|
||||
{
|
||||
label: "Judul",
|
||||
value: `Donasi Lorem ipsum dolor sit amet, consectetur adipisicing elit.`,
|
||||
value: (data && data?.title) || "-",
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: (
|
||||
<BadgeCustom color={colorBadge()}>
|
||||
{_.startCase(status as string)}
|
||||
</BadgeCustom>
|
||||
),
|
||||
value:
|
||||
data && data?.DonasiMaster_Status?.name ? (
|
||||
<BadgeCustom
|
||||
color={colorBadgeStatus({
|
||||
status: data?.DonasiMaster_Status?.name,
|
||||
})}
|
||||
>
|
||||
{_.startCase(data?.DonasiMaster_Status?.name)}
|
||||
</BadgeCustom>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "Durasi",
|
||||
value: "30 Hari",
|
||||
value: (data && data?.DonasiMaster_Durasi?.name) + " hari" || "-",
|
||||
},
|
||||
{
|
||||
label: "Target Dana",
|
||||
value: "Rp 10.000.000",
|
||||
value:
|
||||
data && data?.target
|
||||
? `Rp. ${formatCurrencyDisplay(data?.target)}`
|
||||
: "-",
|
||||
},
|
||||
{
|
||||
label: "Kategori",
|
||||
value: "Kategori Donasi",
|
||||
value: (data && data?.DonasiMaster_Ketegori?.name) || "-",
|
||||
},
|
||||
// {
|
||||
// label: "Total Donatur",
|
||||
// value: "-",
|
||||
// },
|
||||
// {
|
||||
// label: "Progress",
|
||||
// value: "0 %",
|
||||
// },
|
||||
// {
|
||||
// label: "Dana Terkumpul",
|
||||
// value: "Rp 0",
|
||||
// },
|
||||
];
|
||||
|
||||
const listPencarianDana = [
|
||||
{
|
||||
label: "Total Dana Dicairkan",
|
||||
value: "Rp 0",
|
||||
value: `Rp ${(data && formatCurrencyDisplay(data?.totalPencairan)) || 0}`,
|
||||
},
|
||||
{
|
||||
label: "Sisa Dana",
|
||||
value: "Rp 0",
|
||||
label: "Sisa Dana Masuk",
|
||||
value: `Rp ${
|
||||
(data &&
|
||||
formatCurrencyDisplay(data?.terkumpul - data?.totalPencairan)) ||
|
||||
0
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "Akumulasi Pencairan",
|
||||
value: "0 kali",
|
||||
value: `${(data && data?.akumulasiPencairan) || 0} kali`,
|
||||
},
|
||||
{
|
||||
label: "Bank Tujuan",
|
||||
value: "BNI",
|
||||
value: (data && data?.namaBank) || "-",
|
||||
},
|
||||
{
|
||||
label: "Nomor Rekening",
|
||||
value: "123456789",
|
||||
value: (data && data?.rekening) || "-",
|
||||
},
|
||||
];
|
||||
|
||||
const handleReport = async ({
|
||||
changeStatus,
|
||||
}: {
|
||||
changeStatus: "publish" | "review" | "reject";
|
||||
}) => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await funUpdateStatusDonation({
|
||||
id: id as string,
|
||||
changeStatus,
|
||||
data: data,
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Update status gagal",
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Update status berhasil",
|
||||
});
|
||||
|
||||
router.back();
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const rightComponent = (
|
||||
<ActionIcon
|
||||
icon={<IconDot size={ICON_SIZE_BUTTON} />}
|
||||
@@ -118,8 +175,6 @@ export default function AdminDonationDetail() {
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
@@ -147,11 +202,20 @@ export default function AdminDonationDetail() {
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
|
||||
<ButtonCustom
|
||||
iconLeft={
|
||||
<Ionicons name="cash-outline" size={ICON_SIZE_BUTTON} />
|
||||
}
|
||||
disabled={data?.terkumpul - data?.totalPencairan <= 0}
|
||||
onPress={() => {
|
||||
if (data?.terkumpul - data?.totalPencairan <= 0) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Tidak ada dana yang tersisa",
|
||||
});
|
||||
return;
|
||||
}
|
||||
router.push(`/admin/donation/${id}/disbursement-of-funds`);
|
||||
}}
|
||||
>
|
||||
@@ -161,16 +225,32 @@ export default function AdminDonationDetail() {
|
||||
</BaseBox>
|
||||
|
||||
<BaseBox>
|
||||
<ProgressCustom size="lg" />
|
||||
<ProgressCustom
|
||||
size="lg"
|
||||
value={Number(data?.progres) || 0}
|
||||
showLabel={true}
|
||||
label={data?.progres + "%"}
|
||||
animated
|
||||
color="primary"
|
||||
/>
|
||||
<Spacing />
|
||||
|
||||
<StackCustom gap={"xs"}>
|
||||
<GridDetail_4_8
|
||||
label={<TextCustom bold>Jumlah Donatur</TextCustom>}
|
||||
value={<TextCustom>0 orang</TextCustom>}
|
||||
value={
|
||||
<TextCustom>
|
||||
{countDonatur ? countDonatur : 0} orang
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
<GridDetail_4_8
|
||||
label={<TextCustom bold>Dana Terkumpul</TextCustom>}
|
||||
value={<TextCustom>Rp 0</TextCustom>}
|
||||
value={
|
||||
<TextCustom>
|
||||
Rp {formatCurrencyDisplay(data?.terkumpul || 0)}
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
@@ -179,7 +259,7 @@ export default function AdminDonationDetail() {
|
||||
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
<DummyLandscapeImage />
|
||||
<DummyLandscapeImage imageId={data?.imageId || ""} />
|
||||
{listData.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
@@ -190,27 +270,33 @@ export default function AdminDonationDetail() {
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
<AdminDonation_BoxOfDonationStory data={data?.CeritaDonasi as any} />
|
||||
|
||||
{data &&
|
||||
data?.catatan &&
|
||||
(status === "review" || status === "reject") && (
|
||||
<ReportBox text={data?.catatan} />
|
||||
)}
|
||||
|
||||
{status === "review" && (
|
||||
<StackCustom>
|
||||
<AdminDonation_BoxOfDonationStory />
|
||||
|
||||
<AdminButtonReview
|
||||
isLoading={isLoading}
|
||||
onPublish={() => {
|
||||
AlertDefaultSystem({
|
||||
title: "Publish",
|
||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
router.back();
|
||||
handleReport({ changeStatus: "publish" });
|
||||
},
|
||||
});
|
||||
}}
|
||||
onReject={() => {
|
||||
router.push(`/admin/donation/${id}/reject-input`);
|
||||
router.push(
|
||||
`/admin/donation/${id}/reject-input?status=${status}`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</StackCustom>
|
||||
@@ -218,12 +304,12 @@ export default function AdminDonationDetail() {
|
||||
|
||||
{status === "reject" && (
|
||||
<StackCustom>
|
||||
<AdminDonation_BoxOfDonationStory />
|
||||
|
||||
<AdminButtonReject
|
||||
title="Tambah Catatan"
|
||||
onReject={() => {
|
||||
router.push(`/admin/donation/${id}/reject-input`);
|
||||
router.push(
|
||||
`/admin/donation/${id}/reject-input?status=${status}`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</StackCustom>
|
||||
|
||||
@@ -9,51 +9,162 @@ import {
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import {
|
||||
apiAdminDonationInvoiceDetailById,
|
||||
apiAdminDonationInvoiceUpdateById,
|
||||
} from "@/service/api-admin/api-admin-donation";
|
||||
import { colorBadgeTransaction } from "@/utils/colorBadge";
|
||||
import { dateTimeView } from "@/utils/dateTimeView";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminDonasiTransactionDetail() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const { id, status } = useLocalSearchParams();
|
||||
console.log("[STATUS]", id, status);
|
||||
|
||||
const buttonAction = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Terima</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
const [data, setData] = useState<any | null>(null);
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiAdminDonationInvoiceDetailById({
|
||||
id: id as string,
|
||||
});
|
||||
|
||||
console.log("[GET INVOICE BY ID]", JSON.stringify(response, null, 2));
|
||||
if (response.success) {
|
||||
setData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handlerSubmit = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const newData = {
|
||||
donationId: data?.donasiId,
|
||||
nominal: data?.nominal,
|
||||
};
|
||||
|
||||
const response = await apiAdminDonationInvoiceUpdateById({
|
||||
id: id as string,
|
||||
data: newData,
|
||||
status: "berhasil",
|
||||
});
|
||||
|
||||
console.log("[UPDATE INVOICE]", JSON.stringify(response, null, 2));
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: response.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: response.message,
|
||||
});
|
||||
router.back();
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const buttonAction = () => {
|
||||
if (data && data?.DonasiMaster_StatusInvoice?.name === "Menunggu") {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (data && data?.DonasiMaster_StatusInvoice?.name === "Proses") {
|
||||
return (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
isLoading={isLoading}
|
||||
onPress={() => {
|
||||
handlerSubmit();
|
||||
}}
|
||||
>
|
||||
Terima donasi
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom disabled>
|
||||
{data?.DonasiMaster_StatusInvoice?.name}
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Donatur",
|
||||
value: "Bagas Banuna",
|
||||
value: (data && data?.Author?.username) || "-",
|
||||
},
|
||||
{
|
||||
label: "Bank",
|
||||
value: "BCA",
|
||||
value: (data && data?.MasterBank?.namaBank) || "-",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Donasi",
|
||||
value: "Rp. 1.000.000",
|
||||
value: `Rp. ${
|
||||
(data && data?.nominal && formatCurrencyDisplay(data?.nominal)) || "-"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: <BadgeCustom color={MainColor.green}>Berhasil</BadgeCustom>,
|
||||
value:
|
||||
(data && data?.DonasiMaster_StatusInvoice?.name && (
|
||||
<BadgeCustom
|
||||
color={colorBadgeTransaction({
|
||||
status: data?.DonasiMaster_StatusInvoice?.name as any,
|
||||
})}
|
||||
>
|
||||
{_.startCase(
|
||||
(data?.DonasiMaster_StatusInvoice?.name as any) || "-"
|
||||
)}
|
||||
</BadgeCustom>
|
||||
)) ||
|
||||
"-",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: dayjs().format("DD-MM-YYYY HH:mm:ss"),
|
||||
value: (data && dateTimeView({ date: data?.createdAt })) || "-",
|
||||
},
|
||||
{
|
||||
label: "Bukti Transfer",
|
||||
value: (
|
||||
<ButtonCustom
|
||||
onPress={() =>
|
||||
router.push(`/(application)/(image)/preview-image/${id}`)
|
||||
}
|
||||
>
|
||||
Cek
|
||||
</ButtonCustom>
|
||||
),
|
||||
value:
|
||||
(data && data?.imageId && (
|
||||
<ButtonCustom
|
||||
onPress={() =>
|
||||
router.push(
|
||||
`/(application)/(image)/preview-image/${data?.imageId}`
|
||||
)
|
||||
}
|
||||
>
|
||||
Cek
|
||||
</ButtonCustom>
|
||||
)) ||
|
||||
"-",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -61,7 +172,7 @@ export default function AdminDonasiTransactionDetail() {
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Detail Transaksi" />}
|
||||
footerComponent={buttonAction}
|
||||
footerComponent={buttonAction()}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BaseBox,
|
||||
ButtonCustom,
|
||||
@@ -7,27 +8,53 @@ import {
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { apiAdminDonationDisbursementOfFundsListById } from "@/service/api-admin/api-admin-donation";
|
||||
import { dateTimeView } from "@/utils/dateTimeView";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
export default function AdminDonationDetailDisbursementOfFunds() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [data, setData] = React.useState<any | null>(null);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiAdminDonationDisbursementOfFundsListById({
|
||||
id: id as string,
|
||||
category: "get-one",
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
setData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Nominal",
|
||||
value: "Rp 1.000.000",
|
||||
value: `Rp ${(data && formatCurrencyDisplay(data?.nominalCair)) || 0}`,
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: dayjs().format("DD-MM-YYYY HH:mm"),
|
||||
value: dateTimeView({ date: data?.createdAt }),
|
||||
},
|
||||
{
|
||||
label: "Judul",
|
||||
value: `Judul Pencairan Dana ${id}`,
|
||||
value: (data && data?.title) || "-",
|
||||
},
|
||||
{
|
||||
label: "Deskripsi",
|
||||
value: `Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque velit eos facere a dicta nemo repellendus harum laboriosam quos, earum reprehenderit. Nisi sapiente, quo earum quis alias ullam temporibus quidem.`,
|
||||
value: (data && data?.deskripsi) || "-",
|
||||
},
|
||||
];
|
||||
return (
|
||||
@@ -39,7 +66,7 @@ export default function AdminDonationDetailDisbursementOfFunds() {
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
{listData.map((item, index) => (
|
||||
{listData?.map((item, index) => (
|
||||
<GridDetail_4_8
|
||||
key={index}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
@@ -51,7 +78,7 @@ export default function AdminDonationDetailDisbursementOfFunds() {
|
||||
|
||||
<ButtonCustom
|
||||
onPress={() =>
|
||||
router.push(`/(application)/(image)/preview-image/${id}`)
|
||||
router.push(`/(application)/(image)/preview-image/${data?.imageId}`)
|
||||
}
|
||||
>
|
||||
Cek Bukti Transaksi
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BaseBox,
|
||||
BoxButtonOnFooter,
|
||||
@@ -12,15 +13,122 @@ import {
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import DIRECTORY_ID from "@/constants/directory-id";
|
||||
import { apiAdminDonationDetailById, apiAdminDonationDisbursementOfFundsCreated } from "@/service/api-admin/api-admin-donation";
|
||||
import { uploadFileService } from "@/service/upload-service";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import pickFile from "@/utils/pickFile";
|
||||
import { Image } from "expo-image";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import React from "react";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminDonationDisbursementOfFunds() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const handleSubmit = (
|
||||
|
||||
const [data, setData] = React.useState<any | null>(null);
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
|
||||
const [value, setValue] = React.useState({
|
||||
nominalCair: "",
|
||||
title: "",
|
||||
deskripsi: "",
|
||||
});
|
||||
|
||||
const [image, setImage] = React.useState<any | null>(null);
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiAdminDonationDetailById({
|
||||
id: id as string,
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
setData(response.data.donasi);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
setData(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!image) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Harap upload bukti transfer",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!value.nominalCair || !value.title || !value.deskripsi) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Harap isi semua data",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const uploadImage = await uploadFileService({
|
||||
dirId: DIRECTORY_ID.donasi_bukti_trf_pencairan_dana,
|
||||
imageUri: image.uri,
|
||||
});
|
||||
|
||||
if (!uploadFileService) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Gagal mengunggah gambar",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const imageId = uploadImage.data.id;
|
||||
|
||||
const newData = {
|
||||
...value,
|
||||
imageId: imageId,
|
||||
};
|
||||
|
||||
const response = await apiAdminDonationDisbursementOfFundsCreated({
|
||||
id: id as string,
|
||||
data: newData,
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: response.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Pencairan dana berhasil disimpan",
|
||||
});
|
||||
|
||||
router.back();
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
isLoading={isLoading}
|
||||
onPress={() => {
|
||||
router.back();
|
||||
handleSubmit();
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
@@ -31,7 +139,7 @@ export default function AdminDonationDisbursementOfFunds() {
|
||||
return (
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Pencairan Dana" />}
|
||||
footerComponent={handleSubmit}
|
||||
footerComponent={buttonSubmit}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom gap="md">
|
||||
@@ -39,7 +147,7 @@ export default function AdminDonationDisbursementOfFunds() {
|
||||
Dana Tersisa
|
||||
</TextCustom>
|
||||
<TextCustom align="center" bold size="large">
|
||||
Rp 1.000.000
|
||||
Rp {formatCurrencyDisplay(data?.terkumpul - data?.totalPencairan)}
|
||||
</TextCustom>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
@@ -56,9 +164,27 @@ export default function AdminDonationDisbursementOfFunds() {
|
||||
label="Nominal"
|
||||
placeholder="0"
|
||||
iconLeft={"Rp"}
|
||||
value={value.nominalCair}
|
||||
onChangeText={(text) => {
|
||||
setValue({
|
||||
...value,
|
||||
nominalCair: text,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInputCustom required label="Judul" placeholder="Masukan judul" />
|
||||
<TextInputCustom
|
||||
required
|
||||
label="Judul"
|
||||
placeholder="Masukan judul"
|
||||
value={value.title}
|
||||
onChangeText={(text) => {
|
||||
setValue({
|
||||
...value,
|
||||
title: text,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextAreaCustom
|
||||
required
|
||||
@@ -66,20 +192,37 @@ export default function AdminDonationDisbursementOfFunds() {
|
||||
placeholder="Masukan deskripsi"
|
||||
showCount
|
||||
maxLength={500}
|
||||
value={value.deskripsi}
|
||||
onChangeText={(text) => {
|
||||
setValue({
|
||||
...value,
|
||||
deskripsi: text,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
<InformationBox text="Wajib menyertakan bukti transfer" />
|
||||
|
||||
<Spacing />
|
||||
|
||||
<InformationBox text="Wajib menyertakan bukti transfer" />
|
||||
<ButtonCenteredOnly
|
||||
onPress={() => {
|
||||
router.push(`/(application)/(image)/take-picture/${id}`);
|
||||
pickFile({
|
||||
allowedType: "image",
|
||||
aspectRatio: [9, 16],
|
||||
setImageUri: (file) => {
|
||||
setImage(file);
|
||||
},
|
||||
});
|
||||
}}
|
||||
icon="upload"
|
||||
>
|
||||
Upload
|
||||
</ButtonCenteredOnly>
|
||||
<Spacing />
|
||||
<Image source={image?.uri} style={{ width: "100%", height: 300 }} />
|
||||
<Spacing />
|
||||
</ViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,54 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
ActionIcon,
|
||||
CenterCustom,
|
||||
Divider,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
ActionIcon,
|
||||
CenterCustom,
|
||||
Divider,
|
||||
LoaderCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconView } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { apiAdminDonationDisbursementOfFundsListById } from "@/service/api-admin/api-admin-donation";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React, { useCallback } from "react";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function AdminDonasiListOfDisbursementOfFunds() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [listData, setListData] = React.useState<any[] | null>(null);
|
||||
const [loadData, setLoadData] = React.useState(false);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadData(true);
|
||||
const response = await apiAdminDonationDisbursementOfFundsListById({
|
||||
id: id as string,
|
||||
category: "get-all",
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
setListData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
@@ -45,36 +78,47 @@ export default function AdminDonasiListOfDisbursementOfFunds() {
|
||||
/>
|
||||
<Divider />
|
||||
<StackCustom>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<View key={index}>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||
onPress={() => {
|
||||
router.push(
|
||||
`/admin/donation/${id}/detail-disbursement-of-funds`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center" truncate>
|
||||
{dayjs()
|
||||
.add(index + 1, "day")
|
||||
.format("DD-MM-YYYY HH:mm")}
|
||||
</TextCustom>
|
||||
}
|
||||
component3={<TextCustom>Rp. 1.000.000</TextCustom>}
|
||||
/>
|
||||
<Divider />
|
||||
</View>
|
||||
))}
|
||||
{loadData ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(listData) ? (
|
||||
<TextCustom align="center" color="gray">
|
||||
Belum ada data
|
||||
</TextCustom>
|
||||
) : (
|
||||
listData?.map((item, index) => (
|
||||
<View key={index}>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={
|
||||
<IconView size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(
|
||||
`/admin/donation/${item?.id}/detail-disbursement-of-funds`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom align="center" truncate>
|
||||
{dayjs(item?.createdAt).format("DD-MM-YYYY")}
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<TextCustom align="center" truncate>
|
||||
Rp. {formatCurrencyDisplay(item?.nominalCair)}
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
))
|
||||
)}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
ActionIcon,
|
||||
BadgeCustom,
|
||||
CenterCustom,
|
||||
LoaderCustom,
|
||||
SelectCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
@@ -10,23 +12,91 @@ import {
|
||||
import { IconView } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { dummyMasterStatusTransaction } from "@/lib/dummy-data/_master/status-transaction";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import React from "react";
|
||||
import { apiAdminDonationListOfDonatur } from "@/service/api-admin/api-admin-donation";
|
||||
import { apiMasterTransaction } from "@/service/api-client/api-master";
|
||||
import { colorBadgeTransaction } from "@/utils/colorBadge";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React, { useEffect } from "react";
|
||||
import { View } from "react-native";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminDonasiListOfDonatur() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [listData, setListData] = React.useState<any[] | null>(null);
|
||||
const [loadData, setLoadData] = React.useState(false);
|
||||
const [master, setMaster] = React.useState<any[]>([]);
|
||||
|
||||
const [selectValue, setSelectValue] = React.useState<string | null>(null);
|
||||
const [selectedStatus, setSelectedStatus] = React.useState<string | null>(
|
||||
null
|
||||
);
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id, selectValue])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadData(true);
|
||||
const response = await apiAdminDonationListOfDonatur({
|
||||
id: id as string,
|
||||
status: selectedStatus as any,
|
||||
});
|
||||
// console.log("[LIST OF DONATUR]", JSON.stringify(response, null, 2));
|
||||
|
||||
if (response.success) {
|
||||
setListData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
setListData([]);
|
||||
} finally {
|
||||
setLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
onLoadMaster();
|
||||
}, []);
|
||||
|
||||
const onLoadMaster = async () => {
|
||||
try {
|
||||
const response = await apiMasterTransaction();
|
||||
|
||||
if (response.success) {
|
||||
setMaster(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
setMaster([]);
|
||||
}
|
||||
};
|
||||
|
||||
const searchComponent = (
|
||||
<View style={{ flexDirection: "row", gap: 5 }}>
|
||||
<SelectCustom
|
||||
placeholder="Pilih status transaksi"
|
||||
data={dummyMasterStatusTransaction}
|
||||
onChange={(value) => console.log(value)}
|
||||
data={
|
||||
_.isEmpty(master)
|
||||
? []
|
||||
: master?.map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}))
|
||||
}
|
||||
value={selectValue}
|
||||
onChange={(value: any) => {
|
||||
setSelectValue(value);
|
||||
const nameSelected = master.find((item: any) => item.id === value);
|
||||
const statusChooses = _.lowerCase(nameSelected?.name);
|
||||
setSelectedStatus(statusChooses);
|
||||
}}
|
||||
styleContainer={{ width: "100%", marginBottom: 0 }}
|
||||
allowClear
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
@@ -37,63 +107,78 @@ export default function AdminDonasiListOfDonatur() {
|
||||
<AdminBackButtonAntTitle newComponent={searchComponent} />
|
||||
}
|
||||
>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<TextCustom bold align="center">
|
||||
Aksi
|
||||
</TextCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center">
|
||||
Donatur
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<TextCustom bold align="center">
|
||||
Status
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
<StackCustom>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<View key={index}>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||
onPress={() => {
|
||||
router.push(
|
||||
`/admin/donation/${id}/berhasil/transaction-detail`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center" truncate>
|
||||
Bagas Banuna
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<BadgeCustom
|
||||
style={{ alignSelf: "center" }}
|
||||
color={MainColor.green}
|
||||
>
|
||||
Berhasil
|
||||
</BadgeCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
</View>
|
||||
))}
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<TextCustom bold align="center">
|
||||
Aksi
|
||||
</TextCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center">
|
||||
Donatur
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<TextCustom bold align="center">
|
||||
Status
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
<StackCustom>
|
||||
{loadData ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(listData) ? (
|
||||
<TextCustom align="center" color="gray">
|
||||
Belum ada data
|
||||
</TextCustom>
|
||||
) : (
|
||||
listData?.map((item: any, index: number) => (
|
||||
<View key={index}>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={
|
||||
<IconView size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(
|
||||
`/admin/donation/${item?.id}/${_.lowerCase(
|
||||
item?.DonasiMaster_StatusInvoice?.name
|
||||
)}/transaction-detail`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center" truncate>
|
||||
{item?.Author?.username || "-"}
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<BadgeCustom
|
||||
style={{ alignSelf: "center" }}
|
||||
color={colorBadgeTransaction({
|
||||
status: item?.DonasiMaster_StatusInvoice?.name,
|
||||
})}
|
||||
>
|
||||
{item?.DonasiMaster_StatusInvoice?.name}
|
||||
</BadgeCustom>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
))
|
||||
)}
|
||||
</StackCustom>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BoxButtonOnFooter,
|
||||
@@ -6,15 +7,84 @@ import {
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { funUpdateStatusDonation } from "@/screens/Admin/Donation/funDonationUpdateStatus";
|
||||
import {
|
||||
apiAdminDonationDetailById
|
||||
} from "@/service/api-admin/api-admin-donation";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import React from "react";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminDonationRejectInput() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [value, setValue] = useState(id as string);
|
||||
const { id, status } = useLocalSearchParams();
|
||||
|
||||
const [data, setData] = React.useState<any | null>(null);
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiAdminDonationDetailById({
|
||||
id: id as string,
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
setData(response.data.catatan);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
setData(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleReport = async ({
|
||||
changeStatus,
|
||||
}: {
|
||||
changeStatus: "publish" | "review" | "reject";
|
||||
}) => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await funUpdateStatusDonation({
|
||||
id: id as string,
|
||||
changeStatus,
|
||||
data: data,
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Report gagal",
|
||||
});
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Report berhasil",
|
||||
});
|
||||
|
||||
if (status === "review") {
|
||||
router.replace(`/admin/donation/reject/status`);
|
||||
} else if (status === "reject") {
|
||||
router.back();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<AdminButtonReject
|
||||
isLoading={isLoading}
|
||||
title="Reject"
|
||||
onReject={() =>
|
||||
AlertDefaultSystem({
|
||||
@@ -22,12 +92,9 @@ export default function AdminDonationRejectInput() {
|
||||
message: "Apakah anda yakin ingin menolak data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
|
||||
onPressRight: () => {
|
||||
console.log("value:", value);
|
||||
router.replace(`/admin/donation/reject/status`);
|
||||
handleReport({ changeStatus: "reject" });
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -42,8 +109,8 @@ export default function AdminDonationRejectInput() {
|
||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Donasi" />}
|
||||
>
|
||||
<TextAreaCustom
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
value={data}
|
||||
onChangeText={setData}
|
||||
placeholder="Masukan alasan"
|
||||
required
|
||||
showCount
|
||||
|
||||
@@ -1,69 +1,116 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
ActionIcon,
|
||||
SearchInput,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
ActionIcon,
|
||||
LoaderCustom,
|
||||
SearchInput,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
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 { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { apiAdminDonation } from "@/service/api-admin/api-admin-donation";
|
||||
import { Octicons } from "@expo/vector-icons";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminDonationStatus() {
|
||||
const { status } = useLocalSearchParams();
|
||||
console.log("[STATUS]", status);
|
||||
|
||||
const [data, setData] = useState<any | null>(null);
|
||||
const [search, setSearch] = useState<string>("");
|
||||
const [loadData, setLoadData] = useState<boolean>(false);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [status, search])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadData(true);
|
||||
const response = await apiAdminDonation({
|
||||
category: status as "publish" | "review" | "reject",
|
||||
search,
|
||||
});
|
||||
|
||||
console.log("[RES]", JSON.stringify(response, null, 2));
|
||||
|
||||
if (response.success) {
|
||||
setData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
setData([]);
|
||||
} finally {
|
||||
setLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
const rightComponent = (
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari"
|
||||
value={search}
|
||||
onChangeText={(value) => setSearch(value)}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Donasi" />}>
|
||||
<StackCustom gap={"sm"}>
|
||||
<AdminComp_BoxTitle
|
||||
title={`Donasi ${_.startCase(status as string)}`}
|
||||
title={`${_.startCase(status as string)}`}
|
||||
rightComponent={rightComponent}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Donasi"
|
||||
/>
|
||||
<Spacing />
|
||||
<Divider />
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons name="eye" size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/donation/${index}/${status}`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Donasi"
|
||||
/>
|
||||
))}
|
||||
<Divider />
|
||||
|
||||
{loadData ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(data) ? (
|
||||
<TextCustom align="center" size="small" color="gray">
|
||||
Belum ada data
|
||||
</TextCustom>
|
||||
) : (
|
||||
data?.map((item: any, index: number) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons
|
||||
name="eye"
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color="black"
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/donation/${item.id}/${status}`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>{item?.Author?.username || "-"}</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
{item?.title || "-"}
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,15 +1,67 @@
|
||||
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
||||
import {
|
||||
IconList,
|
||||
IconPublish,
|
||||
IconReject,
|
||||
IconReview,
|
||||
IconList,
|
||||
IconPublish,
|
||||
IconReject,
|
||||
IconReview,
|
||||
} from "@/components/_Icon/IconComponent";
|
||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { apiAdminDonation } from "@/service/api-admin/api-admin-donation";
|
||||
import { useFocusEffect } from "expo-router";
|
||||
import { useState, useCallback } from "react";
|
||||
|
||||
export default function AdminDonation() {
|
||||
const [data, setData] = useState<any | null>(null);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
|
||||
const response = await apiAdminDonation({
|
||||
category: "dashboard",
|
||||
});
|
||||
|
||||
console.log("[RES]", JSON.stringify(response, null, 2));
|
||||
|
||||
if (response.success) {
|
||||
setData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
setData([]);
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Publish",
|
||||
value: (data && data.publish) || 0,
|
||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Review",
|
||||
value: (data && data.review) || 0,
|
||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
||||
},
|
||||
{
|
||||
label: "Reject",
|
||||
value: (data && data.reject) || 0,
|
||||
icon: <IconReject size={25} color={MainColor.red} />,
|
||||
},
|
||||
{
|
||||
label: "Kategori",
|
||||
value: (data && data.categoryDonation) || 0,
|
||||
icon: <IconList size={25} color={MainColor.white_gray} />,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
@@ -24,26 +76,3 @@ export default function AdminDonation() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Publish",
|
||||
value: 4,
|
||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Review",
|
||||
value: 7,
|
||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
||||
},
|
||||
{
|
||||
label: "Reject",
|
||||
value: 5,
|
||||
icon: <IconReject size={25} color={MainColor.red} />,
|
||||
},
|
||||
{
|
||||
label: "Kategori",
|
||||
value: 4,
|
||||
icon: <IconList size={25} color={MainColor.white_gray} />,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
ActionIcon,
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
DrawerCustom,
|
||||
MenuDrawerDynamicGrid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
ActionIcon,
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
DrawerCustom,
|
||||
LoaderCustom,
|
||||
MenuDrawerDynamicGrid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconDot, IconList } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
@@ -22,25 +23,22 @@ import { useAuth } from "@/hooks/use-auth";
|
||||
import { funUpdateStatusEvent } from "@/screens/Admin/Event/funUpdateStatus";
|
||||
import { apiAdminEventById } from "@/service/api-admin/api-admin-event";
|
||||
import { DEEP_LINK_URL } from "@/service/api-config";
|
||||
import { colorBadge } from "@/utils/colorBadge";
|
||||
import { colorBadgeStatus } from "@/utils/colorBadge";
|
||||
import { dateTimeView } from "@/utils/dateTimeView";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React, { useCallback } from "react";
|
||||
import QRCode from "react-native-qrcode-svg";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminEventDetail() {
|
||||
const { user } = useAuth();
|
||||
const { id, status } = useLocalSearchParams();
|
||||
|
||||
console.log("[ID QRCODE]", id);
|
||||
console.log("[STATUS Detail]", status);
|
||||
const [openDrawer, setOpenDrawer] = React.useState(false);
|
||||
const newURL = DEEP_LINK_URL
|
||||
console.log("[DEEP LINK URL]", newURL);
|
||||
|
||||
const [data, setData] = React.useState<any | null>(null);
|
||||
const deepLinkURL = `${DEEP_LINK_URL}/--/event/${id}/confirmation?userId=${user?.id}`;
|
||||
const [loadData, setLoadData] = React.useState(false);
|
||||
const deepLinkURL = `${DEEP_LINK_URL}/event/${id}/confirmation?userId=${user?.id}`;
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
@@ -48,17 +46,18 @@ export default function AdminEventDetail() {
|
||||
);
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadData(true);
|
||||
const response = await apiAdminEventById({
|
||||
id: id as string,
|
||||
});
|
||||
|
||||
// console.log(`[RES DATA BY ID: ${id}]`, JSON.stringify(response, null, 2));
|
||||
|
||||
if (response.success) {
|
||||
setData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -75,7 +74,7 @@ export default function AdminEventDetail() {
|
||||
label: "Status",
|
||||
value:
|
||||
(data && (
|
||||
<BadgeCustom color={colorBadge({ status: status as string })}>
|
||||
<BadgeCustom color={colorBadgeStatus({ status: status as string })}>
|
||||
{_.startCase(status as string)}
|
||||
</BadgeCustom>
|
||||
)) ||
|
||||
@@ -124,11 +123,19 @@ export default function AdminEventDetail() {
|
||||
changeStatus: "publish",
|
||||
});
|
||||
|
||||
console.log("[RES PUBLISH]", JSON.stringify(response, null, 2));
|
||||
|
||||
if (response.success) {
|
||||
router.back();
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Gagal mempublikasikan event",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Event berhasil dipublikasikan",
|
||||
});
|
||||
router.back();
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
@@ -170,15 +177,21 @@ export default function AdminEventDetail() {
|
||||
<BaseBox>
|
||||
<StackCustom style={{ alignItems: "center" }}>
|
||||
<TextCustom bold>QR Code Event</TextCustom>
|
||||
<QRCode
|
||||
value={deepLinkURL}
|
||||
size={200}
|
||||
// logo={require("@/assets/images/logo-hipmi.png")}
|
||||
// logoSize={70}
|
||||
// logoBackgroundColor="transparent"
|
||||
// logoBorderRadius={50}
|
||||
// color="black"
|
||||
/>
|
||||
{loadData ? (
|
||||
<LoaderCustom />
|
||||
) : (
|
||||
<QRCode
|
||||
value={deepLinkURL}
|
||||
size={200}
|
||||
// logo={require("@/assets/images/logo-hipmi.png")}
|
||||
// logoSize={70}
|
||||
// logoBackgroundColor="transparent"
|
||||
// logoBorderRadius={50}
|
||||
// color="black"
|
||||
/>
|
||||
)}
|
||||
|
||||
<TextCustom align="center">{deepLinkURL}</TextCustom>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
)}
|
||||
|
||||
@@ -1,41 +1,81 @@
|
||||
import { BadgeCustom, BaseBox, Grid, TextCustom, ViewWrapper } from "@/components";
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
Grid,
|
||||
LoaderCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { apiAdminEventListOfParticipants } from "@/service/api-admin/api-admin-event";
|
||||
import { useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
export default function AdminEventListOfParticipants() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [listData, setListData] = useState<any[] | null>(null);
|
||||
const [loadData, setLoadData] = useState(false);
|
||||
|
||||
const isPresent = ({id}: {id: number}) => {
|
||||
const check = id % 3 * 3;
|
||||
if (check === 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadData(true);
|
||||
const response = await apiAdminEventListOfParticipants({
|
||||
id: id as string,
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
setListData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Daftar Peserta" />}
|
||||
>
|
||||
{Array.from({ length: 10 }).map((item, index) => (
|
||||
<BaseBox key={index}>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<TextCustom bold>Username {index + 1}</TextCustom>
|
||||
<TextCustom>+6282123456789</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6} style={{ justifyContent: "center" }}>
|
||||
<BadgeCustom
|
||||
style={{ alignSelf: "flex-end" }}
|
||||
color={isPresent({id: index}) ? MainColor.green : MainColor.red}
|
||||
>
|
||||
{isPresent({id: index}) ? "Hadir" : "Tidak Hadir"}
|
||||
</BadgeCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
))}
|
||||
{loadData ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(listData) ? (
|
||||
<TextCustom align="center" color="gray">
|
||||
Belum ada peserta
|
||||
</TextCustom>
|
||||
) : (
|
||||
listData?.map((item: any, index: number) => (
|
||||
<BaseBox key={index}>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<StackCustom gap={"sm"}>
|
||||
<TextCustom bold truncate>{item?.User?.username}</TextCustom>
|
||||
<TextCustom>+{item?.User?.nomor}</TextCustom>
|
||||
</StackCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6} style={{ justifyContent: "center" }}>
|
||||
<BadgeCustom
|
||||
style={{ alignSelf: "flex-end" }}
|
||||
color={item?.isPresent ? "green" : "red"}
|
||||
>
|
||||
{item?.isPresent ? "Hadir" : "Tidak Hadir"}
|
||||
</BadgeCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
))
|
||||
)}
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -5,13 +5,48 @@ import {
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { apiEventCreateTypeOfEvent } from "@/service/api-admin/api-master-admin";
|
||||
import { useRouter } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminEventTypeOfEventCreate() {
|
||||
const router = useRouter();
|
||||
const [value, setValue] = useState("");
|
||||
const [isLoading, setLoading] = useState<boolean>(false);
|
||||
|
||||
const handlerSubmit = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await apiEventCreateTypeOfEvent({
|
||||
data: value,
|
||||
});
|
||||
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Gagal menambahkan tipe acara",
|
||||
});
|
||||
return;
|
||||
}
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Berhasil menambahkan tipe acara",
|
||||
});
|
||||
router.back();
|
||||
} catch (error) {
|
||||
console.log("[ERROR CREATE TYPE EVENT]", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Simpan</ButtonCustom>
|
||||
<ButtonCustom isLoading={isLoading} onPress={() => handlerSubmit()}>
|
||||
Simpan
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
@@ -20,7 +55,11 @@ export default function AdminEventTypeOfEventCreate() {
|
||||
headerComponent={<AdminBackButtonAntTitle title="Tambah Tipe Acara" />}
|
||||
footerComponent={buttonSubmit}
|
||||
>
|
||||
<TextInputCustom placeholder="Masukkan Tipe Acara" />
|
||||
<TextInputCustom
|
||||
placeholder="Masukkan Tipe Acara"
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
/>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,23 +1,53 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
BadgeCustom,
|
||||
CenterCustom,
|
||||
LoaderCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import { IconEdit } from "@/components/_Icon";
|
||||
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { router } from "expo-router";
|
||||
import { apiAdminMasterTypeOfEvent } from "@/service/api-admin/api-master-admin";
|
||||
import { colorActivationForBadge } from "@/utils/colorActivationForBadge";
|
||||
import { router, useFocusEffect } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminEventTypeOfEvent() {
|
||||
const [listData, setListData] = useState<any[] | null>(null);
|
||||
const [loadData, setLoadData] = useState<boolean>(false);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadData(true);
|
||||
const response = await apiAdminMasterTypeOfEvent();
|
||||
|
||||
if (response.success) {
|
||||
setListData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]",error);
|
||||
setListData([]);
|
||||
} finally {
|
||||
setLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Event" />}>
|
||||
@@ -32,73 +62,68 @@ export default function AdminEventTypeOfEvent() {
|
||||
}
|
||||
/>
|
||||
|
||||
<BaseBox>
|
||||
<GridDetail_4_8
|
||||
label={
|
||||
<>
|
||||
<GridViewCustomSpan
|
||||
span1={2}
|
||||
span2={5}
|
||||
span3={5}
|
||||
component1={
|
||||
<TextCustom bold align="center">
|
||||
Aksi
|
||||
</TextCustom>
|
||||
}
|
||||
value={<TextCustom bold>Tipe Acara</TextCustom>}
|
||||
component2={<TextCustom bold align="center">Status</TextCustom>}
|
||||
component3={<TextCustom bold>Tipe Acara</TextCustom>}
|
||||
/>
|
||||
<Divider />
|
||||
<Spacing />
|
||||
|
||||
<StackCustom>
|
||||
{listData.map((item, index) => (
|
||||
<View key={index}>
|
||||
<GridDetail_4_8
|
||||
label={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={
|
||||
<IconEdit size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/event/type-update?id=${index}`);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
value={<TextCustom bold>{item.label}</TextCustom>}
|
||||
/>
|
||||
<Divider />
|
||||
</View>
|
||||
))}
|
||||
{loadData ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(listData) ? (
|
||||
<TextCustom align="center" color="gray">
|
||||
Belum ada data
|
||||
</TextCustom>
|
||||
) : (
|
||||
listData?.map((item, index) => (
|
||||
<View key={index}>
|
||||
<GridViewCustomSpan
|
||||
span1={2}
|
||||
span2={5}
|
||||
span3={5}
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={
|
||||
<IconEdit size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/event/type-update?id=${item.id}`);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
style2={{ alignItems: "center" }}
|
||||
component2={
|
||||
<CenterCustom>
|
||||
<BadgeCustom
|
||||
color={colorActivationForBadge({
|
||||
status: item?.active,
|
||||
})}
|
||||
>
|
||||
{item?.active ? "Aktif" : "Tidak Aktif"}
|
||||
</BadgeCustom>
|
||||
</CenterCustom>
|
||||
}
|
||||
component3={<TextCustom >{item.name}</TextCustom>}
|
||||
/>
|
||||
</View>
|
||||
))
|
||||
)}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Seminar",
|
||||
value: "seminar",
|
||||
},
|
||||
{
|
||||
label: "Workshop",
|
||||
value: "workshop",
|
||||
},
|
||||
{
|
||||
label: "Konferensi",
|
||||
value: "konferensi",
|
||||
},
|
||||
{
|
||||
label: "Lomba",
|
||||
value: "lomba",
|
||||
},
|
||||
{
|
||||
label: "Pameran",
|
||||
value: "pameran",
|
||||
},
|
||||
{
|
||||
label: "Pesta",
|
||||
value: "pesta",
|
||||
},
|
||||
{
|
||||
label: "Pertandingan",
|
||||
value: "pertandingan",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,20 +1,91 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { useLocalSearchParams, useRouter } from "expo-router";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import {
|
||||
apiAdminMasterTypeOfEventGetOne,
|
||||
apiAdminMasterTypeOfEventUpdate,
|
||||
} from "@/service/api-admin/api-master-admin";
|
||||
|
||||
import { useFocusEffect, useLocalSearchParams, useRouter } from "expo-router";
|
||||
import { useCallback, useState } from "react";
|
||||
import { Switch } from "react-native-paper";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminEventTypeOfEventUpdate() {
|
||||
const { id } = useLocalSearchParams();
|
||||
console.log("id >", id);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const [data, setData] = useState<{ name: string; active: boolean }>({
|
||||
name: "",
|
||||
active: false,
|
||||
});
|
||||
const [isLoading, setLoading] = useState<boolean>(false);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiAdminMasterTypeOfEventGetOne({
|
||||
id: id as string,
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
setData({
|
||||
name: response.data.name,
|
||||
active: response.data.active,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR UPDATE]", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handlerSubmit = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
const response = await apiAdminMasterTypeOfEventUpdate({
|
||||
id: id as string,
|
||||
data: data,
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Gagal mengupdate tipe acara",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Berhasil mengupdate tipe acara",
|
||||
});
|
||||
router.back();
|
||||
} catch (error) {
|
||||
console.log("[ERROR UPDATE]", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Update</ButtonCustom>
|
||||
<ButtonCustom isLoading={isLoading} onPress={() => handlerSubmit()}>
|
||||
Update
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
@@ -23,7 +94,19 @@ export default function AdminEventTypeOfEventUpdate() {
|
||||
headerComponent={<AdminBackButtonAntTitle title="Ubah Tipe Acara" />}
|
||||
footerComponent={buttonSubmit}
|
||||
>
|
||||
<TextInputCustom placeholder="Masukkan Tipe Acara" value="" />
|
||||
<TextInputCustom
|
||||
placeholder="Masukkan Tipe Acara"
|
||||
value={data.name}
|
||||
onChangeText={(text) => setData({ ...data, name: text })}
|
||||
/>
|
||||
|
||||
<TextCustom>Aktivasi</TextCustom>
|
||||
<Spacing height={10} />
|
||||
<Switch
|
||||
color={MainColor.yellow}
|
||||
value={data.active}
|
||||
onValueChange={(value) => setData({ ...data, active: value })}
|
||||
/>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
ActionIcon,
|
||||
AlertDefaultSystem,
|
||||
@@ -11,7 +12,7 @@ import {
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconProspectus } from "@/components/_Icon";
|
||||
import { IconDot, IconList } from "@/components/_Icon/IconComponent";
|
||||
@@ -19,75 +20,141 @@ import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButt
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import ReportBox from "@/components/Box/ReportBox";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import {
|
||||
apiAdminInvestasiUpdateByStatus,
|
||||
apiAdminInvestmentDetailById,
|
||||
} from "@/service/api-admin/api-admin-investment";
|
||||
import { colorBadgeStatus } from "@/utils/colorBadge";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React from "react";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminInvestmentDetail() {
|
||||
const { id, status } = useLocalSearchParams();
|
||||
const [openDrawer, setOpenDrawer] = React.useState(false);
|
||||
|
||||
const colorBadge = () => {
|
||||
if (status === "publish") {
|
||||
return MainColor.green;
|
||||
} else if (status === "review") {
|
||||
return MainColor.orange;
|
||||
} else if (status === "reject") {
|
||||
return MainColor.red;
|
||||
} else {
|
||||
return MainColor.placeholder;
|
||||
const [data, setData] = React.useState<any | null>(null);
|
||||
const [isLoading, setLoading] = React.useState(false);
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiAdminInvestmentDetailById({ id: id as string });
|
||||
// console.log("[GETONE INVEST]", JSON.stringify(response, null, 2));
|
||||
if (response.success) {
|
||||
setData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Username",
|
||||
value: `Bagas Banuna ${id}`,
|
||||
value: (data && data?.author?.username) || "-",
|
||||
},
|
||||
{
|
||||
label: "Judul",
|
||||
value: `Donasi Lorem ipsum dolor sit amet, consectetur adipisicing elit.`,
|
||||
value: (data && data?.title) || "-",
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: (
|
||||
<BadgeCustom color={colorBadge()}>
|
||||
{_.startCase(status as string)}
|
||||
</BadgeCustom>
|
||||
),
|
||||
value:
|
||||
data && data?.MasterStatusInvestasi?.name ? (
|
||||
<BadgeCustom
|
||||
color={colorBadgeStatus({
|
||||
status: data?.MasterStatusInvestasi?.name as string,
|
||||
})}
|
||||
>
|
||||
{_.startCase(data?.MasterStatusInvestasi?.name as string)}
|
||||
</BadgeCustom>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "Dana Dibutuhkan",
|
||||
value: "Rp 10.000.000",
|
||||
value: `Rp. ${
|
||||
(data && data?.targetDana && formatCurrencyDisplay(data?.targetDana)) ||
|
||||
"-"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "Harga Perlembar",
|
||||
value: "Rp 2500",
|
||||
value: `Rp. ${
|
||||
(data &&
|
||||
data?.hargaLembar &&
|
||||
formatCurrencyDisplay(data?.hargaLembar)) ||
|
||||
"-"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "Total Lembar",
|
||||
value: "2490 lembar",
|
||||
value:
|
||||
(data &&
|
||||
data?.totalLembar &&
|
||||
formatCurrencyDisplay(data?.totalLembar)) ||
|
||||
"-",
|
||||
},
|
||||
{
|
||||
label: "ROI",
|
||||
value: "4 %",
|
||||
value: `${(data && data?.roi && data?.roi) || 0} %`,
|
||||
},
|
||||
{
|
||||
label: "Pembagian Deviden",
|
||||
value: "3 bulan",
|
||||
value: (data && data?.MasterPembagianDeviden?.name) + " bulan" || "-",
|
||||
},
|
||||
{
|
||||
label: "Jadwal Pembagian",
|
||||
value: "Selamanya",
|
||||
value: (data && data?.MasterPeriodeDeviden?.name) || "-",
|
||||
},
|
||||
{
|
||||
label: "Pencarian Investor",
|
||||
value: "30 Hari",
|
||||
value: (data && data?.MasterPencarianInvestor?.name) + " hari" || "-",
|
||||
},
|
||||
];
|
||||
|
||||
const handlerSubmitPublish = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await apiAdminInvestasiUpdateByStatus({
|
||||
id: id as string,
|
||||
status: "publish",
|
||||
data: data,
|
||||
});
|
||||
|
||||
// console.log("[GET ON INVEST]", JSON.stringify(response, null, 2));
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Gagal mempublikasikan data",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Berhasil mempublikasikan data",
|
||||
});
|
||||
router.replace(`/admin/investment/publish/status`);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const rightComponent = (
|
||||
<ActionIcon
|
||||
icon={<IconDot size={ICON_SIZE_BUTTON} />}
|
||||
@@ -109,16 +176,28 @@ export default function AdminInvestmentDetail() {
|
||||
>
|
||||
{status === "publish" && (
|
||||
<BaseBox>
|
||||
<ProgressCustom size="lg" />
|
||||
<ProgressCustom
|
||||
label={data && `${data.progress}%` || "0%"}
|
||||
value={data && data.progress || 0}
|
||||
size="lg"
|
||||
/>
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
<GridDetail_4_8
|
||||
label={<TextCustom bold>Sisa Saham</TextCustom>}
|
||||
value={<TextCustom>2490 lembar</TextCustom>}
|
||||
value={
|
||||
<TextCustom>
|
||||
{data && formatCurrencyDisplay(data && data?.sisaLembar)} lembar
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
<GridDetail_4_8
|
||||
label={<TextCustom bold>Validasi Transaksi</TextCustom>}
|
||||
value={<TextCustom>4 Transaksi</TextCustom>}
|
||||
value={
|
||||
<TextCustom>
|
||||
{data && data?.Investasi_Invoice.length} Proses
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
@@ -126,7 +205,7 @@ export default function AdminInvestmentDetail() {
|
||||
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
<DummyLandscapeImage />
|
||||
<DummyLandscapeImage imageId={data?.imageId} />
|
||||
{listData.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
@@ -150,7 +229,9 @@ export default function AdminInvestmentDetail() {
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/(application)/(file)/${id}`);
|
||||
router.push(
|
||||
`/(application)/(file)/${data?.prospektusFileId}`
|
||||
);
|
||||
}}
|
||||
>
|
||||
Preview
|
||||
@@ -161,46 +242,66 @@ export default function AdminInvestmentDetail() {
|
||||
label={<TextCustom bold>File Dokumen</TextCustom>}
|
||||
value={
|
||||
<StackCustom>
|
||||
{Array.from({ length: 5 }).map((_, i) => (
|
||||
<ButtonCustom
|
||||
key={i}
|
||||
iconLeft={
|
||||
<IconProspectus
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color={MainColor.darkblue}
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/(application)/(file)/${id}`);
|
||||
}}
|
||||
>
|
||||
Dokumen {i + 1}
|
||||
</ButtonCustom>
|
||||
))}
|
||||
{_.isEmpty(data?.DokumenInvestasi) ? (
|
||||
<TextCustom align="center">-</TextCustom>
|
||||
) : (
|
||||
data?.DokumenInvestasi?.map((item: any, index: number) => {
|
||||
const titleFix = item?.title?.substring(0, 10) || "";
|
||||
|
||||
return (
|
||||
<ButtonCustom
|
||||
key={item.id || index} // ✅ pastikan key unik
|
||||
iconLeft={
|
||||
<IconProspectus
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color={MainColor.darkblue}
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(
|
||||
`/(application)/(file)/${item?.fileId}`
|
||||
);
|
||||
}}
|
||||
>
|
||||
<TextCustom color="black" truncate>
|
||||
{titleFix}...
|
||||
</TextCustom>
|
||||
</ButtonCustom>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</StackCustom>
|
||||
}
|
||||
/>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
{data &&
|
||||
data?.catatan &&
|
||||
(status === "review" || status === "reject") && (
|
||||
<ReportBox text={data?.catatan} />
|
||||
)}
|
||||
|
||||
{status === "review" && (
|
||||
<AdminButtonReview
|
||||
isLoading={isLoading}
|
||||
onPublish={() => {
|
||||
AlertDefaultSystem({
|
||||
title: "Publish",
|
||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
router.back();
|
||||
handlerSubmitPublish();
|
||||
},
|
||||
});
|
||||
}}
|
||||
onReject={() => {
|
||||
router.push(`/admin/investment/${id}/reject-input`);
|
||||
router.push(
|
||||
`/admin/investment/${id}/reject-input?status=${_.lowerCase(
|
||||
data?.MasterStatusInvestasi?.name
|
||||
)}`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,67 +1,226 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import GridTwoView from "@/components/_ShareComponent/GridTwoView";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import {
|
||||
apiAdminInvestmentGetOneInvoiceById,
|
||||
apiAdminInvestmentUpdateInvoice,
|
||||
} from "@/service/api-admin/api-admin-investment";
|
||||
import { colorBadgeTransaction } from "@/utils/colorBadge";
|
||||
import { dateTimeView } from "@/utils/dateTimeView";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import { useCallback, useState } from "react";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminInvestmentTransactionDetail() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [data, setData] = useState<any | null>(null);
|
||||
const [isLoading, setLoading] = useState<boolean>(false);
|
||||
|
||||
const buttonAction = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Terima</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiAdminInvestmentGetOneInvoiceById({
|
||||
id: id as string,
|
||||
});
|
||||
// console.log("[RESPONSE]", JSON.stringify(response, null, 2));
|
||||
if (response.success) {
|
||||
setData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Investor",
|
||||
value: "Bagas Banuna",
|
||||
value: (data && data?.Author?.username) || "-",
|
||||
},
|
||||
{
|
||||
label: "Bank",
|
||||
value: "BCA",
|
||||
value: (data && data?.MasterBank?.namaBank) || "-",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Investasi",
|
||||
value: "Rp. 1.000.000",
|
||||
value: (data && `Rp. ${formatCurrencyDisplay(data?.nominal)}`) || "-",
|
||||
},
|
||||
{
|
||||
label: "Lembar terbeli",
|
||||
value: (data && formatCurrencyDisplay(data?.lembarTerbeli)) || "-",
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: <BadgeCustom color={MainColor.green}>Berhasil</BadgeCustom>,
|
||||
value:
|
||||
data && data?.StatusInvoice?.name ? (
|
||||
<BadgeCustom
|
||||
color={colorBadgeTransaction({
|
||||
status: data?.StatusInvoice?.name,
|
||||
})}
|
||||
>
|
||||
{data?.StatusInvoice?.name}
|
||||
</BadgeCustom>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: dayjs().format("DD-MM-YYYY HH:mm:ss"),
|
||||
value: (data && dateTimeView({ date: data?.createdAt })) || "-",
|
||||
},
|
||||
{
|
||||
label: "Bukti Transfer",
|
||||
value: (
|
||||
<ButtonCustom
|
||||
onPress={() =>
|
||||
router.push(`/(application)/(image)/preview-image/${id}`)
|
||||
}
|
||||
>
|
||||
Cek
|
||||
</ButtonCustom>
|
||||
),
|
||||
value:
|
||||
data && data?.imageId ? (
|
||||
<ButtonCustom
|
||||
onPress={() =>
|
||||
router.push(
|
||||
`/(application)/(image)/preview-image/${data?.imageId}`
|
||||
)
|
||||
}
|
||||
>
|
||||
Cek
|
||||
</ButtonCustom>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const handlerSubmit = async ({
|
||||
category,
|
||||
}: {
|
||||
category: "accept" | "deny";
|
||||
}) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await apiAdminInvestmentUpdateInvoice({
|
||||
id: id as string,
|
||||
category: category,
|
||||
data: {
|
||||
investasiId: data?.investasiId,
|
||||
lembarTerbeli: data?.lembarTerbeli,
|
||||
},
|
||||
});
|
||||
|
||||
// console.log("[RESPONSE SUBMIT]", JSON.stringify(response, null, 2));
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Gagal update status transaksi",
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Berhasil update status transaksi",
|
||||
});
|
||||
router.back();
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const buttonAction = () => {
|
||||
if (data?.StatusInvoice?.name === "Proses") {
|
||||
return (
|
||||
<GridTwoView
|
||||
spanLeft={6}
|
||||
spanRight={6}
|
||||
styleLeft={{ paddingRight: 10 }}
|
||||
styleRight={{ paddingLeft: 10 }}
|
||||
leftIcon={
|
||||
<ButtonCustom
|
||||
isLoading={isLoading}
|
||||
backgroundColor={MainColor.red}
|
||||
textColor="white"
|
||||
onPress={() => {
|
||||
AlertDefaultSystem({
|
||||
title: "Konfirmasi transaksi",
|
||||
message: "Apakah anda yakin ingin menolak transaksi ini?",
|
||||
textLeft: "Tidak",
|
||||
textRight: "Ya",
|
||||
onPressRight: () => {
|
||||
handlerSubmit({
|
||||
category: "deny",
|
||||
});
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
Tolak
|
||||
</ButtonCustom>
|
||||
}
|
||||
rightIcon={
|
||||
<ButtonCustom
|
||||
isLoading={isLoading}
|
||||
onPress={() => {
|
||||
AlertDefaultSystem({
|
||||
title: "Konfirmasi transaksi",
|
||||
message: "Apakah anda yakin ingin menyetujui transaksi ini?",
|
||||
textLeft: "Tidak",
|
||||
textRight: "Ya",
|
||||
onPressRight: () => {
|
||||
handlerSubmit({
|
||||
category: "accept",
|
||||
});
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
Terima
|
||||
</ButtonCustom>
|
||||
}
|
||||
/>
|
||||
);
|
||||
} else if (data?.StatusInvoice?.name === "Gagal") {
|
||||
return (
|
||||
<>
|
||||
<ButtonCustom textColor="red" onPress={() => router.back()}>
|
||||
Gagal
|
||||
</ButtonCustom>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
<ButtonCustom disabled={true}>
|
||||
Status: {data?.StatusInvoice?.name}
|
||||
</ButtonCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Detail Transaksi Investor" />}
|
||||
footerComponent={buttonAction}
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle title="Detail Transaksi Investor" />
|
||||
}
|
||||
// footerComponent={buttonAction()}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
@@ -74,6 +233,8 @@ export default function AdminInvestmentTransactionDetail() {
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
<Spacing />
|
||||
{buttonAction()}
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
ActionIcon,
|
||||
BadgeCustom,
|
||||
CenterCustom,
|
||||
LoaderCustom,
|
||||
SelectCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
@@ -10,23 +12,98 @@ import {
|
||||
import { IconView } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import NoDataText from "@/components/_ShareComponent/NoDataText";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { dummyMasterStatusTransaction } from "@/lib/dummy-data/_master/status-transaction";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import React from "react";
|
||||
import { apiAdminInvestmentListOfInvestor } from "@/service/api-admin/api-admin-investment";
|
||||
import { apiMasterTransaction } from "@/service/api-client/api-master";
|
||||
import { colorBadgeTransaction } from "@/utils/colorBadge";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React, { useEffect } from "react";
|
||||
import { View } from "react-native";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminInvestmentListOfInvestor() {
|
||||
const { id } = useLocalSearchParams();
|
||||
console.log("[ID]", id);
|
||||
|
||||
const [listData, setListData] = React.useState<any[] | null>(null);
|
||||
const [loadData, setLoadData] = React.useState(false);
|
||||
const [master, setMaster] = React.useState<any[]>([]);
|
||||
|
||||
const [selectValue, setSelectValue] = React.useState<string | null>(null);
|
||||
const [selectedStatus, setSelectedStatus] = React.useState<string | null>(
|
||||
null
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
onLoadMaster();
|
||||
}, []);
|
||||
|
||||
const onLoadMaster = async () => {
|
||||
try {
|
||||
const response = await apiMasterTransaction();
|
||||
|
||||
if (response.success) {
|
||||
setMaster(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
setMaster([]);
|
||||
}
|
||||
};
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id, selectValue])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadData(true);
|
||||
const response = await apiAdminInvestmentListOfInvestor({
|
||||
id: id as string,
|
||||
status: selectedStatus as any,
|
||||
});
|
||||
console.log("[LIST OF INVESTOR]", JSON.stringify(response, null, 2));
|
||||
|
||||
if (response.success) {
|
||||
setListData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
setListData([]);
|
||||
} finally {
|
||||
setLoadData(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
onLoadMaster();
|
||||
}, []);
|
||||
|
||||
const searchComponent = (
|
||||
<View style={{ flexDirection: "row", gap: 5 }}>
|
||||
<SelectCustom
|
||||
placeholder="Pilih status transaksi"
|
||||
data={dummyMasterStatusTransaction}
|
||||
onChange={(value) => console.log(value)}
|
||||
data={
|
||||
_.isEmpty(master)
|
||||
? []
|
||||
: master?.map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}))
|
||||
}
|
||||
value={selectValue}
|
||||
onChange={(value: any) => {
|
||||
setSelectValue(value);
|
||||
const nameSelected = master.find((item: any) => item.id === value);
|
||||
const statusChooses = _.lowerCase(nameSelected?.name);
|
||||
setSelectedStatus(statusChooses);
|
||||
}}
|
||||
styleContainer={{ width: "100%", marginBottom: 0 }}
|
||||
allowClear
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
@@ -40,66 +117,77 @@ export default function AdminInvestmentListOfInvestor() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={headerComponent}
|
||||
>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<TextCustom bold align="center">
|
||||
Aksi
|
||||
</TextCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center">
|
||||
Investor
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<TextCustom bold align="center">
|
||||
Status
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
<ViewWrapper headerComponent={headerComponent}>
|
||||
<StackCustom>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<View key={index}>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||
onPress={() => {
|
||||
router.push(
|
||||
`/admin/investment/${id}/berhasil/transaction-detail`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center" truncate>
|
||||
Bagas Banuna
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<BadgeCustom
|
||||
style={{ alignSelf: "center" }}
|
||||
color={MainColor.green}
|
||||
>
|
||||
Berhasil
|
||||
</BadgeCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
</View>
|
||||
))}
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<TextCustom bold align="center">
|
||||
Aksi
|
||||
</TextCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center">
|
||||
Investor
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<TextCustom bold align="center">
|
||||
Status
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
<StackCustom>
|
||||
{loadData ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(listData) ? (
|
||||
<NoDataText />
|
||||
) : (
|
||||
listData?.map((item: any, index: number) => (
|
||||
<View key={index}>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={
|
||||
<IconView size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(
|
||||
`/admin/investment/${item?.id}/${_.lowerCase(
|
||||
item?.StatusInvoice?.name
|
||||
)}/transaction-detail`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center" truncate>
|
||||
{item?.Author?.username || "-"}
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<BadgeCustom
|
||||
style={{ alignSelf: "center" }}
|
||||
color={colorBadgeTransaction({
|
||||
status: item?.StatusInvoice?.name,
|
||||
})}
|
||||
>
|
||||
{item?.StatusInvoice?.name}
|
||||
</BadgeCustom>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
))
|
||||
)}
|
||||
</StackCustom>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BoxButtonOnFooter,
|
||||
@@ -6,15 +7,83 @@ import {
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { apiAdminInvestasiUpdateByStatus, apiAdminInvestmentDetailById } from "@/service/api-admin/api-admin-investment";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import { useCallback, useState } from "react";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminInvestmentRejectInput() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [value, setValue] = useState(id as string);
|
||||
const { id, status } = useLocalSearchParams();
|
||||
console.log("[STATUS]", status);
|
||||
const [value, setValue] = useState<any | null>(null);
|
||||
const [isLoading , setLoading] = useState(false)
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiAdminInvestmentDetailById({ id: id as string });
|
||||
console.log("[DATA]", JSON.stringify(response, null, 2));
|
||||
if (response.success) {
|
||||
setValue(response.data?.catatan);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const handlerSubmit = async () => {
|
||||
if (!value) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Harap masukan alasan penolakan",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await apiAdminInvestasiUpdateByStatus({
|
||||
id: id as string,
|
||||
status: "reject",
|
||||
data: value,
|
||||
});
|
||||
|
||||
console.log("[RESPONSE]", JSON.stringify(response, null, 2));
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Gagal melakukan report",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Berhasil melakukan report",
|
||||
});
|
||||
|
||||
if (status === "review") {
|
||||
router.replace(`/admin/investment/reject/status`);
|
||||
} else {
|
||||
router.back();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(["ERROR"], error);
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
};
|
||||
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<AdminButtonReject
|
||||
isLoading={isLoading}
|
||||
title="Reject"
|
||||
onReject={() =>
|
||||
AlertDefaultSystem({
|
||||
@@ -22,12 +91,8 @@ export default function AdminInvestmentRejectInput() {
|
||||
message: "Apakah anda yakin ingin menolak data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
console.log("value:", value);
|
||||
router.replace(`/admin/investment/reject/status`);
|
||||
handlerSubmit();
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -39,7 +104,9 @@ export default function AdminInvestmentRejectInput() {
|
||||
<>
|
||||
<ViewWrapper
|
||||
footerComponent={buttonSubmit}
|
||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Investasi" />}
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle title="Penolakan Investasi" />
|
||||
}
|
||||
>
|
||||
<TextAreaCustom
|
||||
value={value}
|
||||
|
||||
@@ -1,69 +1,114 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
ActionIcon,
|
||||
SearchInput,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
ActionIcon,
|
||||
LoaderCustom,
|
||||
SearchInput,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
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 NoDataText from "@/components/_ShareComponent/NoDataText";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { apiAdminInvestment } from "@/service/api-admin/api-admin-investment";
|
||||
import { Octicons } from "@expo/vector-icons";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React, { useCallback } from "react";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminInvestmentStatus() {
|
||||
const { status } = useLocalSearchParams();
|
||||
console.log("[STATUS]", status);
|
||||
|
||||
const [listData, setListData] = React.useState<any[] | null>(null);
|
||||
const [loadData, setLoadingData] = React.useState(false);
|
||||
const [search, setSearch] = React.useState("");
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [status, search])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
setLoadingData(true);
|
||||
const response = await apiAdminInvestment({
|
||||
category: status as "publish" | "review" | "reject",
|
||||
search,
|
||||
});
|
||||
console.log("[LIST DATA]", JSON.stringify(response, null, 2));
|
||||
if (response.success) {
|
||||
setListData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
setListData([]);
|
||||
} finally {
|
||||
setLoadingData(false);
|
||||
}
|
||||
};
|
||||
|
||||
const rightComponent = (
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari"
|
||||
value={search}
|
||||
onChangeText={setSearch}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Investasi" />}>
|
||||
<StackCustom gap={"sm"}>
|
||||
<AdminComp_BoxTitle
|
||||
title={`Investasi ${_.startCase(status as string)}`}
|
||||
title={`${_.startCase(status as string)}`}
|
||||
rightComponent={rightComponent}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Investasi"
|
||||
/>
|
||||
<Spacing />
|
||||
<Divider />
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons name="eye" size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/investment/${index}/${status}`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Investasi"
|
||||
/>
|
||||
))}
|
||||
|
||||
<Divider />
|
||||
|
||||
{loadData ? (
|
||||
<LoaderCustom />
|
||||
) : _.isEmpty(listData) ? (
|
||||
<NoDataText />
|
||||
) : (
|
||||
listData?.map((item: any, index: number) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons
|
||||
name="eye"
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color="black"
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/investment/${item.id}/${status}`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>{item?.author?.username}</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
{item?.title}
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -7,8 +7,51 @@ import {
|
||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { apiAdminInvestment } from "@/service/api-admin/api-admin-investment";
|
||||
import { useFocusEffect } from "expo-router";
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
export default function AdminInvestment() {
|
||||
const [data, setData] = React.useState<any | null>(null);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [])
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const response = await apiAdminInvestment({
|
||||
category: "dashboard",
|
||||
});
|
||||
console.log(JSON.stringify(response, null, 2));
|
||||
if (response.success) {
|
||||
setData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Publish",
|
||||
value: (data && data.publish) || 0,
|
||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Review",
|
||||
value: (data && data.review) || 0,
|
||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
||||
},
|
||||
{
|
||||
label: "Reject",
|
||||
value: (data && data.reject) || 0,
|
||||
icon: <IconReject size={25} color={MainColor.red} />,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
@@ -23,21 +66,3 @@ export default function AdminInvestment() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Publish",
|
||||
value: 3,
|
||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Review",
|
||||
value: 5,
|
||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
||||
},
|
||||
{
|
||||
label: "Reject",
|
||||
value: 8,
|
||||
icon: <IconReject size={25} color={MainColor.red} />,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
CircleContainer,
|
||||
Grid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
CircleContainer,
|
||||
Grid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
@@ -18,7 +18,7 @@ import ReportBox from "@/components/Box/ReportBox";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import funUpdateStatusVoting from "@/screens/Admin/Voting/funUpdateStatus";
|
||||
import { apiAdminVotingById } from "@/service/api-admin/api-admin-voting";
|
||||
import { colorBadge } from "@/utils/colorBadge";
|
||||
import { colorBadgeStatus } from "@/utils/colorBadge";
|
||||
import { dateTimeView } from "@/utils/dateTimeView";
|
||||
import { Entypo } from "@expo/vector-icons";
|
||||
import dayjs from "dayjs";
|
||||
@@ -68,7 +68,7 @@ export default function AdminVotingDetail() {
|
||||
label: "Status",
|
||||
value:
|
||||
data && data?.Voting_Status?.name ? (
|
||||
<BadgeCustom color={colorBadge({ status: status as string })}>
|
||||
<BadgeCustom color={colorBadgeStatus({ status: status as string })}>
|
||||
{status === "history" ? "Riwayat" : _.startCase(status as string)}
|
||||
</BadgeCustom>
|
||||
) : (
|
||||
|
||||
115
app/(application)/terms-agreement.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
CheckboxCustom,
|
||||
InformationBox,
|
||||
StackCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { apiAcceptTermService, BASE_URL } from "@/service/api-config";
|
||||
import { GStyles } from "@/styles/global-styles";
|
||||
import { openBrowser } from "@/utils/openBrower";
|
||||
import { Stack } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { Text, View } from "react-native";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function TermsAgreement() {
|
||||
const { user, logout } = useAuth();
|
||||
const [term, setTerm] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const url = BASE_URL;
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await apiAcceptTermService({
|
||||
data: {
|
||||
id: user?.id as string,
|
||||
termsOfServiceAccepted: term,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
Toast.show({
|
||||
type: "error",
|
||||
text1: "Gagal",
|
||||
text2: response.message,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Anda berhasil menerima syarat & ketentuan",
|
||||
text2: "Silahkan login kembali",
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
logout();
|
||||
}, 2000);
|
||||
} catch (error) {
|
||||
console.log("error", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const footerComponent = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
onPress={handleSubmit}
|
||||
disabled={!term}
|
||||
isLoading={isLoading}
|
||||
>
|
||||
Setuju
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack.Screen
|
||||
options={{
|
||||
title: "Terms Agreement",
|
||||
}}
|
||||
/>
|
||||
<ViewWrapper footerComponent={footerComponent}>
|
||||
<StackCustom>
|
||||
<InformationBox text="Anda dialihkan ke halaman syarat & ketentuan, karena Anda belum menerima persetujuan syarat & ketentuan." />
|
||||
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginTop: 16,
|
||||
marginBottom: 16,
|
||||
}}
|
||||
>
|
||||
<CheckboxCustom value={term} onChange={() => setTerm(!term)} />
|
||||
|
||||
<Text style={GStyles.textLabel}>
|
||||
Saya setuju dengan{" "}
|
||||
<Text
|
||||
style={{
|
||||
color: MainColor.yellow,
|
||||
textDecorationLine: "underline",
|
||||
}}
|
||||
onPress={() => {
|
||||
const toUrl = `${url}/terms-of-service.html`;
|
||||
openBrowser(toUrl);
|
||||
}}
|
||||
>
|
||||
Syarat & Ketentuan
|
||||
</Text>{" "}
|
||||
yang melarang konten tidak pantas dan perilaku merugikan.
|
||||
</Text>
|
||||
</View>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 509 KiB |
BIN
assets/images/constants/logo-hipmi_back.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/images/icon-arcive.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 509 KiB |
BIN
assets/images/splash-icon-arcive.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 509 KiB |
128
bun.lock
@@ -12,6 +12,7 @@
|
||||
"@react-navigation/elements": "^2.3.8",
|
||||
"@react-navigation/native": "^7.1.6",
|
||||
"@react-navigation/native-stack": "^7.3.10",
|
||||
"@rnmapbox/maps": "^10.2.7",
|
||||
"@types/lodash": "^4.17.20",
|
||||
"@types/react-native-vector-icons": "^6.4.18",
|
||||
"axios": "^1.11.0",
|
||||
@@ -19,22 +20,27 @@
|
||||
"expo": "^54.0.0",
|
||||
"expo-camera": "~17.0.7",
|
||||
"expo-clipboard": "~8.0.7",
|
||||
"expo-constants": "~18.0.8",
|
||||
"expo-constants": "^18.0.10",
|
||||
"expo-dev-client": "~6.0.12",
|
||||
"expo-device": "^8.0.9",
|
||||
"expo-document-picker": "~14.0.7",
|
||||
"expo-file-system": "^19.0.15",
|
||||
"expo-font": "~14.0.8",
|
||||
"expo-haptics": "~15.0.7",
|
||||
"expo-image": "~3.0.8",
|
||||
"expo-image-picker": "~17.0.8",
|
||||
"expo-linear-gradient": "~15.0.7",
|
||||
"expo-linking": "~8.0.8",
|
||||
"expo-location": "~19.0.7",
|
||||
"expo-notifications": "^0.32.13",
|
||||
"expo-router": "~6.0.1",
|
||||
"expo-splash-screen": "~31.0.9",
|
||||
"expo-status-bar": "~3.0.8",
|
||||
"expo-symbols": "~1.0.7",
|
||||
"expo-system-ui": "~6.0.7",
|
||||
"expo-web-browser": "~15.0.7",
|
||||
"expo-web-browser": "~15.0.9",
|
||||
"lodash": "^4.17.21",
|
||||
"moti": "^0.30.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-native": "0.81.4",
|
||||
@@ -336,6 +342,10 @@
|
||||
|
||||
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA=="],
|
||||
|
||||
"@emotion/is-prop-valid": ["@emotion/is-prop-valid@0.8.8", "", { "dependencies": { "@emotion/memoize": "0.7.4" } }, "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA=="],
|
||||
|
||||
"@emotion/memoize": ["@emotion/memoize@0.7.4", "", {}, "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="],
|
||||
|
||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="],
|
||||
|
||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
|
||||
@@ -416,6 +426,8 @@
|
||||
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
|
||||
|
||||
"@ide/backoff": ["@ide/backoff@1.0.0", "", {}, "sha512-F0YfUDjvT+Mtt/R4xdl2X0EYCHMMiJqNLdxHD++jDT5ydEFIyqbCHh51Qx2E211dgZprPKhV7sHmnXKpLuvc5g=="],
|
||||
|
||||
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
|
||||
|
||||
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
|
||||
@@ -472,6 +484,18 @@
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
|
||||
|
||||
"@motionone/animation": ["@motionone/animation@10.18.0", "", { "dependencies": { "@motionone/easing": "^10.18.0", "@motionone/types": "^10.17.1", "@motionone/utils": "^10.18.0", "tslib": "^2.3.1" } }, "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw=="],
|
||||
|
||||
"@motionone/dom": ["@motionone/dom@10.12.0", "", { "dependencies": { "@motionone/animation": "^10.12.0", "@motionone/generators": "^10.12.0", "@motionone/types": "^10.12.0", "@motionone/utils": "^10.12.0", "hey-listen": "^1.0.8", "tslib": "^2.3.1" } }, "sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw=="],
|
||||
|
||||
"@motionone/easing": ["@motionone/easing@10.18.0", "", { "dependencies": { "@motionone/utils": "^10.18.0", "tslib": "^2.3.1" } }, "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg=="],
|
||||
|
||||
"@motionone/generators": ["@motionone/generators@10.18.0", "", { "dependencies": { "@motionone/types": "^10.17.1", "@motionone/utils": "^10.18.0", "tslib": "^2.3.1" } }, "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg=="],
|
||||
|
||||
"@motionone/types": ["@motionone/types@10.17.1", "", {}, "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A=="],
|
||||
|
||||
"@motionone/utils": ["@motionone/utils@10.18.0", "", { "dependencies": { "@motionone/types": "^10.17.1", "hey-listen": "^1.0.8", "tslib": "^2.3.1" } }, "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw=="],
|
||||
|
||||
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.11", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.9.0" } }, "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA=="],
|
||||
|
||||
"@nicolo-ribaudo/chokidar-2": ["@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3", "", {}, "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ=="],
|
||||
@@ -570,6 +594,8 @@
|
||||
|
||||
"@react-navigation/routers": ["@react-navigation/routers@7.4.1", "", { "dependencies": { "nanoid": "^3.3.11" } }, "sha512-42mZrMzQ0LfKxUb5OHIurYrPYyRsXFLolucILrvm21f0O40Sw0Ufh1bnn/jRqnxZZu7wvpUGIGYM8nS9zVE1Aw=="],
|
||||
|
||||
"@rnmapbox/maps": ["@rnmapbox/maps@10.2.7", "", { "dependencies": { "@turf/along": "6.5.0", "@turf/distance": "6.5.0", "@turf/helpers": "6.5.0", "@turf/length": "6.5.0", "@turf/nearest-point-on-line": "6.5.0", "@types/geojson": "^7946.0.7", "debounce": "^2.2.0" }, "peerDependencies": { "expo": ">=47.0.0", "mapbox-gl": "^2.9.0", "react": ">=17.0.0", "react-dom": ">= 17.0.0", "react-native": ">=0.69" }, "optionalPeers": ["expo", "mapbox-gl", "react-dom"] }, "sha512-CJZuBKz2EiHjpJsyPz0jZOcm0jniDJdkeboeuyrcCIGe53Cw8gCFM6hxWOTJTL04o7idbNxD54jD4BQKxs6b1A=="],
|
||||
|
||||
"@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
|
||||
|
||||
"@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
|
||||
@@ -584,6 +610,30 @@
|
||||
|
||||
"@tsconfig/node18": ["@tsconfig/node18@18.2.4", "", {}, "sha512-5xxU8vVs9/FNcvm3gE07fPbn9tl6tqGGWA9tSlwsUEkBxtRnTsNmwrV8gasZ9F/EobaSv9+nu8AxUKccw77JpQ=="],
|
||||
|
||||
"@turf/along": ["@turf/along@6.5.0", "", { "dependencies": { "@turf/bearing": "^6.5.0", "@turf/destination": "^6.5.0", "@turf/distance": "^6.5.0", "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" } }, "sha512-LLyWQ0AARqJCmMcIEAXF4GEu8usmd4Kbz3qk1Oy5HoRNpZX47+i5exQtmIWKdqJ1MMhW26fCTXgpsEs5zgJ5gw=="],
|
||||
|
||||
"@turf/bbox": ["@turf/bbox@7.3.0", "", { "dependencies": { "@turf/helpers": "7.3.0", "@turf/meta": "7.3.0", "@types/geojson": "^7946.0.10", "tslib": "^2.8.1" } }, "sha512-EC5GSUJlhXSiCVCEmgCSheZYm0s1ouKzUNqeEOsEYlqTbMAZ19RWgsg/xH2tjnuUw2JP9eGAUzQnCFX6JEV53w=="],
|
||||
|
||||
"@turf/bearing": ["@turf/bearing@6.5.0", "", { "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" } }, "sha512-dxINYhIEMzgDOztyMZc20I7ssYVNEpSv04VbMo5YPQsqa80KO3TFvbuCahMsCAW5z8Tncc8dwBlEFrmRjJG33A=="],
|
||||
|
||||
"@turf/destination": ["@turf/destination@6.5.0", "", { "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" } }, "sha512-4cnWQlNC8d1tItOz9B4pmJdWpXqS0vEvv65bI/Pj/genJnsL7evI0/Xw42RvEGROS481MPiU80xzvwxEvhQiMQ=="],
|
||||
|
||||
"@turf/distance": ["@turf/distance@6.5.0", "", { "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" } }, "sha512-xzykSLfoURec5qvQJcfifw/1mJa+5UwByZZ5TZ8iaqjGYN0vomhV9aiSLeYdUGtYRESZ+DYC/OzY+4RclZYgMg=="],
|
||||
|
||||
"@turf/helpers": ["@turf/helpers@6.5.0", "", {}, "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw=="],
|
||||
|
||||
"@turf/invariant": ["@turf/invariant@6.5.0", "", { "dependencies": { "@turf/helpers": "^6.5.0" } }, "sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg=="],
|
||||
|
||||
"@turf/length": ["@turf/length@6.5.0", "", { "dependencies": { "@turf/distance": "^6.5.0", "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0" } }, "sha512-5pL5/pnw52fck3oRsHDcSGrj9HibvtlrZ0QNy2OcW8qBFDNgZ4jtl6U7eATVoyWPKBHszW3dWETW+iLV7UARig=="],
|
||||
|
||||
"@turf/line-intersect": ["@turf/line-intersect@6.5.0", "", { "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", "@turf/line-segment": "^6.5.0", "@turf/meta": "^6.5.0", "geojson-rbush": "3.x" } }, "sha512-CS6R1tZvVQD390G9Ea4pmpM6mJGPWoL82jD46y0q1KSor9s6HupMIo1kY4Ny+AEYQl9jd21V3Scz20eldpbTVA=="],
|
||||
|
||||
"@turf/line-segment": ["@turf/line-segment@6.5.0", "", { "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", "@turf/meta": "^6.5.0" } }, "sha512-jI625Ho4jSuJESNq66Mmi290ZJ5pPZiQZruPVpmHkUw257Pew0alMmb6YrqYNnLUuiVVONxAAKXUVeeUGtycfw=="],
|
||||
|
||||
"@turf/meta": ["@turf/meta@6.5.0", "", { "dependencies": { "@turf/helpers": "^6.5.0" } }, "sha512-RrArvtsV0vdsCBegoBtOalgdSOfkBrTJ07VkpiCnq/491W67hnMWmDu7e6Ztw0C3WldRYTXkg3SumfdzZxLBHA=="],
|
||||
|
||||
"@turf/nearest-point-on-line": ["@turf/nearest-point-on-line@6.5.0", "", { "dependencies": { "@turf/bearing": "^6.5.0", "@turf/destination": "^6.5.0", "@turf/distance": "^6.5.0", "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", "@turf/line-intersect": "^6.5.0", "@turf/meta": "^6.5.0" } }, "sha512-WthrvddddvmymnC+Vf7BrkHGbDOUu6Z3/6bFYUGv1kxw8tiZ6n83/VG6kHz4poHOfS0RaNflzXSkmCi64fLBlg=="],
|
||||
|
||||
"@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
|
||||
|
||||
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
|
||||
@@ -800,6 +850,8 @@
|
||||
|
||||
"asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="],
|
||||
|
||||
"assert": ["assert@2.1.0", "", { "dependencies": { "call-bind": "^1.0.2", "is-nan": "^1.3.2", "object-is": "^1.1.5", "object.assign": "^4.1.4", "util": "^0.12.5" } }, "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw=="],
|
||||
|
||||
"async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="],
|
||||
|
||||
"async-limiter": ["async-limiter@1.0.1", "", {}, "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="],
|
||||
@@ -838,6 +890,8 @@
|
||||
|
||||
"babel-preset-jest": ["babel-preset-jest@29.6.3", "", { "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA=="],
|
||||
|
||||
"badgin": ["badgin@1.2.3", "", {}, "sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw=="],
|
||||
|
||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||
@@ -976,6 +1030,8 @@
|
||||
|
||||
"dayjs": ["dayjs@1.11.13", "", {}, "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="],
|
||||
|
||||
"debounce": ["debounce@2.2.0", "", {}, "sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw=="],
|
||||
|
||||
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||
|
||||
"decamelize": ["decamelize@1.2.0", "", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="],
|
||||
@@ -1150,13 +1206,15 @@
|
||||
|
||||
"expo": ["expo@54.0.2", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "54.0.2", "@expo/config": "~12.0.8", "@expo/config-plugins": "~54.0.1", "@expo/devtools": "0.1.7", "@expo/fingerprint": "0.15.0", "@expo/metro": "~0.1.1", "@expo/metro-config": "54.0.2", "@expo/vector-icons": "^15.0.2", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "~54.0.0", "expo-asset": "~12.0.8", "expo-constants": "~18.0.8", "expo-file-system": "~19.0.12", "expo-font": "~14.0.8", "expo-keep-awake": "~15.0.7", "expo-modules-autolinking": "3.0.10", "expo-modules-core": "3.0.15", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", "whatwg-url-without-unicode": "8.0.0-3" }, "peerDependencies": { "@expo/dom-webview": "*", "@expo/metro-runtime": "*", "react": "*", "react-native": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/dom-webview", "@expo/metro-runtime", "react-native-webview"], "bin": { "expo": "bin/cli", "fingerprint": "bin/fingerprint", "expo-modules-autolinking": "bin/autolinking" } }, "sha512-0YcsvMuiZlVFVZRdD4PlhwsYrTmcN1qm5b1IRSLIeLZjH6ZnQwBb3KBSnK8WRC9V6EUPSbuLGpNT5AEewrtakQ=="],
|
||||
|
||||
"expo-application": ["expo-application@7.0.7", "", { "peerDependencies": { "expo": "*" } }, "sha512-Jt1/qqnoDUbZ+bK91+dHaZ1vrPDtRBOltRa681EeedkisqguuEeUx4UHqwVyDK2oHWsK6lO3ojetoA4h8OmNcg=="],
|
||||
|
||||
"expo-asset": ["expo-asset@12.0.8", "", { "dependencies": { "@expo/image-utils": "^0.8.7", "expo-constants": "~18.0.8" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-jj2U8zw9+7orST2rlQGULYiqPoECOuUyffs2NguGrq84bYbkM041T7TOMXH2raPVJnM9lEAP54ezI6XL+GVYqw=="],
|
||||
|
||||
"expo-camera": ["expo-camera@17.0.7", "", { "dependencies": { "invariant": "^2.2.4" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*", "react-native-web": "*" }, "optionalPeers": ["react-native-web"] }, "sha512-jdZfijfFjlVAuuIkDheA41YKpigPjqsN0juRvgyr7Lcyz+fvwZ3/RP50/n/hvuozH657wHxPfiyVVFa00z8TcQ=="],
|
||||
|
||||
"expo-clipboard": ["expo-clipboard@8.0.7", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-zvlfFV+wB2QQrQnHWlo0EKHAkdi2tycLtE+EXFUWTPZYkgu1XcH+aiKfd4ul7Z0SDF+1IuwoiW9AA9eO35aj3Q=="],
|
||||
|
||||
"expo-constants": ["expo-constants@18.0.8", "", { "dependencies": { "@expo/config": "~12.0.8", "@expo/env": "~2.0.7" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-Tetphsx6RVImCTZeBAclRQMy0WOODY3y6qrUoc88YGUBVm8fAKkErCSWxLTCc6nFcJxdoOMYi62LgNIUFjZCLA=="],
|
||||
"expo-constants": ["expo-constants@18.0.10", "", { "dependencies": { "@expo/config": "~12.0.10", "@expo/env": "~2.0.7" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-Rhtv+X974k0Cahmvx6p7ER5+pNhBC0XbP1lRviL2J1Xl4sT2FBaIuIxF/0I0CbhOsySf0ksqc5caFweAy9Ewiw=="],
|
||||
|
||||
"expo-dev-client": ["expo-dev-client@6.0.12", "", { "dependencies": { "expo-dev-launcher": "6.0.11", "expo-dev-menu": "7.0.11", "expo-dev-menu-interface": "2.0.0", "expo-manifests": "~1.0.8", "expo-updates-interface": "~2.0.0" }, "peerDependencies": { "expo": "*" } }, "sha512-Knr2abq0r6ALASsZtrX9QD4V0vP4ZL18iDVF5lgr6iFYawbuqQHuJRktIUETimu6qLusJK8Z3kZRabAdNqT+qw=="],
|
||||
|
||||
@@ -1166,6 +1224,8 @@
|
||||
|
||||
"expo-dev-menu-interface": ["expo-dev-menu-interface@2.0.0", "", { "peerDependencies": { "expo": "*" } }, "sha512-BvAMPt6x+vyXpThsyjjOYyjwfjREV4OOpQkZ0tNl+nGpsPfcY9mc6DRACoWnH9KpLzyIt3BOgh3cuy/h/OxQjw=="],
|
||||
|
||||
"expo-device": ["expo-device@8.0.9", "", { "dependencies": { "ua-parser-js": "^0.7.33" }, "peerDependencies": { "expo": "*" } }, "sha512-XqRpaljDNAYZGZzMpC+b9KZfzfydtkwx3pJAp6ODDH+O/5wjAw+mLc5wQMGJCx8/aqVmMsAokec7iebxDPFZDA=="],
|
||||
|
||||
"expo-document-picker": ["expo-document-picker@14.0.7", "", { "peerDependencies": { "expo": "*" } }, "sha512-81Jh8RDD0GYBUoSTmIBq30hXXjmkDV1ZY2BNIp1+3HR5PDSh2WmdhD/Ezz5YFsv46hIXHsQc+Kh1q8vn6OLT9Q=="],
|
||||
|
||||
"expo-file-system": ["expo-file-system@19.0.15", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-sRLW+3PVJDiuoCE2LuteHhC7OxPjh1cfqLylf1YG1TDEbbQXnzwjfsKeRm6dslEPZLkMWfSLYIrVbnuq5mF7kQ=="],
|
||||
@@ -1184,8 +1244,12 @@
|
||||
|
||||
"expo-keep-awake": ["expo-keep-awake@15.0.7", "", { "peerDependencies": { "expo": "*", "react": "*" } }, "sha512-CgBNcWVPnrIVII5G54QDqoE125l+zmqR4HR8q+MQaCfHet+dYpS5vX5zii/RMayzGN4jPgA4XYIQ28ePKFjHoA=="],
|
||||
|
||||
"expo-linear-gradient": ["expo-linear-gradient@15.0.7", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-yF+y+9Shpr/OQFfy/wglB/0bykFMbwHBTuMRa5Of/r2P1wbkcacx8rg0JsUWkXH/rn2i2iWdubyqlxSJa3ggZA=="],
|
||||
|
||||
"expo-linking": ["expo-linking@8.0.8", "", { "dependencies": { "expo-constants": "~18.0.8", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-MyeMcbFDKhXh4sDD1EHwd0uxFQNAc6VCrwBkNvvvufUsTYFq3glTA9Y8a+x78CPpjNqwNAamu74yIaIz7IEJyg=="],
|
||||
|
||||
"expo-location": ["expo-location@19.0.7", "", { "peerDependencies": { "expo": "*" } }, "sha512-YNkh4r9E6ECbPkBCAMG5A5yHDgS0pw+Rzyd0l2ZQlCtjkhlODB55nMCKr5CZnUI0mXTkaSm8CwfoCO8n2MpYfg=="],
|
||||
|
||||
"expo-manifests": ["expo-manifests@1.0.8", "", { "dependencies": { "@expo/config": "~12.0.8", "expo-json-utils": "~0.15.0" }, "peerDependencies": { "expo": "*" } }, "sha512-nA5PwU2uiUd+2nkDWf9e71AuFAtbrb330g/ecvuu52bmaXtN8J8oiilc9BDvAX0gg2fbtOaZdEdjBYopt1jdlQ=="],
|
||||
|
||||
"expo-module-scripts": ["expo-module-scripts@4.1.10", "", { "dependencies": { "@babel/cli": "^7.23.4", "@babel/plugin-transform-export-namespace-from": "^7.23.4", "@babel/preset-env": "^7.23.8", "@babel/preset-typescript": "^7.23.3", "@expo/npm-proofread": "^1.0.1", "@testing-library/react-native": "^13.1.0", "@tsconfig/node18": "^18.2.2", "@types/jest": "^29.2.1", "babel-plugin-dynamic-import-node": "^2.3.3", "babel-preset-expo": "~13.2.3", "commander": "^12.1.0", "eslint-config-universe": "^15.0.3", "glob": "^10.4.2", "jest-expo": "~53.0.9", "jest-snapshot-prettier": "npm:prettier@^2", "jest-watch-typeahead": "2.2.1", "resolve-workspace-root": "^2.0.0", "ts-jest": "~29.0.4", "typescript": "^5.8.3" }, "bin": { "expo-module": "bin/expo-module.js" } }, "sha512-fQVXVgxqUOz1cnnNumNLm0eI+Y8IhYNa056ad0vxEhcMui6FjS1+beZNHiaClGwd/NQb5RjlT48ABL3XSGHwxQ=="],
|
||||
@@ -1194,6 +1258,8 @@
|
||||
|
||||
"expo-modules-core": ["expo-modules-core@3.0.15", "", { "dependencies": { "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-vGI7osd0/IjprldD08k4bckWSu7ID4HhZNP68l/UtilONQ8XZig8mWJd/Fm7i7KGvE3HyuF+HOXE9l671no42Q=="],
|
||||
|
||||
"expo-notifications": ["expo-notifications@0.32.13", "", { "dependencies": { "@expo/image-utils": "^0.8.7", "@ide/backoff": "^1.0.0", "abort-controller": "^3.0.0", "assert": "^2.0.0", "badgin": "^1.1.5", "expo-application": "~7.0.7", "expo-constants": "~18.0.10" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-PL0R1ulLVUgAswlXtRDKxBlcipNM3YA6+P5nB5JIhXbsjLJ7y+EKVaEhHhbaGzuK1QVsRQSJNm/4oISX+vsmFQ=="],
|
||||
|
||||
"expo-router": ["expo-router@6.0.1", "", { "dependencies": { "@expo/metro-runtime": "6.1.1", "@expo/schema-utils": "^0.1.7", "@expo/server": "^0.7.4", "@radix-ui/react-slot": "1.2.0", "@radix-ui/react-tabs": "^1.1.12", "@react-navigation/bottom-tabs": "^7.4.0", "@react-navigation/native": "^7.1.8", "@react-navigation/native-stack": "^7.3.16", "client-only": "^0.0.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.8", "query-string": "^7.1.3", "react-fast-compare": "^3.2.2", "react-native-is-edge-to-edge": "^1.1.6", "semver": "~7.6.3", "server-only": "^0.0.1", "sf-symbols-typescript": "^2.1.0", "shallowequal": "^1.1.0", "use-latest-callback": "^0.2.1", "vaul": "^1.1.2" }, "peerDependencies": { "@react-navigation/drawer": "^7.5.0", "@testing-library/react-native": ">= 12.0.0", "expo": "*", "expo-constants": "^18.0.8", "expo-linking": "^8.0.8", "react": "*", "react-dom": "*", "react-native": "*", "react-native-gesture-handler": "*", "react-native-reanimated": "*", "react-native-safe-area-context": ">= 5.4.0", "react-native-screens": "*", "react-native-web": "*", "react-server-dom-webpack": ">= 19.0.0" }, "optionalPeers": ["@react-navigation/drawer", "@testing-library/react-native", "react-dom", "react-native-gesture-handler", "react-native-reanimated", "react-native-web", "react-server-dom-webpack"] }, "sha512-5wXkWyNMqUbjCWH0PRkOM0P6UsgLVdgchDkiLz5FY7HfU00ToBcxij965bqtlaATBgoaIo4DuLu6EgxewrKJ8Q=="],
|
||||
|
||||
"expo-splash-screen": ["expo-splash-screen@31.0.9", "", { "dependencies": { "@expo/prebuild-config": "^54.0.1" }, "peerDependencies": { "expo": "*" } }, "sha512-pYLWFrEHn/c8e1a8oDzrlcyYI08oG4i37KA+VN5wwoC1DsQ0rm3kyAk0bmoydV1mBzNfXQFYbA1BGftXJl1f0w=="],
|
||||
@@ -1206,7 +1272,7 @@
|
||||
|
||||
"expo-updates-interface": ["expo-updates-interface@2.0.0", "", { "peerDependencies": { "expo": "*" } }, "sha512-pTzAIufEZdVPKql6iMi5ylVSPqV1qbEopz9G6TSECQmnNde2nwq42PxdFBaUEd8IZJ/fdJLQnOT3m6+XJ5s7jg=="],
|
||||
|
||||
"expo-web-browser": ["expo-web-browser@15.0.7", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-eXnfO3FQ2WthTA8uEPNJ7SDRfPaLIU/P2k082HGEYIHAFZMwh2o9Wo+SDVytO3E95TAv1qwhggUjOrczYzxteQ=="],
|
||||
"expo-web-browser": ["expo-web-browser@15.0.9", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-Dj8kNFO+oXsxqCDNlUT/GhOrJnm10kAElH++3RplLydogFm5jTzXYWDEeNIDmV+F+BzGYs+sIhxiBf7RyaxXZg=="],
|
||||
|
||||
"exponential-backoff": ["exponential-backoff@3.1.2", "", {}, "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA=="],
|
||||
|
||||
@@ -1258,6 +1324,10 @@
|
||||
|
||||
"form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="],
|
||||
|
||||
"framer-motion": ["framer-motion@6.5.1", "", { "dependencies": { "@motionone/dom": "10.12.0", "framesync": "6.0.1", "hey-listen": "^1.0.8", "popmotion": "11.0.3", "style-value-types": "5.0.0", "tslib": "^2.1.0" }, "optionalDependencies": { "@emotion/is-prop-valid": "^0.8.2" }, "peerDependencies": { "react": ">=16.8 || ^17.0.0 || ^18.0.0", "react-dom": ">=16.8 || ^17.0.0 || ^18.0.0" } }, "sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw=="],
|
||||
|
||||
"framesync": ["framesync@6.0.1", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA=="],
|
||||
|
||||
"freeport-async": ["freeport-async@2.0.0", "", {}, "sha512-K7od3Uw45AJg00XUmy15+Hae2hOcgKcmN3/EF6Y7i01O0gaqiRx8sUSpsb9+BRNL8RPBrhzPsVfy8q9ADlJuWQ=="],
|
||||
|
||||
"fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
|
||||
@@ -1276,6 +1346,8 @@
|
||||
|
||||
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
||||
|
||||
"geojson-rbush": ["geojson-rbush@3.2.0", "", { "dependencies": { "@turf/bbox": "*", "@turf/helpers": "6.x", "@turf/meta": "6.x", "@types/geojson": "7946.0.8", "rbush": "^3.0.1" } }, "sha512-oVltQTXolxvsz1sZnutlSuLDEcQAKYC/uXt9zDzJJ6bu0W+baTI8LZBaTup5afzibEH4N3jlq2p+a152wlBJ7w=="],
|
||||
|
||||
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
|
||||
|
||||
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
||||
@@ -1332,6 +1404,8 @@
|
||||
|
||||
"hermes-parser": ["hermes-parser@0.29.1", "", { "dependencies": { "hermes-estree": "0.29.1" } }, "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA=="],
|
||||
|
||||
"hey-listen": ["hey-listen@1.0.8", "", {}, "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="],
|
||||
|
||||
"hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "^16.7.0" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="],
|
||||
|
||||
"hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="],
|
||||
@@ -1378,6 +1452,8 @@
|
||||
|
||||
"invariant": ["invariant@2.2.4", "", { "dependencies": { "loose-envify": "^1.0.0" } }, "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA=="],
|
||||
|
||||
"is-arguments": ["is-arguments@1.2.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA=="],
|
||||
|
||||
"is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="],
|
||||
|
||||
"is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
|
||||
@@ -1418,6 +1494,8 @@
|
||||
|
||||
"is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="],
|
||||
|
||||
"is-nan": ["is-nan@1.3.2", "", { "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" } }, "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w=="],
|
||||
|
||||
"is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="],
|
||||
|
||||
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
||||
@@ -1682,6 +1760,8 @@
|
||||
|
||||
"mkdirp": ["mkdirp@3.0.1", "", { "bin": "dist/cjs/src/bin.js" }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
|
||||
|
||||
"moti": ["moti@0.30.0", "", { "dependencies": { "framer-motion": "^6.5.1" }, "peerDependencies": { "react-native-reanimated": "*" } }, "sha512-YN78mcefo8kvJaL+TZNyusq6YA2aMFvBPl8WiLPy4eb4wqgOFggJOjP9bUr2YO8PrAt0uusmRG8K4RPL4OhCsA=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
|
||||
@@ -1724,6 +1804,8 @@
|
||||
|
||||
"object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
|
||||
|
||||
"object-is": ["object-is@1.1.6", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1" } }, "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q=="],
|
||||
|
||||
"object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="],
|
||||
|
||||
"object.assign": ["object.assign@4.1.7", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0", "has-symbols": "^1.1.0", "object-keys": "^1.1.1" } }, "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw=="],
|
||||
@@ -1796,6 +1878,8 @@
|
||||
|
||||
"pngjs": ["pngjs@5.0.0", "", {}, "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="],
|
||||
|
||||
"popmotion": ["popmotion@11.0.3", "", { "dependencies": { "framesync": "6.0.1", "hey-listen": "^1.0.8", "style-value-types": "5.0.0", "tslib": "^2.1.0" } }, "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA=="],
|
||||
|
||||
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
||||
|
||||
"postcss": ["postcss@8.4.49", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA=="],
|
||||
@@ -1842,10 +1926,14 @@
|
||||
|
||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||
|
||||
"quickselect": ["quickselect@2.0.0", "", {}, "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="],
|
||||
|
||||
"randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="],
|
||||
|
||||
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
|
||||
|
||||
"rbush": ["rbush@3.0.1", "", { "dependencies": { "quickselect": "^2.0.0" } }, "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w=="],
|
||||
|
||||
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": "cli.js" }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
|
||||
|
||||
"react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="],
|
||||
@@ -2104,6 +2192,8 @@
|
||||
|
||||
"structured-headers": ["structured-headers@0.4.1", "", {}, "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg=="],
|
||||
|
||||
"style-value-types": ["style-value-types@5.0.0", "", { "dependencies": { "hey-listen": "^1.0.8", "tslib": "^2.1.0" } }, "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA=="],
|
||||
|
||||
"styleq": ["styleq@0.1.3", "", {}, "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA=="],
|
||||
|
||||
"sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="],
|
||||
@@ -2180,7 +2270,7 @@
|
||||
|
||||
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||
|
||||
"ua-parser-js": ["ua-parser-js@1.0.40", "", { "bin": "script/cli.js" }, "sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew=="],
|
||||
"ua-parser-js": ["ua-parser-js@0.7.41", "", { "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg=="],
|
||||
|
||||
"unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
|
||||
|
||||
@@ -2218,6 +2308,8 @@
|
||||
|
||||
"use-sync-external-store": ["use-sync-external-store@1.5.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A=="],
|
||||
|
||||
"util": ["util@0.12.5", "", { "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", "is-generator-function": "^1.0.7", "is-typed-array": "^1.1.3", "which-typed-array": "^1.1.2" } }, "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA=="],
|
||||
|
||||
"utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="],
|
||||
|
||||
"uuid": ["uuid@7.0.3", "", { "bin": "dist/bin/uuid" }, "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg=="],
|
||||
@@ -2478,6 +2570,10 @@
|
||||
|
||||
"@testing-library/react-native/pretty-format": ["pretty-format@30.0.5", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw=="],
|
||||
|
||||
"@turf/bbox/@turf/helpers": ["@turf/helpers@7.3.0", "", { "dependencies": { "@types/geojson": "^7946.0.10", "tslib": "^2.8.1" } }, "sha512-5kWdgwI6e2vGbkt2qOD+Z2BiKQ7dfKN/PtWRLCpvzyOO59rk19R53CHi8nUT/Y1vQLgWmT6eNpiKwsWwPZGIdg=="],
|
||||
|
||||
"@turf/bbox/@turf/meta": ["@turf/meta@7.3.0", "", { "dependencies": { "@turf/helpers": "7.3.0", "@types/geojson": "^7946.0.10" } }, "sha512-fTLqdQqRm8qA2zHHUbBMY++YT9LDQejLG7OD70XF2dwg9nPiF9mUxO7nrsDp2IY8vNmH9OTAiMtlIjb0ssYccg=="],
|
||||
|
||||
"@types/react-native/@types/react": ["@types/react@19.0.14", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-ixLZ7zG7j1fM0DijL9hDArwhwcCb4vqmePgwtV0GfnkHRSCUEv4LvzarcTdhoqgyMznUx/EhoTUv31CKZzkQlw=="],
|
||||
|
||||
"@types/react-native-vector-icons/@types/react": ["@types/react@19.0.14", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-ixLZ7zG7j1fM0DijL9hDArwhwcCb4vqmePgwtV0GfnkHRSCUEv4LvzarcTdhoqgyMznUx/EhoTUv31CKZzkQlw=="],
|
||||
@@ -2564,8 +2660,16 @@
|
||||
|
||||
"expo/babel-preset-expo": ["babel-preset-expo@54.0.0", "", { "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/plugin-proposal-decorators": "^7.12.9", "@babel/plugin-proposal-export-default-from": "^7.24.7", "@babel/plugin-syntax-export-default-from": "^7.24.7", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-flow-strip-types": "^7.25.2", "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-runtime": "^7.24.7", "@babel/preset-react": "^7.22.15", "@babel/preset-typescript": "^7.23.0", "@react-native/babel-preset": "0.81.4", "babel-plugin-react-compiler": "^19.1.0-rc.2", "babel-plugin-react-native-web": "~0.21.0", "babel-plugin-syntax-hermes-parser": "^0.25.1", "babel-plugin-transform-flow-enums": "^0.0.2", "debug": "^4.3.4", "resolve-from": "^5.0.0" }, "peerDependencies": { "@babel/runtime": "^7.20.0", "expo": "*", "react-refresh": ">=0.14.0 <1.0.0" }, "optionalPeers": ["@babel/runtime", "expo"] }, "sha512-a0Ej4ik6xzvtrA4Ivblov3XVvfntIoqnXOy2jG2k/3hzWqzrJxKyY2gUW9ZCMAicGevj2ju28q+TsK29uTe0eQ=="],
|
||||
|
||||
"expo/expo-constants": ["expo-constants@18.0.8", "", { "dependencies": { "@expo/config": "~12.0.8", "@expo/env": "~2.0.7" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-Tetphsx6RVImCTZeBAclRQMy0WOODY3y6qrUoc88YGUBVm8fAKkErCSWxLTCc6nFcJxdoOMYi62LgNIUFjZCLA=="],
|
||||
|
||||
"expo/expo-file-system": ["expo-file-system@19.0.12", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-gqpxpnjfhzXLcqMOi49isB5S1Af49P9410fsaFfnLZWN3X6Dwc8EplDwbaolOI/wnGwP81P+/nDn5RNmU6m7mQ=="],
|
||||
|
||||
"expo-asset/expo-constants": ["expo-constants@18.0.8", "", { "dependencies": { "@expo/config": "~12.0.8", "@expo/env": "~2.0.7" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-Tetphsx6RVImCTZeBAclRQMy0WOODY3y6qrUoc88YGUBVm8fAKkErCSWxLTCc6nFcJxdoOMYi62LgNIUFjZCLA=="],
|
||||
|
||||
"expo-constants/@expo/config": ["@expo/config@12.0.10", "", { "dependencies": { "@babel/code-frame": "~7.10.4", "@expo/config-plugins": "~54.0.2", "@expo/config-types": "^54.0.8", "@expo/json-file": "^10.0.7", "deepmerge": "^4.3.1", "getenv": "^2.0.0", "glob": "^10.4.2", "require-from-string": "^2.0.2", "resolve-from": "^5.0.0", "resolve-workspace-root": "^2.0.0", "semver": "^7.6.0", "slugify": "^1.3.4", "sucrase": "3.35.0" } }, "sha512-lJMof5Nqakq1DxGYlghYB/ogSBjmv4Fxn1ovyDmcjlRsQdFCXgu06gEUogkhPtc9wBt9WlTTfqENln5HHyLW6w=="],
|
||||
|
||||
"expo-linking/expo-constants": ["expo-constants@18.0.8", "", { "dependencies": { "@expo/config": "~12.0.8", "@expo/env": "~2.0.7" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-Tetphsx6RVImCTZeBAclRQMy0WOODY3y6qrUoc88YGUBVm8fAKkErCSWxLTCc6nFcJxdoOMYi62LgNIUFjZCLA=="],
|
||||
|
||||
"expo-module-scripts/typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||
|
||||
"expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
|
||||
@@ -2578,6 +2682,8 @@
|
||||
|
||||
"fbjs/promise": ["promise@7.3.1", "", { "dependencies": { "asap": "~2.0.3" } }, "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg=="],
|
||||
|
||||
"fbjs/ua-parser-js": ["ua-parser-js@1.0.40", "", { "bin": "script/cli.js" }, "sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew=="],
|
||||
|
||||
"finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||
|
||||
"finalhandler/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
|
||||
@@ -2586,6 +2692,8 @@
|
||||
|
||||
"finalhandler/statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="],
|
||||
|
||||
"geojson-rbush/@types/geojson": ["@types/geojson@7946.0.8", "", {}, "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA=="],
|
||||
|
||||
"glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
|
||||
"hoist-non-react-statics/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
||||
@@ -2946,6 +3054,14 @@
|
||||
|
||||
"expect/jest-matcher-utils/jest-diff": ["jest-diff@29.7.0", "", { "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" } }, "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw=="],
|
||||
|
||||
"expo-constants/@expo/config/@babel/code-frame": ["@babel/code-frame@7.10.4", "", { "dependencies": { "@babel/highlight": "^7.10.4" } }, "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg=="],
|
||||
|
||||
"expo-constants/@expo/config/@expo/config-plugins": ["@expo/config-plugins@54.0.2", "", { "dependencies": { "@expo/config-types": "^54.0.8", "@expo/json-file": "~10.0.7", "@expo/plist": "^0.4.7", "@expo/sdk-runtime-versions": "^1.0.0", "chalk": "^4.1.2", "debug": "^4.3.5", "getenv": "^2.0.0", "glob": "^10.4.2", "resolve-from": "^5.0.0", "semver": "^7.5.4", "slash": "^3.0.0", "slugify": "^1.6.6", "xcode": "^3.0.1", "xml2js": "0.6.0" } }, "sha512-jD4qxFcURQUVsUFGMcbo63a/AnviK8WUGard+yrdQE3ZrB/aurn68SlApjirQQLEizhjI5Ar2ufqflOBlNpyPg=="],
|
||||
|
||||
"expo-constants/@expo/config/@expo/json-file": ["@expo/json-file@10.0.7", "", { "dependencies": { "@babel/code-frame": "~7.10.4", "json5": "^2.2.3" } }, "sha512-z2OTC0XNO6riZu98EjdNHC05l51ySeTto6GP7oSQrCvQgG9ARBwD1YvMQaVZ9wU7p/4LzSf1O7tckL3B45fPpw=="],
|
||||
|
||||
"expo-constants/@expo/config/semver": ["semver@7.7.2", "", { "bin": "bin/semver.js" }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
||||
|
||||
"expo/babel-preset-expo/@react-native/babel-preset": ["@react-native/babel-preset@0.81.4", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/plugin-proposal-export-default-from": "^7.24.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-default-from": "^7.24.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-transform-arrow-functions": "^7.24.7", "@babel/plugin-transform-async-generator-functions": "^7.25.4", "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoping": "^7.25.0", "@babel/plugin-transform-class-properties": "^7.25.4", "@babel/plugin-transform-classes": "^7.25.4", "@babel/plugin-transform-computed-properties": "^7.24.7", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-flow-strip-types": "^7.25.2", "@babel/plugin-transform-for-of": "^7.24.7", "@babel/plugin-transform-function-name": "^7.25.1", "@babel/plugin-transform-literals": "^7.25.2", "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", "@babel/plugin-transform-numeric-separator": "^7.24.7", "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-optional-catch-binding": "^7.24.7", "@babel/plugin-transform-optional-chaining": "^7.24.8", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-react-display-name": "^7.24.7", "@babel/plugin-transform-react-jsx": "^7.25.2", "@babel/plugin-transform-react-jsx-self": "^7.24.7", "@babel/plugin-transform-react-jsx-source": "^7.24.7", "@babel/plugin-transform-regenerator": "^7.24.7", "@babel/plugin-transform-runtime": "^7.24.7", "@babel/plugin-transform-shorthand-properties": "^7.24.7", "@babel/plugin-transform-spread": "^7.24.7", "@babel/plugin-transform-sticky-regex": "^7.24.7", "@babel/plugin-transform-typescript": "^7.25.2", "@babel/plugin-transform-unicode-regex": "^7.24.7", "@babel/template": "^7.25.0", "@react-native/babel-plugin-codegen": "0.81.4", "babel-plugin-syntax-hermes-parser": "0.29.1", "babel-plugin-transform-flow-enums": "^0.0.2", "react-refresh": "^0.14.0" } }, "sha512-VYj0c/cTjQJn/RJ5G6P0L9wuYSbU9yGbPYDHCKstlQZQWkk+L9V8ZDbxdJBTIei9Xl3KPQ1odQ4QaeW+4v+AZg=="],
|
||||
|
||||
"expo/babel-preset-expo/babel-plugin-react-native-web": ["babel-plugin-react-native-web@0.21.1", "", {}, "sha512-7XywfJ5QIRMwjOL+pwJt2w47Jmi5fFLvK7/So4fV4jIN6PcRbylCp9/l3cJY4VJbSz3lnWTeHDTD1LKIc1C09Q=="],
|
||||
@@ -3128,6 +3244,8 @@
|
||||
|
||||
"babel-preset-expo/babel-plugin-syntax-hermes-parser/hermes-parser/hermes-estree": ["hermes-estree@0.25.1", "", {}, "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="],
|
||||
|
||||
"expo-constants/@expo/config/@expo/config-plugins/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
|
||||
|
||||
"expo/babel-preset-expo/@react-native/babel-preset/@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.81.4", "", { "dependencies": { "@babel/traverse": "^7.25.3", "@react-native/codegen": "0.81.4" } }, "sha512-6ztXf2Tl2iWznyI/Da/N2Eqymt0Mnn69GCLnEFxFbNdk0HxHPZBNWU9shTXhsLWOL7HATSqwg/bB1+3kY1q+mA=="],
|
||||
|
||||
"expo/babel-preset-expo/@react-native/babel-preset/babel-plugin-syntax-hermes-parser": ["babel-plugin-syntax-hermes-parser@0.29.1", "", { "dependencies": { "hermes-parser": "0.29.1" } }, "sha512-2WFYnoWGdmih1I1J5eIqxATOeycOqRwYxAQBu3cUu/rhwInwHUg7k60AFNbuGjSDL8tje5GDrAnxzRLcu2pYcA=="],
|
||||
|
||||
@@ -196,6 +196,7 @@ const DateTimeInput_Android: React.FC<DateTimeInputProps> = ({
|
||||
onChange={handleConfirmTime}
|
||||
minimumDate={minimumDate}
|
||||
maximumDate={maximumDate}
|
||||
themeVariant="light"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -145,6 +145,7 @@ const DateTimeInput_IOS: React.FC<DateTimeInputProps> = ({
|
||||
onChange={handleConfirm}
|
||||
minimumDate={minimumDate}
|
||||
maximumDate={maximumDate}
|
||||
themeVariant="light"
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
|
||||
@@ -109,6 +109,7 @@ const styles = StyleSheet.create({
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
justifyContent: "flex-start",
|
||||
marginInline: 0.1
|
||||
// marginInline: 0.1
|
||||
margin: 0.1
|
||||
},
|
||||
});
|
||||
|
||||
@@ -27,6 +27,8 @@ type SelectProps = {
|
||||
onChange: (value: string | number) => void;
|
||||
borderRadius?: number;
|
||||
styleContainer?: StyleProp<ViewStyle>;
|
||||
allowClear?: boolean; // <-- new prop
|
||||
clearLabel?: string; // default: "Kosongkan"
|
||||
};
|
||||
|
||||
const SelectCustom: React.FC<SelectProps> = ({
|
||||
@@ -39,13 +41,21 @@ const SelectCustom: React.FC<SelectProps> = ({
|
||||
onChange,
|
||||
borderRadius = 8,
|
||||
styleContainer,
|
||||
allowClear = true, // bisa dimatikan jika tidak perlu
|
||||
clearLabel = "Hapus Pilihan",
|
||||
}) => {
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
|
||||
const selectedItem = data.find((item) => item.value === value);
|
||||
|
||||
const hasError = required && value === null; // <-- check if empty and required
|
||||
|
||||
// Gabungkan opsi clear di atas daftar
|
||||
const renderData = allowClear
|
||||
? [...data,
|
||||
// { label: clearLabel, value: "__clear__" }
|
||||
]
|
||||
: data;
|
||||
|
||||
return (
|
||||
<View style={[GStyles.inputContainerArea, styleContainer]}>
|
||||
{label && (
|
||||
@@ -54,29 +64,64 @@ const SelectCustom: React.FC<SelectProps> = ({
|
||||
{required && <Text style={GStyles.inputRequired}> *</Text>}
|
||||
</Text>
|
||||
)}
|
||||
<Pressable
|
||||
|
||||
{/* Input Container */}
|
||||
<View
|
||||
style={[
|
||||
{ borderRadius, },
|
||||
hasError ? GStyles.inputErrorBorder : null,
|
||||
{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
// backgroundColor: "red",
|
||||
// flex: 1,
|
||||
borderRadius,
|
||||
},
|
||||
GStyles.inputContainerInput,
|
||||
hasError ? GStyles.inputErrorBorder : null,
|
||||
disabled && GStyles.disabledBox,
|
||||
]} // <-- add error style
|
||||
onPress={() => !disabled && setModalVisible(true)}
|
||||
]}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
selectedItem
|
||||
? disabled
|
||||
? GStyles.inputTextDisabled
|
||||
: GStyles.inputText
|
||||
: disabled
|
||||
? GStyles.inputPlaceholderDisabled
|
||||
: GStyles.inputPlaceholder
|
||||
}
|
||||
<Pressable
|
||||
style={[
|
||||
{
|
||||
flex: 1,
|
||||
borderRadius,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingHorizontal: 10,
|
||||
height: 50,
|
||||
},
|
||||
|
||||
// GStyles.inputContainerInput,
|
||||
// hasError ? GStyles.inputErrorBorder : null,
|
||||
// disabled && GStyles.disabledBox,
|
||||
]}
|
||||
onPress={() => !disabled && setModalVisible(true)}
|
||||
>
|
||||
{selectedItem?.label || placeholder}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Text
|
||||
style={
|
||||
selectedItem
|
||||
? disabled
|
||||
? GStyles.inputTextDisabled
|
||||
: GStyles.inputText
|
||||
: disabled
|
||||
? GStyles.inputPlaceholderDisabled
|
||||
: GStyles.inputPlaceholder
|
||||
}
|
||||
>
|
||||
{selectedItem?.label || placeholder}
|
||||
</Text>
|
||||
</Pressable>
|
||||
|
||||
{/* Tombol Clear (Hanya muncul jika ada nilai terpilih & allowClear aktif) */}
|
||||
{!disabled && allowClear && value !== null && value !== undefined && (
|
||||
<TouchableOpacity
|
||||
style={{ paddingHorizontal: 10 }}
|
||||
onPress={() => onChange(null as any)} // null dikirim sebagai value
|
||||
>
|
||||
<Text style={{ fontSize: 18, color: "#999" }}>×</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<Modal visible={modalVisible} transparent animationType="fade">
|
||||
<TouchableOpacity
|
||||
@@ -86,19 +131,38 @@ const SelectCustom: React.FC<SelectProps> = ({
|
||||
>
|
||||
<View style={GStyles.selectModalContent}>
|
||||
<FlatList
|
||||
data={data}
|
||||
data={renderData}
|
||||
keyExtractor={(item) => String(item.value)}
|
||||
renderItem={({ item }) => (
|
||||
<TouchableOpacity
|
||||
style={GStyles.selectOption}
|
||||
onPress={() => {
|
||||
onChange(item.value);
|
||||
setModalVisible(false);
|
||||
}}
|
||||
>
|
||||
<Text>{item.label}</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
renderItem={({ item }) => {
|
||||
if (item.value === "__clear__") {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
GStyles.selectOption,
|
||||
{ backgroundColor: "#fdd" },
|
||||
]}
|
||||
onPress={() => {
|
||||
onChange(null as any); // kosongkan nilai
|
||||
setModalVisible(false);
|
||||
}}
|
||||
>
|
||||
<Text>{item.label}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={GStyles.selectOption}
|
||||
onPress={() => {
|
||||
onChange(item.value);
|
||||
setModalVisible(false);
|
||||
}}
|
||||
>
|
||||
<Text>{item.label}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
188
components/_ShareComponent/NewWrapper.tsx
Normal file
@@ -0,0 +1,188 @@
|
||||
// @/components/NewWrapper.tsx
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { OS_HEIGHT } from "@/constants/constans-value";
|
||||
import { GStyles } from "@/styles/global-styles";
|
||||
import {
|
||||
ImageBackground,
|
||||
Keyboard,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
ScrollView,
|
||||
FlatList,
|
||||
TouchableWithoutFeedback,
|
||||
View,
|
||||
StyleProp,
|
||||
ViewStyle,
|
||||
} from "react-native";
|
||||
import {
|
||||
NativeSafeAreaViewProps,
|
||||
SafeAreaView,
|
||||
} from "react-native-safe-area-context";
|
||||
import type { ScrollViewProps, FlatListProps } from "react-native";
|
||||
|
||||
// --- ✅ Tambahkan refreshControl ke BaseProps ---
|
||||
interface BaseProps {
|
||||
withBackground?: boolean;
|
||||
headerComponent?: React.ReactNode;
|
||||
footerComponent?: React.ReactNode;
|
||||
floatingButton?: React.ReactNode;
|
||||
hideFooter?: boolean;
|
||||
edgesFooter?: NativeSafeAreaViewProps["edges"];
|
||||
style?: StyleProp<ViewStyle>;
|
||||
refreshControl?: ScrollViewProps["refreshControl"]; // ✅ dipakai di kedua mode
|
||||
}
|
||||
|
||||
interface StaticModeProps extends BaseProps {
|
||||
children: React.ReactNode;
|
||||
listData?: never;
|
||||
renderItem?: never;
|
||||
}
|
||||
|
||||
interface ListModeProps extends BaseProps {
|
||||
children?: never;
|
||||
listData: any[];
|
||||
renderItem: FlatListProps<any>["renderItem"];
|
||||
onEndReached?: () => void;
|
||||
// ✅ Gunakan tipe yang kompatibel dengan FlatList
|
||||
ListHeaderComponent?: React.ReactElement | null;
|
||||
ListFooterComponent?: React.ReactElement | null;
|
||||
ListEmptyComponent?: React.ReactElement | null;
|
||||
keyExtractor?: FlatListProps<any>["keyExtractor"];
|
||||
}
|
||||
|
||||
type NewWrapperProps = StaticModeProps | ListModeProps;
|
||||
|
||||
const NewWrapper = (props: NewWrapperProps) => {
|
||||
const {
|
||||
withBackground = false,
|
||||
headerComponent,
|
||||
footerComponent,
|
||||
floatingButton,
|
||||
hideFooter = false,
|
||||
edgesFooter = [],
|
||||
style,
|
||||
refreshControl, // ✅ sekarang ada di BaseProps
|
||||
} = props;
|
||||
|
||||
const assetBackground = require("../../assets/images/main-background.png");
|
||||
|
||||
const renderContainer = (content: React.ReactNode) => {
|
||||
if (withBackground) {
|
||||
return (
|
||||
<ImageBackground
|
||||
source={assetBackground}
|
||||
resizeMode="cover"
|
||||
style={GStyles.imageBackground}
|
||||
>
|
||||
<View style={[GStyles.containerWithBackground, style]}>
|
||||
{content}
|
||||
</View>
|
||||
</ImageBackground>
|
||||
);
|
||||
}
|
||||
return <View style={[GStyles.container, style]}>{content}</View>;
|
||||
};
|
||||
|
||||
// 🔹 Mode Dinamis
|
||||
if ("listData" in props) {
|
||||
const listProps = props as ListModeProps;
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||
style={{ flex: 1, backgroundColor: MainColor.darkblue }}
|
||||
>
|
||||
{headerComponent && (
|
||||
<View style={GStyles.stickyHeader}>{headerComponent}</View>
|
||||
)}
|
||||
<View style={[GStyles.container, style]}>
|
||||
<FlatList
|
||||
data={listProps.listData}
|
||||
renderItem={listProps.renderItem}
|
||||
keyExtractor={
|
||||
listProps.keyExtractor ||
|
||||
((item) => {
|
||||
if (item.id == null) {
|
||||
console.warn("Item tanpa 'id':", item);
|
||||
return `fallback-${JSON.stringify(item)}`;
|
||||
}
|
||||
return String(item.id);
|
||||
})
|
||||
}
|
||||
|
||||
refreshControl={refreshControl} // ✅ dari BaseProps
|
||||
onEndReached={listProps.onEndReached}
|
||||
onEndReachedThreshold={0.5}
|
||||
ListHeaderComponent={listProps.ListHeaderComponent}
|
||||
ListFooterComponent={listProps.ListFooterComponent}
|
||||
ListEmptyComponent={listProps.ListEmptyComponent}
|
||||
contentContainerStyle={{ flexGrow: 1 }}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
/>
|
||||
</View>
|
||||
|
||||
{footerComponent ? (
|
||||
<SafeAreaView
|
||||
edges={Platform.OS === "ios" ? edgesFooter : ["bottom"]}
|
||||
style={{ backgroundColor: MainColor.darkblue, height: OS_HEIGHT }}
|
||||
>
|
||||
{footerComponent}
|
||||
</SafeAreaView>
|
||||
) : hideFooter ? null : (
|
||||
<SafeAreaView
|
||||
edges={["bottom"]}
|
||||
style={{ backgroundColor: MainColor.darkblue }}
|
||||
/>
|
||||
)}
|
||||
|
||||
{floatingButton && (
|
||||
<View style={GStyles.floatingContainer}>{floatingButton}</View>
|
||||
)}
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
||||
|
||||
// 🔹 Mode Statis
|
||||
const staticProps = props as StaticModeProps;
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||
style={{ flex: 1, backgroundColor: MainColor.darkblue }}
|
||||
>
|
||||
{headerComponent && (
|
||||
<View style={GStyles.stickyHeader}>{headerComponent}</View>
|
||||
)}
|
||||
|
||||
<ScrollView
|
||||
contentContainerStyle={{ flexGrow: 1 }}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
refreshControl={refreshControl} // ✅ sekarang valid
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||
{renderContainer(staticProps.children)}
|
||||
</TouchableWithoutFeedback>
|
||||
</ScrollView>
|
||||
|
||||
{footerComponent ? (
|
||||
<SafeAreaView
|
||||
edges={Platform.OS === "ios" ? edgesFooter : ["bottom"]}
|
||||
style={{ backgroundColor: MainColor.darkblue, height: OS_HEIGHT }}
|
||||
>
|
||||
{footerComponent}
|
||||
</SafeAreaView>
|
||||
) : hideFooter ? null : (
|
||||
<SafeAreaView
|
||||
edges={["bottom"]}
|
||||
style={{ backgroundColor: MainColor.darkblue }}
|
||||
/>
|
||||
)}
|
||||
|
||||
{floatingButton && (
|
||||
<View style={GStyles.floatingContainer}>{floatingButton}</View>
|
||||
)}
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewWrapper;
|
||||
9
components/_ShareComponent/NoDataText.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import TextCustom from "../Text/TextCustom";
|
||||
|
||||
export default function NoDataText({ text }: { text?: string }) {
|
||||
return (
|
||||
<TextCustom color="gray" align="center" bold size={"small"}>
|
||||
{text ? text : "Belum ada data"}
|
||||
</TextCustom>
|
||||
);
|
||||
}
|
||||
59
components/_ShareComponent/SkeletonCustom.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
// components/CustomSkeleton.tsx
|
||||
import React from "react";
|
||||
import { View, StyleProp, ViewStyle, DimensionValue } from "react-native";
|
||||
import { MotiView } from "moti";
|
||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||
|
||||
interface CustomSkeletonProps {
|
||||
isLoading?: boolean;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
width?: DimensionValue;
|
||||
height?: DimensionValue;
|
||||
radius?: number;
|
||||
}
|
||||
|
||||
const CustomSkeleton: React.FC<CustomSkeletonProps> = ({
|
||||
isLoading = true,
|
||||
style,
|
||||
width = "100%",
|
||||
height = 16,
|
||||
radius = 8,
|
||||
}) => {
|
||||
if (!isLoading) return null;
|
||||
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
width,
|
||||
height,
|
||||
borderRadius: radius,
|
||||
backgroundColor: AccentColor.darkblue,
|
||||
overflow: "hidden",
|
||||
position: "relative",
|
||||
},
|
||||
style,
|
||||
]}
|
||||
>
|
||||
<MotiView
|
||||
from={{ translateY: -100 }}
|
||||
animate={{ translateY: 100 }}
|
||||
transition={{
|
||||
duration: 1200,
|
||||
repeat: Infinity,
|
||||
type: "timing",
|
||||
}}
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 100,
|
||||
backgroundColor: MainColor.soft_darkblue,
|
||||
borderRadius: 4,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomSkeleton;
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
View,
|
||||
StyleProp,
|
||||
ViewStyle,
|
||||
ScrollViewProps,
|
||||
} from "react-native";
|
||||
import { NativeSafeAreaViewProps, SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
@@ -23,6 +24,7 @@ interface ViewWrapperProps {
|
||||
hideFooter?: boolean;
|
||||
edgesFooter?: NativeSafeAreaViewProps["edges"];
|
||||
style?: StyleProp<ViewStyle>;
|
||||
refreshControl?: ScrollViewProps["refreshControl"];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,6 +42,7 @@ const ViewWrapper = ({
|
||||
hideFooter = false,
|
||||
edgesFooter =[],
|
||||
style,
|
||||
refreshControl,
|
||||
}: ViewWrapperProps) => {
|
||||
const assetBackground = require("../../assets/images/main-background.png");
|
||||
|
||||
@@ -57,6 +60,7 @@ const ViewWrapper = ({
|
||||
<ScrollView
|
||||
contentContainerStyle={{ flexGrow: 1 }}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
refreshControl={refreshControl}
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||
<View style={{ flex: 1 }}>
|
||||
|
||||
@@ -24,6 +24,7 @@ type AuthContextType = {
|
||||
registerUser: (userData: {
|
||||
username: string;
|
||||
nomor: string;
|
||||
termsOfServiceAccepted: boolean;
|
||||
}) => Promise<void>;
|
||||
userData: (token: string) => Promise<any>;
|
||||
};
|
||||
@@ -91,14 +92,11 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
setToken(token);
|
||||
await AsyncStorage.setItem("authToken", token);
|
||||
|
||||
const responseUser = await apiConfig.get(
|
||||
`/mobile?token=${token}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
const responseUser = await apiConfig.get(`/mobile?token=${token}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
const dataUser = responseUser.data.data;
|
||||
|
||||
setUser(dataUser);
|
||||
@@ -147,9 +145,7 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
await AsyncStorage.setItem("userData", JSON.stringify(dataUser));
|
||||
return dataUser;
|
||||
} catch (error: any) {
|
||||
throw new Error(
|
||||
error.response?.data?.message || "Gagal mengambil data user"
|
||||
);
|
||||
console.log(error.response?.data?.message + "user" || "Gagal mengambil data user");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
@@ -159,10 +155,12 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
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) {
|
||||
|
||||
14
eas.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"cli": {
|
||||
"version": ">= 16.10.0",
|
||||
"appVersionSource": "remote"
|
||||
"appVersionSource": "local"
|
||||
},
|
||||
"build": {
|
||||
"development": {
|
||||
@@ -11,11 +11,19 @@
|
||||
"preview": {
|
||||
"distribution": "internal",
|
||||
"android": {
|
||||
"buildType": "apk"
|
||||
"buildType": "app-bundle"
|
||||
},
|
||||
"ios": {
|
||||
"simulator": false
|
||||
}
|
||||
},
|
||||
"production": {
|
||||
"autoIncrement": true
|
||||
"android": {
|
||||
"buildType": "app-bundle"
|
||||
},
|
||||
"ios": {
|
||||
"resourceClass": "m1-medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"submit": {
|
||||
|
||||
29
google-services.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "608461535079",
|
||||
"project_id": "hipmi-badung-connect",
|
||||
"storage_bucket": "hipmi-badung-connect.firebasestorage.app"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:608461535079:android:4ff12ddc283fb3746761c2",
|
||||
"android_client_info": {
|
||||
"package_name": "com.bip.hipmimobileapp"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyBiDtIk3Q9zffFwIdJ5cjqY7e4390JGSkM"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
15
hipmi-note.md
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
### Buil
|
||||
eas build --profile production : for build production on expo with eas
|
||||
|
||||
npx expo prebuild : untuk build dan membuat folder android & ios
|
||||
|
||||
open ios/<nama-app>.xcworkspace : untuk membuka file xcode
|
||||
Build ios : bun run ios
|
||||
Build android : bun run android
|
||||
Exp: open ios/HIPMIBADUNG.xcworkspace
|
||||
|
||||
### Other
|
||||
perubahan versi : npm version patch
|
||||
ios: bunx expo prebuild --platform ios
|
||||
android: bunx expo prebuild --platform android
|
||||
@@ -1,5 +0,0 @@
|
||||
<?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/>
|
||||
</plist>
|
||||
|
Before Width: | Height: | Size: 259 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 85 KiB |
@@ -8,20 +8,28 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
241CFEB1CBB2124E18A09822 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 51B6792712498367CD1EEA5D /* PrivacyInfo.xcprivacy */; };
|
||||
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
|
||||
7833AA2741E7B2CCBEBEB1C7 /* libPods-HIPMIBadungConnect.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B3A38F3F981E3720B61AC51 /* libPods-HIPMIBadungConnect.a */; };
|
||||
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
|
||||
D138B3E4BC618ADDE62DCDCC /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8F39CC335B3942749573F05 /* ExpoModulesProvider.swift */; };
|
||||
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11748412D0307B40044C1D9 /* AppDelegate.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
13B07F961A680F5B00A75B9A /* HIPMIBADUNG.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HIPMIBADUNG.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = HIPMIBADUNG/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = HIPMIBADUNG/Info.plist; sourceTree = "<group>"; };
|
||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = HIPMIBADUNG/SplashScreen.storyboard; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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 = HIPMIBADUNG/AppDelegate.swift; sourceTree = "<group>"; };
|
||||
F11748442D0722820044C1D9 /* HIPMIBADUNG-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "HIPMIBADUNG-Bridging-Header.h"; path = "HIPMIBADUNG/HIPMIBADUNG-Bridging-Header.h"; 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>"; };
|
||||
F8F39CC335B3942749573F05 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-HIPMIBadungConnect/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -29,33 +37,44 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7833AA2741E7B2CCBEBEB1C7 /* libPods-HIPMIBadungConnect.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
13B07FAE1A68108700A75B9A /* HIPMIBADUNG */ = {
|
||||
13B07FAE1A68108700A75B9A /* HIPMIBadungConnect */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F11748412D0307B40044C1D9 /* AppDelegate.swift */,
|
||||
F11748442D0722820044C1D9 /* HIPMIBADUNG-Bridging-Header.h */,
|
||||
F11748442D0722820044C1D9 /* HIPMIBadungConnect-Bridging-Header.h */,
|
||||
BB2F792B24A3F905000567C9 /* Supporting */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
|
||||
51B6792712498367CD1EEA5D /* PrivacyInfo.xcprivacy */,
|
||||
);
|
||||
name = HIPMIBADUNG;
|
||||
name = HIPMIBadungConnect;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||
9B3A38F3F981E3720B61AC51 /* libPods-HIPMIBadungConnect.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6C62A8BDDB81F7BE378344ED /* ExpoModulesProviders */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C0BA0842F7555AB0104D3227 /* HIPMIBadungConnect */,
|
||||
);
|
||||
name = ExpoModulesProviders;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -66,10 +85,12 @@
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAE1A68108700A75B9A /* HIPMIBADUNG */,
|
||||
13B07FAE1A68108700A75B9A /* HIPMIBadungConnect */,
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||
A30E580F1E4E26A6BD0E3B24 /* Pods */,
|
||||
6C62A8BDDB81F7BE378344ED /* ExpoModulesProviders */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
@@ -79,41 +100,60 @@
|
||||
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* HIPMIBADUNG.app */,
|
||||
13B07F961A680F5B00A75B9A /* HIPMIBadungConnect.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A30E580F1E4E26A6BD0E3B24 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1E94102500A8768C71C74AF6 /* Pods-HIPMIBadungConnect.debug.xcconfig */,
|
||||
C19B4954908DD0D4CD2965DF /* Pods-HIPMIBadungConnect.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BB2F792B24A3F905000567C9 /* Supporting */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BB2F792C24A3F905000567C9 /* Expo.plist */,
|
||||
);
|
||||
name = Supporting;
|
||||
path = HIPMIBADUNG/Supporting;
|
||||
path = HIPMIBadungConnect/Supporting;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C0BA0842F7555AB0104D3227 /* HIPMIBadungConnect */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8F39CC335B3942749573F05 /* ExpoModulesProvider.swift */,
|
||||
);
|
||||
name = HIPMIBadungConnect;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
13B07F861A680F5B00A75B9A /* HIPMIBADUNG */ = {
|
||||
13B07F861A680F5B00A75B9A /* HIPMIBadungConnect */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HIPMIBADUNG" */;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HIPMIBadungConnect" */;
|
||||
buildPhases = (
|
||||
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */,
|
||||
0B90913696EEE0E819CAF510 /* [Expo] Configure project */,
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */,
|
||||
2DA25245F64078F29C0B38E4 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = HIPMIBADUNG;
|
||||
productName = HIPMIBADUNG;
|
||||
productReference = 13B07F961A680F5B00A75B9A /* HIPMIBADUNG.app */;
|
||||
name = HIPMIBadungConnect;
|
||||
productName = HIPMIBadungConnect;
|
||||
productReference = 13B07F961A680F5B00A75B9A /* HIPMIBadungConnect.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
@@ -129,7 +169,7 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "HIPMIBADUNG" */;
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "HIPMIBadungConnect" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
@@ -142,7 +182,7 @@
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* HIPMIBADUNG */,
|
||||
13B07F861A680F5B00A75B9A /* HIPMIBadungConnect */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -155,6 +195,7 @@
|
||||
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */,
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */,
|
||||
241CFEB1CBB2124E18A09822 /* PrivacyInfo.xcprivacy in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -193,33 +234,149 @@
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-HIPMIBADUNG-checkManifestLockResult.txt",
|
||||
"$(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 */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"$(SRCROOT)/.xcode.env",
|
||||
"$(SRCROOT)/.xcode.env.local",
|
||||
"$(SRCROOT)/HIPMIBadungConnect/HIPMIBadungConnect.entitlements",
|
||||
"$(SRCROOT)/Pods/Target Support Files/Pods-HIPMIBadungConnect/expo-configure-project.sh",
|
||||
);
|
||||
name = "[Expo] Configure project";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(SRCROOT)/Pods/Target Support Files/Pods-HIPMIBadungConnect/ExpoModulesProvider.swift",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
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";
|
||||
};
|
||||
2DA25245F64078F29C0B38E4 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-HIPMIBadungConnect/Pods-HIPMIBadungConnect-frameworks.sh",
|
||||
"${BUILT_PRODUCTS_DIR}/MapboxMaps/MapboxMaps.framework",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCommon/MapboxCommon.framework/MapboxCommon",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCoreMaps/MapboxCoreMaps.framework/MapboxCoreMaps",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/React-Core-prebuilt/React.framework/React",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ReactNativeDependencies/ReactNativeDependencies.framework/ReactNativeDependencies",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Turf/Turf.framework/Turf",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxMaps.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCommon.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCoreMaps.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactNativeDependencies.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Turf.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HIPMIBadungConnect/Pods-HIPMIBadungConnect-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-HIPMIBADUNG/Pods-HIPMIBADUNG-resources.sh",
|
||||
"${PODS_ROOT}/Target Support Files/Pods-HIPMIBadungConnect/Pods-HIPMIBadungConnect-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXApplication/ExpoApplication_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXUpdates/EXUpdates.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXNotifications/ExpoNotifications_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoDevice/ExpoDevice_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.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/Entypo.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Feather.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Brands.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Regular.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Solid.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome6_Brands.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome6_Regular.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome6_Solid.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Foundation.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-launcher/EXDevLauncher.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-menu/EXDevMenu.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/react-native-maps/ReactNativeMapsPrivacy.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoApplication_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXUpdates.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoNotifications_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}/ExpoSystemUI_privacy.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}/AntDesign.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Feather.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Brands.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Regular.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Solid.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome6_Brands.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome6_Regular.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome6_Solid.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Fontisto.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Foundation.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Ionicons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialCommunityIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.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}/EXDevMenu.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ReactNativeMapsPrivacy.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HIPMIBADUNG/Pods-HIPMIBADUNG-resources.sh\"\n";
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HIPMIBadungConnect/Pods-HIPMIBadungConnect-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
@@ -230,6 +387,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */,
|
||||
D138B3E4BC618ADDE62DCDCC /* ExpoModulesProvider.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -238,16 +396,19 @@
|
||||
/* Begin XCBuildConfiguration section */
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1E94102500A8768C71C74AF6 /* Pods-HIPMIBadungConnect.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
CODE_SIGN_ENTITLEMENTS = HIPMIBadungConnect/HIPMIBadungConnect.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 2;
|
||||
DEVELOPMENT_TEAM = BMY6GT6W3D;
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"FB_SONARKIT_ENABLED=1",
|
||||
);
|
||||
INFOPLIST_FILE = HIPMIBADUNG/Info.plist;
|
||||
INFOPLIST_FILE = HIPMIBadungConnect/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -259,24 +420,27 @@
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
||||
PRODUCT_NAME = "HIPMIBADUNG";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBADUNG/HIPMIBADUNG-Bridging-Header.h";
|
||||
PRODUCT_NAME = HIPMIBadungConnect;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
CODE_SIGN_ENTITLEMENTS = HIPMIBADUNG/HIPMIBADUNG.entitlements;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = C19B4954908DD0D4CD2965DF /* Pods-HIPMIBadungConnect.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
INFOPLIST_FILE = HIPMIBADUNG/Info.plist;
|
||||
CODE_SIGN_ENTITLEMENTS = HIPMIBadungConnect/HIPMIBadungConnect.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 2;
|
||||
DEVELOPMENT_TEAM = BMY6GT6W3D;
|
||||
INFOPLIST_FILE = HIPMIBadungConnect/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -288,13 +452,13 @@
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
||||
PRODUCT_NAME = "HIPMIBADUNG";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBADUNG/HIPMIBADUNG-Bridging-Header.h";
|
||||
PRODUCT_NAME = HIPMIBadungConnect;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
CODE_SIGN_ENTITLEMENTS = HIPMIBADUNG/HIPMIBADUNG.entitlements;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -350,10 +514,14 @@
|
||||
/usr/lib/swift,
|
||||
"$(inherited)",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "\"$(inherited)\"";
|
||||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"$(inherited)\"";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
|
||||
SWIFT_ENABLE_EXPLICIT_MODULES = NO;
|
||||
USE_HERMES = true;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -402,9 +570,12 @@
|
||||
/usr/lib/swift,
|
||||
"$(inherited)",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "\"$(inherited)\"";
|
||||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"$(inherited)\"";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ENABLE_EXPLICIT_MODULES = NO;
|
||||
USE_HERMES = true;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
@@ -412,7 +583,7 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HIPMIBADUNG" */ = {
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HIPMIBadungConnect" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
13B07F941A680F5B00A75B9A /* Debug */,
|
||||
@@ -421,7 +592,7 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "HIPMIBADUNG" */ = {
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "HIPMIBadungConnect" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83CBBA201A601CBA00E9B192 /* Debug */,
|
||||
@@ -15,9 +15,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "HIPMIBADUNG.app"
|
||||
BlueprintName = "HIPMIBADUNG"
|
||||
ReferencedContainer = "container:HIPMIBADUNG.xcodeproj">
|
||||
BuildableName = "HIPMIBadungConnect.app"
|
||||
BlueprintName = "HIPMIBadungConnect"
|
||||
ReferencedContainer = "container:HIPMIBadungConnect.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
@@ -33,9 +33,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
|
||||
BuildableName = "HIPMIBADUNGTests.xctest"
|
||||
BlueprintName = "HIPMIBADUNGTests"
|
||||
ReferencedContainer = "container:HIPMIBADUNG.xcodeproj">
|
||||
BuildableName = "HIPMIBadungConnectTests.xctest"
|
||||
BlueprintName = "HIPMIBadungConnectTests"
|
||||
ReferencedContainer = "container:HIPMIBadungConnect.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
@@ -55,9 +55,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "HIPMIBADUNG.app"
|
||||
BlueprintName = "HIPMIBADUNG"
|
||||
ReferencedContainer = "container:HIPMIBADUNG.xcodeproj">
|
||||
BuildableName = "HIPMIBadungConnect.app"
|
||||
BlueprintName = "HIPMIBadungConnect"
|
||||
ReferencedContainer = "container:HIPMIBadungConnect.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
@@ -72,9 +72,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "HIPMIBADUNG.app"
|
||||
BlueprintName = "HIPMIBADUNG"
|
||||
ReferencedContainer = "container:HIPMIBADUNG.xcodeproj">
|
||||
BuildableName = "HIPMIBadungConnect.app"
|
||||
BlueprintName = "HIPMIBadungConnect"
|
||||
ReferencedContainer = "container:HIPMIBadungConnect.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
10
ios/HIPMIBadungConnect.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:HIPMIBadungConnect.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||