From 0770237fe51e95ebea34206ff8b7ec77f5dd3a63 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Thu, 16 Oct 2025 16:44:43 +0800 Subject: [PATCH] Integrasi API: Admin Job Add: - service/api-admin/api-admin-job.ts Fix: modified: app/(application)/admin/job/[status]/status.tsx modified: app/(application)/admin/job/index.tsx modified: components/_ShareComponent/SearchInput.tsx ### No issue --- .../admin/job/[status]/status.tsx | 115 ++++++++++++------ app/(application)/admin/job/index.tsx | 41 ++++++- components/_ShareComponent/SearchInput.tsx | 17 ++- service/api-admin/api-admin-job.ts | 18 +++ 4 files changed, 148 insertions(+), 43 deletions(-) create mode 100644 service/api-admin/api-admin-job.ts diff --git a/app/(application)/admin/job/[status]/status.tsx b/app/(application)/admin/job/[status]/status.tsx index b8f398f..028dcc4 100644 --- a/app/(application)/admin/job/[status]/status.tsx +++ b/app/(application)/admin/job/[status]/status.tsx @@ -1,8 +1,9 @@ +/* eslint-disable react-hooks/exhaustive-deps */ import { ActionIcon, - BaseBox, + LoaderCustom, SearchInput, - Spacing, + StackCustom, TextCustom, ViewWrapper } from "@/components"; @@ -11,17 +12,52 @@ 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 { apiAdminJob } from "@/service/api-admin/api-admin-job"; import { Octicons } from "@expo/vector-icons"; -import { router, useLocalSearchParams } from "expo-router"; +import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; import _ from "lodash"; +import { useCallback, useState } from "react"; import { Divider } from "react-native-paper"; export default function AdminJobStatus() { const { status } = useLocalSearchParams(); + console.log("[STATUS]", status); + + const [list, setList] = useState(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, + }); + + console.log("[RESPONSE >>]", JSON.stringify(response, null, 2)); + + if (response.success) { + setList(response.data); + } + } catch (error) { + console.log("[ERROR]", error); + } finally { + setLoadList(false); + } + }; + const rightComponent = ( ); return ( @@ -32,44 +68,53 @@ export default function AdminJobStatus() { rightComponent={rightComponent} /> - + - + {/* */} - {Array.from({ length: 10 }).map((_, index) => ( - - } - onPress={() => { - router.push(`/admin/job/${index}/${status}`); - }} - /> - } - value2={Username username} - value3={ - - 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. - - } - /> - ))} - + {loadList ? ( + + ) : _.isEmpty(list) ? ( + + Tidak ada data + + ) : ( + list?.map((item: any, index: number) => ( + + } + onPress={() => { + router.push(`/admin/job/${item.id}/${status}`); + }} + /> + } + value2={ + + {item?.Author?.username || "-"} + + } + value3={ + + {item?.title || "-"} + + } + /> + )) + )} + ); diff --git a/app/(application)/admin/job/index.tsx b/app/(application)/admin/job/index.tsx index e58c36a..ec9d39e 100644 --- a/app/(application)/admin/job/index.tsx +++ b/app/(application)/admin/job/index.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { Spacing, StackCustom, ViewWrapper } from "@/components"; import { IconPublish, @@ -7,15 +8,45 @@ import { import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard"; import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; 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() { + const [data, setData] = useState(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 ( <> - {listData.map((item, i) => ( + {listData(data).map((item: any, i: number) => ( ))} @@ -24,20 +55,20 @@ export default function AdminJob() { ); } -const listData = [ +const listData = (data: any) => [ { label: "Publish", - value: 4, + value: (data && data?.publish) || 0, icon: , }, { label: "Review", - value: 7, + value: (data && data?.review) || 0, icon: , }, { label: "Reject", - value: 5, + value: (data && data?.reject) || 0, icon: , }, ]; diff --git a/components/_ShareComponent/SearchInput.tsx b/components/_ShareComponent/SearchInput.tsx index 01d297a..2c43ef4 100644 --- a/components/_ShareComponent/SearchInput.tsx +++ b/components/_ShareComponent/SearchInput.tsx @@ -2,7 +2,7 @@ import { MainColor } from "@/constants/color-palet"; import { ICON_SIZE_SMALL } from "@/constants/constans-value"; import TextInputCustom from "../TextInput/TextInputCustom"; import { Ionicons } from "@expo/vector-icons"; -import { StyleProp, ViewStyle, TextStyle } from "react-native"; +import { StyleProp, ViewStyle, TextStyle, StyleSheet } from "react-native"; interface SearchInputProps { placeholder?: string; @@ -12,6 +12,8 @@ interface SearchInputProps { containerStyle?: StyleProp; style?: StyleProp; onChangeText?: (value: string) => void; + value?: string; + disabled?: boolean; } export default function SearchInput({ placeholder, @@ -21,6 +23,8 @@ export default function SearchInput({ containerStyle, style, onChangeText, + value, + disabled, ...props }: SearchInputProps) { return ( @@ -29,14 +33,21 @@ export default function SearchInput({ } + value={value} onChangeText={onChangeText} placeholder={placeholder} borderRadius={50} - containerStyle={[containerStyle, { marginBottom: 0 }]} + containerStyle={[disabled ? styleses.disabled : styleses.containerStyle]} + disabled={disabled} {...props} /> ); } + +const styleses = StyleSheet.create({ + containerStyle: { width: "100%", marginBottom: 0 }, + disabled: { width: "100%", marginBottom: 0, color: MainColor.white_gray }, +}); diff --git a/service/api-admin/api-admin-job.ts b/service/api-admin/api-admin-job.ts new file mode 100644 index 0000000..f02f72b --- /dev/null +++ b/service/api-admin/api-admin-job.ts @@ -0,0 +1,18 @@ +import { apiConfig } from "../api-config"; + +export async function apiAdminJob({ + category, + search, +}: { + category: "dashboard" | "publish" | "review" | "reject"; + search?: string; +}) { + try { + const response = await apiConfig.get( + `/mobile/admin/job?category=${category}&search=${search}` + ); + return response.data; + } catch (error) { + throw error; + } +}