Compare commits
20 Commits
api-maps/1
...
api-admin/
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d4328a139 | |||
| 125bf16605 | |||
| 73a803f2e8 | |||
| 1bcd1a044f | |||
| 1e0b72de22 | |||
| 36dbfa3296 | |||
| 966e55597c | |||
| 4da55a5a8a | |||
| faf0f36e53 | |||
| 57285e5697 | |||
| 1fd9694ebf | |||
| d31df8c390 | |||
| 90cfb042d8 | |||
| b9f93ff46a | |||
| 0770237fe5 | |||
| 6f4dd79568 | |||
| 9faa0b0f64 | |||
| e05a7c8701 | |||
| f50c5099d8 | |||
| 5f36620988 |
42
.gitignore
vendored
42
.gitignore
vendored
@@ -40,3 +40,45 @@ app-example
|
|||||||
.qodo
|
.qodo
|
||||||
|
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
# @generated expo-cli sync-8d4afeec25ea8a192358fae2f8e2fc766bdce4ec
|
||||||
|
# The following patterns were generated by expo-cli
|
||||||
|
|
||||||
|
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Expo
|
||||||
|
.expo/
|
||||||
|
dist/
|
||||||
|
web-build/
|
||||||
|
expo-env.d.ts
|
||||||
|
|
||||||
|
# Native
|
||||||
|
*.orig.*
|
||||||
|
*.jks
|
||||||
|
*.p8
|
||||||
|
*.p12
|
||||||
|
*.key
|
||||||
|
*.mobileprovision
|
||||||
|
|
||||||
|
# Metro
|
||||||
|
.metro-health-check*
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.*
|
||||||
|
yarn-debug.*
|
||||||
|
yarn-error.*
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# @end expo-cli
|
||||||
@@ -64,9 +64,9 @@ react {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
|
* Set this to true in release builds to optimize the app using [R8](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization).
|
||||||
*/
|
*/
|
||||||
def enableProguardInReleaseBuilds = (findProperty('android.enableProguardInReleaseBuilds') ?: false).toBoolean()
|
def enableMinifyInReleaseBuilds = (findProperty('android.enableMinifyInReleaseBuilds') ?: false).toBoolean()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The preferred build flavor of JavaScriptCore (JSC)
|
* The preferred build flavor of JavaScriptCore (JSC)
|
||||||
@@ -94,6 +94,8 @@ android {
|
|||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0.0"
|
versionName "1.0.0"
|
||||||
|
|
||||||
|
buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
debug {
|
debug {
|
||||||
@@ -111,15 +113,18 @@ android {
|
|||||||
// Caution! In production, you need to generate your own keystore file.
|
// Caution! In production, you need to generate your own keystore file.
|
||||||
// see https://reactnative.dev/docs/signed-apk-android.
|
// see https://reactnative.dev/docs/signed-apk-android.
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false)
|
def enableShrinkResources = findProperty('android.enableShrinkResourcesInReleaseBuilds') ?: 'false'
|
||||||
minifyEnabled enableProguardInReleaseBuilds
|
shrinkResources enableShrinkResources.toBoolean()
|
||||||
|
minifyEnabled enableMinifyInReleaseBuilds
|
||||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||||
crunchPngs (findProperty('android.enablePngCrunchInReleaseBuilds')?.toBoolean() ?: true)
|
def enablePngCrunchInRelease = findProperty('android.enablePngCrunchInReleaseBuilds') ?: 'true'
|
||||||
|
crunchPngs enablePngCrunchInRelease.toBoolean()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
packagingOptions {
|
packagingOptions {
|
||||||
jniLibs {
|
jniLibs {
|
||||||
useLegacyPackaging (findProperty('expo.useLegacyPackaging')?.toBoolean() ?: false)
|
def enableLegacyPackaging = findProperty('expo.useLegacyPackaging') ?: 'false'
|
||||||
|
useLegacyPackaging enableLegacyPackaging.toBoolean()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
androidResources {
|
androidResources {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<data android:scheme="https"/>
|
<data android:scheme="https"/>
|
||||||
</intent>
|
</intent>
|
||||||
</queries>
|
</queries>
|
||||||
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true">
|
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true" android:enableOnBackInvokedCallback="false">
|
||||||
<meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
|
<meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
|
||||||
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
|
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
|
||||||
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
|
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import android.content.res.Configuration
|
|||||||
|
|
||||||
import com.facebook.react.PackageList
|
import com.facebook.react.PackageList
|
||||||
import com.facebook.react.ReactApplication
|
import com.facebook.react.ReactApplication
|
||||||
|
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
|
||||||
import com.facebook.react.ReactNativeHost
|
import com.facebook.react.ReactNativeHost
|
||||||
import com.facebook.react.ReactPackage
|
import com.facebook.react.ReactPackage
|
||||||
import com.facebook.react.ReactHost
|
import com.facebook.react.ReactHost
|
||||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
|
import com.facebook.react.common.ReleaseLevel
|
||||||
|
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
|
||||||
import com.facebook.react.defaults.DefaultReactNativeHost
|
import com.facebook.react.defaults.DefaultReactNativeHost
|
||||||
import com.facebook.react.soloader.OpenSourceMergedSoMapping
|
|
||||||
import com.facebook.soloader.SoLoader
|
|
||||||
|
|
||||||
import expo.modules.ApplicationLifecycleDispatcher
|
import expo.modules.ApplicationLifecycleDispatcher
|
||||||
import expo.modules.ReactNativeHostWrapper
|
import expo.modules.ReactNativeHostWrapper
|
||||||
@@ -19,21 +19,19 @@ import expo.modules.ReactNativeHostWrapper
|
|||||||
class MainApplication : Application(), ReactApplication {
|
class MainApplication : Application(), ReactApplication {
|
||||||
|
|
||||||
override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(
|
override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(
|
||||||
this,
|
this,
|
||||||
object : DefaultReactNativeHost(this) {
|
object : DefaultReactNativeHost(this) {
|
||||||
override fun getPackages(): List<ReactPackage> {
|
override fun getPackages(): List<ReactPackage> =
|
||||||
val packages = PackageList(this).packages
|
PackageList(this).packages.apply {
|
||||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||||
// packages.add(MyReactNativePackage())
|
// add(MyReactNativePackage())
|
||||||
return packages
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun getJSMainModuleName(): String = ".expo/.virtual-metro-entry"
|
override fun getJSMainModuleName(): String = ".expo/.virtual-metro-entry"
|
||||||
|
|
||||||
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
|
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
|
||||||
|
|
||||||
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
||||||
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,11 +40,12 @@ class MainApplication : Application(), ReactApplication {
|
|||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
SoLoader.init(this, OpenSourceMergedSoMapping)
|
DefaultNewArchitectureEntryPoint.releaseLevel = try {
|
||||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
ReleaseLevel.valueOf(BuildConfig.REACT_NATIVE_RELEASE_LEVEL.uppercase())
|
||||||
// If you opted-in for the New Architecture, we load the native entry point for this app.
|
} catch (e: IllegalArgumentException) {
|
||||||
load()
|
ReleaseLevel.STABLE
|
||||||
}
|
}
|
||||||
|
loadReactNative(this)
|
||||||
ApplicationLifecycleDispatcher.onApplicationCreate(this)
|
ApplicationLifecycleDispatcher.onApplicationCreate(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<style name="AppTheme" parent="Theme.EdgeToEdge">
|
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||||
|
<item name="android:enforceNavigationBarContrast" tools:targetApi="29">true</item>
|
||||||
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="android:statusBarColor">#ffffff</item>
|
<item name="android:statusBarColor">#ffffff</item>
|
||||||
@@ -8,5 +9,6 @@
|
|||||||
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
|
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
|
||||||
<item name="windowSplashScreenAnimatedIcon">@drawable/splashscreen_logo</item>
|
<item name="windowSplashScreenAnimatedIcon">@drawable/splashscreen_logo</item>
|
||||||
<item name="postSplashScreenTheme">@style/AppTheme</item>
|
<item name="postSplashScreenTheme">@style/AppTheme</item>
|
||||||
|
<item name="android:windowSplashScreenBehavior">icon_preferred</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -12,21 +12,8 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def reactNativeAndroidDir = new File(
|
|
||||||
providers.exec {
|
|
||||||
workingDir(rootDir)
|
|
||||||
commandLine("node", "--print", "require.resolve('react-native/package.json')")
|
|
||||||
}.standardOutput.asText.get().trim(),
|
|
||||||
"../android"
|
|
||||||
)
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
|
||||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
|
||||||
url(reactNativeAndroidDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url 'https://www.jitpack.io' }
|
maven { url 'https://www.jitpack.io' }
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
|
|||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
# org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
|
|
||||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||||
# Android operating system, and which are packaged with your app's APK
|
# Android operating system, and which are packaged with your app's APK
|
||||||
@@ -41,6 +41,11 @@ newArchEnabled=true
|
|||||||
# If set to false, you will be using JSC instead.
|
# If set to false, you will be using JSC instead.
|
||||||
hermesEnabled=true
|
hermesEnabled=true
|
||||||
|
|
||||||
|
# Use this property to enable edge-to-edge display support.
|
||||||
|
# This allows your app to draw behind system bars for an immersive UI.
|
||||||
|
# Note: Only works with ReactActivity and should not be used with custom Activity.
|
||||||
|
edgeToEdgeEnabled=true
|
||||||
|
|
||||||
# Enable GIF support in React Native images (~200 B increase)
|
# Enable GIF support in React Native images (~200 B increase)
|
||||||
expo.gif.enabled=true
|
expo.gif.enabled=true
|
||||||
# Enable webp support in React Native images (~85 KB increase)
|
# Enable webp support in React Native images (~85 KB increase)
|
||||||
@@ -55,5 +60,6 @@ EX_DEV_CLIENT_NETWORK_INSPECTOR=true
|
|||||||
# Use legacy packaging to compress native libraries in the resulting APK.
|
# Use legacy packaging to compress native libraries in the resulting APK.
|
||||||
expo.useLegacyPackaging=false
|
expo.useLegacyPackaging=false
|
||||||
|
|
||||||
# Whether the app is configured to use edge-to-edge via the app config or `react-native-edge-to-edge` plugin
|
# Specifies whether the app is configured to use edge-to-edge via the app config or plugin
|
||||||
expo.edgeToEdgeEnabled=true
|
# WARNING: This property has been deprecated and will be removed in Expo SDK 55. Use `edgeToEdgeEnabled` or `react.edgeToEdgeEnabled` to determine whether the project is using edge-to-edge.
|
||||||
|
expo.edgeToEdgeEnabled=true
|
||||||
|
|||||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
4
android/gradlew
vendored
4
android/gradlew
vendored
@@ -114,7 +114,7 @@ case "$( uname )" in #(
|
|||||||
NONSTOP* ) nonstop=true ;;
|
NONSTOP* ) nonstop=true ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH="\\\"\\\""
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
@@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
-classpath "$CLASSPATH" \
|
-classpath "$CLASSPATH" \
|
||||||
org.gradle.wrapper.GradleWrapperMain \
|
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
# Stop when "xargs" is not available.
|
# Stop when "xargs" is not available.
|
||||||
|
|||||||
4
android/gradlew.bat
vendored
4
android/gradlew.bat
vendored
@@ -70,11 +70,11 @@ goto fail
|
|||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
set CLASSPATH=
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@rem Execute Gradle
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
|||||||
@@ -70,5 +70,6 @@ export default {
|
|||||||
// Tambahkan environment variables ke sini
|
// Tambahkan environment variables ke sini
|
||||||
API_BASE_URL: process.env.API_BASE_URL,
|
API_BASE_URL: process.env.API_BASE_URL,
|
||||||
BASE_URL: process.env.BASE_URL,
|
BASE_URL: process.env.BASE_URL,
|
||||||
|
DEEP_LINK_URL: process.env.DEEP_LINK_URL,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -19,7 +19,6 @@ import Toast from "react-native-toast-message";
|
|||||||
|
|
||||||
export default function CollaborationEdit() {
|
export default function CollaborationEdit() {
|
||||||
const { id } = useLocalSearchParams();
|
const { id } = useLocalSearchParams();
|
||||||
console.log("id :", id);
|
|
||||||
const [data, setData] = useState<any>();
|
const [data, setData] = useState<any>();
|
||||||
const [listMaster, setListMaster] = useState<any[]>([]);
|
const [listMaster, setListMaster] = useState<any[]>([]);
|
||||||
const [loadingData, setLoadingData] = useState(false);
|
const [loadingData, setLoadingData] = useState(false);
|
||||||
|
|||||||
@@ -16,20 +16,19 @@ import Donation_ComponentInfoFundrising from "@/screens/Donation/ComponentInfoFu
|
|||||||
import Donation_ComponentStoryFunrising from "@/screens/Donation/ComponentStoryFunrising";
|
import Donation_ComponentStoryFunrising from "@/screens/Donation/ComponentStoryFunrising";
|
||||||
import Donation_ProgressSection from "@/screens/Donation/ProgressSection";
|
import Donation_ProgressSection from "@/screens/Donation/ProgressSection";
|
||||||
import { apiDonationGetOne } from "@/service/api-client/api-donation";
|
import { apiDonationGetOne } from "@/service/api-client/api-donation";
|
||||||
|
import { countDownAndCondition } from "@/utils/countDownAndCondition";
|
||||||
import {
|
import {
|
||||||
router,
|
router,
|
||||||
Stack,
|
Stack,
|
||||||
useFocusEffect,
|
useFocusEffect,
|
||||||
useLocalSearchParams,
|
useLocalSearchParams,
|
||||||
} from "expo-router";
|
} from "expo-router";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
export default function DonasiDetailBeranda() {
|
export default function DonasiDetailBeranda() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const { id } = useLocalSearchParams();
|
const { id } = useLocalSearchParams();
|
||||||
console.log("ID ", id);
|
|
||||||
const [openDrawer, setOpenDrawer] = useState(false);
|
const [openDrawer, setOpenDrawer] = useState(false);
|
||||||
|
|
||||||
const [data, setData] = useState<any>();
|
const [data, setData] = useState<any>();
|
||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
@@ -45,21 +44,41 @@ export default function DonasiDetailBeranda() {
|
|||||||
category: "permanent",
|
category: "permanent",
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("[RES GET ONE]", JSON.stringify(response.data, null, 2));
|
|
||||||
|
|
||||||
setData(response.data);
|
setData(response.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[ERROR]", 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 = (
|
const buttonSection = (
|
||||||
<>
|
<>
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
|
disabled={value?.reminder}
|
||||||
onPress={() => router.navigate(`/donation/${id}/(transaction-flow)`)}
|
onPress={() => router.navigate(`/donation/${id}/(transaction-flow)`)}
|
||||||
>
|
>
|
||||||
Donasi
|
{value?.reminder ? "Waktu berakhir" : "Donasi"}
|
||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
</BoxButtonOnFooter>
|
</BoxButtonOnFooter>
|
||||||
</>
|
</>
|
||||||
@@ -80,6 +99,8 @@ export default function DonasiDetailBeranda() {
|
|||||||
<ViewWrapper footerComponent={buttonSection}>
|
<ViewWrapper footerComponent={buttonSection}>
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
<Donation_ComponentBoxDetailData
|
<Donation_ComponentBoxDetailData
|
||||||
|
sisaHari={value.sisa}
|
||||||
|
reminder={value.reminder}
|
||||||
data={data}
|
data={data}
|
||||||
bottomSection={<Donation_ProgressSection id={id as string} />}
|
bottomSection={<Donation_ProgressSection id={id as string} />}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ export default function EventBeranda() {
|
|||||||
<TextCustom align="center">Belum ada event</TextCustom>
|
<TextCustom align="center">Belum ada event</TextCustom>
|
||||||
) : (
|
) : (
|
||||||
listData.map((item: any, index) => (
|
listData.map((item: any, index) => (
|
||||||
|
|
||||||
|
|
||||||
<Event_BoxPublishSection
|
<Event_BoxPublishSection
|
||||||
key={index}
|
key={index}
|
||||||
href={`/event/${item.id}/publish`}
|
href={`/event/${item.id}/publish`}
|
||||||
|
|||||||
554
app/(application)/(user)/event/[id]/confirmation.tsx
Normal file
554
app/(application)/(user)/event/[id]/confirmation.tsx
Normal file
@@ -0,0 +1,554 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import {
|
||||||
|
BaseBox,
|
||||||
|
ButtonCustom,
|
||||||
|
CenterCustom,
|
||||||
|
LoaderCustom,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
|
ViewWrapper,
|
||||||
|
} from "@/components";
|
||||||
|
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||||
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
|
import {
|
||||||
|
apiEventConfirmationAction,
|
||||||
|
apiEventGetConfirmation,
|
||||||
|
apiEventJoin,
|
||||||
|
} from "@/service/api-client/api-event";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import isBetween from "dayjs/plugin/isBetween";
|
||||||
|
import {
|
||||||
|
Redirect,
|
||||||
|
router,
|
||||||
|
Stack,
|
||||||
|
useFocusEffect,
|
||||||
|
useLocalSearchParams,
|
||||||
|
} from "expo-router";
|
||||||
|
import React, { useCallback, useState } from "react";
|
||||||
|
import { View } from "react-native";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
|
// Extend Day.js dengan plugin isBetween
|
||||||
|
dayjs.extend(isBetween);
|
||||||
|
|
||||||
|
interface DataEvent {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
tanggal: Date;
|
||||||
|
tanggalSelesai: Date;
|
||||||
|
lokasi: string;
|
||||||
|
Author: {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
Profile: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function UserEventConfirmation() {
|
||||||
|
const { token } = useAuth();
|
||||||
|
const { id, userId: authorId } = useLocalSearchParams();
|
||||||
|
const { user } = useAuth();
|
||||||
|
const [data, setData] = useState<DataEvent | null>(null);
|
||||||
|
const [peserta, setPeserta] = useState<boolean | null>(null);
|
||||||
|
const [konfirmasi, setKonfirmasi] = useState<boolean | null>(null);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
checkTokenAndDataParticipants() || console.log("Token is null");
|
||||||
|
}, [token, id, user?.id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const checkTokenAndDataParticipants = async () => {
|
||||||
|
if (!token) {
|
||||||
|
return <Redirect href={`/`} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await apiEventGetConfirmation({
|
||||||
|
id: id as string,
|
||||||
|
userId: user?.id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data?.dataEvent);
|
||||||
|
setPeserta(response.data?.peserta);
|
||||||
|
setKonfirmasi(response.data?.kehadiran);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR CONFIRMATION]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlerReturn = () => {
|
||||||
|
const now = dayjs(); // asumsi: UTC, sesuai dengan API
|
||||||
|
|
||||||
|
// --- [1] Loading & Data tidak ditemukan ---
|
||||||
|
if (data === undefined || data === null) {
|
||||||
|
if (peserta === null && konfirmasi === null) {
|
||||||
|
return <LoaderCustom />;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<BaseBox>
|
||||||
|
<TextCustom bold align="center" size={"large"}>
|
||||||
|
Data Tidak Ditemukan
|
||||||
|
</TextCustom>
|
||||||
|
<BackToOtherPath path="home" />
|
||||||
|
</BaseBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- [2] Ambil waktu event dari `data` ---
|
||||||
|
const eventStart = dayjs(data.tanggal);
|
||||||
|
const eventEnd = dayjs(data.tanggalSelesai);
|
||||||
|
|
||||||
|
// --- [3] Definisikan jendela konfirmasi: 1 jam sebelum mulai → 1 jam setelah selesai ---
|
||||||
|
const confirmationStart = eventStart.subtract(1, "hour");
|
||||||
|
const confirmationEnd = eventEnd.add(1, "hour");
|
||||||
|
const isWithinConfirmationWindow = now.isBetween(
|
||||||
|
confirmationStart,
|
||||||
|
confirmationEnd,
|
||||||
|
null,
|
||||||
|
"[]"
|
||||||
|
);
|
||||||
|
|
||||||
|
// --- [4] Status waktu event (untuk pesan UI) ---
|
||||||
|
const isBeforeEvent = now.isBefore(eventStart);
|
||||||
|
const isAfterEvent = now.isAfter(eventEnd);
|
||||||
|
const isDuringEvent = !isBeforeEvent && !isAfterEvent;
|
||||||
|
|
||||||
|
// --- [5] Handle berdasarkan waktu dan status peserta/konfirmasi ---
|
||||||
|
|
||||||
|
// 🟢 Acara sudah selesai
|
||||||
|
if (isAfterEvent) {
|
||||||
|
if (peserta === false) {
|
||||||
|
return (
|
||||||
|
<TamplateBox data={data}>
|
||||||
|
<TamplateText text="Event telah selesai, sehingga konfirmasi kehadiran sudah tidak dapat dilakukan. Terima kasih atas perhatian dan minat Anda. Kami berharap dapat bertemu di acara kami berikutnya." />
|
||||||
|
<BackToOtherPath
|
||||||
|
path="event"
|
||||||
|
id={data.id}
|
||||||
|
isAfterEvent={isAfterEvent}
|
||||||
|
/>
|
||||||
|
</TamplateBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<TamplateBox data={data}>
|
||||||
|
<TamplateText
|
||||||
|
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.`}
|
||||||
|
/>
|
||||||
|
<BackToOtherPath
|
||||||
|
path="event"
|
||||||
|
id={data.id}
|
||||||
|
isAfterEvent={isAfterEvent}
|
||||||
|
/>
|
||||||
|
</TamplateBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔵 Acara belum mulai & belum terdaftar
|
||||||
|
if (isBeforeEvent) {
|
||||||
|
if (peserta === false) {
|
||||||
|
return (
|
||||||
|
<NotStarted_And_UserNotParticipan
|
||||||
|
id={data.id}
|
||||||
|
userId={user?.id as string}
|
||||||
|
data={data}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Peserta sudah daftar → cek apakah sudah boleh konfirmasi
|
||||||
|
if (isWithinConfirmationWindow && peserta === true) {
|
||||||
|
if (konfirmasi === false) {
|
||||||
|
return (
|
||||||
|
<UserParticipan_And_DuringEvent
|
||||||
|
id={data.id}
|
||||||
|
userId={user?.id as string}
|
||||||
|
data={data}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<TamplateBox data={data}>
|
||||||
|
<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}
|
||||||
|
isAfterEvent={isAfterEvent}
|
||||||
|
/>
|
||||||
|
</TamplateBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TamplateBox data={data}>
|
||||||
|
<TamplateText text="Anda telah terdaftar sebagai peserta pada Event ini. Konfirmasi kehadiran dibuka 1 jam sebelum acara dimulai." />
|
||||||
|
<BackToOtherPath
|
||||||
|
path="event"
|
||||||
|
id={data.id}
|
||||||
|
isAfterEvent={isAfterEvent}
|
||||||
|
/>
|
||||||
|
</TamplateBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🟡 Acara sedang berlangsung & belum terdaftar
|
||||||
|
if (isDuringEvent) {
|
||||||
|
if (peserta === false) {
|
||||||
|
return (
|
||||||
|
<UserNotParticipan_And_DuringEvent
|
||||||
|
id={data.id}
|
||||||
|
userId={user?.id as string}
|
||||||
|
data={data}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peserta === true) {
|
||||||
|
if (isWithinConfirmationWindow) {
|
||||||
|
if (konfirmasi === false) {
|
||||||
|
return (
|
||||||
|
<TamplateBox data={data}>
|
||||||
|
<TamplateText text="Konfirmasi Kehadiran" />
|
||||||
|
</TamplateBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<TamplateBox data={data}>
|
||||||
|
<TamplateText text="Anda telah mengonfirmasi kehadiran dalam event ini. Terima kasih dan selamat menikmati acara. Have fun!" />
|
||||||
|
<BackToOtherPath
|
||||||
|
path="event"
|
||||||
|
id={data.id}
|
||||||
|
isAfterEvent={isAfterEvent}
|
||||||
|
/>
|
||||||
|
</TamplateBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ini sangat jarang terjadi selama event berlangsung, tapi aman
|
||||||
|
return (
|
||||||
|
<TamplateBox data={data}>
|
||||||
|
<TamplateText text="Konfirmasi kehadiran tidak tersedia saat ini." />
|
||||||
|
<BackToOtherPath path="home" />
|
||||||
|
</TamplateBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🛑 Fallback aman
|
||||||
|
return (
|
||||||
|
<BaseBox>
|
||||||
|
<StackCustom>
|
||||||
|
<TamplateText text="Terjadi kesalahan tak terduga pada logika waktu." />
|
||||||
|
<BackToOtherPath path="home" />
|
||||||
|
</StackCustom>
|
||||||
|
</BaseBox>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Stack.Screen
|
||||||
|
options={{
|
||||||
|
title: "Konfirmasi Event",
|
||||||
|
headerLeft: () => (
|
||||||
|
<Ionicons
|
||||||
|
name="arrow-back"
|
||||||
|
size={20}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
onPress={() =>
|
||||||
|
router.navigate("/(application)/(user)/event/create")
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ViewWrapper>{handlerReturn()}</ViewWrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const TamplateBox = ({
|
||||||
|
data,
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
data: DataEvent;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<CenterCustom>
|
||||||
|
<BaseBox>
|
||||||
|
<StackCustom gap={"lg"}>
|
||||||
|
<StackCustom gap={"sm"}>
|
||||||
|
<TextCustom bold align="center" size={"large"}>
|
||||||
|
{data?.title}
|
||||||
|
</TextCustom>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "center",
|
||||||
|
// backgroundColor: AccentColor.blue,
|
||||||
|
// borderColor: AccentColor.blue,
|
||||||
|
// borderWidth: 1,
|
||||||
|
// borderRadius: 4,
|
||||||
|
// padding: 3
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextCustom align="center" size="small" bold>
|
||||||
|
{dayjs(data?.tanggal).format("DD MMM YYYY: HH:mm")}
|
||||||
|
</TextCustom>
|
||||||
|
<TextCustom align="center" size="small" bold>
|
||||||
|
{" "}
|
||||||
|
-{" "}
|
||||||
|
</TextCustom>
|
||||||
|
<TextCustom align="center" size="small" bold>
|
||||||
|
{dayjs(data?.tanggalSelesai).format("DD MMM YYYY: HH:mm")}
|
||||||
|
</TextCustom>
|
||||||
|
</View>
|
||||||
|
</StackCustom>
|
||||||
|
|
||||||
|
{children}
|
||||||
|
</StackCustom>
|
||||||
|
</BaseBox>
|
||||||
|
</CenterCustom>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const TamplateText = ({ text }: { text: React.ReactNode }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TextCustom align="center">{text}</TextCustom>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type BackToOtherPathProps =
|
||||||
|
| { path: "home" | "beranda-event"; id?: never; isAfterEvent?: never }
|
||||||
|
| { path: "event"; id: string; isAfterEvent: boolean };
|
||||||
|
|
||||||
|
const BackToOtherPath = ({ path, id, isAfterEvent }: BackToOtherPathProps) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{path === "home" ? (
|
||||||
|
<ButtonCustom
|
||||||
|
onPress={() => {
|
||||||
|
router.replace("/(application)/home");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Home
|
||||||
|
</ButtonCustom>
|
||||||
|
) : (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
gap: 10,
|
||||||
|
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ButtonCustom
|
||||||
|
onPress={() => {
|
||||||
|
router.replace("/(application)/home");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Home
|
||||||
|
</ButtonCustom>
|
||||||
|
<ButtonCustom
|
||||||
|
onPress={() => {
|
||||||
|
if (path === "event") {
|
||||||
|
if (isAfterEvent) {
|
||||||
|
router.push(`/(application)/(user)/event/${id}/history`);
|
||||||
|
} else {
|
||||||
|
router.push(`/(application)/(user)/event/${id}/publish`);
|
||||||
|
}
|
||||||
|
} else if (path === "beranda-event") {
|
||||||
|
router.push(`/(application)/(user)/event`);
|
||||||
|
} else {
|
||||||
|
console.log("[PATH]", path);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Lihat {path === "event" ? "Event" : "Beranda Event"}
|
||||||
|
</ButtonCustom>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 🔵 Acara belum mulai & belum terdaftar
|
||||||
|
const NotStarted_And_UserNotParticipan = ({
|
||||||
|
id,
|
||||||
|
userId,
|
||||||
|
data,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
data: DataEvent;
|
||||||
|
}) => {
|
||||||
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const handlerJoinEvent = async () => {
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
|
const response = await apiEventJoin({
|
||||||
|
id: id as string,
|
||||||
|
userId: userId as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Anda gagal join",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Anda berhasil join",
|
||||||
|
});
|
||||||
|
router.navigate(`/(application)/(user)/event/${id}/publish`);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR JOIN EVENT]", error);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TamplateBox data={data}>
|
||||||
|
<TamplateText text="Anda belum terdaftar sebagai peserta & Event belum dimulai. Silahkan daftarkan diri anda terlebih dahulu" />
|
||||||
|
<ButtonCustom onPress={handlerJoinEvent} isLoading={isLoading}>
|
||||||
|
Join
|
||||||
|
</ButtonCustom>
|
||||||
|
</TamplateBox>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 🟡 ZONA ACARA BERLANGSUNG
|
||||||
|
// Acara sedang berlangsung & belum terdaftar & user harus join dan konfirmasi
|
||||||
|
const UserNotParticipan_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: "join_and_confirm",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Anda gagal join & konfirmasi",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Anda berhasil join & 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 belum terdaftar sebagai peserta & Event sedang berlangsung. Silahkan daftarkan diri anda & Konfirmasi kehadiran" />
|
||||||
|
|
||||||
|
<ButtonCustom onPress={() => handlerSubmit()} isLoading={isLoading}>
|
||||||
|
Join & Konfirmasi
|
||||||
|
</ButtonCustom>
|
||||||
|
</TamplateBox>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 🟡 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,
|
apiEventGetOne,
|
||||||
apiEventListOfParticipants,
|
apiEventListOfParticipants,
|
||||||
} from "@/service/api-client/api-event";
|
} from "@/service/api-client/api-event";
|
||||||
import { useLocalSearchParams } from "expo-router";
|
import dayjs, { Dayjs } from "dayjs";
|
||||||
import { useEffect, useState } from "react";
|
import { useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
|
|
||||||
export default function EventListOfParticipants() {
|
export default function EventListOfParticipants() {
|
||||||
const { id } = useLocalSearchParams();
|
const { id } = useLocalSearchParams();
|
||||||
const [startDate, setStartDate] = useState();
|
const [startDate, setStartDate] = useState<Dayjs | undefined>();
|
||||||
const [listData, setListData] = useState([]);
|
const [listData, setListData] = useState<any[] | null>(null);
|
||||||
const [isLoadData, setIsLoadData] = useState(false);
|
const [loadtData, setLoadData] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useFocusEffect(
|
||||||
handlerLoadData();
|
useCallback(() => {
|
||||||
}, [id]);
|
handlerLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
const handlerLoadData = () => {
|
const handlerLoadData = () => {
|
||||||
try {
|
try {
|
||||||
setIsLoadData(true);
|
|
||||||
onLoadData();
|
onLoadData();
|
||||||
onLoadList();
|
onLoadList();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[ERROR]", error);
|
console.log("[ERROR]", error);
|
||||||
} finally {
|
|
||||||
setIsLoadData(false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,7 +42,8 @@ export default function EventListOfParticipants() {
|
|||||||
try {
|
try {
|
||||||
const response = await apiEventGetOne({ id: id as string });
|
const response = await apiEventGetOne({ id: id as string });
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setStartDate(response.data.tanggal);
|
const date = dayjs(response.data.tanggal);
|
||||||
|
setStartDate(date);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[ERROR]", error);
|
console.log("[ERROR]", error);
|
||||||
@@ -50,30 +52,36 @@ export default function EventListOfParticipants() {
|
|||||||
|
|
||||||
const onLoadList = async () => {
|
const onLoadList = async () => {
|
||||||
try {
|
try {
|
||||||
|
setLoadData(true);
|
||||||
const response = await apiEventListOfParticipants({ id: id as string });
|
const response = await apiEventListOfParticipants({ id: id as string });
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setListData(response.data);
|
setListData(response.data);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[ERROR]", error);
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadData(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ViewWrapper>
|
<ViewWrapper>
|
||||||
{isLoadData ? (
|
{loadtData && !listData ? (
|
||||||
<LoaderCustom />
|
<LoaderCustom />
|
||||||
) : listData.length === 0 ? (
|
) : _.isEmpty(listData) ? (
|
||||||
<TextCustom align="center">Belum ada peserta</TextCustom>
|
<TextCustom align="center" color="gray">
|
||||||
|
Belum ada peserta
|
||||||
|
</TextCustom>
|
||||||
) : (
|
) : (
|
||||||
listData.map((item: any, index: number) => (
|
listData?.map((item: any, index: number) => (
|
||||||
<BaseBox key={index}>
|
<BaseBox key={index}>
|
||||||
<AvatarUsernameAndOtherComponent
|
<AvatarUsernameAndOtherComponent
|
||||||
avatar={item?.User?.Profile?.imageId}
|
avatar={item?.User?.Profile?.imageId}
|
||||||
name={item?.User?.username}
|
name={item?.User?.username}
|
||||||
avatarHref={`/profile/${item?.User?.Profile?.id}`}
|
avatarHref={`/profile/${item?.User?.Profile?.id}`}
|
||||||
rightComponent={
|
rightComponent={
|
||||||
new Date().getTime() > new Date(startDate as any).getTime() ? (
|
startDate && startDate.subtract(1, "hour").diff(dayjs()) < 0 ? (
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
justifyContent: "flex-end",
|
justifyContent: "flex-end",
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ export default function EventDetailPublish() {
|
|||||||
userId: user?.id as string,
|
userId: user?.id as string,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("[RES CHECK PARTICIPANTS]", responseCheckParticipants);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
responseCheckParticipants.success &&
|
responseCheckParticipants.success &&
|
||||||
responseCheckParticipants.data
|
responseCheckParticipants.data
|
||||||
@@ -69,6 +71,8 @@ export default function EventDetailPublish() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("[participans]", isParticipant);
|
||||||
|
|
||||||
const handlePress = (item: IMenuDrawerItem) => {
|
const handlePress = (item: IMenuDrawerItem) => {
|
||||||
console.log("PATH ", item.path);
|
console.log("PATH ", item.path);
|
||||||
router.navigate(item.path as any);
|
router.navigate(item.path as any);
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ export default function EventCreate() {
|
|||||||
placeholder="Masukkan deskripsi event"
|
placeholder="Masukkan deskripsi event"
|
||||||
required
|
required
|
||||||
showCount
|
showCount
|
||||||
maxLength={100}
|
maxLength={1000}
|
||||||
onChangeText={(value: any) =>
|
onChangeText={(value: any) =>
|
||||||
setData({ ...data, deskripsi: value })
|
setData({ ...data, deskripsi: value })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { IconEdit } from "@/components/_Icon";
|
import { IconEdit } from "@/components/_Icon";
|
||||||
import { IMenuDrawerItem } from "@/components/_Interface/types";
|
import { IMenuDrawerItem } from "@/components/_Interface/types";
|
||||||
|
import ReportBox from "@/components/Box/ReportBox";
|
||||||
import Job_BoxDetailSection from "@/screens/Job/BoxDetailSection";
|
import Job_BoxDetailSection from "@/screens/Job/BoxDetailSection";
|
||||||
import Job_ButtonStatusSection from "@/screens/Job/ButtonStatusSection";
|
import Job_ButtonStatusSection from "@/screens/Job/ButtonStatusSection";
|
||||||
import { apiJobGetOne } from "@/service/api-client/api-job";
|
import { apiJobGetOne } from "@/service/api-client/api-job";
|
||||||
@@ -70,7 +71,13 @@ export default function JobDetailStatus() {
|
|||||||
<LoaderCustom />
|
<LoaderCustom />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<StackCustom>
|
<StackCustom gap={"xs"}>
|
||||||
|
{data &&
|
||||||
|
data?.catatan &&
|
||||||
|
(status === "draft" || status === "rejected") && (
|
||||||
|
<ReportBox text={data?.catatan} />
|
||||||
|
)}
|
||||||
|
|
||||||
<Job_BoxDetailSection data={data} />
|
<Job_BoxDetailSection data={data} />
|
||||||
<Job_ButtonStatusSection
|
<Job_ButtonStatusSection
|
||||||
id={id as string}
|
id={id as string}
|
||||||
|
|||||||
@@ -102,11 +102,13 @@ export default function Portofolio() {
|
|||||||
<Portofolio_SocialMediaSection
|
<Portofolio_SocialMediaSection
|
||||||
data={data?.Portofolio_MediaSosial}
|
data={data?.Portofolio_MediaSosial}
|
||||||
/>
|
/>
|
||||||
<Portofolio_ButtonDelete
|
{data?.Profile?.id !== profileId ? null : (
|
||||||
id={id as string}
|
<Portofolio_ButtonDelete
|
||||||
isLoadingDelete={isLoadingDelete}
|
id={id as string}
|
||||||
setIsLoadingDelete={setIsLoadingDelete}
|
isLoadingDelete={isLoadingDelete}
|
||||||
/>
|
setIsLoadingDelete={setIsLoadingDelete}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<Spacing />
|
<Spacing />
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export default function Profile() {
|
|||||||
const [dataToken, setDataToken] = useState<IProfile>();
|
const [dataToken, setDataToken] = useState<IProfile>();
|
||||||
const [listPortofolio, setListPortofolio] = useState<any[]>();
|
const [listPortofolio, setListPortofolio] = useState<any[]>();
|
||||||
|
|
||||||
const { logout, isAdmin, user } = useAuth();
|
const { token, logout, isAdmin, user, userData } = useAuth();
|
||||||
|
|
||||||
const openDrawer = () => {
|
const openDrawer = () => {
|
||||||
setIsDrawerOpen(true);
|
setIsDrawerOpen(true);
|
||||||
@@ -42,7 +42,8 @@ export default function Profile() {
|
|||||||
onLoadPortofolio(id as string);
|
onLoadPortofolio(id as string);
|
||||||
onLoadUserByToken();
|
onLoadUserByToken();
|
||||||
isUserCheck();
|
isUserCheck();
|
||||||
}, [id])
|
userData(token as string);
|
||||||
|
}, [id, token])
|
||||||
);
|
);
|
||||||
|
|
||||||
const isUserCheck = () => {
|
const isUserCheck = () => {
|
||||||
@@ -136,10 +137,7 @@ const ButtonnDot = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const isId = id === undefined || id === null;
|
const isId = id === undefined || id === null;
|
||||||
|
|
||||||
console.log("ID CHECK", id);
|
|
||||||
|
|
||||||
if (isId) {
|
if (isId) {
|
||||||
console.log("ID UNDEFINED", id);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TouchableOpacity onPress={logout}>
|
<TouchableOpacity onPress={logout}>
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import {
|
|||||||
LoaderCustom,
|
LoaderCustom,
|
||||||
MenuDrawerDynamicGrid,
|
MenuDrawerDynamicGrid,
|
||||||
Spacing,
|
Spacing,
|
||||||
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { IconArchive, IconContribution, IconEdit } from "@/components/_Icon";
|
import { IconArchive, IconContribution, IconEdit } from "@/components/_Icon";
|
||||||
import { IMenuDrawerItem } from "@/components/_Interface/types";
|
import { IMenuDrawerItem } from "@/components/_Interface/types";
|
||||||
|
import ReportBox from "@/components/Box/ReportBox";
|
||||||
import Voting_BoxDetailHasilVotingSection from "@/screens/Voting/BoxDetailHasilVotingSection";
|
import Voting_BoxDetailHasilVotingSection from "@/screens/Voting/BoxDetailHasilVotingSection";
|
||||||
import { Voting_BoxDetailSection } from "@/screens/Voting/BoxDetailSection";
|
import { Voting_BoxDetailSection } from "@/screens/Voting/BoxDetailSection";
|
||||||
import Voting_ButtonStatusSection from "@/screens/Voting/ButtonStatusSection";
|
import Voting_ButtonStatusSection from "@/screens/Voting/ButtonStatusSection";
|
||||||
@@ -49,6 +51,8 @@ export default function VotingDetailStatus() {
|
|||||||
setLoadingGetData(true);
|
setLoadingGetData(true);
|
||||||
const response = await apiVotingGetOne({ id: id as string });
|
const response = await apiVotingGetOne({ id: id as string });
|
||||||
|
|
||||||
|
console.log("[DATA BY ID]", JSON.stringify(response, null, 2));
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setData(response.data);
|
setData(response.data);
|
||||||
}
|
}
|
||||||
@@ -127,6 +131,13 @@ export default function VotingDetailStatus() {
|
|||||||
</BaseBox>
|
</BaseBox>
|
||||||
)}
|
)}
|
||||||
<Spacing height={0} />
|
<Spacing height={0} />
|
||||||
|
|
||||||
|
{data &&
|
||||||
|
data?.catatan &&
|
||||||
|
(status === "draft" || status === "rejected") && (
|
||||||
|
<ReportBox text={data?.catatan} />
|
||||||
|
)}
|
||||||
|
|
||||||
<Voting_BoxDetailSection data={data as any} />
|
<Voting_BoxDetailSection data={data as any} />
|
||||||
{status === "publish" ? (
|
{status === "publish" ? (
|
||||||
<Voting_BoxDetailHasilVotingSection
|
<Voting_BoxDetailHasilVotingSection
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
import { useAuth } from "@/hooks/use-auth";
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
|
import { apiUser } from "@/service/api-client/api-user";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
@@ -19,12 +20,25 @@ export default function WaitingRoom() {
|
|||||||
async function handleCheck() {
|
async function handleCheck() {
|
||||||
try {
|
try {
|
||||||
const response = await userData(token as string);
|
const response = await userData(token as string);
|
||||||
|
|
||||||
if (response.active) {
|
if (response.active) {
|
||||||
Toast.show({
|
const checkProfile = await apiUser(response.id);
|
||||||
type: "success",
|
|
||||||
text1: "Akun anda telah aktif", // text2: "Anda berhasil login",
|
if (checkProfile?.data?.Profile) {
|
||||||
});
|
Toast.show({
|
||||||
router.replace(`/(application)/(user)/profile/create`);
|
type: "success",
|
||||||
|
text1: "Akun anda telah aktif kembali", // text2: "Anda berhasil login",
|
||||||
|
});
|
||||||
|
router.replace(`/(application)/(user)/home`);
|
||||||
|
} else {
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Akun anda telah aktif", // text2: "Anda berhasil login",
|
||||||
|
});
|
||||||
|
router.replace(`/(application)/(user)/profile/create`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// router.replace(`/(application)/(user)/profile/create`);
|
||||||
} else {
|
} else {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "error",
|
type: "error",
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ import {
|
|||||||
ICON_SIZE_XLARGE,
|
ICON_SIZE_XLARGE,
|
||||||
} from "@/constants/constans-value";
|
} from "@/constants/constans-value";
|
||||||
import { useAuth } from "@/hooks/use-auth";
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import { adminListMenu } from "@/screens/Admin/listPageAdmin";
|
import {
|
||||||
|
adminListMenu,
|
||||||
|
superAdminListMenu,
|
||||||
|
} from "@/screens/Admin/listPageAdmin";
|
||||||
import { GStyles } from "@/styles/global-styles";
|
import { GStyles } from "@/styles/global-styles";
|
||||||
import { FontAwesome6, Ionicons } from "@expo/vector-icons";
|
import { FontAwesome6, Ionicons } from "@expo/vector-icons";
|
||||||
import { router, Stack } from "expo-router";
|
import { router, Stack } from "expo-router";
|
||||||
@@ -24,8 +27,11 @@ import { useState } from "react";
|
|||||||
export default function AdminLayout() {
|
export default function AdminLayout() {
|
||||||
const [openDrawerNavbar, setOpenDrawerNavbar] = useState(false);
|
const [openDrawerNavbar, setOpenDrawerNavbar] = useState(false);
|
||||||
const [openDrawerUser, setOpenDrawerUser] = useState(false);
|
const [openDrawerUser, setOpenDrawerUser] = useState(false);
|
||||||
|
// const [user, setUser] = useState(null);
|
||||||
|
|
||||||
const { logout } = useAuth();
|
const { logout, user } = useAuth();
|
||||||
|
|
||||||
|
console.log("[USER LAYOUT]", JSON.stringify(user, null, 2));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -56,58 +62,58 @@ export default function AdminLayout() {
|
|||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack.Screen name="dashboard" />
|
{/* <Stack.Screen name="dashboard" /> */}
|
||||||
{/* ================== Investment Start ================== */}
|
{/* ================== Investment Start ================== */}
|
||||||
<Stack.Screen name="investment/index" />
|
{/* <Stack.Screen name="investment/index" /> */}
|
||||||
{/* ================== Investment End ================== */}
|
{/* ================== Investment End ================== */}
|
||||||
|
|
||||||
{/* ================== Maps Start ================== */}
|
{/* ================== Maps Start ================== */}
|
||||||
<Stack.Screen name="maps" />
|
{/* <Stack.Screen name="maps" /> */}
|
||||||
{/* ================== Maps End ================== */}
|
{/* ================== Maps End ================== */}
|
||||||
|
|
||||||
{/* ================== App Information Start ================== */}
|
{/* ================== App Information Start ================== */}
|
||||||
<Stack.Screen name="app-information/index" />
|
{/* <Stack.Screen name="app-information/index" /> */}
|
||||||
{/* ================== App Information End ================== */}
|
{/* ================== App Information End ================== */}
|
||||||
|
|
||||||
{/* ================== Job Start ================== */}
|
{/* ================== Job Start ================== */}
|
||||||
<Stack.Screen name="job/index" />
|
{/* <Stack.Screen name="job/index" /> */}
|
||||||
{/* <Stack.Screen name="job/publish" />
|
{/* <Stack.Screen name="job/publish" />
|
||||||
<Stack.Screen name="job/review" />
|
<Stack.Screen name="job/review" />
|
||||||
<Stack.Screen name="job/reject" /> */}
|
<Stack.Screen name="job/reject" /> */}
|
||||||
<Stack.Screen name="job/[status]/status" />
|
{/* <Stack.Screen name="job/[status]/status" />
|
||||||
<Stack.Screen name="job/[id]/[status]/index" />
|
<Stack.Screen name="job/[id]/[status]/index" /> */}
|
||||||
|
|
||||||
{/* ================== Collaboration Start ================== */}
|
{/* ================== Collaboration Start ================== */}
|
||||||
<Stack.Screen name="collaboration/index" />
|
{/* <Stack.Screen name="collaboration/index" /> */}
|
||||||
<Stack.Screen name="collaboration/publish" />
|
{/* <Stack.Screen name="collaboration/publish" />
|
||||||
<Stack.Screen name="collaboration/group" />
|
<Stack.Screen name="collaboration/group" />
|
||||||
<Stack.Screen name="collaboration/reject" />
|
<Stack.Screen name="collaboration/reject" />
|
||||||
<Stack.Screen name="collaboration/[id]/[status]" />
|
<Stack.Screen name="collaboration/[id]/[status]" />
|
||||||
<Stack.Screen name="collaboration/[id]/group" />
|
<Stack.Screen name="collaboration/[id]/group" /> */}
|
||||||
{/* ================== Collaboration End ================== */}
|
{/* ================== Collaboration End ================== */}
|
||||||
|
|
||||||
{/* ================== Forum Start ================== */}
|
{/* ================== Forum Start ================== */}
|
||||||
<Stack.Screen name="forum/index" />
|
{/* <Stack.Screen name="forum/index" /> */}
|
||||||
<Stack.Screen name="forum/[id]/index" />
|
{/* <Stack.Screen name="forum/[id]/index" />
|
||||||
<Stack.Screen name="forum/report-comment" />
|
<Stack.Screen name="forum/report-comment" />
|
||||||
<Stack.Screen name="forum/report-posting" />
|
<Stack.Screen name="forum/report-posting" />
|
||||||
<Stack.Screen name="forum/[id]/list-report-posting" />
|
<Stack.Screen name="forum/[id]/list-report-posting" />
|
||||||
<Stack.Screen name="forum/[id]/list-report-comment" />
|
<Stack.Screen name="forum/[id]/list-report-comment" /> */}
|
||||||
{/* ================== Forum End ================== */}
|
{/* ================== Forum End ================== */}
|
||||||
|
|
||||||
{/* ================== Voting Start ================== */}
|
{/* ================== Voting Start ================== */}
|
||||||
<Stack.Screen name="voting/index" />
|
{/* <Stack.Screen name="voting/index" />
|
||||||
<Stack.Screen name="voting/[status]/status" />
|
<Stack.Screen name="voting/[status]/status" />
|
||||||
<Stack.Screen name="voting/[id]/[status]/index" />
|
<Stack.Screen name="voting/[id]/[status]/index" />
|
||||||
<Stack.Screen name="voting/[id]/reject-input" />
|
<Stack.Screen name="voting/[id]/reject-input" /> */}
|
||||||
{/* ================== Voting End ================== */}
|
{/* ================== Voting End ================== */}
|
||||||
|
|
||||||
{/* ================== Event Start ================== */}
|
{/* ================== Event Start ================== */}
|
||||||
<Stack.Screen name="event/index" />
|
{/* <Stack.Screen name="event/index" />
|
||||||
<Stack.Screen name="event/[status]/status" />
|
<Stack.Screen name="event/[status]/status" />
|
||||||
<Stack.Screen name="event/type-of-event" />
|
<Stack.Screen name="event/type-of-event" />
|
||||||
<Stack.Screen name="event/type-create" />
|
<Stack.Screen name="event/type-create" />
|
||||||
<Stack.Screen name="event/type-update" />
|
<Stack.Screen name="event/type-update" /> */}
|
||||||
{/* <Stack.Screen name="event/[id]/[status]/index" />
|
{/* <Stack.Screen name="event/[id]/[status]/index" />
|
||||||
<Stack.Screen name="event/[id]/reject-input"/> */}
|
<Stack.Screen name="event/[id]/reject-input"/> */}
|
||||||
{/* ================== Event End ================== */}
|
{/* ================== Event End ================== */}
|
||||||
@@ -134,7 +140,11 @@ export default function AdminLayout() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<NavbarMenu
|
<NavbarMenu
|
||||||
items={adminListMenu}
|
items={
|
||||||
|
user?.masterUserRoleId === "2"
|
||||||
|
? adminListMenu
|
||||||
|
: superAdminListMenu
|
||||||
|
}
|
||||||
onClose={() => setOpenDrawerNavbar(false)}
|
onClose={() => setOpenDrawerNavbar(false)}
|
||||||
/>
|
/>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
@@ -155,7 +165,7 @@ export default function AdminLayout() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<TextCustom>Username</TextCustom>
|
<TextCustom>{user?.username || "-"}</TextCustom>
|
||||||
</GridComponentView>
|
</GridComponentView>
|
||||||
<GridComponentView
|
<GridComponentView
|
||||||
leftIcon={
|
leftIcon={
|
||||||
@@ -166,7 +176,13 @@ export default function AdminLayout() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<TextCustom>User Role</TextCustom>
|
<TextCustom>
|
||||||
|
{user
|
||||||
|
? user?.masterUserRoleId === "2"
|
||||||
|
? "Admin"
|
||||||
|
: "Super Admin"
|
||||||
|
: "-"}
|
||||||
|
</TextCustom>
|
||||||
</GridComponentView>
|
</GridComponentView>
|
||||||
|
|
||||||
<MenuDrawerDynamicGrid
|
<MenuDrawerDynamicGrid
|
||||||
|
|||||||
@@ -1,18 +1,89 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
TextInputCustom,
|
TextInputCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import { router } from "expo-router";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import {
|
||||||
|
apiAdminMasterBusinessFieldById,
|
||||||
|
apiAdminMasterBusinessFieldUpdate,
|
||||||
|
} from "@/service/api-admin/api-master-admin";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { Switch } from "react-native-paper";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminAppInformation_BusinessFieldDetail() {
|
export default function AdminAppInformation_BusinessFieldDetail() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadDetail();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadDetail = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminMasterBusinessFieldById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
setData(response.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
setData(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlerSubmit = async () => {
|
||||||
|
if (!data.name) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Lengkapi Data",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
const response = await apiAdminMasterBusinessFieldUpdate({
|
||||||
|
id: id as string,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Gagal update data",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Data berhasil di update",
|
||||||
|
});
|
||||||
|
router.back();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const buttonSubmit = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
onPress={() => router.back()}
|
disabled={!data?.name}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onPress={() => handlerSubmit()}
|
||||||
>
|
>
|
||||||
Update
|
Update
|
||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
@@ -28,6 +99,15 @@ export default function AdminAppInformation_BusinessFieldDetail() {
|
|||||||
label="Nama Bidang Bisnis"
|
label="Nama Bidang Bisnis"
|
||||||
placeholder="Masukan Nama Bidang Bisnis"
|
placeholder="Masukan Nama Bidang Bisnis"
|
||||||
required
|
required
|
||||||
|
value={data?.name}
|
||||||
|
onChangeText={(value) => setData({ ...data, name: value })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextCustom>Status Aktivasi</TextCustom>
|
||||||
|
<Switch
|
||||||
|
color={MainColor.yellow}
|
||||||
|
value={data?.active}
|
||||||
|
onValueChange={(value) => setData({ ...data, active: value })}
|
||||||
/>
|
/>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
|
|||||||
@@ -6,13 +6,52 @@ import {
|
|||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import { apiAdminMasterBusinessFieldCreate } from "@/service/api-admin/api-master-admin";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
|
import { useState } from "react";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminAppInformation_BusinessFieldCreate() {
|
export default function AdminAppInformation_BusinessFieldCreate() {
|
||||||
|
const [data, setData] = useState<any>({
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
const handlerSubmit = async () => {
|
||||||
|
if (!data.name) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Lengkapi Data",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
const response = await apiAdminMasterBusinessFieldCreate({ data: data });
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Data berhasil di tambah",
|
||||||
|
});
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Gagal tambah data",
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const buttonSubmit = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
onPress={() => router.back()}
|
onPress={() => handlerSubmit()}
|
||||||
|
isLoading={isLoading}
|
||||||
>
|
>
|
||||||
Tambah
|
Tambah
|
||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
@@ -28,6 +67,8 @@ export default function AdminAppInformation_BusinessFieldCreate() {
|
|||||||
label="Nama Bidang Bisnis"
|
label="Nama Bidang Bisnis"
|
||||||
placeholder="Masukan Nama Bidang Bisnis"
|
placeholder="Masukan Nama Bidang Bisnis"
|
||||||
required
|
required
|
||||||
|
value={data.name}
|
||||||
|
onChangeText={(value) => setData({ ...data, name: value })}
|
||||||
/>
|
/>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
import {
|
import { ScrollableCustom, StackCustom, ViewWrapper } from "@/components";
|
||||||
ScrollableCustom,
|
|
||||||
StackCustom,
|
|
||||||
ViewWrapper
|
|
||||||
} from "@/components";
|
|
||||||
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
|
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
|
||||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||||
import AdminAppInformation_BusinessFieldSection from "@/screens/Admin/App-Information/BusinessFieldSection";
|
import AdminAppInformation_BusinessFieldSection from "@/screens/Admin/App-Information/BusinessFieldSection";
|
||||||
@@ -10,6 +6,7 @@ import AdminAppInformation_Bank from "@/screens/Admin/App-Information/Informatio
|
|||||||
import AdminAppInformation_StickerSection from "@/screens/Admin/App-Information/StickerSection";
|
import AdminAppInformation_StickerSection from "@/screens/Admin/App-Information/StickerSection";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { Alert } from "react-native";
|
||||||
|
|
||||||
export default function AdminInformation() {
|
export default function AdminInformation() {
|
||||||
const [activeCategory, setActiveCategory] = useState<string | null>("bank");
|
const [activeCategory, setActiveCategory] = useState<string | null>("bank");
|
||||||
@@ -57,7 +54,8 @@ export default function AdminInformation() {
|
|||||||
} else if (activeCategory === "business") {
|
} else if (activeCategory === "business") {
|
||||||
router.push("/admin/app-information/business-field/create");
|
router.push("/admin/app-information/business-field/create");
|
||||||
} else if (activeCategory === "sticker") {
|
} else if (activeCategory === "sticker") {
|
||||||
router.push("/admin/app-information/sticker/create");
|
Alert.alert("Coming Soon", "Next Update");
|
||||||
|
// router.push("/admin/app-information/sticker/create");
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,18 +1,90 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
StackCustom,
|
CenterCustom,
|
||||||
TextInputCustom,
|
Grid,
|
||||||
ViewWrapper,
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
|
TextInputCustom,
|
||||||
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import { router } from "expo-router";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import {
|
||||||
|
apiAdminMasterBankById,
|
||||||
|
apiAdminMasterBankUpdate,
|
||||||
|
} from "@/service/api-admin/api-master-admin";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { Switch } from "react-native-paper";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminAppInformation_BankDetail() {
|
export default function AdminAppInformation_BankDetail() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadList();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadList = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminMasterBankById({ id: id as string });
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlerUpdate = async () => {
|
||||||
|
if (!data.namaBank || !data.namaAkun || !data.norek) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Lengkapi Data",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const response = await apiAdminMasterBankUpdate({
|
||||||
|
id: id as string,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Gagal update data",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Success",
|
||||||
|
text2: "Data berhasil di update",
|
||||||
|
});
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const buttonSubmit = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
onPress={() => router.back()}
|
disabled={!data?.namaBank || !data?.namaAkun || !data?.norek}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onPress={() => handlerUpdate()}
|
||||||
>
|
>
|
||||||
Update
|
Update
|
||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
@@ -25,22 +97,46 @@ export default function AdminAppInformation_BankDetail() {
|
|||||||
<AdminBackButtonAntTitle title="Update Bank" />
|
<AdminBackButtonAntTitle title="Update Bank" />
|
||||||
|
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
<TextInputCustom
|
<Grid>
|
||||||
label="Nama Bank"
|
<Grid.Col span={6}>
|
||||||
placeholder="Masukan Nama Bank"
|
<TextInputCustom
|
||||||
required
|
label="Nama Bank"
|
||||||
/>
|
placeholder="Masukan Nama Bank"
|
||||||
|
required
|
||||||
|
value={data?.namaBank}
|
||||||
|
onChangeText={(value) =>
|
||||||
|
setData({ ...data, namaBank: value })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6} style={{ alignItems: "center" }}>
|
||||||
|
<TextCustom>Status Aktivasi</TextCustom>
|
||||||
|
<CenterCustom>
|
||||||
|
<Switch
|
||||||
|
onValueChange={(value) =>
|
||||||
|
setData({ ...data, isActive: value })
|
||||||
|
}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
value={data?.isActive}
|
||||||
|
/>
|
||||||
|
</CenterCustom>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<TextInputCustom
|
<TextInputCustom
|
||||||
label="Nama Rekening"
|
label="Nama Rekening"
|
||||||
placeholder="Masukan Nama Rekening"
|
placeholder="Masukan Nama Rekening"
|
||||||
required
|
required
|
||||||
|
value={data?.namaAkun}
|
||||||
|
onChangeText={(value) => setData({ ...data, namaAkun: value })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextInputCustom
|
<TextInputCustom
|
||||||
label="Nomor Rekening"
|
label="Nomor Rekening"
|
||||||
placeholder="Masukan Nomor Rekening"
|
placeholder="Masukan Nomor Rekening"
|
||||||
required
|
required
|
||||||
|
value={data?.norek}
|
||||||
|
onChangeText={(value) => setData({ ...data, norek: value })}
|
||||||
/>
|
/>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
|
|||||||
@@ -1,19 +1,51 @@
|
|||||||
import {
|
import {
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextInputCustom,
|
TextInputCustom,
|
||||||
ViewWrapper
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import { apiAdminMasterBankCreate } from "@/service/api-admin/api-master-admin";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
|
import { useState } from "react";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminAppInformation_BankCreate() {
|
export default function AdminAppInformation_BankCreate() {
|
||||||
|
const [data, setData] = useState<any>({
|
||||||
|
namaBank: "",
|
||||||
|
namaAkun: "",
|
||||||
|
norek: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const handlerSubmit = async () => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const response = await apiAdminMasterBankCreate({ data: data });
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Data berhasil di tambah",
|
||||||
|
});
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Gagal tambah data",
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const buttonSubmit = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<ButtonCustom
|
<ButtonCustom isLoading={isLoading} onPress={handlerSubmit}>
|
||||||
onPress={() => router.back()}
|
|
||||||
>
|
|
||||||
Tambah
|
Tambah
|
||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
</BoxButtonOnFooter>
|
</BoxButtonOnFooter>
|
||||||
@@ -29,18 +61,25 @@ export default function AdminAppInformation_BankCreate() {
|
|||||||
label="Nama Bank"
|
label="Nama Bank"
|
||||||
placeholder="Masukan Nama Bank"
|
placeholder="Masukan Nama Bank"
|
||||||
required
|
required
|
||||||
|
value={data.namaBank}
|
||||||
|
onChangeText={(value) => setData({ ...data, namaBank: value })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextInputCustom
|
<TextInputCustom
|
||||||
label="Nama Rekening"
|
label="Nama Rekening"
|
||||||
placeholder="Masukan Nama Rekening"
|
placeholder="Masukan Nama Rekening"
|
||||||
required
|
required
|
||||||
|
value={data.namaAkun}
|
||||||
|
onChangeText={(value) => setData({ ...data, namaAkun: value })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextInputCustom
|
<TextInputCustom
|
||||||
|
keyboardType="numeric"
|
||||||
label="Nomor Rekening"
|
label="Nomor Rekening"
|
||||||
placeholder="Masukan Nomor Rekening"
|
placeholder="Masukan Nomor Rekening"
|
||||||
required
|
required
|
||||||
|
value={data.norek}
|
||||||
|
onChangeText={(value) => setData({ ...data, norek: value })}
|
||||||
/>
|
/>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
BaseBox,
|
BaseBox,
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
@@ -8,18 +9,45 @@ import {
|
|||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import GridTwoView from "@/components/_ShareComponent/GridTwoView";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { useLocalSearchParams } from "expo-router";
|
import { apiAdminCollaborationGetById } from "@/service/api-admin/api-admin-collaboration";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function AdminCollaborationPublish() {
|
export default function AdminCollaborationPublish() {
|
||||||
const { id, status } = useLocalSearchParams();
|
const { id, status } = useLocalSearchParams();
|
||||||
console.log("params:", id, status);
|
const [data, setData] = useState<any | null>(null);
|
||||||
const bottomFooter = (
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
handlerLoadData();
|
||||||
|
}, [status])
|
||||||
|
);
|
||||||
|
|
||||||
|
const handlerLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminCollaborationGetById({
|
||||||
|
id: id as string,
|
||||||
|
category: status as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const bottomFooter = status === "publish" && (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
backgroundColor={MainColor.red}
|
backgroundColor={MainColor.red}
|
||||||
textColor="white"
|
textColor="white"
|
||||||
onPress={() => {}}
|
onPress={() => {
|
||||||
|
router.push(`/admin/collaboration/${id}/reject-input`);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Reject
|
Reject
|
||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
@@ -29,12 +57,12 @@ export default function AdminCollaborationPublish() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
headerComponent={<AdminBackButtonAntTitle title={`Detail ${status}`} />}
|
headerComponent={<AdminBackButtonAntTitle title={`Detail`} />}
|
||||||
footerComponent={bottomFooter}
|
footerComponent={bottomFooter}
|
||||||
>
|
>
|
||||||
<BaseBox>
|
<BaseBox>
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
{listData.map((item, i) => (
|
{listData(data)?.map((item, i) => (
|
||||||
<Grid key={i}>
|
<Grid key={i}>
|
||||||
<Grid.Col
|
<Grid.Col
|
||||||
span={4}
|
span={4}
|
||||||
@@ -49,41 +77,49 @@ export default function AdminCollaborationPublish() {
|
|||||||
))}
|
))}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
|
|
||||||
|
{data?.report && (
|
||||||
|
<BaseBox>
|
||||||
|
<GridTwoView
|
||||||
|
spanLeft={4}
|
||||||
|
spanRight={8}
|
||||||
|
leftIcon={<TextCustom bold>Catatan report</TextCustom>}
|
||||||
|
rightIcon={<TextCustom>{data?.report}</TextCustom>}
|
||||||
|
/>
|
||||||
|
</BaseBox>
|
||||||
|
)}
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
const listData = (data: any) => [
|
||||||
{
|
{
|
||||||
label: "Username",
|
label: "Username",
|
||||||
value: "Bagas Banuna",
|
value: (data && data?.Author?.username) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Judul Proyek",
|
label: "Judul Proyek",
|
||||||
value:
|
value: (data && data?.title) || "-",
|
||||||
"Judul Proyek: Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Industri",
|
label: "Industri",
|
||||||
value: "Kesehatan",
|
value: (data && data?.ProjectCollaborationMaster_Industri?.name) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Jumlah Partisipan ",
|
label: "Jumlah Partisipan ",
|
||||||
value: "0",
|
value: (data && data?.ProjectCollaboration_Partisipasi.length) || "0",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Lokasi",
|
label: "Lokasi",
|
||||||
value: "Kuta Selatan, Bali",
|
value: (data && data?.lokasi) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Tujuan Proyek",
|
label: "Tujuan Proyek",
|
||||||
value:
|
value: (data && data?.purpose) || "-",
|
||||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Keuntungan",
|
label: "Keuntungan",
|
||||||
value:
|
value: (data && data?.benefit) || "-",
|
||||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
BaseBox,
|
BaseBox,
|
||||||
Grid,
|
Grid,
|
||||||
@@ -6,23 +7,45 @@ import {
|
|||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import { useLocalSearchParams } from "expo-router";
|
import { apiAdminCollaborationGetById } from "@/service/api-admin/api-admin-collaboration";
|
||||||
|
import { useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function AdminCollaborationGroup() {
|
export default function AdminCollaborationGroup() {
|
||||||
const { id } = useLocalSearchParams();
|
const { id } = useLocalSearchParams();
|
||||||
console.log("params:", id);
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminCollaborationGetById({
|
||||||
|
id: id as string,
|
||||||
|
category: "group",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
headerComponent={
|
headerComponent={<AdminBackButtonAntTitle title={`Detail Group`} />}
|
||||||
<AdminBackButtonAntTitle title={`Detail Group ${id}`} />
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<StackCustom gap={"xs"}>
|
<StackCustom gap={"xs"}>
|
||||||
<BaseBox>
|
<BaseBox>
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
{listData.map((item, i) => (
|
{listData(data).map((item: any, index: number) => (
|
||||||
<Grid key={i}>
|
<Grid key={index}>
|
||||||
<Grid.Col
|
<Grid.Col
|
||||||
span={4}
|
span={4}
|
||||||
style={{ justifyContent: "center", paddingRight: 10 }}
|
style={{ justifyContent: "center", paddingRight: 10 }}
|
||||||
@@ -40,21 +63,36 @@ export default function AdminCollaborationGroup() {
|
|||||||
<StackCustom>
|
<StackCustom>
|
||||||
<TextCustom align="center">Anggota</TextCustom>
|
<TextCustom align="center">Anggota</TextCustom>
|
||||||
|
|
||||||
{Array.from({ length: 10 }).map((_, i) => (
|
{data?.ProjectCollaboration_AnggotaRoomChat?.map(
|
||||||
<Grid key={i}>
|
(item: any, index: number) => (
|
||||||
<Grid.Col
|
<StackCustom key={index} gap={0}>
|
||||||
span={4}
|
<Grid>
|
||||||
style={{ justifyContent: "center", paddingRight: 10 }}
|
<Grid.Col
|
||||||
>
|
span={4}
|
||||||
<TextCustom bold>Username</TextCustom>
|
style={{ justifyContent: "center", paddingRight: 10 }}
|
||||||
</Grid.Col>
|
>
|
||||||
<Grid.Col span={8} style={{ justifyContent: "center" }}>
|
<TextCustom bold>Nama</TextCustom>
|
||||||
<TextCustom>
|
</Grid.Col>
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
<Grid.Col span={8} style={{ justifyContent: "center" }}>
|
||||||
</TextCustom>
|
<TextCustom>
|
||||||
</Grid.Col>
|
{item?.User?.Profile?.name || "-"}
|
||||||
</Grid>
|
</TextCustom>
|
||||||
))}
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
<Grid>
|
||||||
|
<Grid.Col
|
||||||
|
span={4}
|
||||||
|
style={{ justifyContent: "center", paddingRight: 10 }}
|
||||||
|
>
|
||||||
|
<TextCustom bold>Username</TextCustom>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={8} style={{ justifyContent: "center" }}>
|
||||||
|
<TextCustom>{item?.User?.username || "-"}</TextCustom>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</StackCustom>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
@@ -63,35 +101,35 @@ export default function AdminCollaborationGroup() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
const listData = (data: any) => [
|
||||||
{
|
{
|
||||||
label: "Admin Group",
|
label: "Admin Group",
|
||||||
value: "Bagas Banuna",
|
value: data?.ProjectCollaboration?.Author?.username || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Nama Group",
|
label: "Nama Group",
|
||||||
value: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
value: data?.name || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Industri",
|
label: "Industri",
|
||||||
value: "Kesehatan",
|
value:
|
||||||
|
data?.ProjectCollaboration?.ProjectCollaborationMaster_Industri?.name ||
|
||||||
|
"-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Jumlah Partisipan ",
|
label: "Jumlah Partisipan ",
|
||||||
value: "0",
|
value: data?.ProjectCollaboration_AnggotaRoomChat?.length || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Lokasi",
|
label: "Lokasi",
|
||||||
value: "Kuta Selatan, Bali",
|
value: data?.ProjectCollaboration?.lokasi || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Tujuan Proyek",
|
label: "Tujuan Proyek",
|
||||||
value:
|
value: data?.ProjectCollaboration?.purpose || "-",
|
||||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Keuntungan",
|
label: "Keuntungan",
|
||||||
value:
|
value: data?.ProjectCollaboration?.benefit || "-",
|
||||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -6,12 +6,42 @@ import {
|
|||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||||
|
import { apiAdminCollaborationReject } from "@/service/api-admin/api-admin-collaboration";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import { router, useLocalSearchParams } from "expo-router";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminJobRejectInput() {
|
export default function AdminCollaborationRejectInput() {
|
||||||
const { id } = useLocalSearchParams();
|
const { id } = useLocalSearchParams();
|
||||||
const [value, setValue] = useState(id as string);
|
const [value, setValue] = useState("");
|
||||||
|
|
||||||
|
const handlerReject = async () => {
|
||||||
|
console.log("value:", value);
|
||||||
|
// router.replace(`/admin/job/reject/status`);
|
||||||
|
try {
|
||||||
|
const response = await apiAdminCollaborationReject({
|
||||||
|
id: id as string,
|
||||||
|
data: value,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Report gagal",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Report berhasil",
|
||||||
|
});
|
||||||
|
|
||||||
|
router.back();
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const buttonSubmit = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<AdminButtonReject
|
<AdminButtonReject
|
||||||
@@ -22,12 +52,8 @@ export default function AdminJobRejectInput() {
|
|||||||
message: "Apakah anda yakin ingin menolak data ini?",
|
message: "Apakah anda yakin ingin menolak data ini?",
|
||||||
textLeft: "Batal",
|
textLeft: "Batal",
|
||||||
textRight: "Ya",
|
textRight: "Ya",
|
||||||
onPressLeft: () => {
|
|
||||||
router.back();
|
|
||||||
},
|
|
||||||
onPressRight: () => {
|
onPressRight: () => {
|
||||||
console.log("value:", value);
|
handlerReject();
|
||||||
router.replace(`/admin/job/reject/status`);
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -39,7 +65,9 @@ export default function AdminJobRejectInput() {
|
|||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
footerComponent={buttonSubmit}
|
footerComponent={buttonSubmit}
|
||||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Job" />}
|
headerComponent={
|
||||||
|
<AdminBackButtonAntTitle title="Penolakan Collaboration" />
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<TextAreaCustom
|
<TextAreaCustom
|
||||||
value={value}
|
value={value}
|
||||||
@@ -1,67 +1,101 @@
|
|||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
LoaderCustom,
|
||||||
Spacing,
|
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
|
import { apiAdminCollaboration } from "@/service/api-admin/api-admin-collaboration";
|
||||||
import { Octicons } from "@expo/vector-icons";
|
import { Octicons } from "@expo/vector-icons";
|
||||||
import { router } from "expo-router";
|
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";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminCollaborationGroup() {
|
export default function AdminCollaborationGroup() {
|
||||||
|
const [list, setList] = useState<any[] | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
handlerLoadList();
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const handlerLoadList = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
const response = await apiAdminCollaboration({
|
||||||
|
category: "group",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setList(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
||||||
<StackCustom gap={"xs"}>
|
<StackCustom>
|
||||||
<AdminComp_BoxTitle title="Group" />
|
<AdminComp_BoxTitle title="Group" />
|
||||||
<BaseBox>
|
<>
|
||||||
<AdminTitleTable
|
<AdminTitleTable
|
||||||
title1="Aksi"
|
title1="Aksi"
|
||||||
title2="Admin Group"
|
title2="Jumlah peserta"
|
||||||
title3="Nama Group"
|
title3="Nama group"
|
||||||
/>
|
/>
|
||||||
<Spacing height={10} />
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
{loadList ? (
|
||||||
<AdminTableValue
|
<LoaderCustom />
|
||||||
key={index}
|
) : _.isEmpty(list) ? (
|
||||||
value1={
|
<TextCustom align="center" color="gray">
|
||||||
<ActionIcon
|
Belum ada data
|
||||||
icon={
|
</TextCustom>
|
||||||
<Octicons
|
) : (
|
||||||
name="eye"
|
list?.map((item: any, index: number) => (
|
||||||
size={ICON_SIZE_BUTTON}
|
<View key={index}>
|
||||||
color="black"
|
<AdminTableValue
|
||||||
|
value1={
|
||||||
|
<ActionIcon
|
||||||
|
icon={
|
||||||
|
<Octicons
|
||||||
|
name="eye"
|
||||||
|
size={ICON_SIZE_BUTTON}
|
||||||
|
color="black"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onPress={() => {
|
||||||
|
router.push(`/admin/collaboration/${item.id}/group`);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onPress={() => {
|
value2={
|
||||||
router.push(`/admin/collaboration/${index}/group`);
|
<TextCustom truncate={1}>
|
||||||
}}
|
{item?.ProjectCollaboration_AnggotaRoomChat?.length ||
|
||||||
|
"-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom truncate={2}>{item?.name || "-"}</TextCustom>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
}
|
</View>
|
||||||
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>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</BaseBox>
|
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -2,14 +2,39 @@ import { StackCustom, ViewWrapper } from "@/components";
|
|||||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { apiAdminCollaboration } from "@/service/api-admin/api-admin-collaboration";
|
||||||
import { Entypo, FontAwesome } from "@expo/vector-icons";
|
import { Entypo, FontAwesome } from "@expo/vector-icons";
|
||||||
|
import { useFocusEffect } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function AdminCollaboration() {
|
export default function AdminCollaboration() {
|
||||||
|
const [list, setList] = useState<any | null>(null);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
handlerLoadList();
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const handlerLoadList = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminCollaboration({
|
||||||
|
category: "dashboard",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setList(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
||||||
<StackCustom gap={"xs"}>
|
<StackCustom gap={"xs"}>
|
||||||
{listData.map((item, i) => (
|
{listData(list as any).map((item, i) => (
|
||||||
<AdminComp_BoxDashboard key={i} item={item} />
|
<AdminComp_BoxDashboard key={i} item={item} />
|
||||||
))}
|
))}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
@@ -18,20 +43,22 @@ export default function AdminCollaboration() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
const listData = (list: any) => {
|
||||||
{
|
return [
|
||||||
label: "Publish",
|
{
|
||||||
value: 4,
|
label: "Publish",
|
||||||
icon: <Entypo name="publish" size={25} color={MainColor.green} />,
|
value: (list && list?.publish) || "0",
|
||||||
},
|
icon: <Entypo name="publish" size={25} color={MainColor.green} />,
|
||||||
{
|
},
|
||||||
label: "Group",
|
{
|
||||||
value: 7,
|
label: "Group",
|
||||||
icon: <FontAwesome name="group" size={25} color={MainColor.yellow} />,
|
value: (list && list?.group) || "0",
|
||||||
},
|
icon: <FontAwesome name="group" size={25} color={MainColor.yellow} />,
|
||||||
{
|
},
|
||||||
label: "Reject",
|
{
|
||||||
value: 7,
|
label: "Reject",
|
||||||
icon: <FontAwesome name="warning" size={25} color={MainColor.red} />,
|
value: (list && list?.reject) || "0",
|
||||||
},
|
icon: <FontAwesome name="warning" size={25} color={MainColor.red} />,
|
||||||
];
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
LoaderCustom,
|
||||||
Spacing,
|
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
@@ -11,60 +10,95 @@ import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
|||||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
|
import { apiAdminCollaboration } from "@/service/api-admin/api-admin-collaboration";
|
||||||
import { Octicons } from "@expo/vector-icons";
|
import { Octicons } from "@expo/vector-icons";
|
||||||
import { router } from "expo-router";
|
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";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminCollaborationPublish() {
|
export default function AdminCollaborationPublish() {
|
||||||
|
const [list, setList] = useState<any[] | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
handlerLoadList();
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const handlerLoadList = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
const response = await apiAdminCollaboration({
|
||||||
|
category: "publish",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setList(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
||||||
<StackCustom gap={"xs"}>
|
<StackCustom>
|
||||||
<AdminComp_BoxTitle title="Publish" />
|
<AdminComp_BoxTitle title="Publish" />
|
||||||
<BaseBox>
|
|
||||||
<AdminTitleTable
|
|
||||||
title1="Aksi"
|
|
||||||
title2="Username"
|
|
||||||
title3="Judul Proyek"
|
|
||||||
/>
|
|
||||||
<Spacing height={10} />
|
|
||||||
<Divider />
|
|
||||||
|
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
<AdminTitleTable
|
||||||
<AdminTableValue
|
title1="Aksi"
|
||||||
key={index}
|
title2="Username"
|
||||||
value1={
|
title3="Judul Proyek"
|
||||||
<ActionIcon
|
/>
|
||||||
icon={
|
{/* <Spacing height={10} /> */}
|
||||||
<Octicons
|
<Divider />
|
||||||
name="eye"
|
|
||||||
size={ICON_SIZE_BUTTON}
|
{loadList ? (
|
||||||
color="black"
|
<LoaderCustom />
|
||||||
/>
|
) : _.isEmpty(list) ? (
|
||||||
}
|
<TextCustom align="center" color="gray">
|
||||||
onPress={() => {
|
Belum ada data
|
||||||
router.push(`/admin/collaboration/${index}/publish`);
|
</TextCustom>
|
||||||
}}
|
) : (
|
||||||
/>
|
list?.map((item: any, index: number) => (
|
||||||
}
|
<View key={index}>
|
||||||
value2={
|
<AdminTableValue
|
||||||
<TextCustom truncate={1}>Username username </TextCustom>
|
value1={
|
||||||
}
|
<ActionIcon
|
||||||
value3={
|
icon={
|
||||||
<TextCustom truncate={2}>
|
<Octicons
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
name="eye"
|
||||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
size={ICON_SIZE_BUTTON}
|
||||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
color="black"
|
||||||
ducimus! Dolorem nobis modi officia debitis, beatae
|
/>
|
||||||
mollitia.
|
}
|
||||||
</TextCustom>
|
onPress={() => {
|
||||||
}
|
router.push(`/admin/collaboration/${item?.id}/publish`);
|
||||||
/>
|
}}
|
||||||
))}
|
/>
|
||||||
</BaseBox>
|
}
|
||||||
|
value2={
|
||||||
|
<TextCustom align="center" truncate={1}>
|
||||||
|
{item?.Author?.username || "-"}{" "}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom align="center" truncate={2}>
|
||||||
|
{item?.title || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
))
|
||||||
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,67 +1,99 @@
|
|||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
LoaderCustom,
|
||||||
Spacing,
|
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
|
import { apiAdminCollaboration } from "@/service/api-admin/api-admin-collaboration";
|
||||||
import { Octicons } from "@expo/vector-icons";
|
import { Octicons } from "@expo/vector-icons";
|
||||||
import { router } from "expo-router";
|
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";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminCollaborationReject() {
|
export default function AdminCollaborationReject() {
|
||||||
|
const [list, setList] = useState<any[] | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
handlerLoadList();
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const handlerLoadList = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
const response = await apiAdminCollaboration({
|
||||||
|
category: "reject",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setList(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
||||||
<StackCustom gap={"xs"}>
|
<StackCustom>
|
||||||
<AdminComp_BoxTitle title="Reject" />
|
<AdminComp_BoxTitle title="Reject" />
|
||||||
<BaseBox>
|
<AdminTitleTable
|
||||||
<AdminTitleTable
|
title1="Aksi"
|
||||||
title1="Aksi"
|
title2="Username"
|
||||||
title2="Username"
|
title3="Judul Proyek"
|
||||||
title3="Judul Proyek"
|
/>
|
||||||
/>
|
<Divider />
|
||||||
<Spacing height={10} />
|
|
||||||
<Divider />
|
|
||||||
|
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
{loadList ? (
|
||||||
<AdminTableValue
|
<LoaderCustom />
|
||||||
key={index}
|
) : _.isEmpty(list) ? (
|
||||||
value1={
|
<TextCustom>Belum ada data</TextCustom>
|
||||||
<ActionIcon
|
) : (
|
||||||
icon={
|
list?.map((item: any) => (
|
||||||
<Octicons
|
<View key={item.id}>
|
||||||
name="eye"
|
<AdminTableValue
|
||||||
size={ICON_SIZE_BUTTON}
|
key={item?.id}
|
||||||
color="black"
|
value1={
|
||||||
/>
|
<ActionIcon
|
||||||
}
|
icon={
|
||||||
onPress={() => {
|
<Octicons
|
||||||
router.push(`/admin/collaboration/${index}/reject`);
|
name="eye"
|
||||||
}}
|
size={ICON_SIZE_BUTTON}
|
||||||
/>
|
color="black"
|
||||||
}
|
/>
|
||||||
value2={
|
}
|
||||||
<TextCustom truncate={1}>Username username </TextCustom>
|
onPress={() => {
|
||||||
}
|
router.push(`/admin/collaboration/${item?.id}/reject`);
|
||||||
value3={
|
}}
|
||||||
<TextCustom truncate={2}>
|
/>
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
}
|
||||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
value2={
|
||||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
<TextCustom align="center" truncate={1}>
|
||||||
ducimus! Dolorem nobis modi officia debitis, beatae
|
{item?.Author?.username || "-"}
|
||||||
mollitia.
|
</TextCustom>
|
||||||
</TextCustom>
|
}
|
||||||
}
|
value3={
|
||||||
/>
|
<TextCustom align="center" truncate={2}>
|
||||||
))}
|
{item?.title || "-"}
|
||||||
</BaseBox>
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
))
|
||||||
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,13 +1,31 @@
|
|||||||
import {
|
import { StackCustom, TextCustom, ViewWrapper } from "@/components";
|
||||||
StackCustom,
|
|
||||||
TextCustom,
|
|
||||||
ViewWrapper
|
|
||||||
} from "@/components";
|
|
||||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { apiAdminMainDashboardGetAll } from "@/service/api-admin/api-admin-main-dashboard";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
export default function AdminDashboard() {
|
export default function AdminDashboard() {
|
||||||
|
const [countUser, setCountUser] = useState(0);
|
||||||
|
const [countPortofolio, setCountPortofolio] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminMainDashboardGetAll();
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setCountUser(response.data.user);
|
||||||
|
setCountPortofolio(response.data.portofolio);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR LOAD DATA]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper>
|
<ViewWrapper>
|
||||||
@@ -15,7 +33,7 @@ export default function AdminDashboard() {
|
|||||||
<TextCustom bold size={30}>
|
<TextCustom bold size={30}>
|
||||||
Main Dashboard
|
Main Dashboard
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
{listData.map((item, i) => (
|
{listData(countUser, countPortofolio).map((item, i) => (
|
||||||
<AdminComp_BoxDashboard key={i} item={item} />
|
<AdminComp_BoxDashboard key={i} item={item} />
|
||||||
))}
|
))}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
@@ -24,15 +42,15 @@ export default function AdminDashboard() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
const listData = (countUser: number, countPortofolio: number) => [
|
||||||
{
|
{
|
||||||
label: "User",
|
label: "User",
|
||||||
value: 4,
|
value: countUser,
|
||||||
icon: <Ionicons name="people" size={30} color={MainColor.yellow} />,
|
icon: <Ionicons name="people" size={30} color={MainColor.yellow} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Portofolio",
|
label: "Portofolio",
|
||||||
value: 7,
|
value: countPortofolio,
|
||||||
icon: (
|
icon: (
|
||||||
<Ionicons name="id-card-outline" size={30} color={MainColor.yellow} />
|
<Ionicons name="id-card-outline" size={30} color={MainColor.yellow} />
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
AlertDefaultSystem,
|
AlertDefaultSystem,
|
||||||
@@ -18,97 +19,147 @@ import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButt
|
|||||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
import { 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 { ICON_SIZE_BUTTON, TEXT_SIZE_LARGE } from "@/constants/constans-value";
|
||||||
import AdminDonation_BoxOfDonationStory from "@/screens/Admin/Donation/BoxOfDonationStory";
|
import AdminDonation_BoxOfDonationStory from "@/screens/Admin/Donation/BoxOfDonationStory";
|
||||||
|
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 { Ionicons } from "@expo/vector-icons";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminDonationDetail() {
|
export default function AdminDonationDetail() {
|
||||||
const { id, status } = useLocalSearchParams();
|
const { id, status } = useLocalSearchParams();
|
||||||
const [openDrawer, setOpenDrawer] = React.useState(false);
|
const [openDrawer, setOpenDrawer] = React.useState(false);
|
||||||
|
|
||||||
const colorBadge = () => {
|
const [data, setData] = React.useState<any | null>(null);
|
||||||
if (status === "publish") {
|
const [isLoading, setIsLoading] = React.useState(false);
|
||||||
return MainColor.green;
|
|
||||||
} else if (status === "review") {
|
useFocusEffect(
|
||||||
return MainColor.orange;
|
React.useCallback(() => {
|
||||||
} else if (status === "reject") {
|
onLoadData();
|
||||||
return MainColor.red;
|
}, [id])
|
||||||
} else {
|
);
|
||||||
return MainColor.placeholder;
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminDonationDetailById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[RES GET BY ID]", JSON.stringify(response, null, 2));
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
setData(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const listData = [
|
const listData = [
|
||||||
{
|
{
|
||||||
label: "Penggalang Dana",
|
label: "Penggalang Dana",
|
||||||
value: `Bagas Banuna ${id}`,
|
value: (data && data?.Author?.username) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Judul",
|
label: "Judul",
|
||||||
value: `Donasi Lorem ipsum dolor sit amet, consectetur adipisicing elit.`,
|
value: (data && data?.title) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Status",
|
label: "Status",
|
||||||
value: (
|
value:
|
||||||
<BadgeCustom color={colorBadge()}>
|
data && data?.DonasiMaster_Status?.name ? (
|
||||||
{_.startCase(status as string)}
|
<BadgeCustom
|
||||||
</BadgeCustom>
|
color={colorBadgeStatus({ status: data?.DonasiMaster_Status?.name })}
|
||||||
),
|
>
|
||||||
|
{_.startCase(data?.DonasiMaster_Status?.name)}
|
||||||
|
</BadgeCustom>
|
||||||
|
) : (
|
||||||
|
"-"
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Durasi",
|
label: "Durasi",
|
||||||
value: "30 Hari",
|
value: (data && data?.DonasiMaster_Durasi?.name) + " hari" || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Target Dana",
|
label: "Target Dana",
|
||||||
value: "Rp 10.000.000",
|
value:
|
||||||
|
data && data?.target
|
||||||
|
? `Rp. ${formatCurrencyDisplay(data?.target)}`
|
||||||
|
: "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Kategori",
|
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 = [
|
const listPencarianDana = [
|
||||||
{
|
{
|
||||||
label: "Total Dana Dicairkan",
|
label: "Total Dana Dicairkan",
|
||||||
value: "Rp 0",
|
value: `Rp ${(data && data?.totalPencairan) || 0}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Sisa Dana",
|
label: "Sisa Dana",
|
||||||
value: "Rp 0",
|
value: `Rp ${(data && data?.terkumpul - data?.totalPencairan) || 0}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Akumulasi Pencairan",
|
label: "Akumulasi Pencairan",
|
||||||
value: "0 kali",
|
value: `${(data && data?.totalPencairan) || 0} kali`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Bank Tujuan",
|
label: "Bank Tujuan",
|
||||||
value: "BNI",
|
value: (data && data?.namaBank) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Nomor Rekening",
|
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 = (
|
const rightComponent = (
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
icon={<IconDot size={ICON_SIZE_BUTTON} />}
|
icon={<IconDot size={ICON_SIZE_BUTTON} />}
|
||||||
@@ -118,8 +169,6 @@ export default function AdminDonationDetail() {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
@@ -147,6 +196,7 @@ export default function AdminDonationDetail() {
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
|
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
iconLeft={
|
iconLeft={
|
||||||
<Ionicons name="cash-outline" size={ICON_SIZE_BUTTON} />
|
<Ionicons name="cash-outline" size={ICON_SIZE_BUTTON} />
|
||||||
@@ -179,7 +229,7 @@ export default function AdminDonationDetail() {
|
|||||||
|
|
||||||
<BaseBox>
|
<BaseBox>
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
<DummyLandscapeImage />
|
<DummyLandscapeImage imageId={data?.imageId || ""} />
|
||||||
{listData.map((item, i) => (
|
{listData.map((item, i) => (
|
||||||
<GridDetail_4_8
|
<GridDetail_4_8
|
||||||
key={i}
|
key={i}
|
||||||
@@ -190,27 +240,33 @@ export default function AdminDonationDetail() {
|
|||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
|
|
||||||
|
<AdminDonation_BoxOfDonationStory data={data?.CeritaDonasi as any} />
|
||||||
|
|
||||||
|
{data &&
|
||||||
|
data?.catatan &&
|
||||||
|
(status === "review" || status === "reject") && (
|
||||||
|
<ReportBox text={data?.catatan} />
|
||||||
|
)}
|
||||||
|
|
||||||
{status === "review" && (
|
{status === "review" && (
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
<AdminDonation_BoxOfDonationStory />
|
|
||||||
|
|
||||||
<AdminButtonReview
|
<AdminButtonReview
|
||||||
|
isLoading={isLoading}
|
||||||
onPublish={() => {
|
onPublish={() => {
|
||||||
AlertDefaultSystem({
|
AlertDefaultSystem({
|
||||||
title: "Publish",
|
title: "Publish",
|
||||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||||
textLeft: "Batal",
|
textLeft: "Batal",
|
||||||
textRight: "Ya",
|
textRight: "Ya",
|
||||||
onPressLeft: () => {
|
|
||||||
router.back();
|
|
||||||
},
|
|
||||||
onPressRight: () => {
|
onPressRight: () => {
|
||||||
router.back();
|
handleReport({ changeStatus: "publish" });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
onReject={() => {
|
onReject={() => {
|
||||||
router.push(`/admin/donation/${id}/reject-input`);
|
router.push(
|
||||||
|
`/admin/donation/${id}/reject-input?status=${status}`
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
@@ -218,12 +274,12 @@ export default function AdminDonationDetail() {
|
|||||||
|
|
||||||
{status === "reject" && (
|
{status === "reject" && (
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
<AdminDonation_BoxOfDonationStory />
|
|
||||||
|
|
||||||
<AdminButtonReject
|
<AdminButtonReject
|
||||||
title="Tambah Catatan"
|
title="Tambah Catatan"
|
||||||
onReject={() => {
|
onReject={() => {
|
||||||
router.push(`/admin/donation/${id}/reject-input`);
|
router.push(
|
||||||
|
`/admin/donation/${id}/reject-input?status=${status}`
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BadgeCustom,
|
BadgeCustom,
|
||||||
@@ -10,22 +11,86 @@ import {
|
|||||||
import { IconView } from "@/components/_Icon/IconComponent";
|
import { IconView } from "@/components/_Icon/IconComponent";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
import { dummyMasterStatusTransaction } from "@/lib/dummy-data/_master/status-transaction";
|
import { apiAdminDonationListOfDonatur } from "@/service/api-admin/api-admin-donation";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import { apiMasterTransaction } from "@/service/api-client/api-master";
|
||||||
import React from "react";
|
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 { View } from "react-native";
|
||||||
import { Divider } from "react-native-paper";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminDonasiListOfDonatur() {
|
export default function AdminDonasiListOfDonatur() {
|
||||||
const { id } = useLocalSearchParams();
|
const { id } = useLocalSearchParams();
|
||||||
|
console.log("[ID >>]", id);
|
||||||
|
const [listData, setListData] = React.useState<any[] | null>(null);
|
||||||
|
const [master, setMaster] = React.useState<any[]>([]);
|
||||||
|
|
||||||
|
const [selectStatus, setSelectStatus] = React.useState<
|
||||||
|
"berhasil" | "gagal" | "proses" | "menunggu" | ""
|
||||||
|
>("");
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
React.useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id, selectStatus])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminDonationListOfDonatur({
|
||||||
|
id: id as string,
|
||||||
|
status: "" 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([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = (
|
const searchComponent = (
|
||||||
<View style={{ flexDirection: "row", gap: 5 }}>
|
<View style={{ flexDirection: "row", gap: 5 }}>
|
||||||
<SelectCustom
|
<SelectCustom
|
||||||
placeholder="Pilih status transaksi"
|
placeholder="Pilih status transaksi"
|
||||||
data={dummyMasterStatusTransaction}
|
data={
|
||||||
onChange={(value) => console.log(value)}
|
_.isEmpty(master)
|
||||||
|
? []
|
||||||
|
: master?.map((item: any) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.name
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
onChange={(value: any) => {
|
||||||
|
console.log("[SELECT STATUS]", value);
|
||||||
|
const statusChooses = _.lowerCase(value);
|
||||||
|
setSelectStatus(statusChooses as any);
|
||||||
|
}}
|
||||||
styleContainer={{ width: "100%", marginBottom: 0 }}
|
styleContainer={{ width: "100%", marginBottom: 0 }}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
@@ -59,7 +124,7 @@ export default function AdminDonasiListOfDonatur() {
|
|||||||
/>
|
/>
|
||||||
<Divider />
|
<Divider />
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
{listData?.map((item: any, index: number) => (
|
||||||
<View key={index}>
|
<View key={index}>
|
||||||
<GridViewCustomSpan
|
<GridViewCustomSpan
|
||||||
span1={3}
|
span1={3}
|
||||||
@@ -79,15 +144,15 @@ export default function AdminDonasiListOfDonatur() {
|
|||||||
}
|
}
|
||||||
component2={
|
component2={
|
||||||
<TextCustom bold align="center" truncate>
|
<TextCustom bold align="center" truncate>
|
||||||
Bagas Banuna
|
{item?.Author?.username || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
component3={
|
component3={
|
||||||
<BadgeCustom
|
<BadgeCustom
|
||||||
style={{ alignSelf: "center" }}
|
style={{ alignSelf: "center" }}
|
||||||
color={MainColor.green}
|
color={colorBadgeTransaction({status: item?.DonasiMaster_StatusInvoice?.name})}
|
||||||
>
|
>
|
||||||
Berhasil
|
{item?.DonasiMaster_StatusInvoice?.name}
|
||||||
</BadgeCustom>
|
</BadgeCustom>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
AlertDefaultSystem,
|
AlertDefaultSystem,
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
@@ -6,15 +7,84 @@ import {
|
|||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import { funUpdateStatusDonation } from "@/screens/Admin/Donation/funDonationUpdateStatus";
|
||||||
import { useState } from "react";
|
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() {
|
export default function AdminDonationRejectInput() {
|
||||||
const { id } = useLocalSearchParams();
|
const { id, status } = useLocalSearchParams();
|
||||||
const [value, setValue] = useState(id as string);
|
|
||||||
|
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 = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<AdminButtonReject
|
<AdminButtonReject
|
||||||
|
isLoading={isLoading}
|
||||||
title="Reject"
|
title="Reject"
|
||||||
onReject={() =>
|
onReject={() =>
|
||||||
AlertDefaultSystem({
|
AlertDefaultSystem({
|
||||||
@@ -22,12 +92,9 @@ export default function AdminDonationRejectInput() {
|
|||||||
message: "Apakah anda yakin ingin menolak data ini?",
|
message: "Apakah anda yakin ingin menolak data ini?",
|
||||||
textLeft: "Batal",
|
textLeft: "Batal",
|
||||||
textRight: "Ya",
|
textRight: "Ya",
|
||||||
onPressLeft: () => {
|
|
||||||
router.back();
|
|
||||||
},
|
|
||||||
onPressRight: () => {
|
onPressRight: () => {
|
||||||
console.log("value:", value);
|
handleReport({ changeStatus: "reject" });
|
||||||
router.replace(`/admin/donation/reject/status`);
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -42,8 +109,8 @@ export default function AdminDonationRejectInput() {
|
|||||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Donasi" />}
|
headerComponent={<AdminBackButtonAntTitle title="Penolakan Donasi" />}
|
||||||
>
|
>
|
||||||
<TextAreaCustom
|
<TextAreaCustom
|
||||||
value={value}
|
value={data}
|
||||||
onChangeText={setValue}
|
onChangeText={setData}
|
||||||
placeholder="Masukan alasan"
|
placeholder="Masukan alasan"
|
||||||
required
|
required
|
||||||
showCount
|
showCount
|
||||||
|
|||||||
@@ -1,69 +1,116 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
SearchInput,
|
LoaderCustom,
|
||||||
Spacing,
|
SearchInput,
|
||||||
TextCustom,
|
StackCustom,
|
||||||
ViewWrapper
|
TextCustom,
|
||||||
|
ViewWrapper
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||||
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
|
import { apiAdminDonation } from "@/service/api-admin/api-admin-donation";
|
||||||
import { Octicons } from "@expo/vector-icons";
|
import { Octicons } from "@expo/vector-icons";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
import { Divider } from "react-native-paper";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminDonationStatus() {
|
export default function AdminDonationStatus() {
|
||||||
const { status } = useLocalSearchParams();
|
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 = (
|
const rightComponent = (
|
||||||
<SearchInput
|
<SearchInput
|
||||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||||
placeholder="Cari"
|
placeholder="Cari"
|
||||||
|
value={search}
|
||||||
|
onChangeText={(value) => setSearch(value)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper headerComponent={<AdminTitlePage title="Donasi" />}>
|
||||||
headerComponent={
|
<StackCustom gap={"sm"}>
|
||||||
<AdminComp_BoxTitle
|
<AdminComp_BoxTitle
|
||||||
title={`Donasi ${_.startCase(status as string)}`}
|
title={`${_.startCase(status as string)}`}
|
||||||
rightComponent={rightComponent}
|
rightComponent={rightComponent}
|
||||||
/>
|
/>
|
||||||
}
|
<AdminTitleTable
|
||||||
>
|
title1="Aksi"
|
||||||
<AdminTitleTable
|
title2="Username"
|
||||||
title1="Aksi"
|
title3="Judul Donasi"
|
||||||
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>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
))}
|
<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>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,15 +1,67 @@
|
|||||||
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
||||||
import {
|
import {
|
||||||
IconList,
|
IconList,
|
||||||
IconPublish,
|
IconPublish,
|
||||||
IconReject,
|
IconReject,
|
||||||
IconReview,
|
IconReview,
|
||||||
} from "@/components/_Icon/IconComponent";
|
} from "@/components/_Icon/IconComponent";
|
||||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
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() {
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper>
|
<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,112 +1,110 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
AlertDefaultSystem,
|
AlertDefaultSystem,
|
||||||
BadgeCustom,
|
BadgeCustom,
|
||||||
BaseBox,
|
BaseBox,
|
||||||
DrawerCustom,
|
DrawerCustom,
|
||||||
MenuDrawerDynamicGrid,
|
LoaderCustom,
|
||||||
Spacing,
|
MenuDrawerDynamicGrid,
|
||||||
StackCustom,
|
Spacing,
|
||||||
TextCustom,
|
StackCustom,
|
||||||
ViewWrapper,
|
TextCustom,
|
||||||
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { IconDot, IconList } from "@/components/_Icon/IconComponent";
|
import { IconDot, IconList } from "@/components/_Icon/IconComponent";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
import { 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 } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
import dayjs from "dayjs";
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
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 { colorBadgeStatus } from "@/utils/colorBadge";
|
||||||
|
import { dateTimeView } from "@/utils/dateTimeView";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import React from "react";
|
import React, { useCallback } from "react";
|
||||||
import QRCode from "react-native-qrcode-svg";
|
import QRCode from "react-native-qrcode-svg";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminEventDetail() {
|
export default function AdminEventDetail() {
|
||||||
|
const { user } = useAuth();
|
||||||
const { id, status } = useLocalSearchParams();
|
const { id, status } = useLocalSearchParams();
|
||||||
const [openDrawer, setOpenDrawer] = React.useState(false);
|
const [openDrawer, setOpenDrawer] = React.useState(false);
|
||||||
|
|
||||||
const colorBadge = () => {
|
const [data, setData] = React.useState<any | null>(null);
|
||||||
if (status === "publish") {
|
const [loadData, setLoadData] = React.useState(false);
|
||||||
return MainColor.green;
|
const deepLinkURL = `${DEEP_LINK_URL}/--/event/${id}/confirmation?userId=${user?.id}`;
|
||||||
} else if (status === "review") {
|
useFocusEffect(
|
||||||
return MainColor.orange;
|
useCallback(() => {
|
||||||
} else if (status === "reject") {
|
onLoadData();
|
||||||
return MainColor.red;
|
}, [id])
|
||||||
} else {
|
);
|
||||||
return MainColor.placeholder;
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setLoadData(true);
|
||||||
|
const response = await apiAdminEventById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadData(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const listData = [
|
const listData = [
|
||||||
{
|
{
|
||||||
label: "Pembuat Event",
|
label: "Pembuat Event",
|
||||||
value: `Bagas Banuna ${id}`,
|
value: (data && data?.Author?.username) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Judul Event",
|
label: "Judul Event",
|
||||||
value: `Event 123`,
|
value: (data && data?.title) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Status",
|
label: "Status",
|
||||||
value: (
|
value:
|
||||||
<BadgeCustom color={colorBadge()}>
|
(data && (
|
||||||
{_.startCase(status as string)}
|
<BadgeCustom color={colorBadgeStatus({ status: status as string })}>
|
||||||
</BadgeCustom>
|
{_.startCase(status as string)}
|
||||||
),
|
</BadgeCustom>
|
||||||
|
)) ||
|
||||||
|
"-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Lokasi",
|
label: "Lokasi",
|
||||||
value: "Lokasi Event",
|
value: (data && data?.lokasi) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Tipe Acara",
|
label: "Tipe Acara",
|
||||||
value: "Tipe Acara",
|
value: (data && data?.EventMaster_TipeAcara?.name) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Mulai Event",
|
label: "Mulai Event",
|
||||||
value: dayjs().format("DD/MM/YYYY HH:mm:ss"),
|
value:
|
||||||
|
(data && data?.tanggal && dateTimeView({ date: data?.tanggal })) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Event Berakhir",
|
label: "Event Berakhir",
|
||||||
value: dayjs().add(3, "day").format("DD/MM/YYYY HH:mm:ss"),
|
value:
|
||||||
|
(data &&
|
||||||
|
data?.tanggalSelesai &&
|
||||||
|
dateTimeView({ date: data?.tanggalSelesai })) ||
|
||||||
|
"-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Deskripsi",
|
label: "Deskripsi",
|
||||||
value: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
value: (data && data?.deskripsi) || "-",
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// label: "Daftar Tipe Acara",
|
|
||||||
// value: (
|
|
||||||
// <>
|
|
||||||
// <List.Item
|
|
||||||
// title={<TextCustom>Pilihan 1</TextCustom>}
|
|
||||||
// left={(props) => (
|
|
||||||
// <List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
|
||||||
// )}
|
|
||||||
// />
|
|
||||||
// <List.Item
|
|
||||||
// title={<TextCustom>Pilihan 2</TextCustom>}
|
|
||||||
// left={(props) => (
|
|
||||||
// <List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
|
||||||
// )}
|
|
||||||
// />
|
|
||||||
// <List.Item
|
|
||||||
// title={<TextCustom>Pilihan 3</TextCustom>}
|
|
||||||
// left={(props) => (
|
|
||||||
// <List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
|
||||||
// )}
|
|
||||||
// />
|
|
||||||
// <List.Item
|
|
||||||
// title={<TextCustom>Pilihan 4</TextCustom>}
|
|
||||||
// left={(props) => (
|
|
||||||
// <List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
|
||||||
// )}
|
|
||||||
// />
|
|
||||||
// </>
|
|
||||||
// ),
|
|
||||||
// },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const rightComponent = (
|
const rightComponent = (
|
||||||
@@ -118,6 +116,31 @@ export default function AdminEventDetail() {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handlerSubmit = async () => {
|
||||||
|
try {
|
||||||
|
const response = await funUpdateStatusEvent({
|
||||||
|
id: id as string,
|
||||||
|
changeStatus: "publish",
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
@@ -125,7 +148,7 @@ export default function AdminEventDetail() {
|
|||||||
<AdminBackButtonAntTitle
|
<AdminBackButtonAntTitle
|
||||||
title={`Detail Data`}
|
title={`Detail Data`}
|
||||||
rightComponent={
|
rightComponent={
|
||||||
(status === "publish" || status === "riwayat") && rightComponent
|
(status === "publish" || status === "history") && rightComponent
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@@ -143,19 +166,30 @@ export default function AdminEventDetail() {
|
|||||||
|
|
||||||
<Spacing />
|
<Spacing />
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
{(status === "publish" || status === "riwayat") && (
|
|
||||||
|
{data &&
|
||||||
|
data?.catatan &&
|
||||||
|
(status === "reject" || status === "review") && (
|
||||||
|
<ReportBox text={data?.catatan} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{(status === "publish" || status === "history") && (
|
||||||
<BaseBox>
|
<BaseBox>
|
||||||
<StackCustom style={{ alignItems: "center" }}>
|
<StackCustom style={{ alignItems: "center" }}>
|
||||||
<TextCustom bold>QR Code Event</TextCustom>
|
<TextCustom bold>QR Code Event</TextCustom>
|
||||||
<QRCode
|
{loadData ? (
|
||||||
value="https://google.com"
|
<LoaderCustom />
|
||||||
size={200}
|
) : (
|
||||||
// logo={require("@/assets/images/logo-hipmi.png")}
|
<QRCode
|
||||||
// logoSize={70}
|
value={deepLinkURL}
|
||||||
// logoBackgroundColor="transparent"
|
size={200}
|
||||||
// logoBorderRadius={50}
|
// logo={require("@/assets/images/logo-hipmi.png")}
|
||||||
// color="black"
|
// logoSize={70}
|
||||||
/>
|
// logoBackgroundColor="transparent"
|
||||||
|
// logoBorderRadius={50}
|
||||||
|
// color="black"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
)}
|
)}
|
||||||
@@ -168,16 +202,11 @@ export default function AdminEventDetail() {
|
|||||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||||
textLeft: "Batal",
|
textLeft: "Batal",
|
||||||
textRight: "Ya",
|
textRight: "Ya",
|
||||||
onPressLeft: () => {
|
onPressRight: () => handlerSubmit(),
|
||||||
router.back();
|
|
||||||
},
|
|
||||||
onPressRight: () => {
|
|
||||||
router.back();
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
onReject={() => {
|
onReject={() => {
|
||||||
router.push(`/admin/event/${id}/reject-input`);
|
router.push(`/admin/event/${id}/reject-input?status=${status}`);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -186,7 +215,7 @@ export default function AdminEventDetail() {
|
|||||||
<AdminButtonReject
|
<AdminButtonReject
|
||||||
title="Tambah Catatan"
|
title="Tambah Catatan"
|
||||||
onReject={() => {
|
onReject={() => {
|
||||||
router.push(`/admin/event/${id}/reject-input`);
|
router.push(`/admin/event/${id}/reject-input?status=${status}`);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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 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() {
|
export default function AdminEventListOfParticipants() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
const [listData, setListData] = useState<any[] | null>(null);
|
||||||
|
const [loadData, setLoadData] = useState(false);
|
||||||
|
|
||||||
const isPresent = ({id}: {id: number}) => {
|
useFocusEffect(
|
||||||
const check = id % 3 * 3;
|
useCallback(() => {
|
||||||
if (check === 0) {
|
onLoadData();
|
||||||
return true;
|
}, [id])
|
||||||
} else {
|
);
|
||||||
return false;
|
|
||||||
}
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
headerComponent={<AdminBackButtonAntTitle title="Daftar Peserta" />}
|
headerComponent={<AdminBackButtonAntTitle title="Daftar Peserta" />}
|
||||||
>
|
>
|
||||||
{Array.from({ length: 10 }).map((item, index) => (
|
{loadData ? (
|
||||||
<BaseBox key={index}>
|
<LoaderCustom />
|
||||||
<Grid>
|
) : _.isEmpty(listData) ? (
|
||||||
<Grid.Col span={6}>
|
<TextCustom align="center" color="gray">
|
||||||
<TextCustom bold>Username {index + 1}</TextCustom>
|
Belum ada peserta
|
||||||
<TextCustom>+6282123456789</TextCustom>
|
</TextCustom>
|
||||||
</Grid.Col>
|
) : (
|
||||||
<Grid.Col span={6} style={{ justifyContent: "center" }}>
|
listData?.map((item: any, index: number) => (
|
||||||
<BadgeCustom
|
<BaseBox key={index}>
|
||||||
style={{ alignSelf: "flex-end" }}
|
<Grid>
|
||||||
color={isPresent({id: index}) ? MainColor.green : MainColor.red}
|
<Grid.Col span={6}>
|
||||||
>
|
<StackCustom gap={"sm"}>
|
||||||
{isPresent({id: index}) ? "Hadir" : "Tidak Hadir"}
|
<TextCustom bold truncate>{item?.User?.username}</TextCustom>
|
||||||
</BadgeCustom>
|
<TextCustom>+{item?.User?.nomor}</TextCustom>
|
||||||
</Grid.Col>
|
</StackCustom>
|
||||||
</Grid>
|
</Grid.Col>
|
||||||
</BaseBox>
|
<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>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
AlertDefaultSystem,
|
AlertDefaultSystem,
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
@@ -6,15 +7,78 @@ import {
|
|||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import { funUpdateStatusEvent } from "@/screens/Admin/Event/funUpdateStatus";
|
||||||
import { useState } from "react";
|
import { apiAdminEventById } from "@/service/api-admin/api-admin-event";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminEventRejectInput() {
|
export default function AdminEventRejectInput() {
|
||||||
const { id } = useLocalSearchParams();
|
const { id, status } = useLocalSearchParams();
|
||||||
const [value, setValue] = useState(id as string);
|
|
||||||
|
const [data, setData] = useState<any>("");
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminEventById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data.catatan);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpdate = async ({
|
||||||
|
changeStatus,
|
||||||
|
}: {
|
||||||
|
changeStatus: "publish" | "review" | "reject";
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
const response = await funUpdateStatusEvent({
|
||||||
|
id: id as string,
|
||||||
|
changeStatus,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Report gagal",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Report berhasil",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (status === "review") {
|
||||||
|
router.replace(`/admin/event/reject/status`);
|
||||||
|
} else if (status === "reject") {
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const buttonSubmit = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<AdminButtonReject
|
<AdminButtonReject
|
||||||
|
isLoading={isLoading}
|
||||||
title="Reject"
|
title="Reject"
|
||||||
onReject={() =>
|
onReject={() =>
|
||||||
AlertDefaultSystem({
|
AlertDefaultSystem({
|
||||||
@@ -22,12 +86,8 @@ export default function AdminEventRejectInput() {
|
|||||||
message: "Apakah anda yakin ingin menolak data ini?",
|
message: "Apakah anda yakin ingin menolak data ini?",
|
||||||
textLeft: "Batal",
|
textLeft: "Batal",
|
||||||
textRight: "Ya",
|
textRight: "Ya",
|
||||||
onPressLeft: () => {
|
|
||||||
router.back();
|
|
||||||
},
|
|
||||||
onPressRight: () => {
|
onPressRight: () => {
|
||||||
console.log("value:", value);
|
handleUpdate({ changeStatus: "reject" });
|
||||||
router.replace(`/admin/event/reject/status`);
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -42,8 +102,8 @@ export default function AdminEventRejectInput() {
|
|||||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Event" />}
|
headerComponent={<AdminBackButtonAntTitle title="Penolakan Event" />}
|
||||||
>
|
>
|
||||||
<TextAreaCustom
|
<TextAreaCustom
|
||||||
value={value}
|
value={data}
|
||||||
onChangeText={setValue}
|
onChangeText={setData}
|
||||||
placeholder="Masukan alasan"
|
placeholder="Masukan alasan"
|
||||||
required
|
required
|
||||||
showCount
|
showCount
|
||||||
|
|||||||
@@ -1,27 +1,67 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
LoaderCustom,
|
||||||
SearchInput,
|
SearchInput,
|
||||||
Spacing,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
|
import { apiAdminEvent } from "@/service/api-admin/api-admin-event";
|
||||||
import { Octicons } from "@expo/vector-icons";
|
import { Octicons } from "@expo/vector-icons";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
import { Divider } from "react-native-paper";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminEventStatus() {
|
export default function AdminEventStatus() {
|
||||||
const { status } = useLocalSearchParams();
|
const { status } = useLocalSearchParams();
|
||||||
|
console.log("[STATUS EVENT]", status);
|
||||||
|
|
||||||
|
const [listData, setListData] = useState<any[] | null>(null);
|
||||||
|
const [loadData, setLoadData] = useState(false);
|
||||||
|
const [search, setSearch] = useState<string>("");
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [status, search])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setLoadData(true);
|
||||||
|
const response = await apiAdminEvent({
|
||||||
|
category: status as "publish" | "review" | "reject" | "history" as any,
|
||||||
|
search,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[RES LIST BY STATUS: ${status}]`,
|
||||||
|
JSON.stringify(response, null, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setListData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadData(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const rightComponent = (
|
const rightComponent = (
|
||||||
<SearchInput
|
<SearchInput
|
||||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||||
placeholder="Cari"
|
placeholder="Cari"
|
||||||
|
value={search}
|
||||||
|
onChangeText={(value) => setSearch(value)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
@@ -32,44 +72,50 @@ export default function AdminEventStatus() {
|
|||||||
rightComponent={rightComponent}
|
rightComponent={rightComponent}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<BaseBox>
|
<StackCustom gap={"sm"}>
|
||||||
<AdminTitleTable
|
<AdminTitleTable
|
||||||
title1="Aksi"
|
title1="Aksi"
|
||||||
title2="Username"
|
title2="Username"
|
||||||
title3="Judul Event"
|
title3="Judul Event"
|
||||||
/>
|
/>
|
||||||
<Spacing />
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
{loadData ? (
|
||||||
<AdminTableValue
|
<LoaderCustom />
|
||||||
key={index}
|
) : _.isEmpty(listData) ? (
|
||||||
value1={
|
<TextCustom align="center" size="small" color="gray">Belum ada data</TextCustom>
|
||||||
<ActionIcon
|
) : (
|
||||||
icon={
|
listData?.map((item, index) => (
|
||||||
<Octicons
|
<AdminTableValue
|
||||||
name="eye"
|
key={index}
|
||||||
size={ICON_SIZE_BUTTON}
|
value1={
|
||||||
color="black"
|
<ActionIcon
|
||||||
/>
|
icon={
|
||||||
}
|
<Octicons
|
||||||
onPress={() => {
|
name="eye"
|
||||||
router.push(`/admin/event/${index}/${status}`);
|
size={ICON_SIZE_BUTTON}
|
||||||
}}
|
color="black"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
onPress={() => {
|
||||||
value3={
|
router.push(`/admin/event/${item.id}/${status}`);
|
||||||
<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
|
value2={
|
||||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
<TextCustom truncate={1}>
|
||||||
</TextCustom>
|
{item?.Author?.username || "-"}
|
||||||
}
|
</TextCustom>
|
||||||
/>
|
}
|
||||||
))}
|
value3={
|
||||||
</BaseBox>
|
<TextCustom align="center" truncate={2}>
|
||||||
|
{item?.title || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,13 +9,67 @@ import {
|
|||||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { apiAdminEvent } from "@/service/api-admin/api-admin-event";
|
||||||
|
import { useFocusEffect } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function AdminVoting() {
|
export default function AdminVoting() {
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminEvent({
|
||||||
|
category: "dashboard",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", 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} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Riwayat",
|
||||||
|
value: (data && data.history) || 0,
|
||||||
|
icon: <IconArchive size={25} color={MainColor.placeholder} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Tipe Acara",
|
||||||
|
value: (data && data.typeOfEvent) || 0,
|
||||||
|
icon: <IconList size={25} color={MainColor.placeholder} />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper>
|
<ViewWrapper>
|
||||||
<AdminTitlePage title="Event" />
|
<AdminTitlePage title="Event" />
|
||||||
<Spacing />
|
<Spacing />
|
||||||
|
|
||||||
<StackCustom gap={"xs"}>
|
<StackCustom gap={"xs"}>
|
||||||
{listData.map((item, i) => (
|
{listData.map((item, i) => (
|
||||||
<AdminComp_BoxDashboard key={i} item={item} />
|
<AdminComp_BoxDashboard key={i} item={item} />
|
||||||
@@ -25,31 +79,3 @@ export default function AdminVoting() {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
|
||||||
{
|
|
||||||
label: "Publish",
|
|
||||||
value: 3,
|
|
||||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Review",
|
|
||||||
value: 8,
|
|
||||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Reject",
|
|
||||||
value: 4,
|
|
||||||
icon: <IconReject size={25} color={MainColor.red} />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Riwayat",
|
|
||||||
value: 6,
|
|
||||||
icon: <IconArchive size={25} color={MainColor.placeholder} />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Tipe Acara",
|
|
||||||
value: 7,
|
|
||||||
icon: <IconList size={25} color={MainColor.placeholder} />,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -5,13 +5,48 @@ import {
|
|||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import { apiEventCreateTypeOfEvent } from "@/service/api-admin/api-master-admin";
|
||||||
import { useRouter } from "expo-router";
|
import { useRouter } from "expo-router";
|
||||||
|
import { useState } from "react";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminEventTypeOfEventCreate() {
|
export default function AdminEventTypeOfEventCreate() {
|
||||||
const router = useRouter();
|
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 = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<ButtonCustom onPress={() => router.back()}>Simpan</ButtonCustom>
|
<ButtonCustom isLoading={isLoading} onPress={() => handlerSubmit()}>
|
||||||
|
Simpan
|
||||||
|
</ButtonCustom>
|
||||||
</BoxButtonOnFooter>
|
</BoxButtonOnFooter>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
@@ -20,7 +55,11 @@ export default function AdminEventTypeOfEventCreate() {
|
|||||||
headerComponent={<AdminBackButtonAntTitle title="Tambah Tipe Acara" />}
|
headerComponent={<AdminBackButtonAntTitle title="Tambah Tipe Acara" />}
|
||||||
footerComponent={buttonSubmit}
|
footerComponent={buttonSubmit}
|
||||||
>
|
>
|
||||||
<TextInputCustom placeholder="Masukkan Tipe Acara" />
|
<TextInputCustom
|
||||||
|
placeholder="Masukkan Tipe Acara"
|
||||||
|
value={value}
|
||||||
|
onChangeText={setValue}
|
||||||
|
/>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,23 +1,53 @@
|
|||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
BadgeCustom,
|
||||||
CenterCustom,
|
CenterCustom,
|
||||||
|
LoaderCustom,
|
||||||
Spacing,
|
Spacing,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { IconEdit } from "@/components/_Icon";
|
import { IconEdit } from "@/components/_Icon";
|
||||||
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
|
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
|
||||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
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 { View } from "react-native";
|
||||||
import { Divider } from "react-native-paper";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminEventTypeOfEvent() {
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper headerComponent={<AdminTitlePage title="Event" />}>
|
<ViewWrapper headerComponent={<AdminTitlePage title="Event" />}>
|
||||||
@@ -32,73 +62,68 @@ export default function AdminEventTypeOfEvent() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<BaseBox>
|
<>
|
||||||
<GridDetail_4_8
|
<GridViewCustomSpan
|
||||||
label={
|
span1={2}
|
||||||
|
span2={5}
|
||||||
|
span3={5}
|
||||||
|
component1={
|
||||||
<TextCustom bold align="center">
|
<TextCustom bold align="center">
|
||||||
Aksi
|
Aksi
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
}
|
}
|
||||||
value={<TextCustom bold>Tipe Acara</TextCustom>}
|
component2={<TextCustom bold align="center">Status</TextCustom>}
|
||||||
|
component3={<TextCustom bold>Tipe Acara</TextCustom>}
|
||||||
/>
|
/>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Spacing />
|
<Spacing />
|
||||||
|
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
{listData.map((item, index) => (
|
{loadData ? (
|
||||||
<View key={index}>
|
<LoaderCustom />
|
||||||
<GridDetail_4_8
|
) : _.isEmpty(listData) ? (
|
||||||
label={
|
<TextCustom align="center" color="gray">
|
||||||
<CenterCustom>
|
Belum ada data
|
||||||
<ActionIcon
|
</TextCustom>
|
||||||
icon={
|
) : (
|
||||||
<IconEdit size={ICON_SIZE_BUTTON} color="black" />
|
listData?.map((item, index) => (
|
||||||
}
|
<View key={index}>
|
||||||
onPress={() => {
|
<GridViewCustomSpan
|
||||||
router.push(`/admin/event/type-update?id=${index}`);
|
span1={2}
|
||||||
}}
|
span2={5}
|
||||||
/>
|
span3={5}
|
||||||
</CenterCustom>
|
component1={
|
||||||
}
|
<CenterCustom>
|
||||||
value={<TextCustom bold>{item.label}</TextCustom>}
|
<ActionIcon
|
||||||
/>
|
icon={
|
||||||
<Divider />
|
<IconEdit size={ICON_SIZE_BUTTON} color="black" />
|
||||||
</View>
|
}
|
||||||
))}
|
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>
|
</StackCustom>
|
||||||
</BaseBox>
|
</>
|
||||||
</ViewWrapper>
|
</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 {
|
import {
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
|
Spacing,
|
||||||
|
TextCustom,
|
||||||
TextInputCustom,
|
TextInputCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
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() {
|
export default function AdminEventTypeOfEventUpdate() {
|
||||||
const { id } = useLocalSearchParams();
|
const { id } = useLocalSearchParams();
|
||||||
console.log("id >", id);
|
|
||||||
|
|
||||||
const router = useRouter();
|
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 = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<ButtonCustom onPress={() => router.back()}>Update</ButtonCustom>
|
<ButtonCustom isLoading={isLoading} onPress={() => handlerSubmit()}>
|
||||||
|
Update
|
||||||
|
</ButtonCustom>
|
||||||
</BoxButtonOnFooter>
|
</BoxButtonOnFooter>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
@@ -23,7 +94,19 @@ export default function AdminEventTypeOfEventUpdate() {
|
|||||||
headerComponent={<AdminBackButtonAntTitle title="Ubah Tipe Acara" />}
|
headerComponent={<AdminBackButtonAntTitle title="Ubah Tipe Acara" />}
|
||||||
footerComponent={buttonSubmit}
|
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>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,58 +1,79 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
AlertDefaultSystem,
|
|
||||||
BadgeCustom,
|
BadgeCustom,
|
||||||
BaseBox,
|
BaseBox,
|
||||||
DrawerCustom,
|
DrawerCustom,
|
||||||
MenuDrawerDynamicGrid,
|
MenuDrawerDynamicGrid,
|
||||||
Spacing,
|
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { IconDot, IconView } from "@/components/_Icon/IconComponent";
|
import { IconDot } from "@/components/_Icon/IconComponent";
|
||||||
import { IconTrash } from "@/components/_Icon/IconTrash";
|
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
|
||||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
|
||||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import {
|
import { ICON_SIZE_XLARGE } from "@/constants/constans-value";
|
||||||
ICON_SIZE_BUTTON,
|
import { apiAdminForumPostingById } from "@/service/api-admin/api-admin-forum";
|
||||||
ICON_SIZE_MEDIUM,
|
|
||||||
ICON_SIZE_XLARGE,
|
|
||||||
} from "@/constants/constans-value";
|
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import { router } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import { useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { Divider } from "react-native-paper";
|
|
||||||
import Toast from "react-native-toast-message";
|
|
||||||
|
|
||||||
export default function AdminForumDetailPosting() {
|
export default function AdminForumDetailPosting() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
const [openDrawerPage, setOpenDrawerPage] = useState(false);
|
const [openDrawerPage, setOpenDrawerPage] = useState(false);
|
||||||
const [openDrawerAction, setOpenDrawerAction] = useState(false);
|
const [data, setData] = useState<any | null>(null);
|
||||||
const [id, setId] = useState<any>();
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
const handlerAction = (item: { value: string; path: string }) => {
|
const onLoadData = async () => {
|
||||||
if (item.value === "delete") {
|
try {
|
||||||
AlertDefaultSystem({
|
const response = await apiAdminForumPostingById({
|
||||||
title: "Hapus Posting",
|
id: id as string,
|
||||||
message: "Apakah Anda yakin ingin menghapus posting ini?",
|
|
||||||
textLeft: "Batal",
|
|
||||||
textRight: "Hapus",
|
|
||||||
onPressRight: () => {
|
|
||||||
Toast.show({
|
|
||||||
type: "success",
|
|
||||||
text1: "Posting berhasil dihapus",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
router.navigate(item.path as any);
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
}
|
}
|
||||||
setOpenDrawerAction(false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const listDataAction = [
|
||||||
|
{
|
||||||
|
label: "Username",
|
||||||
|
value: data?.Author?.username || "-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Status",
|
||||||
|
value:
|
||||||
|
(data && (
|
||||||
|
<BadgeCustom
|
||||||
|
color={
|
||||||
|
data?.ForumMaster_StatusPosting?.status === "Open"
|
||||||
|
? MainColor.green
|
||||||
|
: MainColor.red
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{data?.ForumMaster_StatusPosting?.status || "-"}
|
||||||
|
</BadgeCustom>
|
||||||
|
)) ||
|
||||||
|
"-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Komentar",
|
||||||
|
value: data?.JumlahKomentar || 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Total Report",
|
||||||
|
value: data?.JumlahReportPosting || 0,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
@@ -60,14 +81,25 @@ export default function AdminForumDetailPosting() {
|
|||||||
<AdminBackButtonAntTitle
|
<AdminBackButtonAntTitle
|
||||||
title="Detail Posting"
|
title="Detail Posting"
|
||||||
rightComponent={
|
rightComponent={
|
||||||
<ActionIcon
|
data &&
|
||||||
icon={<IconDot size={16} color={MainColor.darkblue} />}
|
data?.isActive && (
|
||||||
onPress={() => setOpenDrawerPage(true)}
|
<ActionIcon
|
||||||
/>
|
icon={<IconDot size={16} color={MainColor.darkblue} />}
|
||||||
|
onPress={() => setOpenDrawerPage(true)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
{data && !data?.isActive && (
|
||||||
|
<BaseBox>
|
||||||
|
<TextCustom bold align="center" color="red">
|
||||||
|
Postingan ini telah di nonaktifkan
|
||||||
|
</TextCustom>
|
||||||
|
</BaseBox>
|
||||||
|
)}
|
||||||
|
|
||||||
<BaseBox>
|
<BaseBox>
|
||||||
<StackCustom gap={"sm"}>
|
<StackCustom gap={"sm"}>
|
||||||
{listDataAction.map((item, i) => (
|
{listDataAction.map((item, i) => (
|
||||||
@@ -77,50 +109,14 @@ export default function AdminForumDetailPosting() {
|
|||||||
value={<TextCustom>{item.value}</TextCustom>}
|
value={<TextCustom>{item.value}</TextCustom>}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<TextCustom bold>Posting</TextCustom>
|
|
||||||
<TextCustom>
|
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
|
||||||
Asperiores cupiditate nobis dignissimos explicabo quo unde dolorum
|
|
||||||
numquam eos ab laborum fugiat illo nam velit quibusdam, maxime
|
|
||||||
assumenda aut vero provident!
|
|
||||||
</TextCustom>
|
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
|
|
||||||
{/* <AdminComp_BoxTitle title="Komentar" rightComponent={rightComponent} /> */}
|
|
||||||
<BaseBox>
|
<BaseBox>
|
||||||
<AdminTitleTable title1="Aksi" title2="Username" title3="Komentar" />
|
<StackCustom gap={"sm"}>
|
||||||
<Spacing />
|
<TextCustom bold>Postingan</TextCustom>
|
||||||
<Divider />
|
<TextCustom>{(data && data?.diskusi) || "-"}</TextCustom>
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
</StackCustom>
|
||||||
<AdminTableValue
|
|
||||||
key={index}
|
|
||||||
value1={
|
|
||||||
<ActionIcon
|
|
||||||
icon={
|
|
||||||
<Ionicons
|
|
||||||
name="ellipsis-vertical-outline"
|
|
||||||
size={ICON_SIZE_BUTTON}
|
|
||||||
color="black"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onPress={() => {
|
|
||||||
setOpenDrawerAction(true);
|
|
||||||
setId(index + 1);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
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>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
|
|
||||||
@@ -143,6 +139,18 @@ export default function AdminForumDetailPosting() {
|
|||||||
value: "detail",
|
value: "detail",
|
||||||
path: `/admin/forum/${id}/list-report-posting`,
|
path: `/admin/forum/${id}/list-report-posting`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
icon: (
|
||||||
|
<Ionicons
|
||||||
|
name="list"
|
||||||
|
size={ICON_SIZE_XLARGE}
|
||||||
|
color={MainColor.white}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
label: "Daftar Komentar",
|
||||||
|
value: "detail",
|
||||||
|
path: `/admin/forum/${id}/list-comment`,
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
onPressItem={(item) => {
|
onPressItem={(item) => {
|
||||||
router.navigate(item.path as any);
|
router.navigate(item.path as any);
|
||||||
@@ -150,54 +158,6 @@ export default function AdminForumDetailPosting() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</DrawerCustom>
|
</DrawerCustom>
|
||||||
|
|
||||||
<DrawerCustom
|
|
||||||
isVisible={openDrawerAction}
|
|
||||||
closeDrawer={() => setOpenDrawerAction(false)}
|
|
||||||
height={"auto"}
|
|
||||||
>
|
|
||||||
<MenuDrawerDynamicGrid
|
|
||||||
data={[
|
|
||||||
{
|
|
||||||
icon: <IconView />,
|
|
||||||
label: "Detail Komentar",
|
|
||||||
value: "detail",
|
|
||||||
path: `admin/forum/${id}/list-report-comment`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: (
|
|
||||||
<IconTrash size={ICON_SIZE_MEDIUM} color={MainColor.white} />
|
|
||||||
),
|
|
||||||
label: "Hapus Komentar",
|
|
||||||
value: "delete",
|
|
||||||
path: "",
|
|
||||||
color: MainColor.red,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
onPressItem={(item) => {
|
|
||||||
handlerAction(item as any);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</DrawerCustom>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listDataAction = [
|
|
||||||
{
|
|
||||||
label: "Username",
|
|
||||||
value: "Username",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Status",
|
|
||||||
value: <BadgeCustom color={MainColor.green}>Open</BadgeCustom>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Komentar",
|
|
||||||
value: "10",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Total Report",
|
|
||||||
value: "1",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|||||||
91
app/(application)/admin/forum/[id]/list-comment.tsx
Normal file
91
app/(application)/admin/forum/[id]/list-comment.tsx
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import {
|
||||||
|
LoaderCustom,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
|
ViewWrapper
|
||||||
|
} from "@/components";
|
||||||
|
import { IconOpenTo } from "@/components/_Icon/IconOpenTo";
|
||||||
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||||
|
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||||
|
import { apiAdminForumCommentById } from "@/service/api-admin/api-admin-forum";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
|
export default function AdminForumListComment() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
const [listComment, setListComment] = useState<any[] | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadComment();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadComment = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
const response = await apiAdminForumCommentById({
|
||||||
|
id: id as string,
|
||||||
|
category: "get-all",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setListComment(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
setListComment([]);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ViewWrapper
|
||||||
|
headerComponent={<AdminBackButtonAntTitle title="Daftar Komentar" />}
|
||||||
|
>
|
||||||
|
<StackCustom>
|
||||||
|
<AdminTitleTable title1="Aksi" title2="Report" title3="Komentar" />
|
||||||
|
<Divider />
|
||||||
|
{loadList ? (
|
||||||
|
<LoaderCustom />
|
||||||
|
) : _.isEmpty(listComment) ? (
|
||||||
|
<TextCustom align="center" color="gray">
|
||||||
|
Tidak ada komentar
|
||||||
|
</TextCustom>
|
||||||
|
) : (
|
||||||
|
listComment?.map((item: any, index: number) => (
|
||||||
|
<AdminTableValue
|
||||||
|
key={index}
|
||||||
|
value1={
|
||||||
|
<IconOpenTo
|
||||||
|
onPress={() => {
|
||||||
|
router.push(
|
||||||
|
`/admin/forum/${item.id}/list-report-comment`
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
value2={
|
||||||
|
<TextCustom truncate={1}>
|
||||||
|
{item?.countReport || 0}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom truncate={2}>{item?.komentar || "-"}</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
|
</ViewWrapper>
|
||||||
|
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
AlertDefaultSystem,
|
AlertDefaultSystem,
|
||||||
BaseBox,
|
BaseBox,
|
||||||
DrawerCustom,
|
DrawerCustom,
|
||||||
|
LoaderCustom,
|
||||||
MenuDrawerDynamicGrid,
|
MenuDrawerDynamicGrid,
|
||||||
Spacing,
|
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
@@ -18,14 +19,64 @@ import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
|||||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
import { router } from "expo-router";
|
import {
|
||||||
import { useState } from "react";
|
apiAdminForumCommentById,
|
||||||
|
apiAdminForumDeactivateComment,
|
||||||
|
apiAdminForumListReportCommentById,
|
||||||
|
} from "@/service/api-admin/api-admin-forum";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
import { Divider } from "react-native-paper";
|
import { Divider } from "react-native-paper";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminForumReportComment() {
|
export default function AdminForumReportComment() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
const [listReport, setListReport] = useState<any[] | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState(false);
|
||||||
const [openDrawer, setOpenDrawer] = useState(false);
|
const [openDrawer, setOpenDrawer] = useState(false);
|
||||||
const [openDrawerAction, setOpenDrawerAction] = useState(false);
|
const [openDrawerAction, setOpenDrawerAction] = useState(false);
|
||||||
|
const [selectedReport, setSelectedReport] = useState({
|
||||||
|
id: "",
|
||||||
|
username: "",
|
||||||
|
kategori: "",
|
||||||
|
keterangan: "",
|
||||||
|
deskripsi: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
const response = await apiAdminForumCommentById({
|
||||||
|
id: id as string,
|
||||||
|
category: "get-one",
|
||||||
|
});
|
||||||
|
|
||||||
|
const responseReport = await apiAdminForumListReportCommentById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
if (responseReport.success) {
|
||||||
|
setListReport(responseReport.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
setData(null);
|
||||||
|
setListReport([]);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -44,53 +95,65 @@ export default function AdminForumReportComment() {
|
|||||||
>
|
>
|
||||||
<BaseBox>
|
<BaseBox>
|
||||||
<StackCustom gap={"sm"}>
|
<StackCustom gap={"sm"}>
|
||||||
{listData.map((item, i) => (
|
<GridDetail_4_8
|
||||||
<GridDetail_4_8
|
label={<TextCustom bold>Username</TextCustom>}
|
||||||
key={i}
|
value={<TextCustom>{data?.Author?.username || "-"}</TextCustom>}
|
||||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
/>
|
||||||
value={<TextCustom>{item.value}</TextCustom>}
|
<GridDetail_4_8
|
||||||
/>
|
label={<TextCustom bold>Komentar</TextCustom>}
|
||||||
))}
|
value={<TextCustom>{data?.komentar || "-"}</TextCustom>}
|
||||||
<TextCustom bold>Posting</TextCustom>
|
/>
|
||||||
<TextCustom>
|
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
|
||||||
Asperiores cupiditate nobis dignissimos explicabo quo unde dolorum
|
|
||||||
numquam eos ab laborum fugiat illo nam velit quibusdam, maxime
|
|
||||||
assumenda aut vero provident!
|
|
||||||
</TextCustom>
|
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
|
|
||||||
<AdminComp_BoxTitle title="Daftar Report Komentar" />
|
<AdminComp_BoxTitle title="Daftar Report Komentar" />
|
||||||
|
|
||||||
<BaseBox>
|
<StackCustom>
|
||||||
<AdminTitleTable
|
<AdminTitleTable
|
||||||
title1="Aksi"
|
title1="Aksi"
|
||||||
title2="Username"
|
title2="Pelapor"
|
||||||
title3="Kategori Report"
|
title3="Kategori Report"
|
||||||
/>
|
/>
|
||||||
<Spacing />
|
|
||||||
<Divider />
|
<Divider />
|
||||||
{Array.from({ length: 5 }).map((_, index) => (
|
{loadList ? (
|
||||||
<AdminTableValue
|
<LoaderCustom />
|
||||||
key={index}
|
) : _.isEmpty(listReport) ? (
|
||||||
value1={
|
<TextCustom align="center" color="gray">
|
||||||
<ActionIcon
|
Tidak ada report
|
||||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
</TextCustom>
|
||||||
onPress={() => {
|
) : (
|
||||||
setOpenDrawerAction(true);
|
listReport?.map((item: any, index: number) => (
|
||||||
}}
|
<AdminTableValue
|
||||||
/>
|
key={index}
|
||||||
}
|
value1={
|
||||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
<ActionIcon
|
||||||
value3={
|
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||||
<TextCustom truncate={2} align="center">
|
onPress={() => {
|
||||||
SPAM
|
setOpenDrawerAction(true);
|
||||||
</TextCustom>
|
setSelectedReport({
|
||||||
}
|
id: item.id,
|
||||||
/>
|
username: item.User?.username,
|
||||||
))}
|
kategori: item.ForumMaster_KategoriReport?.title,
|
||||||
</BaseBox>
|
keterangan: item.ForumMaster_KategoriReport?.deskripsi,
|
||||||
|
deskripsi: item.deskripsi,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
value2={
|
||||||
|
<TextCustom truncate={1}>
|
||||||
|
{item?.User?.username || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom truncate={2} align="center">
|
||||||
|
{item?.ForumMaster_KategoriReport?.title || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
|
|
||||||
<DrawerCustom
|
<DrawerCustom
|
||||||
@@ -114,7 +177,19 @@ export default function AdminForumReportComment() {
|
|||||||
message: "Apakah Anda yakin ingin menghapus komentar ini?",
|
message: "Apakah Anda yakin ingin menghapus komentar ini?",
|
||||||
textLeft: "Batal",
|
textLeft: "Batal",
|
||||||
textRight: "Hapus",
|
textRight: "Hapus",
|
||||||
onPressRight: () => {
|
onPressRight: async () => {
|
||||||
|
const deleteComment = await apiAdminForumDeactivateComment({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!deleteComment.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Komentar gagal dihapus",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setOpenDrawer(false);
|
setOpenDrawer(false);
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "success",
|
type: "success",
|
||||||
@@ -132,37 +207,39 @@ export default function AdminForumReportComment() {
|
|||||||
closeDrawer={() => setOpenDrawerAction(false)}
|
closeDrawer={() => setOpenDrawerAction(false)}
|
||||||
height={"auto"}
|
height={"auto"}
|
||||||
>
|
>
|
||||||
{listDataAction.map((item, i) => (
|
<StackCustom>
|
||||||
<GridDetail_4_8
|
<GridDetail_4_8
|
||||||
key={i}
|
label={<TextCustom bold>Pelapor</TextCustom>}
|
||||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
value={<TextCustom>{selectedReport?.username || "-"}</TextCustom>}
|
||||||
value={<TextCustom>{item.value}</TextCustom>}
|
|
||||||
/>
|
/>
|
||||||
))}
|
|
||||||
|
{selectedReport?.kategori && (
|
||||||
|
<>
|
||||||
|
<GridDetail_4_8
|
||||||
|
label={<TextCustom bold>Kategori Report</TextCustom>}
|
||||||
|
value={
|
||||||
|
<TextCustom>{selectedReport?.kategori || "-"}</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<GridDetail_4_8
|
||||||
|
label={<TextCustom bold>Keterangan</TextCustom>}
|
||||||
|
value={
|
||||||
|
<TextCustom>{selectedReport?.keterangan || "-"}</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{selectedReport?.deskripsi && (
|
||||||
|
<GridDetail_4_8
|
||||||
|
label={<TextCustom bold>Deskripsi</TextCustom>}
|
||||||
|
value={
|
||||||
|
<TextCustom>{selectedReport?.deskripsi || "-"}</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
</DrawerCustom>
|
</DrawerCustom>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
|
||||||
{
|
|
||||||
label: "Username",
|
|
||||||
value: "Username",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const listDataAction = [
|
|
||||||
{
|
|
||||||
label: "Username",
|
|
||||||
value: "Riyusa",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Kategori Report",
|
|
||||||
value: "SPAM",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Deskripsi",
|
|
||||||
value:
|
|
||||||
"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.",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
AlertDefaultSystem,
|
AlertDefaultSystem,
|
||||||
BadgeCustom,
|
BadgeCustom,
|
||||||
BaseBox,
|
BaseBox,
|
||||||
DrawerCustom,
|
DrawerCustom,
|
||||||
|
LoaderCustom,
|
||||||
MenuDrawerDynamicGrid,
|
MenuDrawerDynamicGrid,
|
||||||
Spacing,
|
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
@@ -19,15 +20,64 @@ import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
|||||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
import { router } from "expo-router";
|
import {
|
||||||
import { useState } from "react";
|
apiAdminForumDeactivatePosting,
|
||||||
|
apiAdminForumListReportPostingById,
|
||||||
|
apiAdminForumPostingById,
|
||||||
|
} from "@/service/api-admin/api-admin-forum";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
import { Divider } from "react-native-paper";
|
import { Divider } from "react-native-paper";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminForumReportPosting() {
|
export default function AdminForumReportPosting() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
const [openDrawerPage, setOpenDrawerPage] = useState(false);
|
const [openDrawerPage, setOpenDrawerPage] = useState(false);
|
||||||
const [openDrawerAction, setOpenDrawerAction] = useState(false);
|
const [openDrawerAction, setOpenDrawerAction] = useState(false);
|
||||||
|
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
const [listReport, setListReport] = useState<any[] | null>(null);
|
||||||
|
const [loadListReport, setLoadListReport] = useState(false);
|
||||||
|
const [selectedReport, setSelectedReport] = useState({
|
||||||
|
id: "",
|
||||||
|
username: "",
|
||||||
|
kategori: "",
|
||||||
|
keterangan: "",
|
||||||
|
deskripsi: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setLoadListReport(true);
|
||||||
|
const response = await apiAdminForumPostingById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
const responseReport = await apiAdminForumListReportPostingById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseReport.success) {
|
||||||
|
setListReport(responseReport.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadListReport(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
@@ -45,50 +95,86 @@ export default function AdminForumReportPosting() {
|
|||||||
>
|
>
|
||||||
<BaseBox>
|
<BaseBox>
|
||||||
<StackCustom gap={"sm"}>
|
<StackCustom gap={"sm"}>
|
||||||
{listData.map((item, i) => (
|
<GridDetail_4_8
|
||||||
<GridDetail_4_8
|
label={<TextCustom bold>Username</TextCustom>}
|
||||||
key={i}
|
value={<TextCustom>{data?.Author?.username || "-"}</TextCustom>}
|
||||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
/>
|
||||||
value={<TextCustom>{item.value}</TextCustom>}
|
|
||||||
/>
|
<GridDetail_4_8
|
||||||
))}
|
label={<TextCustom bold>Status</TextCustom>}
|
||||||
<TextCustom bold>Posting</TextCustom>
|
value={
|
||||||
<TextCustom>
|
data && data?.ForumMaster_StatusPosting?.status ? (
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
<BadgeCustom
|
||||||
Asperiores cupiditate nobis dignissimos explicabo quo unde dolorum
|
color={
|
||||||
numquam eos ab laborum fugiat illo nam velit quibusdam, maxime
|
data?.ForumMaster_StatusPosting?.status === "Open"
|
||||||
assumenda aut vero provident!
|
? MainColor.green
|
||||||
</TextCustom>
|
: MainColor.red
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{data?.ForumMaster_StatusPosting?.status === "Open"
|
||||||
|
? "Open"
|
||||||
|
: "Close"}
|
||||||
|
</BadgeCustom>
|
||||||
|
) : (
|
||||||
|
<TextCustom>{"-"}</TextCustom>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<GridDetail_4_8
|
||||||
|
label={<TextCustom bold>Postingan</TextCustom>}
|
||||||
|
value={<TextCustom>{data?.diskusi || "-"}</TextCustom>}
|
||||||
|
/>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
|
|
||||||
<AdminComp_BoxTitle title="Daftar Report Posting" />
|
<AdminComp_BoxTitle title="Daftar Report Posting" />
|
||||||
<BaseBox>
|
<StackCustom gap={"sm"}>
|
||||||
<AdminTitleTable
|
<AdminTitleTable
|
||||||
title1="Aksi"
|
title1="Aksi"
|
||||||
title2="Username"
|
title2="Pelapor"
|
||||||
title3="Kategori Report"
|
title3="Kategori Report"
|
||||||
/>
|
/>
|
||||||
<Spacing />
|
|
||||||
<Divider />
|
<Divider />
|
||||||
{Array.from({ length: 5 }).map((_, index) => (
|
{loadListReport ? (
|
||||||
<AdminTableValue
|
<LoaderCustom />
|
||||||
key={index}
|
) : _.isEmpty(listReport) ? (
|
||||||
value1={
|
<TextCustom align="center" color={"gray"}>
|
||||||
<ActionIcon
|
Belum ada report
|
||||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
</TextCustom>
|
||||||
onPress={() => setOpenDrawerAction(true)}
|
) : (
|
||||||
/>
|
listReport?.map((item: any, index: number) => (
|
||||||
}
|
<AdminTableValue
|
||||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
key={index}
|
||||||
value3={
|
value1={
|
||||||
<TextCustom truncate={2} align="center">
|
<ActionIcon
|
||||||
SPAM
|
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||||
</TextCustom>
|
onPress={() => {
|
||||||
}
|
setOpenDrawerAction(true);
|
||||||
/>
|
setSelectedReport({
|
||||||
))}
|
id: item?.id,
|
||||||
</BaseBox>
|
username: item?.User?.username,
|
||||||
|
kategori: item?.ForumMaster_KategoriReport?.title,
|
||||||
|
keterangan: item?.ForumMaster_KategoriReport?.deskripsi,
|
||||||
|
deskripsi: item?.deskripsi,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
value2={
|
||||||
|
<TextCustom truncate={1}>
|
||||||
|
{item?.User?.username || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom truncate={2} align="center">
|
||||||
|
{item?.ForumMaster_KategoriReport?.title || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
|
|
||||||
<DrawerCustom
|
<DrawerCustom
|
||||||
@@ -112,13 +198,25 @@ export default function AdminForumReportPosting() {
|
|||||||
message: "Apakah Anda yakin ingin menghapus posting ini?",
|
message: "Apakah Anda yakin ingin menghapus posting ini?",
|
||||||
textLeft: "Batal",
|
textLeft: "Batal",
|
||||||
textRight: "Hapus",
|
textRight: "Hapus",
|
||||||
onPressRight: () => {
|
onPressRight: async () => {
|
||||||
|
const response = await apiAdminForumDeactivatePosting({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Posting gagal dihapus",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setOpenDrawerPage(false);
|
setOpenDrawerPage(false);
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "success",
|
type: "success",
|
||||||
text1: "Posting berhasil dihapus",
|
text1: "Posting berhasil dihapus",
|
||||||
});
|
});
|
||||||
router.back()
|
router.back();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
@@ -130,41 +228,39 @@ export default function AdminForumReportPosting() {
|
|||||||
closeDrawer={() => setOpenDrawerAction(false)}
|
closeDrawer={() => setOpenDrawerAction(false)}
|
||||||
height={"auto"}
|
height={"auto"}
|
||||||
>
|
>
|
||||||
{listDataAction.map((item, i) => (
|
<StackCustom>
|
||||||
<GridDetail_4_8
|
<GridDetail_4_8
|
||||||
key={i}
|
label={<TextCustom bold>Pelapor</TextCustom>}
|
||||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
value={<TextCustom>{selectedReport?.username || "-"}</TextCustom>}
|
||||||
value={<TextCustom>{item.value}</TextCustom>}
|
|
||||||
/>
|
/>
|
||||||
))}
|
|
||||||
|
{selectedReport?.kategori && (
|
||||||
|
<>
|
||||||
|
<GridDetail_4_8
|
||||||
|
label={<TextCustom bold>Kategori Report</TextCustom>}
|
||||||
|
value={
|
||||||
|
<TextCustom>{selectedReport?.kategori || "-"}</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<GridDetail_4_8
|
||||||
|
label={<TextCustom bold>Keterangan</TextCustom>}
|
||||||
|
value={
|
||||||
|
<TextCustom>{selectedReport?.keterangan || "-"}</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{selectedReport?.deskripsi && (
|
||||||
|
<GridDetail_4_8
|
||||||
|
label={<TextCustom bold>Deskripsi</TextCustom>}
|
||||||
|
value={
|
||||||
|
<TextCustom>{selectedReport?.deskripsi || "-"}</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
</DrawerCustom>
|
</DrawerCustom>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
|
||||||
{
|
|
||||||
label: "Username",
|
|
||||||
value: "Username",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Status",
|
|
||||||
value: <BadgeCustom color={MainColor.green}>Open</BadgeCustom>,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const listDataAction = [
|
|
||||||
{
|
|
||||||
label: "Username",
|
|
||||||
value: "Firman Nusantara",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Kategori Report",
|
|
||||||
value: "SPAM",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Deskripsi",
|
|
||||||
value:
|
|
||||||
"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.",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -1,13 +1,53 @@
|
|||||||
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
||||||
import {
|
import { IconPublish, IconReport } from "@/components/_Icon/IconComponent";
|
||||||
IconPublish,
|
|
||||||
IconReport,
|
|
||||||
} from "@/components/_Icon/IconComponent";
|
|
||||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { apiAdminForum } from "@/service/api-admin/api-admin-forum";
|
||||||
|
import { useFocusEffect } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function AdminForum() {
|
export default function AdminForum() {
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
handlerLoadList();
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const handlerLoadList = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminForum({
|
||||||
|
category: "dashboard",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const listData = [
|
||||||
|
{
|
||||||
|
label: "Posting",
|
||||||
|
value: data?.posting || 0,
|
||||||
|
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Report Posting",
|
||||||
|
value: data?.reportPosting || 0,
|
||||||
|
icon: <IconReport size={25} color={MainColor.orange} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Report Comment",
|
||||||
|
value: data?.reportComment || 0,
|
||||||
|
icon: <IconReport size={25} color={MainColor.red} />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper>
|
<ViewWrapper>
|
||||||
@@ -22,21 +62,3 @@ export default function AdminForum() {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
|
||||||
{
|
|
||||||
label: "Posting",
|
|
||||||
value: 4,
|
|
||||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Report Posting",
|
|
||||||
value: 7,
|
|
||||||
icon: <IconReport size={25} color={MainColor.orange} />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Report Comment",
|
|
||||||
value: 5,
|
|
||||||
icon: <IconReport size={25} color={MainColor.red} />,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
LoaderCustom,
|
||||||
SearchInput,
|
SearchInput,
|
||||||
Spacing,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
@@ -12,15 +13,47 @@ import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
|||||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
import { router } from "expo-router";
|
import { apiAdminForum } from "@/service/api-admin/api-admin-forum";
|
||||||
import React from "react";
|
import { router, useFocusEffect } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import React, { useCallback, useState } from "react";
|
||||||
import { Divider } from "react-native-paper";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminForumPosting() {
|
export default function AdminForumPosting() {
|
||||||
|
const [list, setList] = useState<any | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState(false);
|
||||||
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
handlerLoadList();
|
||||||
|
}, [search])
|
||||||
|
);
|
||||||
|
|
||||||
|
const handlerLoadList = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
const response = await apiAdminForum({
|
||||||
|
category: "posting",
|
||||||
|
search: search,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setList(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const rightComponent = (
|
const rightComponent = (
|
||||||
<SearchInput
|
<SearchInput
|
||||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||||
placeholder="Cari"
|
placeholder="Cari"
|
||||||
|
value={search}
|
||||||
|
onChangeText={setSearch}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -28,33 +61,39 @@ export default function AdminForumPosting() {
|
|||||||
<>
|
<>
|
||||||
<ViewWrapper headerComponent={<AdminTitlePage title="Forum" />}>
|
<ViewWrapper headerComponent={<AdminTitlePage title="Forum" />}>
|
||||||
<AdminComp_BoxTitle title={"Posting"} rightComponent={rightComponent} />
|
<AdminComp_BoxTitle title={"Posting"} rightComponent={rightComponent} />
|
||||||
<BaseBox>
|
<StackCustom>
|
||||||
<AdminTitleTable title1="Aksi" title2="Username" title3="Postingan" />
|
<AdminTitleTable title1="Aksi" title2="Username" title3="Postingan" />
|
||||||
<Spacing />
|
|
||||||
<Divider />
|
<Divider />
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
{loadList ? (
|
||||||
<AdminTableValue
|
<LoaderCustom />
|
||||||
key={index}
|
) : _.isEmpty(list) ? (
|
||||||
value1={
|
<TextCustom align="center" color="gray">
|
||||||
<ActionIcon
|
Belum ada data
|
||||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
</TextCustom>
|
||||||
onPress={() => {
|
) : (
|
||||||
router.push(`/admin/forum/${index + 1}`);
|
list?.map((item: any, index: number) => (
|
||||||
}}
|
<AdminTableValue
|
||||||
/>
|
key={index}
|
||||||
}
|
value1={
|
||||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
<ActionIcon
|
||||||
value3={
|
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||||
<TextCustom truncate={2}>
|
onPress={() => {
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
router.push(`/admin/forum/${item?.id}`);
|
||||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
}}
|
||||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
/>
|
||||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
}
|
||||||
</TextCustom>
|
value2={
|
||||||
}
|
<TextCustom truncate={1}>
|
||||||
/>
|
{item?.Author?.username || "-"}
|
||||||
))}
|
</TextCustom>
|
||||||
</BaseBox>
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom truncate={2}>{item?.diskusi || "-"}</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
LoaderCustom,
|
||||||
Divider,
|
|
||||||
SearchInput,
|
SearchInput,
|
||||||
Spacing,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
@@ -14,14 +14,48 @@ import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
|||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
import { router } from "expo-router";
|
import { apiAdminForum } from "@/service/api-admin/api-admin-forum";
|
||||||
|
import { router, useFocusEffect } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminForumReportComment() {
|
export default function AdminForumReportComment() {
|
||||||
|
const [listData, setListData] = useState<any[] | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState<boolean>(false);
|
||||||
|
const [search, setSearch] = useState<string>("");
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [search])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
|
||||||
|
const response = await apiAdminForum({
|
||||||
|
category: "report_comment",
|
||||||
|
search: search,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setListData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const rightComponent = (
|
const rightComponent = (
|
||||||
<SearchInput
|
<SearchInput
|
||||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||||
placeholder="Cari Komentar"
|
placeholder="Cari Komentar"
|
||||||
|
value={search}
|
||||||
|
onChangeText={setSearch}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -29,36 +63,56 @@ export default function AdminForumReportComment() {
|
|||||||
<>
|
<>
|
||||||
<ViewWrapper headerComponent={<AdminTitlePage title="Forum" />}>
|
<ViewWrapper headerComponent={<AdminTitlePage title="Forum" />}>
|
||||||
<AdminComp_BoxTitle
|
<AdminComp_BoxTitle
|
||||||
title="Report Comment"
|
title="Report Komentar"
|
||||||
rightComponent={rightComponent}
|
rightComponent={rightComponent}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<BaseBox>
|
<StackCustom gap={"sm"}>
|
||||||
<AdminTitleTable title1="Aksi" title2="Pelapor" title3="Jenis Laporan" />
|
<AdminTitleTable
|
||||||
<Spacing />
|
title1="Aksi"
|
||||||
|
title2="Pelapor"
|
||||||
|
title3="Jenis Laporan"
|
||||||
|
/>
|
||||||
<Divider />
|
<Divider />
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
{loadList ? (
|
||||||
<AdminTableValue
|
<LoaderCustom />
|
||||||
key={index}
|
) : _.isEmpty(listData) ? (
|
||||||
value1={
|
<TextCustom align="center" color="gray">
|
||||||
<ActionIcon
|
Belum ada data
|
||||||
icon={
|
</TextCustom>
|
||||||
<IconView size={ICON_SIZE_BUTTON} color={MainColor.black} />
|
) : (
|
||||||
}
|
listData?.map((item: any, index: number) => (
|
||||||
onPress={() => {
|
<AdminTableValue
|
||||||
router.push(`/admin/forum/${index + 1}/list-report-comment`);
|
key={index}
|
||||||
}}
|
value1={
|
||||||
/>
|
<ActionIcon
|
||||||
}
|
icon={
|
||||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
<IconView
|
||||||
value3={
|
size={ICON_SIZE_BUTTON}
|
||||||
<TextCustom truncate={2} align="center">
|
color={MainColor.black}
|
||||||
SPAM
|
/>
|
||||||
</TextCustom>
|
}
|
||||||
}
|
onPress={() => {
|
||||||
/>
|
router.push(
|
||||||
))}
|
`/admin/forum/${item?.Forum_Komentar?.id}/list-report-comment`
|
||||||
</BaseBox>
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
value2={
|
||||||
|
<TextCustom truncate={1}>
|
||||||
|
{item?.User?.username || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom truncate={2} align="center">
|
||||||
|
{item?.ForumMaster_KategoriReport?.title || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
|
||||||
Divider,
|
Divider,
|
||||||
|
LoaderCustom,
|
||||||
SearchInput,
|
SearchInput,
|
||||||
Spacing,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { IconView } from "@/components/_Icon/IconComponent";
|
import { IconView } from "@/components/_Icon/IconComponent";
|
||||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||||
@@ -15,17 +15,47 @@ import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
|||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
import { router } from "expo-router";
|
import { apiAdminForum } from "@/service/api-admin/api-admin-forum";
|
||||||
import { useState } from "react";
|
import { router, useFocusEffect } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function AdminForumReportPosting() {
|
export default function AdminForumReportPosting() {
|
||||||
const [openDrawer, setOpenDrawer] = useState(false);
|
const [listData, setListData] = useState<any[] | null>(null);
|
||||||
const [id, setId] = useState<any>();
|
const [loadList, setLoadList] = useState<boolean>(false);
|
||||||
|
const [search, setSearch] = useState<string>("");
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [search])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
|
||||||
|
const response = await apiAdminForum({
|
||||||
|
category: "report_posting",
|
||||||
|
search: search,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setListData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const rightComponent = (
|
const rightComponent = (
|
||||||
<SearchInput
|
<SearchInput
|
||||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||||
placeholder="Cari"
|
placeholder="Cari Postingan"
|
||||||
|
value={search}
|
||||||
|
onChangeText={setSearch}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -37,36 +67,49 @@ export default function AdminForumReportPosting() {
|
|||||||
rightComponent={rightComponent}
|
rightComponent={rightComponent}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<BaseBox>
|
<StackCustom gap={"sm"}>
|
||||||
<AdminTitleTable title1="Aksi" title2="Pelapor" title3="Postingan" />
|
<AdminTitleTable title1="Aksi" title2="Pelapor" title3="Postingan" />
|
||||||
<Spacing />
|
|
||||||
<Divider />
|
<Divider />
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
{loadList ? (
|
||||||
<AdminTableValue
|
<LoaderCustom />
|
||||||
key={index}
|
) : _.isEmpty(listData) ? (
|
||||||
value1={
|
<TextCustom align="center" color="gray">
|
||||||
<ActionIcon
|
Belum ada data
|
||||||
icon={
|
</TextCustom>
|
||||||
<IconView size={ICON_SIZE_BUTTON} color={MainColor.black} />
|
) : (
|
||||||
}
|
listData?.map((item: any, index: number) => (
|
||||||
onPress={() => {
|
<AdminTableValue
|
||||||
router.push(`/admin/forum/${id}/list-report-posting`);
|
key={index}
|
||||||
}}
|
value1={
|
||||||
/>
|
<ActionIcon
|
||||||
}
|
icon={
|
||||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
<IconView
|
||||||
value3={
|
size={ICON_SIZE_BUTTON}
|
||||||
<TextCustom truncate={2} align="center">
|
color={MainColor.black}
|
||||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit.
|
/>
|
||||||
Omnis laborum doloremque eius velit voluptate corrupti vel,
|
}
|
||||||
provident quaerat tempore animi sed accusamus amet.
|
onPress={() => {
|
||||||
Temporibus, praesentium? Rem voluptatum nesciunt voluptas
|
router.push(
|
||||||
repellat.
|
`/admin/forum/${item?.Forum_Posting?.id}/list-report-posting`
|
||||||
</TextCustom>
|
);
|
||||||
}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
}
|
||||||
</BaseBox>
|
value2={
|
||||||
|
<TextCustom truncate={1}>
|
||||||
|
{item?.User?.username || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom truncate={2} align="center">
|
||||||
|
{item?.Forum_Posting?.diskusi || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
AlertDefaultSystem,
|
AlertDefaultSystem,
|
||||||
BadgeCustom,
|
BadgeCustom,
|
||||||
@@ -7,17 +8,43 @@ import {
|
|||||||
Spacing,
|
Spacing,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||||
|
import ReportBox from "@/components/Box/ReportBox";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import funUpdateStatusJob from "@/screens/Admin/Job/funUpdateStatus";
|
||||||
|
import { apiAdminJobGetById } from "@/service/api-admin/api-admin-job";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminJobDetailStatus() {
|
export default function AdminJobDetailStatus() {
|
||||||
const { id, status } = useLocalSearchParams();
|
const { id, status } = useLocalSearchParams();
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminJobGetById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const colorBadge = () => {
|
const colorBadge = () => {
|
||||||
if (status === "publish") {
|
if (status === "publish") {
|
||||||
@@ -32,11 +59,11 @@ export default function AdminJobDetailStatus() {
|
|||||||
const listData = [
|
const listData = [
|
||||||
{
|
{
|
||||||
label: "Username",
|
label: "Username",
|
||||||
value: "Bagas Banuna",
|
value: data?.Author?.username || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Judul",
|
label: "Judul",
|
||||||
value: `Judul Proyek: ${id}Lorem ipsum dolor sit amet consectetur adipisicing elit.`,
|
value: data?.title || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Status",
|
label: "Status",
|
||||||
@@ -48,24 +75,43 @@ export default function AdminJobDetailStatus() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Konten",
|
label: "Konten",
|
||||||
value: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
value: data?.content || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Deskripsi",
|
label: "Deskripsi",
|
||||||
value: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
value: data?.deskripsi || "-",
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// label: "Poster",
|
|
||||||
// value: (
|
|
||||||
// <ButtonCustom
|
|
||||||
// href={`/(application)/()/${id}`}
|
|
||||||
// >
|
|
||||||
// Lihat Poster
|
|
||||||
// </ButtonCustom>
|
|
||||||
// ),
|
|
||||||
// },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const handleUpdate = async ({
|
||||||
|
changeStatus,
|
||||||
|
}: {
|
||||||
|
changeStatus: "publish" | "review" | "reject";
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
const response = await funUpdateStatusJob({
|
||||||
|
id: id as string,
|
||||||
|
changeStatus,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Gagal mempublikasikan data",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Berhasil mempublikasikan data",
|
||||||
|
});
|
||||||
|
|
||||||
|
router.back();
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
@@ -73,8 +119,8 @@ export default function AdminJobDetailStatus() {
|
|||||||
>
|
>
|
||||||
<BaseBox>
|
<BaseBox>
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
{listData.map((item, i) => (
|
{listData?.map((item, index) => (
|
||||||
<Grid key={i}>
|
<Grid key={index}>
|
||||||
<Grid.Col
|
<Grid.Col
|
||||||
span={4}
|
span={4}
|
||||||
style={{ justifyContent: "center", paddingRight: 10 }}
|
style={{ justifyContent: "center", paddingRight: 10 }}
|
||||||
@@ -87,12 +133,19 @@ export default function AdminJobDetailStatus() {
|
|||||||
</Grid>
|
</Grid>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<TextCustom bold>Poster</TextCustom>
|
{data && data?.imageId && (
|
||||||
|
<StackCustom>
|
||||||
<DummyLandscapeImage />
|
<TextCustom bold>Poster</TextCustom>
|
||||||
|
<DummyLandscapeImage imageId={data?.imageId} />
|
||||||
|
</StackCustom>
|
||||||
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
|
|
||||||
|
{data && data?.catatan && (status === "reject" || status === "review") && (
|
||||||
|
<ReportBox text={data?.catatan}/>
|
||||||
|
)}
|
||||||
|
|
||||||
{status === "review" && (
|
{status === "review" && (
|
||||||
<AdminButtonReview
|
<AdminButtonReview
|
||||||
onPublish={() => {
|
onPublish={() => {
|
||||||
@@ -101,24 +154,22 @@ export default function AdminJobDetailStatus() {
|
|||||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||||
textLeft: "Batal",
|
textLeft: "Batal",
|
||||||
textRight: "Ya",
|
textRight: "Ya",
|
||||||
onPressLeft: () => {
|
|
||||||
router.back();
|
|
||||||
},
|
|
||||||
onPressRight: () => {
|
onPressRight: () => {
|
||||||
router.back();
|
handleUpdate({ changeStatus: "publish" });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
onReject={() => {
|
onReject={() => {
|
||||||
router.push(`/admin/job/${id}/reject-input`);
|
router.push(`/admin/job/${id}/${status}/reject-input`);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{status === "reject" && (
|
{status === "reject" && (
|
||||||
<AdminButtonReject
|
<AdminButtonReject
|
||||||
title="Tambah Catatan"
|
title="Tambah Catatan"
|
||||||
onReject={() => {
|
onReject={() => {
|
||||||
router.push(`/admin/job/${id}/reject-input`);
|
router.push(`/admin/job/${id}/${status}/reject-input`);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
115
app/(application)/admin/job/[id]/[status]/reject-input.tsx
Normal file
115
app/(application)/admin/job/[id]/[status]/reject-input.tsx
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import {
|
||||||
|
AlertDefaultSystem,
|
||||||
|
BoxButtonOnFooter,
|
||||||
|
TextAreaCustom,
|
||||||
|
ViewWrapper,
|
||||||
|
} from "@/components";
|
||||||
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||||
|
import funUpdateStatusJob from "@/screens/Admin/Job/funUpdateStatus";
|
||||||
|
import { apiAdminJobGetById } from "@/service/api-admin/api-admin-job";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
|
export default function AdminJobRejectInput() {
|
||||||
|
const { id, status } = useLocalSearchParams();
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminJobGetById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data.catatan);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpdate = async ({
|
||||||
|
changeStatus,
|
||||||
|
}: {
|
||||||
|
changeStatus: "publish" | "review" | "reject";
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
const response = await funUpdateStatusJob({
|
||||||
|
id: id as string,
|
||||||
|
changeStatus,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Report gagal",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Report berhasil",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (status === "review") {
|
||||||
|
router.replace(`/admin/job/reject/status`);
|
||||||
|
} else if (status === "reject") {
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const buttonSubmit = (
|
||||||
|
<BoxButtonOnFooter>
|
||||||
|
<AdminButtonReject
|
||||||
|
isLoading={isLoading}
|
||||||
|
title="Report"
|
||||||
|
onReject={() =>
|
||||||
|
AlertDefaultSystem({
|
||||||
|
title: "Reject",
|
||||||
|
message: "Apakah anda yakin ingin menolak data ini?",
|
||||||
|
textLeft: "Batal",
|
||||||
|
textRight: "Ya",
|
||||||
|
onPressRight: () => {
|
||||||
|
handleUpdate({ changeStatus: "reject" });
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</BoxButtonOnFooter>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ViewWrapper
|
||||||
|
footerComponent={buttonSubmit}
|
||||||
|
headerComponent={<AdminBackButtonAntTitle title="Penolakan Job" />}
|
||||||
|
>
|
||||||
|
<TextAreaCustom
|
||||||
|
value={data}
|
||||||
|
onChangeText={setData}
|
||||||
|
placeholder="Masukan alasan"
|
||||||
|
required
|
||||||
|
showCount
|
||||||
|
maxLength={1000}
|
||||||
|
/>
|
||||||
|
</ViewWrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
LoaderCustom,
|
||||||
SearchInput,
|
SearchInput,
|
||||||
Spacing,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper
|
ViewWrapper
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
@@ -11,17 +12,48 @@ import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
|||||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
|
import { apiAdminJob } from "@/service/api-admin/api-admin-job";
|
||||||
import { Octicons } from "@expo/vector-icons";
|
import { Octicons } from "@expo/vector-icons";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
import { Divider } from "react-native-paper";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminJobStatus() {
|
export default function AdminJobStatus() {
|
||||||
const { status } = useLocalSearchParams();
|
const { status } = useLocalSearchParams();
|
||||||
|
const [list, setList] = useState<any | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState(false);
|
||||||
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
handlerLoadList();
|
||||||
|
}, [status, search])
|
||||||
|
);
|
||||||
|
|
||||||
|
const handlerLoadList = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
const response = await apiAdminJob({
|
||||||
|
category: status as "publish" | "review" | "reject",
|
||||||
|
search,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setList(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const rightComponent = (
|
const rightComponent = (
|
||||||
<SearchInput
|
<SearchInput
|
||||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
|
||||||
placeholder="Cari"
|
placeholder="Cari"
|
||||||
|
onChangeText={setSearch}
|
||||||
|
value={search}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
@@ -32,44 +64,53 @@ export default function AdminJobStatus() {
|
|||||||
rightComponent={rightComponent}
|
rightComponent={rightComponent}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<BaseBox>
|
<StackCustom>
|
||||||
<AdminTitleTable
|
<AdminTitleTable
|
||||||
title1="Aksi"
|
title1="Aksi"
|
||||||
title2="Username"
|
title2="Username"
|
||||||
title3="Judul Pekerjaan"
|
title3="Judul Pekerjaan"
|
||||||
/>
|
/>
|
||||||
<Spacing />
|
{/* <Spacing /> */}
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
{loadList ? (
|
||||||
<AdminTableValue
|
<LoaderCustom />
|
||||||
key={index}
|
) : _.isEmpty(list) ? (
|
||||||
value1={
|
<TextCustom align="center" color="gray">
|
||||||
<ActionIcon
|
Tidak ada data
|
||||||
icon={
|
</TextCustom>
|
||||||
<Octicons
|
) : (
|
||||||
name="eye"
|
list?.map((item: any, index: number) => (
|
||||||
size={ICON_SIZE_BUTTON}
|
<AdminTableValue
|
||||||
color="black"
|
key={index}
|
||||||
/>
|
value1={
|
||||||
}
|
<ActionIcon
|
||||||
onPress={() => {
|
icon={
|
||||||
router.push(`/admin/job/${index}/${status}`);
|
<Octicons
|
||||||
}}
|
name="eye"
|
||||||
/>
|
size={ICON_SIZE_BUTTON}
|
||||||
}
|
color="black"
|
||||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
/>
|
||||||
value3={
|
}
|
||||||
<TextCustom truncate={2}>
|
onPress={() => {
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
router.push(`/admin/job/${item.id}/${status}`);
|
||||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
}}
|
||||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
/>
|
||||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
}
|
||||||
</TextCustom>
|
value2={
|
||||||
}
|
<TextCustom align="center" truncate={1}>
|
||||||
/>
|
{item?.Author?.username || "-"}
|
||||||
))}
|
</TextCustom>
|
||||||
</BaseBox>
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom truncate={2} align="center">
|
||||||
|
{item?.title || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
||||||
import {
|
import {
|
||||||
IconPublish,
|
IconPublish,
|
||||||
@@ -7,15 +8,45 @@ import {
|
|||||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { apiAdminJob } from "@/service/api-admin/api-admin-job";
|
||||||
|
import { useFocusEffect } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function AdminJob() {
|
export default function AdminJob() {
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
handlerLoadList();
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const handlerLoadList = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
const response = await apiAdminJob({
|
||||||
|
category: "dashboard",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper>
|
<ViewWrapper>
|
||||||
<AdminTitlePage title="Job Vacancy" />
|
<AdminTitlePage title="Job Vacancy" />
|
||||||
<Spacing />
|
<Spacing />
|
||||||
<StackCustom gap={"xs"}>
|
<StackCustom gap={"xs"}>
|
||||||
{listData.map((item, i) => (
|
{listData(data).map((item: any, i: number) => (
|
||||||
<AdminComp_BoxDashboard key={i} item={item} />
|
<AdminComp_BoxDashboard key={i} item={item} />
|
||||||
))}
|
))}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
@@ -24,20 +55,20 @@ export default function AdminJob() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
const listData = (data: any) => [
|
||||||
{
|
{
|
||||||
label: "Publish",
|
label: "Publish",
|
||||||
value: 4,
|
value: (data && data?.publish) || 0,
|
||||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Review",
|
label: "Review",
|
||||||
value: 7,
|
value: (data && data?.review) || 0,
|
||||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
icon: <IconReview size={25} color={MainColor.orange} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Reject",
|
label: "Reject",
|
||||||
value: 5,
|
value: (data && data?.reject) || 0,
|
||||||
icon: <IconReject size={25} color={MainColor.red} />,
|
icon: <IconReject size={25} color={MainColor.red} />,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,11 +1,224 @@
|
|||||||
import { MapCustom, ViewWrapper } from "@/components";
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface LocationItem {
|
||||||
|
id: string | number;
|
||||||
|
latitude: number;
|
||||||
|
longitude: number;
|
||||||
|
name: string;
|
||||||
|
imageId?: string;
|
||||||
|
}
|
||||||
export default function AdminMaps() {
|
export default function AdminMaps() {
|
||||||
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper>
|
<ViewWrapper style={{ paddingInline: 0, paddingBlock: 0 }}>
|
||||||
<MapCustom height={"100%"} />
|
{/* <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>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: API_IMAGE.GET({
|
||||||
|
fileId: item?.Portofolio?.logoId,
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
borderRadius: 100,
|
||||||
|
borderWidth: 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</Marker>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</MapView>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
</ViewWrapper>
|
</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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
128
app/(application)/admin/super-admin/[id]/index.tsx
Normal file
128
app/(application)/admin/super-admin/[id]/index.tsx
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import {
|
||||||
|
BoxButtonOnFooter,
|
||||||
|
ButtonCustom,
|
||||||
|
LoaderCustom,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
|
ViewWrapper,
|
||||||
|
} from "@/components";
|
||||||
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import GridTwoView from "@/components/_ShareComponent/GridTwoView";
|
||||||
|
import {
|
||||||
|
apiAdminUserAccessGetById,
|
||||||
|
apiAdminUserAccessUpdateStatus,
|
||||||
|
} from "@/service/api-admin/api-admin-user-access";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
|
export default function SuperAdminDetail() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
const [loadData, setLoadData] = useState(false);
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setLoadData(true);
|
||||||
|
const response = await apiAdminUserAccessGetById({ id: id as string });
|
||||||
|
|
||||||
|
setData(response.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR LOAD DATA]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadData(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlerSubmit = async () => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const response = await apiAdminUserAccessUpdateStatus({
|
||||||
|
id: id as string,
|
||||||
|
role: data?.masterUserRoleId === "2" ? "user" : "admin",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Update role gagal",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Update role berhasil ",
|
||||||
|
});
|
||||||
|
router.back();
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR UPDATE STATUS]", error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ViewWrapper
|
||||||
|
headerComponent={<AdminBackButtonAntTitle title={`Detail User`} />}
|
||||||
|
footerComponent={
|
||||||
|
data && (
|
||||||
|
<BoxButtonOnFooter>
|
||||||
|
<ButtonCustom
|
||||||
|
isLoading={isLoading}
|
||||||
|
backgroundColor={
|
||||||
|
data?.masterUserRoleId === "2" ? "red" : "green"
|
||||||
|
}
|
||||||
|
textColor={"white"}
|
||||||
|
onPress={handlerSubmit}
|
||||||
|
>
|
||||||
|
{data?.masterUserRoleId === "2"
|
||||||
|
? "Hapus akses admin"
|
||||||
|
: "Tambah sebagai admin"}
|
||||||
|
</ButtonCustom>
|
||||||
|
</BoxButtonOnFooter>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{loadData ? (
|
||||||
|
<LoaderCustom />
|
||||||
|
) : (
|
||||||
|
<StackCustom>
|
||||||
|
{listData(data && data)?.map((item: any, index: number) => (
|
||||||
|
<GridTwoView
|
||||||
|
key={index}
|
||||||
|
spanLeft={4}
|
||||||
|
spanRight={8}
|
||||||
|
leftIcon={<TextCustom bold>{item?.label}</TextCustom>}
|
||||||
|
rightIcon={<TextCustom>{item?.value}</TextCustom>}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</StackCustom>
|
||||||
|
)}
|
||||||
|
</ViewWrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const listData = (data: any) => [
|
||||||
|
{
|
||||||
|
label: "Username",
|
||||||
|
value: (data && data?.username) || "-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Role",
|
||||||
|
value: data && data?.masterUserRoleId === "2" ? "Admin" : "User",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Nomor",
|
||||||
|
value: (data && `+${data?.nomor}`) || "-",
|
||||||
|
},
|
||||||
|
];
|
||||||
148
app/(application)/admin/super-admin/index.tsx
Normal file
148
app/(application)/admin/super-admin/index.tsx
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import {
|
||||||
|
BadgeCustom,
|
||||||
|
CenterCustom,
|
||||||
|
Divider,
|
||||||
|
SearchInput,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
|
ViewWrapper,
|
||||||
|
} from "@/components";
|
||||||
|
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||||
|
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||||
|
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||||
|
import { ICON_SIZE_XLARGE } from "@/constants/constans-value";
|
||||||
|
import { apiAdminUserAccessGetAll } from "@/service/api-admin/api-admin-user-access";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
|
||||||
|
import { router, useFocusEffect } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
|
export default function SuperAdmin_ListUser() {
|
||||||
|
const [listData, setListData] = useState<any[] | null>(null);
|
||||||
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [search])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminUserAccessGetAll({
|
||||||
|
search: search,
|
||||||
|
category: "all-role",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setListData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR LOAD DATA]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const rightComponent = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SearchInput
|
||||||
|
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||||
|
placeholder="Cari Username"
|
||||||
|
onChangeText={(text) => setSearch(text)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ViewWrapper
|
||||||
|
headerComponent={
|
||||||
|
<AdminComp_BoxTitle
|
||||||
|
title={"Super Admin"}
|
||||||
|
rightComponent={rightComponent()}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<GridViewCustomSpan
|
||||||
|
span1={2}
|
||||||
|
span2={5}
|
||||||
|
span3={5}
|
||||||
|
component1={
|
||||||
|
<TextCustom align="center" bold>
|
||||||
|
Aksi
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
component2={
|
||||||
|
<TextCustom align="center" bold>
|
||||||
|
Username
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
component3={
|
||||||
|
<TextCustom align="center" bold>
|
||||||
|
Role
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
<StackCustom>
|
||||||
|
{_.isEmpty(listData) ? (
|
||||||
|
<TextCustom align="center" color="gray" size={"small"}>
|
||||||
|
Tidak ada data
|
||||||
|
</TextCustom>
|
||||||
|
) : (
|
||||||
|
listData?.map((item: any, index: number) => (
|
||||||
|
<GridViewCustomSpan
|
||||||
|
key={index}
|
||||||
|
span1={2}
|
||||||
|
span2={5}
|
||||||
|
span3={5}
|
||||||
|
component1={
|
||||||
|
<CenterCustom>
|
||||||
|
<Ionicons
|
||||||
|
onPress={() =>
|
||||||
|
router.push(`/admin/super-admin/${item?.id}`)
|
||||||
|
}
|
||||||
|
name="open"
|
||||||
|
size={ICON_SIZE_XLARGE}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
/>
|
||||||
|
</CenterCustom>
|
||||||
|
|
||||||
|
// <ButtonCustom
|
||||||
|
// onPress={() =>
|
||||||
|
// router.push(`/admin/super-admin/${item?.id}`)
|
||||||
|
// }
|
||||||
|
// >
|
||||||
|
// Detail
|
||||||
|
// </ButtonCustom>
|
||||||
|
}
|
||||||
|
component2={
|
||||||
|
<TextCustom bold truncate>
|
||||||
|
{item?.username || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
component3={
|
||||||
|
<CenterCustom>
|
||||||
|
{item?.masterUserRoleId === "2" ? (
|
||||||
|
<BadgeCustom color={AccentColor.blue}>Admin</BadgeCustom>
|
||||||
|
) : (
|
||||||
|
<BadgeCustom color={AccentColor.softblue}>
|
||||||
|
User
|
||||||
|
</BadgeCustom>
|
||||||
|
)}
|
||||||
|
</CenterCustom>
|
||||||
|
}
|
||||||
|
style3={{ alignItems: "center", justifyContent: "center" }}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
|
</ViewWrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
import {
|
|
||||||
ButtonCustom,
|
|
||||||
Divider,
|
|
||||||
Grid,
|
|
||||||
SearchInput,
|
|
||||||
StackCustom,
|
|
||||||
TextCustom,
|
|
||||||
ViewWrapper
|
|
||||||
} from "@/components";
|
|
||||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
|
||||||
import { MainColor } from "@/constants/color-palet";
|
|
||||||
import { ICON_SIZE_MEDIUM } from "@/constants/constans-value";
|
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
|
||||||
|
|
||||||
export default function AdminUserAccess() {
|
|
||||||
const rightComponent = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<SearchInput
|
|
||||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
|
||||||
placeholder="Cari User"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<ViewWrapper
|
|
||||||
headerComponent={
|
|
||||||
<AdminComp_BoxTitle
|
|
||||||
title="User Access"
|
|
||||||
rightComponent={rightComponent()}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Grid>
|
|
||||||
<Grid.Col span={4} style={{ alignItems: "center" }}>
|
|
||||||
<TextCustom bold>Aksi</TextCustom>
|
|
||||||
</Grid.Col>
|
|
||||||
<Grid.Col span={4} style={{ alignItems: "center" }}>
|
|
||||||
<TextCustom bold>Username</TextCustom>
|
|
||||||
</Grid.Col>
|
|
||||||
<Grid.Col span={4} style={{ alignItems: "center" }}>
|
|
||||||
<TextCustom bold>Nomor</TextCustom>
|
|
||||||
</Grid.Col>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Divider />
|
|
||||||
|
|
||||||
<StackCustom>
|
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
|
||||||
<Grid key={index}>
|
|
||||||
<Grid.Col
|
|
||||||
span={4}
|
|
||||||
style={{
|
|
||||||
alignItems: "center",
|
|
||||||
paddingLeft: 5,
|
|
||||||
paddingRight: 5,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextCustom bold>
|
|
||||||
<ButtonCustom
|
|
||||||
iconLeft={
|
|
||||||
<Ionicons
|
|
||||||
name={
|
|
||||||
index % 2 === 0
|
|
||||||
? "checkmark-outline"
|
|
||||||
: "close-circle-outline"
|
|
||||||
}
|
|
||||||
size={ICON_SIZE_MEDIUM}
|
|
||||||
color="black"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onPress={() => {}}
|
|
||||||
backgroundColor={
|
|
||||||
index % 2 === 0 ? MainColor.green : MainColor.red
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<TextCustom size={"small"} color={"black"}>
|
|
||||||
{index % 2 === 0 ? "Berikan Akses" : "Hapus Akses"}
|
|
||||||
</TextCustom>
|
|
||||||
</ButtonCustom>
|
|
||||||
</TextCustom>
|
|
||||||
</Grid.Col>
|
|
||||||
<Grid.Col
|
|
||||||
span={4}
|
|
||||||
style={{
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
paddingLeft: 5,
|
|
||||||
paddingRight: 5,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextCustom bold truncate>
|
|
||||||
Useraname
|
|
||||||
</TextCustom>
|
|
||||||
</Grid.Col>
|
|
||||||
<Grid.Col
|
|
||||||
span={4}
|
|
||||||
style={{
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
paddingLeft: 5,
|
|
||||||
paddingRight: 5,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextCustom bold truncate>
|
|
||||||
08123456789
|
|
||||||
</TextCustom>
|
|
||||||
</Grid.Col>
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
</StackCustom>
|
|
||||||
</ViewWrapper>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
124
app/(application)/admin/user-access/[id]/index.tsx
Normal file
124
app/(application)/admin/user-access/[id]/index.tsx
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import {
|
||||||
|
BoxButtonOnFooter,
|
||||||
|
ButtonCustom,
|
||||||
|
LoaderCustom,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
|
ViewWrapper,
|
||||||
|
} from "@/components";
|
||||||
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import GridTwoView from "@/components/_ShareComponent/GridTwoView";
|
||||||
|
import {
|
||||||
|
apiAdminUserAccessGetById,
|
||||||
|
apiAdminUserAccessUpdateStatus,
|
||||||
|
} from "@/service/api-admin/api-admin-user-access";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
|
export default function AdminUserAccessDetail() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
const [loadData, setLoadData] = useState(false);
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setLoadData(true);
|
||||||
|
const response = await apiAdminUserAccessGetById({ id: id as string });
|
||||||
|
|
||||||
|
setData(response.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR LOAD DATA]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadData(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlerSubmit = async () => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const response = await apiAdminUserAccessUpdateStatus({
|
||||||
|
id: id as string,
|
||||||
|
active: !data?.active,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Update aktifasi gagal",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Update aktifasi berhasil ",
|
||||||
|
});
|
||||||
|
router.back();
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR UPDATE STATUS]", error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ViewWrapper
|
||||||
|
headerComponent={<AdminBackButtonAntTitle title={`Detail User`} />}
|
||||||
|
footerComponent={
|
||||||
|
data && (
|
||||||
|
<BoxButtonOnFooter>
|
||||||
|
<ButtonCustom
|
||||||
|
isLoading={isLoading}
|
||||||
|
backgroundColor={data?.active ? "red" : "green"}
|
||||||
|
textColor={"white"}
|
||||||
|
onPress={handlerSubmit}
|
||||||
|
>
|
||||||
|
{data?.active ? "Hapus Akses" : "Berikan Akses"}
|
||||||
|
</ButtonCustom>
|
||||||
|
</BoxButtonOnFooter>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{loadData ? (
|
||||||
|
<LoaderCustom />
|
||||||
|
) : (
|
||||||
|
<StackCustom>
|
||||||
|
{listData(data && data)?.map((item: any, index: number) => (
|
||||||
|
<GridTwoView
|
||||||
|
key={index}
|
||||||
|
spanLeft={4}
|
||||||
|
spanRight={8}
|
||||||
|
leftIcon={<TextCustom bold>{item?.label}</TextCustom>}
|
||||||
|
rightIcon={<TextCustom>{item?.value}</TextCustom>}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</StackCustom>
|
||||||
|
)}
|
||||||
|
</ViewWrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const listData = (data: any) => [
|
||||||
|
{
|
||||||
|
label: "Username",
|
||||||
|
value: (data && data?.username) || "-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Aktivasi",
|
||||||
|
value: data && data?.active ? "Aktif" : "Tidak Aktif",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Nomor",
|
||||||
|
value: (data && `+${data?.nomor}`) || "-",
|
||||||
|
},
|
||||||
|
];
|
||||||
143
app/(application)/admin/user-access/index.tsx
Normal file
143
app/(application)/admin/user-access/index.tsx
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import {
|
||||||
|
BadgeCustom,
|
||||||
|
CenterCustom,
|
||||||
|
Divider,
|
||||||
|
SearchInput,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
|
ViewWrapper,
|
||||||
|
} from "@/components";
|
||||||
|
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||||
|
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { ICON_SIZE_XLARGE } from "@/constants/constans-value";
|
||||||
|
import { apiAdminUserAccessGetAll } from "@/service/api-admin/api-admin-user-access";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { router, useFocusEffect } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
|
export default function AdminUserAccess() {
|
||||||
|
const [listData, setListData] = useState<any[] | null>(null);
|
||||||
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [search])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminUserAccessGetAll({
|
||||||
|
search: search,
|
||||||
|
category: "only-user",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setListData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR LOAD DATA]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const rightComponent = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SearchInput
|
||||||
|
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||||
|
placeholder="Cari User"
|
||||||
|
onChangeText={(text) => setSearch(text)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ViewWrapper
|
||||||
|
headerComponent={
|
||||||
|
<AdminComp_BoxTitle
|
||||||
|
title="User Access"
|
||||||
|
rightComponent={rightComponent()}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<GridViewCustomSpan
|
||||||
|
span1={2}
|
||||||
|
span2={5}
|
||||||
|
span3={5}
|
||||||
|
component1={
|
||||||
|
<TextCustom align="center" bold>
|
||||||
|
Aksi
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
component2={
|
||||||
|
<TextCustom align="center" bold>
|
||||||
|
Username
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
component3={
|
||||||
|
<TextCustom align="center" bold>
|
||||||
|
Status Akses
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
<StackCustom>
|
||||||
|
{_.isEmpty(listData) ? (
|
||||||
|
<TextCustom align="center" color="gray" size={"small"}>
|
||||||
|
Tidak ada data
|
||||||
|
</TextCustom>
|
||||||
|
) : (
|
||||||
|
listData?.map((item: any, index: number) => (
|
||||||
|
<GridViewCustomSpan
|
||||||
|
key={index}
|
||||||
|
span1={2}
|
||||||
|
span2={5}
|
||||||
|
span3={5}
|
||||||
|
component1={
|
||||||
|
<CenterCustom>
|
||||||
|
<Ionicons
|
||||||
|
onPress={() =>
|
||||||
|
router.push(`/admin/user-access/${item?.id}`)
|
||||||
|
}
|
||||||
|
name="open"
|
||||||
|
size={ICON_SIZE_XLARGE}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
/>
|
||||||
|
</CenterCustom>
|
||||||
|
// <ButtonCustom
|
||||||
|
// onPress={() =>
|
||||||
|
// router.push(`/admin/user-access/${item?.id}`)
|
||||||
|
// }
|
||||||
|
// >
|
||||||
|
// Detail
|
||||||
|
// </ButtonCustom>
|
||||||
|
}
|
||||||
|
component2={
|
||||||
|
<TextCustom bold truncate>
|
||||||
|
{item?.username || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
component3={
|
||||||
|
<CenterCustom>
|
||||||
|
{item?.active ? (
|
||||||
|
<BadgeCustom color="green">Aktif</BadgeCustom>
|
||||||
|
) : (
|
||||||
|
<BadgeCustom color="red">Tidak Aktif</BadgeCustom>
|
||||||
|
)}
|
||||||
|
</CenterCustom>
|
||||||
|
}
|
||||||
|
style3={{ alignItems: "center", justifyContent: "center" }}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
|
</ViewWrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,102 +1,166 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
AlertDefaultSystem,
|
AlertDefaultSystem,
|
||||||
BadgeCustom,
|
BadgeCustom,
|
||||||
BaseBox,
|
BaseBox,
|
||||||
CircleContainer,
|
CircleContainer,
|
||||||
Grid,
|
Grid,
|
||||||
Spacing,
|
Spacing,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||||
|
import ReportBox from "@/components/Box/ReportBox";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import funUpdateStatusVoting from "@/screens/Admin/Voting/funUpdateStatus";
|
||||||
|
import { apiAdminVotingById } from "@/service/api-admin/api-admin-voting";
|
||||||
|
import { colorBadgeStatus } from "@/utils/colorBadge";
|
||||||
|
import { dateTimeView } from "@/utils/dateTimeView";
|
||||||
|
import { Entypo } from "@expo/vector-icons";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
import { List } from "react-native-paper";
|
import { List } from "react-native-paper";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminVotingDetail() {
|
export default function AdminVotingDetail() {
|
||||||
const { id, status } = useLocalSearchParams();
|
const { id, status } = useLocalSearchParams();
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const colorBadge = () => {
|
console.log("[status]", status);
|
||||||
if (status === "publish") {
|
|
||||||
return MainColor.green;
|
useFocusEffect(
|
||||||
} else if (status === "review") {
|
useCallback(() => {
|
||||||
return MainColor.orange;
|
onLoadData();
|
||||||
} else if (status === "reject") {
|
}, [id])
|
||||||
return MainColor.red;
|
);
|
||||||
} else {
|
|
||||||
return MainColor.placeholder;
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminVotingById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const listData = [
|
const listData = [
|
||||||
{
|
{
|
||||||
label: "Username",
|
label: "Username",
|
||||||
value: "Bagas Banuna",
|
value: (data && data?.Author?.username) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Judul",
|
label: "Judul",
|
||||||
value: `Judul Proyek: ${id}Lorem ipsum dolor sit amet consectetur adipisicing elit.`,
|
value: (data && data?.title) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Status",
|
label: "Status",
|
||||||
value: (
|
value:
|
||||||
<BadgeCustom color={colorBadge()}>
|
data && data?.Voting_Status?.name ? (
|
||||||
{_.startCase(status as string)}
|
<BadgeCustom color={colorBadgeStatus({ status: status as string })}>
|
||||||
</BadgeCustom>
|
{status === "history" ? "Riwayat" : _.startCase(status as string)}
|
||||||
),
|
</BadgeCustom>
|
||||||
|
) : (
|
||||||
|
"-"
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Mulai Voting",
|
label: "Mulai Voting",
|
||||||
value: dayjs().format("DD/MM/YYYY"),
|
value:
|
||||||
|
(data && data?.awalVote && dateTimeView({ date: data?.awalVote })) ||
|
||||||
|
"-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Voting Berakhir",
|
label: "Voting Berakhir",
|
||||||
value: dayjs().format("DD/MM/YYYY"),
|
value:
|
||||||
|
(data && data?.akhirVote && dateTimeView({ date: data?.akhirVote })) ||
|
||||||
|
"-",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "Deskripsi",
|
label: "Deskripsi",
|
||||||
value: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
value: (data && data?.deskripsi) || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Daftar Pilhan",
|
label: "Daftar Pilihan",
|
||||||
value: (
|
value:
|
||||||
<>
|
data && data?.Voting_DaftarNamaVote
|
||||||
<List.Item
|
? data?.Voting_DaftarNamaVote?.map((item: any, i: number) => (
|
||||||
title={<TextCustom>Pilihan 1</TextCustom>}
|
<List.Item
|
||||||
left={(props) => (
|
key={i}
|
||||||
<List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
title={<TextCustom>{item?.value}</TextCustom>}
|
||||||
)}
|
left={(props) => (
|
||||||
/>
|
<Entypo name="chevron-right" color={MainColor.yellow} />
|
||||||
<List.Item
|
)}
|
||||||
title={<TextCustom>Pilihan 2</TextCustom>}
|
/>
|
||||||
left={(props) => (
|
))
|
||||||
<List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
: "-",
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<List.Item
|
|
||||||
title={<TextCustom>Pilihan 3</TextCustom>}
|
|
||||||
left={(props) => (
|
|
||||||
<List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<List.Item
|
|
||||||
title={<TextCustom>Pilihan 4</TextCustom>}
|
|
||||||
left={(props) => (
|
|
||||||
<List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const handleUpdate = async ({
|
||||||
|
changeStatus,
|
||||||
|
}: {
|
||||||
|
changeStatus: "publish" | "review" | "reject";
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
const dateNow = new Date();
|
||||||
|
// const dateNowHour = dateNow.getHours();
|
||||||
|
// const awalVoteHour = dayjs(data?.awalVote).hour();
|
||||||
|
|
||||||
|
const isBefore = dayjs(dateNow).diff(dayjs(data?.awalVote), "hours") < 0;
|
||||||
|
console.log("[IS BEFORE]", isBefore);
|
||||||
|
|
||||||
|
if (!isBefore) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Tanggal & waktu telah lewat",
|
||||||
|
text2: "Silahkan report dan ubah tanggal & waktu voting",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Berhasil mempublikasikan data",
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
const response = await funUpdateStatusVoting({
|
||||||
|
id: id as string,
|
||||||
|
changeStatus,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Gagal mempublikasikan data",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Berhasil mempublikasikan data",
|
||||||
|
});
|
||||||
|
|
||||||
|
router.back();
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
@@ -114,46 +178,59 @@ export default function AdminVotingDetail() {
|
|||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
|
|
||||||
{status === "publish" && (
|
{status === "publish" ||
|
||||||
<BaseBox>
|
(status === "history" && (
|
||||||
<TextCustom bold align="center">
|
<BaseBox>
|
||||||
Hasil Voting
|
<TextCustom bold align="center">
|
||||||
</TextCustom>
|
Hasil Voting
|
||||||
<Spacing />
|
</TextCustom>
|
||||||
<Grid>
|
<Spacing />
|
||||||
|
<Grid>
|
||||||
{Array.from({length: 4}).map((_, index) => (
|
{data?.Voting_DaftarNamaVote?.map(
|
||||||
<Grid.Col key={index} span={3} style={{ paddingRight: 3, paddingLeft: 3 }}>
|
(item: any, index: number) => (
|
||||||
<StackCustom gap={"sm"}>
|
<Grid.Col
|
||||||
<CircleContainer value={index % 3 * 3} style={{ alignSelf: "center" }} />
|
key={index}
|
||||||
<TextCustom size="small" align="center">
|
span={12 / data?.Voting_DaftarNamaVote?.length}
|
||||||
Pilihan {index + 1}
|
style={{ paddingRight: 3, paddingLeft: 3 }}
|
||||||
</TextCustom>
|
>
|
||||||
</StackCustom>
|
<StackCustom gap={"sm"}>
|
||||||
</Grid.Col>
|
<CircleContainer
|
||||||
))}
|
value={item?.jumlah}
|
||||||
</Grid>
|
style={{ alignSelf: "center" }}
|
||||||
</BaseBox>
|
/>
|
||||||
)}
|
<TextCustom size="small" align="center">
|
||||||
|
{item?.value}
|
||||||
|
</TextCustom>
|
||||||
|
</StackCustom>
|
||||||
|
</Grid.Col>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
</BaseBox>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{data &&
|
||||||
|
data?.catatan &&
|
||||||
|
(status === "review" || status === "reject") && (
|
||||||
|
<ReportBox text={data?.catatan} />
|
||||||
|
)}
|
||||||
|
|
||||||
{status === "review" && (
|
{status === "review" && (
|
||||||
<AdminButtonReview
|
<AdminButtonReview
|
||||||
|
isLoading={isLoading}
|
||||||
onPublish={() => {
|
onPublish={() => {
|
||||||
AlertDefaultSystem({
|
AlertDefaultSystem({
|
||||||
title: "Publish",
|
title: "Publish",
|
||||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||||
textLeft: "Cancel",
|
textLeft: "Cancel",
|
||||||
textRight: "Publish",
|
textRight: "Publish",
|
||||||
onPressLeft: () => {
|
|
||||||
router.back();
|
|
||||||
},
|
|
||||||
onPressRight: () => {
|
onPressRight: () => {
|
||||||
router.back();
|
handleUpdate({ changeStatus: "publish" });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
onReject={() => {
|
onReject={() => {
|
||||||
router.push(`/admin/voting/${id}/reject-input`);
|
router.push(`/admin/voting/${id}/${status}/reject-input`);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -162,7 +239,7 @@ export default function AdminVotingDetail() {
|
|||||||
<AdminButtonReject
|
<AdminButtonReject
|
||||||
title="Tambah Catatan"
|
title="Tambah Catatan"
|
||||||
onReject={() => {
|
onReject={() => {
|
||||||
router.push(`/admin/voting/${id}/reject-input`);
|
router.push(`/admin/voting/${id}/${status}/reject-input`);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
113
app/(application)/admin/voting/[id]/[status]/reject-input.tsx
Normal file
113
app/(application)/admin/voting/[id]/[status]/reject-input.tsx
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import {
|
||||||
|
AlertDefaultSystem,
|
||||||
|
BoxButtonOnFooter,
|
||||||
|
TextAreaCustom,
|
||||||
|
ViewWrapper,
|
||||||
|
} from "@/components";
|
||||||
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||||
|
import funUpdateStatusVoting from "@/screens/Admin/Voting/funUpdateStatus";
|
||||||
|
import { apiAdminVotingById } from "@/service/api-admin/api-admin-voting";
|
||||||
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
|
export default function AdminVotingRejectInput() {
|
||||||
|
const { id, status } = useLocalSearchParams();
|
||||||
|
const [data, setData] = useState("");
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminVotingById({
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data.catatan);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpdate = async ({
|
||||||
|
changeStatus,
|
||||||
|
}: {
|
||||||
|
changeStatus: "publish" | "review" | "reject";
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
const response = await funUpdateStatusVoting({
|
||||||
|
id: id as string,
|
||||||
|
changeStatus,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Report gagal",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Report berhasil",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (status === "review") {
|
||||||
|
router.replace(`/admin/voting/reject/status`);
|
||||||
|
} else if (status === "reject") {
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const buttonSubmit = (
|
||||||
|
<BoxButtonOnFooter>
|
||||||
|
<AdminButtonReject
|
||||||
|
title="Reject"
|
||||||
|
isLoading={isLoading}
|
||||||
|
onReject={() =>
|
||||||
|
AlertDefaultSystem({
|
||||||
|
title: "Reject",
|
||||||
|
message: "Apakah anda yakin ingin menolak data ini?",
|
||||||
|
textLeft: "Batal",
|
||||||
|
textRight: "Ya",
|
||||||
|
onPressRight: () => handleUpdate({ changeStatus: "reject" }),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</BoxButtonOnFooter>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ViewWrapper
|
||||||
|
footerComponent={buttonSubmit}
|
||||||
|
headerComponent={<AdminBackButtonAntTitle title="Penolakan Voting" />}
|
||||||
|
>
|
||||||
|
<TextAreaCustom
|
||||||
|
value={data}
|
||||||
|
onChangeText={setData}
|
||||||
|
placeholder="Masukan alasan"
|
||||||
|
required
|
||||||
|
showCount
|
||||||
|
maxLength={1000}
|
||||||
|
/>
|
||||||
|
</ViewWrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import {
|
|
||||||
AlertDefaultSystem,
|
|
||||||
BoxButtonOnFooter,
|
|
||||||
TextAreaCustom,
|
|
||||||
ViewWrapper,
|
|
||||||
} 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";
|
|
||||||
|
|
||||||
export default function AdminVotingRejectInput() {
|
|
||||||
const { id } = useLocalSearchParams();
|
|
||||||
const [value, setValue] = useState(id as string);
|
|
||||||
const buttonSubmit = (
|
|
||||||
<BoxButtonOnFooter>
|
|
||||||
<AdminButtonReject
|
|
||||||
title="Reject"
|
|
||||||
onReject={() =>
|
|
||||||
AlertDefaultSystem({
|
|
||||||
title: "Reject",
|
|
||||||
message: "Apakah anda yakin ingin menolak data ini?",
|
|
||||||
textLeft: "Batal",
|
|
||||||
textRight: "Ya",
|
|
||||||
onPressLeft: () => {
|
|
||||||
router.back();
|
|
||||||
},
|
|
||||||
onPressRight: () => {
|
|
||||||
console.log("value:", value);
|
|
||||||
router.replace(`/admin/voting/reject/status`);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</BoxButtonOnFooter>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<ViewWrapper
|
|
||||||
footerComponent={buttonSubmit}
|
|
||||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Voting" />}
|
|
||||||
>
|
|
||||||
<TextAreaCustom
|
|
||||||
value={value}
|
|
||||||
onChangeText={setValue}
|
|
||||||
placeholder="Masukan alasan"
|
|
||||||
required
|
|
||||||
showCount
|
|
||||||
maxLength={1000}
|
|
||||||
/>
|
|
||||||
</ViewWrapper>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,27 +1,60 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
LoaderCustom,
|
||||||
SearchInput,
|
SearchInput,
|
||||||
Spacing,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
|
import { apiAdminVoting } from "@/service/api-admin/api-admin-voting";
|
||||||
import { Octicons } from "@expo/vector-icons";
|
import { Octicons } from "@expo/vector-icons";
|
||||||
import { router, useLocalSearchParams } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
import { Divider } from "react-native-paper";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminVotingStatus() {
|
export default function AdminVotingStatus() {
|
||||||
const { status } = useLocalSearchParams();
|
const { status } = useLocalSearchParams();
|
||||||
|
const [list, setList] = useState<any | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState(false);
|
||||||
|
const [search, setSearch] = useState<string>("");
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [status, search])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
const response = await apiAdminVoting({
|
||||||
|
category: status as "publish" | "review" | "reject" as any,
|
||||||
|
search,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setList(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const rightComponent = (
|
const rightComponent = (
|
||||||
<SearchInput
|
<SearchInput
|
||||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||||
placeholder="Cari"
|
placeholder="Cari"
|
||||||
|
value={search}
|
||||||
|
onChangeText={setSearch}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
@@ -32,44 +65,52 @@ export default function AdminVotingStatus() {
|
|||||||
rightComponent={rightComponent}
|
rightComponent={rightComponent}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<BaseBox>
|
<StackCustom gap={"sm"}>
|
||||||
<AdminTitleTable
|
<AdminTitleTable
|
||||||
title1="Aksi"
|
title1="Aksi"
|
||||||
title2="Username"
|
title2="Username"
|
||||||
title3="Judul Voting"
|
title3="Judul Voting"
|
||||||
/>
|
/>
|
||||||
<Spacing />
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
{loadList ? (
|
||||||
<AdminTableValue
|
<LoaderCustom />
|
||||||
key={index}
|
) : _.isEmpty(list) ? (
|
||||||
value1={
|
<TextCustom align="center" bold color="gray">
|
||||||
<ActionIcon
|
Belum ada data
|
||||||
icon={
|
</TextCustom>
|
||||||
<Octicons
|
) : (
|
||||||
name="eye"
|
list.map((item: any, i: number) => (
|
||||||
size={ICON_SIZE_BUTTON}
|
<AdminTableValue
|
||||||
color="black"
|
key={i}
|
||||||
/>
|
value1={
|
||||||
}
|
<ActionIcon
|
||||||
onPress={() => {
|
icon={
|
||||||
router.push(`/admin/voting/${index}/${status}`);
|
<Octicons
|
||||||
}}
|
name="eye"
|
||||||
/>
|
size={ICON_SIZE_BUTTON}
|
||||||
}
|
color="black"
|
||||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
/>
|
||||||
value3={
|
}
|
||||||
<TextCustom truncate={2}>
|
onPress={() => {
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
router.push(`/admin/voting/${item.id}/${status}`);
|
||||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
}}
|
||||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
/>
|
||||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
}
|
||||||
</TextCustom>
|
value2={
|
||||||
}
|
<TextCustom truncate={1}>
|
||||||
/>
|
{item?.Author?.username || "-"}
|
||||||
))}
|
</TextCustom>
|
||||||
</BaseBox>
|
}
|
||||||
|
value3={
|
||||||
|
<TextCustom align="center" truncate={2}>
|
||||||
|
{item?.title || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
104
app/(application)/admin/voting/history.tsx
Normal file
104
app/(application)/admin/voting/history.tsx
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import {
|
||||||
|
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 { apiAdminVoting } from "@/service/api-admin/api-admin-voting";
|
||||||
|
import { Octicons } from "@expo/vector-icons";
|
||||||
|
import { router, useFocusEffect } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
|
export default function AdminVotingHistory() {
|
||||||
|
const [list, setList] = useState<any | null>(null);
|
||||||
|
const [loadList, setLoadList] = useState(false);
|
||||||
|
const [search, setSearch] = useState<string>("");
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [ search])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setLoadList(true);
|
||||||
|
const response = await apiAdminVoting({
|
||||||
|
category: "history",
|
||||||
|
search,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setList(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setLoadList(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const rightComponent = (
|
||||||
|
<SearchInput
|
||||||
|
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||||
|
placeholder="Cari"
|
||||||
|
value={search}
|
||||||
|
onChangeText={setSearch}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ViewWrapper headerComponent={<AdminTitlePage title="Voting" />}>
|
||||||
|
<AdminComp_BoxTitle
|
||||||
|
title="Riwayat"
|
||||||
|
rightComponent={rightComponent}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StackCustom gap={"sm"}>
|
||||||
|
<AdminTitleTable
|
||||||
|
title1="Aksi"
|
||||||
|
title2="Username"
|
||||||
|
title3="Judul Voting"
|
||||||
|
/>
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
{loadList ? <LoaderCustom/> : _.isEmpty(list) ? <TextCustom align="center" bold color="gray">Belum ada data</TextCustom> : list.map((item: any, i: number) => (
|
||||||
|
<AdminTableValue
|
||||||
|
key={i}
|
||||||
|
value1={
|
||||||
|
<ActionIcon
|
||||||
|
icon={
|
||||||
|
<Octicons
|
||||||
|
name="eye"
|
||||||
|
size={ICON_SIZE_BUTTON}
|
||||||
|
color="black"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onPress={() => {
|
||||||
|
router.push(`/admin/voting/${item.id}/history`);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
value2={<TextCustom truncate={1}>{item?.Author?.username || "-"}</TextCustom>}
|
||||||
|
value3={
|
||||||
|
<TextCustom align="center" truncate={2}>
|
||||||
|
{item?.title || "-"}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</StackCustom>
|
||||||
|
</ViewWrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -8,8 +8,56 @@ import {
|
|||||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { apiAdminVoting } from "@/service/api-admin/api-admin-voting";
|
||||||
|
import { useFocusEffect } from "expo-router";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function AdminVoting() {
|
export default function AdminVoting() {
|
||||||
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiAdminVoting({
|
||||||
|
category: "dashboard",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", 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} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Riwayat",
|
||||||
|
value: (data && data?.history) || 0,
|
||||||
|
icon: <IconArchive size={25} color={MainColor.white_gray} />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper>
|
<ViewWrapper>
|
||||||
@@ -24,26 +72,3 @@ export default function AdminVoting() {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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: "Riwayat",
|
|
||||||
value: 5,
|
|
||||||
icon: <IconArchive size={25} color={MainColor.white_gray} />,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|||||||
3
bun.lock
3
bun.lock
@@ -17,7 +17,6 @@
|
|||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"expo": "^54.0.0",
|
"expo": "^54.0.0",
|
||||||
"expo-blur": "~15.0.7",
|
|
||||||
"expo-camera": "~17.0.7",
|
"expo-camera": "~17.0.7",
|
||||||
"expo-clipboard": "~8.0.7",
|
"expo-clipboard": "~8.0.7",
|
||||||
"expo-constants": "~18.0.8",
|
"expo-constants": "~18.0.8",
|
||||||
@@ -1153,8 +1152,6 @@
|
|||||||
|
|
||||||
"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-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-blur": ["expo-blur@15.0.7", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-SugQQbQd+zRPy8z2G5qDD4NqhcD7srBF7fN7O7yq6q7ZFK59VWvpDxtMoUkmSfdxgqONsrBN/rLdk00USADrMg=="],
|
|
||||||
|
|
||||||
"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-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-clipboard": ["expo-clipboard@8.0.7", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-zvlfFV+wB2QQrQnHWlo0EKHAkdi2tycLtE+EXFUWTPZYkgu1XcH+aiKfd4ul7Z0SDF+1IuwoiW9AA9eO35aj3Q=="],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { Href, router } from "expo-router";
|
import { Href, router } from "expo-router";
|
||||||
import { DimensionValue, TouchableOpacity } from "react-native";
|
import { DimensionValue, StyleProp, TouchableOpacity, ViewStyle } from "react-native";
|
||||||
|
|
||||||
type SizeType = "xs" | "sm" | "md" | "lg" | "xl" | number | string | undefined;
|
type SizeType = "xs" | "sm" | "md" | "lg" | "xl" | number | string | undefined;
|
||||||
|
|
||||||
@@ -10,12 +10,14 @@ export default function ActionIcon({
|
|||||||
icon,
|
icon,
|
||||||
size = "md",
|
size = "md",
|
||||||
disabled = false,
|
disabled = false,
|
||||||
|
style,
|
||||||
}: {
|
}: {
|
||||||
href?: Href;
|
href?: Href;
|
||||||
onPress?: () => void;
|
onPress?: () => void;
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
size?: SizeType;
|
size?: SizeType;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
style?: StyleProp<ViewStyle>;
|
||||||
}) {
|
}) {
|
||||||
const sizeMap = {
|
const sizeMap = {
|
||||||
xs: 22,
|
xs: 22,
|
||||||
@@ -39,7 +41,7 @@ export default function ActionIcon({
|
|||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
activeOpacity={0.7}
|
activeOpacity={0.7}
|
||||||
style={{
|
style={[{
|
||||||
backgroundColor: disabled ? MainColor.disabled : MainColor.yellow,
|
backgroundColor: disabled ? MainColor.disabled : MainColor.yellow,
|
||||||
padding: 5,
|
padding: 5,
|
||||||
borderRadius: 50,
|
borderRadius: 50,
|
||||||
@@ -47,7 +49,7 @@ export default function ActionIcon({
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
width: iconSize,
|
width: iconSize,
|
||||||
height: iconSize,
|
height: iconSize,
|
||||||
}}
|
}, style]}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
if (disabled) return;
|
if (disabled) return;
|
||||||
if (href) {
|
if (href) {
|
||||||
|
|||||||
16
components/Box/ReportBox.tsx
Normal file
16
components/Box/ReportBox.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import StackCustom from "../Stack/StackCustom";
|
||||||
|
import TextCustom from "../Text/TextCustom";
|
||||||
|
import BaseBox from "./BaseBox";
|
||||||
|
|
||||||
|
export default function ReportBox({ text }: { text: string }) {
|
||||||
|
return (
|
||||||
|
<BaseBox>
|
||||||
|
<StackCustom gap={"sm"}>
|
||||||
|
<TextCustom bold>
|
||||||
|
Catatan penolakan
|
||||||
|
</TextCustom>
|
||||||
|
<TextCustom>{text}</TextCustom>
|
||||||
|
</StackCustom>
|
||||||
|
</BaseBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,27 +1,39 @@
|
|||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { StyleProp, StyleSheet, TextInput, View, ViewStyle } from "react-native";
|
import {
|
||||||
|
StyleProp,
|
||||||
|
StyleSheet,
|
||||||
|
View,
|
||||||
|
ViewStyle
|
||||||
|
} from "react-native";
|
||||||
|
import TextCustom from "../Text/TextCustom";
|
||||||
|
|
||||||
interface CircularInputProps {
|
interface CircularInputProps {
|
||||||
value?: string | number
|
value?: string | number;
|
||||||
onChange?: (value: string | number) => void;
|
onChange?: (value: string | number) => void;
|
||||||
icon?: React.ReactNode;
|
icon?: React.ReactNode;
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CircularInput: React.FC<CircularInputProps> = ({ value, onChange, icon, style }) => {
|
const CircularInput: React.FC<CircularInputProps> = ({
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
icon,
|
||||||
|
style,
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<View style={[styles.circleContainer, style]}>
|
<View style={[styles.circleContainer, style]}>
|
||||||
{icon ? (
|
{icon ? (
|
||||||
icon
|
icon
|
||||||
) : (
|
) : (
|
||||||
<TextInput
|
<TextCustom
|
||||||
value={String(value)}
|
// text={String(value)}
|
||||||
onChangeText={onChange}
|
|
||||||
style={styles.input}
|
style={styles.input}
|
||||||
keyboardType="numeric"
|
// keyboardType="numeric"
|
||||||
maxLength={2} // Batasan maksimal karakter
|
// maxLength={2} // Batasan maksimal karakter
|
||||||
/>
|
>
|
||||||
|
{value}
|
||||||
|
</TextCustom>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
@@ -39,7 +51,7 @@ const styles = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
input: {
|
input: {
|
||||||
color: MainColor.yellow, // Warna kuning
|
color: MainColor.yellow, // Warna kuning
|
||||||
fontSize: 24,
|
fontSize: 18,
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
padding: 0,
|
padding: 0,
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ const DateTimeInput_Android: React.FC<DateTimeInputProps> = ({
|
|||||||
onChange={handleConfirmTime}
|
onChange={handleConfirmTime}
|
||||||
minimumDate={minimumDate}
|
minimumDate={minimumDate}
|
||||||
maximumDate={maximumDate}
|
maximumDate={maximumDate}
|
||||||
|
themeVariant="light"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ const DateTimeInput_IOS: React.FC<DateTimeInputProps> = ({
|
|||||||
onChange={handleConfirm}
|
onChange={handleConfirm}
|
||||||
minimumDate={minimumDate}
|
minimumDate={minimumDate}
|
||||||
maximumDate={maximumDate}
|
maximumDate={maximumDate}
|
||||||
|
themeVariant="light"
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ interface TextCustomProps {
|
|||||||
bold?: boolean;
|
bold?: boolean;
|
||||||
semiBold?: boolean;
|
semiBold?: boolean;
|
||||||
size?: "default" | "large" | "small" | "xlarge" | number
|
size?: "default" | "large" | "small" | "xlarge" | number
|
||||||
color?: "default" | "yellow" | "red" | "gray" | "green" | "black"
|
color?: "default" | "yellow" | "red" | "gray" | "green" | "black" | "orange"
|
||||||
align?: TextAlign; // Prop untuk alignment
|
align?: TextAlign; // Prop untuk alignment
|
||||||
truncate?: boolean | number;
|
truncate?: boolean | number;
|
||||||
onPress?: () => void;
|
onPress?: () => void;
|
||||||
@@ -62,6 +62,7 @@ const TextCustom: React.FC<TextCustomProps> = ({
|
|||||||
else if (color === "gray") selectedStyles.push(styles.gray);
|
else if (color === "gray") selectedStyles.push(styles.gray);
|
||||||
else if (color === "green") selectedStyles.push(styles.green);
|
else if (color === "green") selectedStyles.push(styles.green);
|
||||||
else if (color === "black") selectedStyles.push(styles.black);
|
else if (color === "black") selectedStyles.push(styles.black);
|
||||||
|
else if (color === "orange") selectedStyles.push(styles.orange);
|
||||||
|
|
||||||
// Alignment
|
// Alignment
|
||||||
if (align) {
|
if (align) {
|
||||||
@@ -140,4 +141,7 @@ export const styles = StyleSheet.create({
|
|||||||
black: {
|
black: {
|
||||||
color: MainColor.black,
|
color: MainColor.black,
|
||||||
},
|
},
|
||||||
|
orange: {
|
||||||
|
color: MainColor.orange,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
27
components/_Icon/IconOpenTo.tsx
Normal file
27
components/_Icon/IconOpenTo.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { ICON_SIZE_XLARGE } from "@/constants/constans-value";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export { IconOpenTo };
|
||||||
|
|
||||||
|
function IconOpenTo({
|
||||||
|
color,
|
||||||
|
size,
|
||||||
|
onPress,
|
||||||
|
}: {
|
||||||
|
color?: string;
|
||||||
|
size?: number;
|
||||||
|
onPress?: () => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Ionicons
|
||||||
|
onPress={onPress}
|
||||||
|
name="open"
|
||||||
|
size={size || ICON_SIZE_XLARGE}
|
||||||
|
color={color || MainColor.yellow}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -5,17 +5,20 @@ import { MainColor } from "@/constants/color-palet";
|
|||||||
export default function AdminButtonReject({
|
export default function AdminButtonReject({
|
||||||
title,
|
title,
|
||||||
onReject,
|
onReject,
|
||||||
|
isLoading,
|
||||||
}: {
|
}: {
|
||||||
title: string;
|
title: string;
|
||||||
onReject: () => void;
|
onReject: () => void;
|
||||||
|
isLoading?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
iconLeft={<IconReject />}
|
iconLeft={<IconReject size={16} />}
|
||||||
backgroundColor={MainColor.red}
|
backgroundColor={MainColor.red}
|
||||||
textColor="white"
|
textColor="white"
|
||||||
onPress={onReject}
|
onPress={onReject}
|
||||||
|
isLoading={isLoading}
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import Grid from "@/components/Grid/GridCustom";
|
|||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
|
||||||
export default function AdminButtonReview({
|
export default function AdminButtonReview({
|
||||||
|
isLoading,
|
||||||
onPublish,
|
onPublish,
|
||||||
onReject,
|
onReject,
|
||||||
}: {
|
}: {
|
||||||
|
isLoading?: boolean;
|
||||||
onPublish: () => void;
|
onPublish: () => void;
|
||||||
onReject: () => void;
|
onReject: () => void;
|
||||||
}) {
|
}) {
|
||||||
@@ -15,6 +17,7 @@ export default function AdminButtonReview({
|
|||||||
<Grid>
|
<Grid>
|
||||||
<Grid.Col span={6} style={{ paddingRight: 10 }}>
|
<Grid.Col span={6} style={{ paddingRight: 10 }}>
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
|
isLoading={isLoading}
|
||||||
iconLeft={<IconPublish />}
|
iconLeft={<IconPublish />}
|
||||||
backgroundColor={MainColor.green}
|
backgroundColor={MainColor.green}
|
||||||
textColor="white"
|
textColor="white"
|
||||||
|
|||||||
@@ -13,14 +13,32 @@ export default function AdminTitleTable({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.Col span={3} style={{ alignItems: "center", justifyContent: "center" }}>
|
<Grid.Col
|
||||||
<TextCustom bold align="center">{title1}</TextCustom>
|
span={3}
|
||||||
|
style={{
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
paddingLeft: 5,
|
||||||
|
paddingRight: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextCustom truncate bold align="center">
|
||||||
|
{title1}
|
||||||
|
</TextCustom>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col span={3} style={{ alignItems: "center", justifyContent: "center" }}>
|
<Grid.Col
|
||||||
<TextCustom bold align="center">{title2}</TextCustom>
|
span={3}
|
||||||
|
style={{ alignItems: "center", justifyContent: "center", paddingLeft: 5, paddingRight: 5 }}
|
||||||
|
>
|
||||||
|
<TextCustom truncate bold align="center">
|
||||||
|
{title2}
|
||||||
|
</TextCustom>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col span={6} style={{ alignItems: "center", justifyContent: "center" }}>
|
<Grid.Col
|
||||||
<TextCustom bold align="center">{title3}</TextCustom>
|
span={6}
|
||||||
|
style={{ alignItems: "center", justifyContent: "center", paddingLeft: 5, paddingRight: 5 }}
|
||||||
|
>
|
||||||
|
<TextCustom truncate bold align="center">{title3}</TextCustom>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid>
|
</Grid>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ export default function AdminTableValue({
|
|||||||
value1,
|
value1,
|
||||||
value2,
|
value2,
|
||||||
value3,
|
value3,
|
||||||
|
bottomLine = false,
|
||||||
}: {
|
}: {
|
||||||
value1: React.ReactNode;
|
value1: React.ReactNode;
|
||||||
value2: React.ReactNode;
|
value2: React.ReactNode;
|
||||||
value3: React.ReactNode;
|
value3: React.ReactNode;
|
||||||
|
bottomLine?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -21,8 +23,8 @@ export default function AdminTableValue({
|
|||||||
style={{
|
style={{
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
paddingLeft: 5,
|
paddingLeft: 10,
|
||||||
paddingRight: 5,
|
paddingRight: 10,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{value1}
|
{value1}
|
||||||
@@ -32,8 +34,8 @@ export default function AdminTableValue({
|
|||||||
style={{
|
style={{
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
paddingLeft: 5,
|
paddingLeft: 10,
|
||||||
paddingRight: 5,
|
paddingRight: 10,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{value2}
|
{value2}
|
||||||
@@ -42,14 +44,15 @@ export default function AdminTableValue({
|
|||||||
span={6}
|
span={6}
|
||||||
style={{
|
style={{
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
paddingLeft: 5,
|
alignItems: "center",
|
||||||
paddingRight: 5,
|
paddingLeft: 10,
|
||||||
|
paddingRight: 10,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{value3}
|
{value3}
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Divider />
|
{bottomLine && <Divider />}
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { StyleProp, ViewStyle } from "react-native";
|
import { ViewStyle } from "react-native";
|
||||||
import Grid from "../Grid/GridCustom";
|
import Grid from "../Grid/GridCustom";
|
||||||
|
|
||||||
export default function GridTwoView({
|
export default function GridTwoView({
|
||||||
@@ -13,15 +13,23 @@ export default function GridTwoView({
|
|||||||
spanRight?: number;
|
spanRight?: number;
|
||||||
leftIcon?: React.ReactNode;
|
leftIcon?: React.ReactNode;
|
||||||
rightIcon?: React.ReactNode;
|
rightIcon?: React.ReactNode;
|
||||||
styleLeft?: StyleProp<ViewStyle>;
|
styleLeft?: ViewStyle;
|
||||||
styleRight?: StyleProp<ViewStyle>;
|
styleRight?: ViewStyle;
|
||||||
}) {
|
}) {
|
||||||
|
const baseStyle: ViewStyle = { justifyContent: "center" };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid containerStyle={{ marginBottom: 0 }}>
|
<Grid containerStyle={{ marginBottom: 0 }}>
|
||||||
<Grid.Col span={spanLeft} style={{ justifyContent: "center" }}>
|
<Grid.Col
|
||||||
|
span={spanLeft}
|
||||||
|
style={styleLeft ? { ...baseStyle, ...styleLeft } : baseStyle}
|
||||||
|
>
|
||||||
{leftIcon}
|
{leftIcon}
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col span={spanRight} style={{ justifyContent: "center" }}>
|
<Grid.Col
|
||||||
|
span={spanRight}
|
||||||
|
style={styleRight ? { ...baseStyle, ...styleRight } : baseStyle}
|
||||||
|
>
|
||||||
{rightIcon}
|
{rightIcon}
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Grid } from "@/components";
|
import { Grid } from "@/components";
|
||||||
|
import { StyleProp, ViewStyle } from "react-native";
|
||||||
|
|
||||||
export const GridViewCustomSpan = ({
|
export const GridViewCustomSpan = ({
|
||||||
span1,
|
span1,
|
||||||
@@ -7,31 +8,52 @@ export const GridViewCustomSpan = ({
|
|||||||
component1,
|
component1,
|
||||||
component2,
|
component2,
|
||||||
component3,
|
component3,
|
||||||
|
style1,
|
||||||
|
style2,
|
||||||
|
style3,
|
||||||
}: {
|
}: {
|
||||||
span1: number;
|
span1?: number;
|
||||||
span2: number;
|
span2?: number;
|
||||||
span3: number;
|
span3?: number;
|
||||||
component1: React.ReactNode;
|
component1: React.ReactNode;
|
||||||
component2: React.ReactNode;
|
component2: React.ReactNode;
|
||||||
component3: React.ReactNode;
|
component3: React.ReactNode;
|
||||||
|
style1?: StyleProp<ViewStyle>;
|
||||||
|
style2?: StyleProp<ViewStyle>;
|
||||||
|
style3?: StyleProp<ViewStyle>;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.Col
|
<Grid.Col
|
||||||
span={span1 || 4}
|
span={span1 || 4}
|
||||||
style={{ justifyContent: "center", paddingRight: 5, paddingLeft: 5 }}
|
style={{
|
||||||
|
justifyContent: "center",
|
||||||
|
paddingRight: 10,
|
||||||
|
paddingLeft: 10,
|
||||||
|
...(style1 as object)
|
||||||
|
} as ViewStyle}
|
||||||
>
|
>
|
||||||
{component1}
|
{component1}
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col
|
<Grid.Col
|
||||||
span={span2 || 4}
|
span={span2 || 4}
|
||||||
style={{ justifyContent: "center", paddingRight: 5, paddingLeft: 5 }}
|
style={{
|
||||||
|
justifyContent: "center",
|
||||||
|
paddingRight: 10,
|
||||||
|
paddingLeft: 10,
|
||||||
|
...(style2 as object)
|
||||||
|
} as ViewStyle}
|
||||||
>
|
>
|
||||||
{component2}
|
{component2}
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col
|
<Grid.Col
|
||||||
span={span3 || 4}
|
span={span3 || 4}
|
||||||
style={{ justifyContent: "center", paddingRight: 5, paddingLeft: 5 }}
|
style={{
|
||||||
|
justifyContent: "center",
|
||||||
|
paddingRight: 10,
|
||||||
|
paddingLeft: 10,
|
||||||
|
...(style3 as object)
|
||||||
|
} as ViewStyle}
|
||||||
>
|
>
|
||||||
{component3}
|
{component3}
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { MainColor } from "@/constants/color-palet";
|
|||||||
import { ICON_SIZE_SMALL } from "@/constants/constans-value";
|
import { ICON_SIZE_SMALL } from "@/constants/constans-value";
|
||||||
import TextInputCustom from "../TextInput/TextInputCustom";
|
import TextInputCustom from "../TextInput/TextInputCustom";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import { StyleProp, ViewStyle, TextStyle } from "react-native";
|
import { StyleProp, ViewStyle, TextStyle, StyleSheet } from "react-native";
|
||||||
|
|
||||||
interface SearchInputProps {
|
interface SearchInputProps {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
@@ -12,6 +12,8 @@ interface SearchInputProps {
|
|||||||
containerStyle?: StyleProp<ViewStyle>;
|
containerStyle?: StyleProp<ViewStyle>;
|
||||||
style?: StyleProp<TextStyle>;
|
style?: StyleProp<TextStyle>;
|
||||||
onChangeText?: (value: string) => void;
|
onChangeText?: (value: string) => void;
|
||||||
|
value?: string;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
export default function SearchInput({
|
export default function SearchInput({
|
||||||
placeholder,
|
placeholder,
|
||||||
@@ -21,6 +23,8 @@ export default function SearchInput({
|
|||||||
containerStyle,
|
containerStyle,
|
||||||
style,
|
style,
|
||||||
onChangeText,
|
onChangeText,
|
||||||
|
value,
|
||||||
|
disabled,
|
||||||
...props
|
...props
|
||||||
}: SearchInputProps) {
|
}: SearchInputProps) {
|
||||||
return (
|
return (
|
||||||
@@ -29,14 +33,21 @@ export default function SearchInput({
|
|||||||
<Ionicons
|
<Ionicons
|
||||||
name="search-outline"
|
name="search-outline"
|
||||||
size={ICON_SIZE_SMALL}
|
size={ICON_SIZE_SMALL}
|
||||||
color={MainColor.placeholder}
|
color={disabled ? MainColor.white_gray : MainColor.placeholder}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
value={value}
|
||||||
onChangeText={onChangeText}
|
onChangeText={onChangeText}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
borderRadius={50}
|
borderRadius={50}
|
||||||
containerStyle={[containerStyle, { marginBottom: 0 }]}
|
containerStyle={[disabled ? styleses.disabled : styleses.containerStyle]}
|
||||||
|
disabled={disabled}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const styleses = StyleSheet.create({
|
||||||
|
containerStyle: { width: "100%", marginBottom: 0 },
|
||||||
|
disabled: { width: "100%", marginBottom: 0, color: MainColor.white_gray },
|
||||||
|
});
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
StyleProp,
|
StyleProp,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import { SafeAreaView } from "react-native-safe-area-context";
|
import { NativeSafeAreaViewProps, SafeAreaView } from "react-native-safe-area-context";
|
||||||
|
|
||||||
interface ViewWrapperProps {
|
interface ViewWrapperProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
@@ -21,6 +21,7 @@ interface ViewWrapperProps {
|
|||||||
footerComponent?: React.ReactNode;
|
footerComponent?: React.ReactNode;
|
||||||
floatingButton?: React.ReactNode;
|
floatingButton?: React.ReactNode;
|
||||||
hideFooter?: boolean;
|
hideFooter?: boolean;
|
||||||
|
edgesFooter?: NativeSafeAreaViewProps["edges"];
|
||||||
style?: StyleProp<ViewStyle>;
|
style?: StyleProp<ViewStyle>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ const ViewWrapper = ({
|
|||||||
footerComponent,
|
footerComponent,
|
||||||
floatingButton,
|
floatingButton,
|
||||||
hideFooter = false,
|
hideFooter = false,
|
||||||
|
edgesFooter =[],
|
||||||
style,
|
style,
|
||||||
}: ViewWrapperProps) => {
|
}: ViewWrapperProps) => {
|
||||||
const assetBackground = require("../../assets/images/main-background.png");
|
const assetBackground = require("../../assets/images/main-background.png");
|
||||||
@@ -77,7 +79,7 @@ const ViewWrapper = ({
|
|||||||
|
|
||||||
{footerComponent ? (
|
{footerComponent ? (
|
||||||
<SafeAreaView
|
<SafeAreaView
|
||||||
edges={["bottom"]}
|
edges={Platform.OS === "ios" ? edgesFooter : ["bottom"]}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: MainColor.darkblue,
|
backgroundColor: MainColor.darkblue,
|
||||||
height: OS_HEIGHT
|
height: OS_HEIGHT
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export {
|
|||||||
|
|
||||||
// OS Height
|
// OS Height
|
||||||
const OS_ANDROID_HEIGHT = 115
|
const OS_ANDROID_HEIGHT = 115
|
||||||
const OS_IOS_HEIGHT = 65
|
const OS_IOS_HEIGHT = 70
|
||||||
const OS_HEIGHT = Platform.OS === "ios" ? OS_IOS_HEIGHT : OS_ANDROID_HEIGHT
|
const OS_HEIGHT = Platform.OS === "ios" ? OS_IOS_HEIGHT : OS_ANDROID_HEIGHT
|
||||||
|
|
||||||
// Text Size
|
// Text Size
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
const userData = async (token: string) => {
|
const userData = async (token: string) => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await apiConfig.get(`/mobile/user?token=${token}`, {
|
const response = await apiConfig.get(`/mobile?token=${token}`, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
|
|||||||
8
index.js
Normal file
8
index.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { registerRootComponent } from 'expo';
|
||||||
|
|
||||||
|
import App from './App';
|
||||||
|
|
||||||
|
// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
|
||||||
|
// It also ensures that whether you load the app in Expo Go or in a native build,
|
||||||
|
// the environment is set up appropriately
|
||||||
|
registerRootComponent(App);
|
||||||
@@ -9,25 +9,17 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
|
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
|
||||||
3E483D87269347231471F774 /* libPods-HIPMIBADUNG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 10F5AA024C601F56B4EEA12E /* libPods-HIPMIBADUNG.a */; };
|
|
||||||
3E9DE75169D0FBDB1B473165 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = F0C0055A487C52DF43B9AA8C /* PrivacyInfo.xcprivacy */; };
|
|
||||||
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
|
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
|
||||||
E3BE778B8B6E53CE5D518808 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A445166333AB51CC299A7683 /* ExpoModulesProvider.swift */; };
|
|
||||||
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11748412D0307B40044C1D9 /* AppDelegate.swift */; };
|
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11748412D0307B40044C1D9 /* AppDelegate.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
10F5AA024C601F56B4EEA12E /* libPods-HIPMIBADUNG.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HIPMIBADUNG.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
13B07F961A680F5B00A75B9A /* HIPMIBADUNG.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HIPMIBADUNG.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
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>"; };
|
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>"; };
|
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = HIPMIBADUNG/Info.plist; sourceTree = "<group>"; };
|
||||||
43EA3CD4BD89A00F8AB4791D /* Pods-HIPMIBADUNG.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HIPMIBADUNG.release.xcconfig"; path = "Target Support Files/Pods-HIPMIBADUNG/Pods-HIPMIBADUNG.release.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
7355472C9F7484C7F5780400 /* Pods-HIPMIBADUNG.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HIPMIBADUNG.debug.xcconfig"; path = "Target Support Files/Pods-HIPMIBADUNG/Pods-HIPMIBADUNG.debug.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
A445166333AB51CC299A7683 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-HIPMIBADUNG/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
|
|
||||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = HIPMIBADUNG/SplashScreen.storyboard; sourceTree = "<group>"; };
|
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = HIPMIBADUNG/SplashScreen.storyboard; sourceTree = "<group>"; };
|
||||||
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; };
|
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; };
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||||
F0C0055A487C52DF43B9AA8C /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = HIPMIBADUNG/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
|
||||||
F11748412D0307B40044C1D9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = HIPMIBADUNG/AppDelegate.swift; sourceTree = "<group>"; };
|
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>"; };
|
F11748442D0722820044C1D9 /* HIPMIBADUNG-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "HIPMIBADUNG-Bridging-Header.h"; path = "HIPMIBADUNG/HIPMIBADUNG-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
@@ -37,7 +29,6 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
3E483D87269347231471F774 /* libPods-HIPMIBADUNG.a in Frameworks */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -53,7 +44,6 @@
|
|||||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
|
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
|
||||||
F0C0055A487C52DF43B9AA8C /* PrivacyInfo.xcprivacy */,
|
|
||||||
);
|
);
|
||||||
name = HIPMIBADUNG;
|
name = HIPMIBADUNG;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -62,28 +52,10 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||||
10F5AA024C601F56B4EEA12E /* libPods-HIPMIBADUNG.a */,
|
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
523B30FE431343BE096F5C21 /* Pods */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
7355472C9F7484C7F5780400 /* Pods-HIPMIBADUNG.debug.xcconfig */,
|
|
||||||
43EA3CD4BD89A00F8AB4791D /* Pods-HIPMIBADUNG.release.xcconfig */,
|
|
||||||
);
|
|
||||||
path = Pods;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
7E80613205F5353A90501151 /* HIPMIBADUNG */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
A445166333AB51CC299A7683 /* ExpoModulesProvider.swift */,
|
|
||||||
);
|
|
||||||
name = HIPMIBADUNG;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -98,8 +70,6 @@
|
|||||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||||
83CBBA001A601CBA00E9B192 /* Products */,
|
83CBBA001A601CBA00E9B192 /* Products */,
|
||||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||||
523B30FE431343BE096F5C21 /* Pods */,
|
|
||||||
92643B17548A700FA33507C4 /* ExpoModulesProviders */,
|
|
||||||
);
|
);
|
||||||
indentWidth = 2;
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -114,14 +84,6 @@
|
|||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
92643B17548A700FA33507C4 /* ExpoModulesProviders */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
7E80613205F5353A90501151 /* HIPMIBADUNG */,
|
|
||||||
);
|
|
||||||
name = ExpoModulesProviders;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
BB2F792B24A3F905000567C9 /* Supporting */ = {
|
BB2F792B24A3F905000567C9 /* Supporting */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -139,13 +101,11 @@
|
|||||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HIPMIBADUNG" */;
|
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HIPMIBADUNG" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */,
|
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */,
|
||||||
4DF2145C6600FA4F2932F421 /* [Expo] Configure project */,
|
|
||||||
13B07F871A680F5B00A75B9A /* Sources */,
|
13B07F871A680F5B00A75B9A /* Sources */,
|
||||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||||
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */,
|
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */,
|
||||||
4BE0A502450842B2C872639D /* [CP] Embed Pods Frameworks */,
|
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@@ -195,7 +155,6 @@
|
|||||||
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */,
|
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */,
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||||
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */,
|
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */,
|
||||||
3E9DE75169D0FBDB1B473165 /* PrivacyInfo.xcprivacy in Resources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -209,6 +168,8 @@
|
|||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
|
"$(SRCROOT)/.xcode.env",
|
||||||
|
"$(SRCROOT)/.xcode.env.local",
|
||||||
);
|
);
|
||||||
name = "Bundle React Native code and images";
|
name = "Bundle React Native code and images";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
@@ -239,43 +200,6 @@
|
|||||||
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";
|
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;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
4BE0A502450842B2C872639D /* [CP] Embed Pods Frameworks */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-HIPMIBADUNG/Pods-HIPMIBADUNG-frameworks.sh",
|
|
||||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
|
|
||||||
);
|
|
||||||
name = "[CP] Embed Pods Frameworks";
|
|
||||||
outputPaths = (
|
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HIPMIBADUNG/Pods-HIPMIBADUNG-frameworks.sh\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
4DF2145C6600FA4F2932F421 /* [Expo] Configure project */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
alwaysOutOfDate = 1;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputFileListPaths = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
);
|
|
||||||
name = "[Expo] Configure project";
|
|
||||||
outputFileListPaths = (
|
|
||||||
);
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
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-HIPMIBADUNG/expo-configure-project.sh\"\n";
|
|
||||||
};
|
|
||||||
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = {
|
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -284,76 +208,14 @@
|
|||||||
inputPaths = (
|
inputPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-HIPMIBADUNG/Pods-HIPMIBADUNG-resources.sh",
|
"${PODS_ROOT}/Target Support Files/Pods-HIPMIBADUNG/Pods-HIPMIBADUNG-resources.sh",
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
|
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle",
|
"${PODS_CONFIGURATION_BUILD_DIR}/EXUpdates/EXUpdates.bundle",
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
|
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle",
|
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_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}/boost/boost_privacy.bundle",
|
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-launcher/EXDevLauncher.bundle",
|
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-menu/EXDevMenu.bundle",
|
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/glog/glog_privacy.bundle",
|
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/react-native-maps/ReactNativeMapsPrivacy.bundle",
|
|
||||||
);
|
);
|
||||||
name = "[CP] Copy Pods Resources";
|
name = "[CP] Copy Pods Resources";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle",
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXUpdates.bundle",
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoSystemUI_privacy.bundle",
|
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_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}/boost_privacy.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}/glog_privacy.bundle",
|
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ReactNativeMapsPrivacy.bundle",
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
@@ -368,7 +230,6 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */,
|
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */,
|
||||||
E3BE778B8B6E53CE5D518808 /* ExpoModulesProvider.swift in Sources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -377,13 +238,10 @@
|
|||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7355472C9F7484C7F5780400 /* Pods-HIPMIBADUNG.debug.xcconfig */;
|
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = HIPMIBADUNG/HIPMIBADUNG.entitlements;
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = A3FZDNQTUG;
|
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -401,26 +259,23 @@
|
|||||||
"-ObjC",
|
"-ObjC",
|
||||||
"-lc++",
|
"-lc++",
|
||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
||||||
PRODUCT_NAME = HIPMIBADUNG;
|
PRODUCT_NAME = "HIPMIBADUNG";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBADUNG/HIPMIBADUNG-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBADUNG/HIPMIBADUNG-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
CODE_SIGN_ENTITLEMENTS = HIPMIBADUNG/HIPMIBADUNG.entitlements;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 43EA3CD4BD89A00F8AB4791D /* Pods-HIPMIBADUNG.release.xcconfig */;
|
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = HIPMIBADUNG/HIPMIBADUNG.entitlements;
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = A3FZDNQTUG;
|
|
||||||
INFOPLIST_FILE = HIPMIBADUNG/Info.plist;
|
INFOPLIST_FILE = HIPMIBADUNG/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@@ -433,13 +288,13 @@
|
|||||||
"-ObjC",
|
"-ObjC",
|
||||||
"-lc++",
|
"-lc++",
|
||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
||||||
PRODUCT_NAME = HIPMIBADUNG;
|
PRODUCT_NAME = "HIPMIBADUNG";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBADUNG/HIPMIBADUNG-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBADUNG/HIPMIBADUNG-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
CODE_SIGN_ENTITLEMENTS = HIPMIBADUNG/HIPMIBADUNG.entitlements;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
@@ -495,14 +350,10 @@
|
|||||||
/usr/lib/swift,
|
/usr/lib/swift,
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
);
|
);
|
||||||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"$(inherited)\"";
|
LIBRARY_SEARCH_PATHS = "\"$(inherited)\"";
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
OTHER_LDFLAGS = "$(inherited) ";
|
|
||||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
|
|
||||||
USE_HERMES = true;
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
@@ -551,12 +402,9 @@
|
|||||||
/usr/lib/swift,
|
/usr/lib/swift,
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
);
|
);
|
||||||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"$(inherited)\"";
|
LIBRARY_SEARCH_PATHS = "\"$(inherited)\"";
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
OTHER_LDFLAGS = "$(inherited) ";
|
|
||||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
USE_HERMES = true;
|
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
|||||||
10
ios/HIPMIBADUNG.xcworkspace/contents.xcworkspacedata
generated
10
ios/HIPMIBADUNG.xcworkspace/contents.xcworkspacedata
generated
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Workspace
|
|
||||||
version = "1.0">
|
|
||||||
<FileRef
|
|
||||||
location = "group:HIPMIBADUNG.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
<FileRef
|
|
||||||
location = "group:Pods/Pods.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
</Workspace>
|
|
||||||
@@ -1,48 +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>
|
|
||||||
<key>NSPrivacyAccessedAPITypes</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPIType</key>
|
|
||||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
|
||||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
||||||
<array>
|
|
||||||
<string>CA92.1</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPIType</key>
|
|
||||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
|
||||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
||||||
<array>
|
|
||||||
<string>0A2A.1</string>
|
|
||||||
<string>3B52.1</string>
|
|
||||||
<string>C617.1</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPIType</key>
|
|
||||||
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
|
|
||||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
||||||
<array>
|
|
||||||
<string>E174.1</string>
|
|
||||||
<string>85F4.1</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPIType</key>
|
|
||||||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
|
|
||||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
||||||
<array>
|
|
||||||
<string>35F9.1</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
<key>NSPrivacyCollectedDataTypes</key>
|
|
||||||
<array/>
|
|
||||||
<key>NSPrivacyTracking</key>
|
|
||||||
<false/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="EXPO-VIEWCONTROLLER-1">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="EXPO-VIEWCONTROLLER-1">
|
||||||
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24053.1"/>
|
||||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<scenes>
|
<scenes>
|
||||||
@@ -35,6 +36,9 @@
|
|||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="SplashScreenLogo" width="200" height="200"/>
|
<image name="SplashScreenLogo" width="200" height="200"/>
|
||||||
|
<systemColor name="systemBackgroundColor">
|
||||||
|
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
</systemColor>
|
||||||
<namedColor name="SplashScreenBackground">
|
<namedColor name="SplashScreenBackground">
|
||||||
<color alpha="1.000" blue="1.00000000000000" green="1.00000000000000" red="1.00000000000000" customColorSpace="sRGB" colorSpace="custom"/>
|
<color alpha="1.000" blue="1.00000000000000" green="1.00000000000000" red="1.00000000000000" customColorSpace="sRGB" colorSpace="custom"/>
|
||||||
</namedColor>
|
</namedColor>
|
||||||
|
|||||||
20
ios/Podfile
20
ios/Podfile
@@ -4,12 +4,11 @@ require File.join(File.dirname(`node --print "require.resolve('react-native/pack
|
|||||||
require 'json'
|
require 'json'
|
||||||
podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
|
podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
|
||||||
|
|
||||||
ENV['RCT_NEW_ARCH_ENABLED'] = '0' if podfile_properties['newArchEnabled'] == 'false'
|
ENV['RCT_NEW_ARCH_ENABLED'] ||= '0' if podfile_properties['newArchEnabled'] == 'false'
|
||||||
ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
|
ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] ||= podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
|
||||||
|
ENV['RCT_USE_RN_DEP'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false'
|
||||||
|
ENV['RCT_USE_PREBUILT_RNCORE'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false'
|
||||||
platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1'
|
platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1'
|
||||||
install! 'cocoapods',
|
|
||||||
:deterministic_uuids => false
|
|
||||||
|
|
||||||
prepare_react_native_project!
|
prepare_react_native_project!
|
||||||
|
|
||||||
@@ -49,16 +48,5 @@ target 'HIPMIBADUNG' do
|
|||||||
:mac_catalyst_enabled => false,
|
:mac_catalyst_enabled => false,
|
||||||
:ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true',
|
:ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true',
|
||||||
)
|
)
|
||||||
|
|
||||||
# This is necessary for Xcode 14, because it signs resource bundles by default
|
|
||||||
# when building for devices.
|
|
||||||
installer.target_installation_results.pod_target_installation_results
|
|
||||||
.each do |pod_name, target_installation_result|
|
|
||||||
target_installation_result.resource_bundle_targets.each do |resource_bundle_target|
|
|
||||||
resource_bundle_target.build_configurations.each do |config|
|
|
||||||
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
2944
ios/Podfile.lock
2944
ios/Podfile.lock
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user