Fix Admin #53

Merged
bagasbanuna merged 1 commits from fixed-admin/13-feb-26 into staging 2026-02-13 17:42:41 +08:00
11 changed files with 516 additions and 444 deletions

View File

@@ -1,135 +1,5 @@
/* eslint-disable react-hooks/exhaustive-deps */
import {
ActionIcon,
BaseBox,
CenterCustom,
LoaderCustom,
Spacing,
StackCustom,
TextCustom,
ViewWrapper,
} from "@/components";
import { IconEdit } from "@/components/_Icon";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { GridSpan_NewComponent } from "@/components/_ShareComponent/GridSpan_NewComponent";
import { MainColor } from "@/constants/color-palet";
import { apiAdminMasterBusinessFieldById } from "@/service/api-admin/api-master-admin";
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
import { useCallback, useState } from "react";
import { Divider } from "react-native-paper";
import { Admin_ScreenBusinessFieldDetail } from "@/screens/Admin/App-Information/ScreenBusinessFieldDetail";
export default function AdminAppInformation_BusinessFieldDetail() {
const { id } = useLocalSearchParams();
const [data, setData] = useState<any | null>(null);
const [isLoading, setIsLoading] = useState(false);
useFocusEffect(
useCallback(() => {
onLoadDetail();
}, [id])
);
const onLoadDetail = async () => {
try {
const response = await apiAdminMasterBusinessFieldById({
id: id as string,
category: "all",
});
console.log("Response >>", JSON.stringify(response, null, 2));
setData(response.data);
} catch (error) {
console.log("[ERROR]", error);
setData(null);
}
};
return (
<>
<ViewWrapper>
<StackCustom>
<AdminBackButtonAntTitle title="Detail Bidang & Sub Bidang" />
{!data ? (
<LoaderCustom />
) : (
<StackCustom gap={"xs"}>
<TextCustom bold>Nama Bidang</TextCustom>
<Spacing height={5} />
<BaseBox>
<StackCustom gap={"xs"}>
<TextCustom bold>
Status: {data?.bidang?.active ? "Aktif" : "Tidak Aktif"}
</TextCustom>
<GridSpan_NewComponent
span1={10}
span2={2}
text1={
<TextCustom bold size={"large"}>
{data?.bidang?.name}
</TextCustom>
}
text2={
<CenterCustom>
<ActionIcon
icon={<IconEdit size={16} color={MainColor.black} />}
onPress={() =>
router.push(
`/admin/app-information/business-field/${id}/bidang-update`
)
}
/>
</CenterCustom>
}
/>
</StackCustom>
</BaseBox>
{/* <Divider /> */}
<Spacing height={5} />
<TextCustom bold>Sub Bidang Bisnis</TextCustom>
<Spacing height={5} />
{data?.subBidang?.map((item: any, index: number) => (
<BaseBox key={index}>
<StackCustom gap={0}>
<TextCustom bold>
Status: {item?.isActive ? "Aktif" : "Tidak Aktif"}
</TextCustom>
<GridSpan_NewComponent
span1={10}
span2={2}
text1={
<TextCustom bold size={"large"}>
{item.name}
</TextCustom>
}
text2={
<CenterCustom>
<ActionIcon
icon={
<IconEdit size={16} color={MainColor.black} />
}
onPress={() =>
router.push(
`/admin/app-information/business-field/${item?.id}/sub-bidang-update`
)
}
/>
</CenterCustom>
}
/>
</StackCustom>
</BaseBox>
))}
</StackCustom>
)}
{/* <TextCustom>{JSON.stringify(data, null, 2)}</TextCustom> */}
</StackCustom>
</ViewWrapper>
</>
);
return <Admin_ScreenBusinessFieldDetail />;
}

View File

@@ -1,86 +1,5 @@
import { ScrollableCustom, StackCustom, ViewWrapper } from "@/components";
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
import AdminAppInformation_BusinessFieldSection from "@/screens/Admin/App-Information/BusinessFieldSection";
import AdminAppInformation_Bank from "@/screens/Admin/App-Information/InformationBankSection";
import AdminAppInformation_StickerSection from "@/screens/Admin/App-Information/StickerSection";
import { router } from "expo-router";
import { useState } from "react";
import { Alert } from "react-native";
import { Admin_ScreenAppInformation } from "@/screens/Admin/App-Information/ScreenAppInformation";
export default function AdminInformation() {
const [activeCategory, setActiveCategory] = useState<string | null>("bank");
const [activePage, setActivePage] = useState<string>("Informasi Bank");
const handlePress = (item: any) => {
setActiveCategory(item.value);
setActivePage(item.label);
// tambahkan logika lain seperti filter dsb.
};
const scrollComponent = (
<StackCustom>
<ScrollableCustom
data={listPage}
onButtonPress={handlePress}
activeId={activeCategory as any}
/>
</StackCustom>
);
const renderContent = () => {
switch (activeCategory) {
case "bank":
return <AdminAppInformation_Bank />;
case "business":
return <AdminAppInformation_BusinessFieldSection />;
case "sticker":
return <AdminAppInformation_StickerSection />;
default:
return <AdminAppInformation_Bank />;
}
};
return (
<>
<ViewWrapper headerComponent={scrollComponent}>
<AdminComp_BoxTitle
title={activePage}
rightComponent={
<AdminActionIconPlus
onPress={() => {
if (activeCategory === "bank") {
router.push("/admin/app-information/information-bank/create");
} else if (activeCategory === "business") {
router.push("/admin/app-information/business-field/create");
} else if (activeCategory === "sticker") {
Alert.alert("Coming Soon", "Next Update");
// router.push("/admin/app-information/sticker/create");
}
}}
/>
}
/>
{renderContent()}
</ViewWrapper>
</>
);
return <Admin_ScreenAppInformation />;
}
const listPage = [
{
id: "1",
label: "Informasi Bank",
value: "bank",
},
{
id: "2",
label: "Bidang & Sub Bidang",
value: "business",
},
{
id: "3",
label: "Stiker",
value: "sticker",
},
];

View File

@@ -24,8 +24,8 @@ export default function AdminComp_BoxTitle({
style={{
backgroundColor: AccentColor.darkblue,
borderColor: AccentColor.blue,
padding: 10,
paddingBlock: 5,
paddingInline: 10,
borderWidth: 1,
borderRadius: 10,
}}

View File

@@ -60,24 +60,48 @@ Gunakan bahasa indonesia pada cli agar saya mudah membacanya.eclar
<!-- End Random Prompt -->
<!-- START Prompt Admin Refactoring -->
File source: app/(application)/admin/user-access/index.tsx
Folder tujuan: screens/Admin/User-Access
Nama file utama: ScreenUserAccess.tsx
Nama function utama: Admin_ScreenUserAccess
<!-- Pindah kode ke Screen Component -->
File source: app/(application)/admin/app-information/business-field/[id]/index.tsx
Folder tujuan: screens/Admin/App-Information
Nama file utama: ScreenBusinessFieldDetail.tsx
Nama function utama: Admin_ScreenBusinessFieldDetail
File komponen wrapper: components/_ShareComponent/NewWrapper.tsx
Function fecth: apiAdminUserAccessGetAll
File function fetch: service/api-admin/api-admin-user-access.ts
Buat file baru pada "Folder tujuan" dengan nama "Nama file utama" dan ubah nama function menjadi "Nama function utama" kemudian clean code, import dan panggil function tersebut pada file "File source"
Analisa juga file "Nama file utama" , jika belum menggunakan NewWrapper pada file "File komponen wrapper" , maka terapkan juga dan ganti wrapper lama yaitu komponen ViewWrapper
<!-- Penerapan Pagination -->
Function fecth: apiAdminMasterBank
File function fetch: service/api-admin/api-master-admin.ts
Terapkan pagination pada file "Nama file utama"
Komponen pagination yang digunaka berada pada file hooks/use-pagination.tsx dan helpers/paginationHelpers.tsx
Perbaiki fetch "Function fecth" , pada file "File function fetch"
Jika tidak ada props page maka tambahkan props page dan default page: "1"
Gunakan bahasa indonesia pada cli agar saya mudah membacanya.
<!-- END Prompt Admin Refactoring -->
<!-- END Prompt Admin Refactoring -->
<!-- Use Prompt Now -->
Terapkan NewWrapper pada file: screens/Admin/App-Information/InformationBankSection.tsx
Component yang digunakan: components/_ShareComponent/NewWrapper.tsx
Function fecth: apiAdminMasterBank
File function fetch: service/api-admin/api-master-admin.ts
Terapkan pagination pada file "Nama file utama"
Komponen pagination yang digunaka berada pada file hooks/use-pagination.tsx dan helpers/paginationHelpers.tsx
Perbaiki fetch "Function fecth" , pada file "File function fetch"
Jika tidak ada props page maka tambahkan props page dan default page: "1" ( string )
<!-- Baru -->
File Utama: screens/Admin/App-Information/InformationBankSection.tsx
Terapkan FlatList dan pagination pada file "File Utama"
Komponen pagination yang digunaka berada pada file hooks/use-pagination.tsx dan helpers/paginationHelpers.tsx
Function fecth: apiAdminMasterBank
File function fetch: service/api-admin/api-master-admin.ts
Jika tidak ada props page maka tambahkan props page dan default page: "1" ( string )
Jika butuh refrensi FlatList bisa lihat pada file components/_ShareComponent/NewWrapper.tsx
<!-- END Use Prompt Now -->

View File

@@ -1,114 +1,56 @@
import {
ActionIcon,
BadgeCustom,
CenterCustom,
Grid,
LoaderCustom,
StackCustom,
TextCustom,
TextCustom
} from "@/components";
import { AccentColor } from "@/constants/color-palet";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { apiAdminMasterBusinessField } from "@/service/api-admin/api-master-admin";
import { FontAwesome5 } from "@expo/vector-icons";
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 AdminBasicBox from "@/components/_ShareComponent/Admin/AdminBasicBox";
import { router } from "expo-router";
export default function AdminAppInformation_BusinessFieldSection() {
const [listData, setListData] = useState<any[] | null>(null);
const [loadData, setLoadData] = useState(false);
useFocusEffect(
useCallback(() => {
onLoadList();
}, [])
);
const onLoadList = async () => {
try {
setLoadData(true);
const response = await apiAdminMasterBusinessField();
if (response.success) {
setListData(response.data);
}
} catch (error) {
console.log("[ERROR LIST BUSINESS FIELD]", error);
setListData([]);
} finally {
setLoadData(false);
}
interface Bidang {
item: {
id: string;
name: string;
slug: string;
active: boolean;
createdAt: string;
updatedAt: string;
};
}
export default function AdminAppInformation_BusinessFieldSection({
item,
}: {
item: any;
}) {
return (
<>
<StackCustom>
<AdminBasicBox
onPress={() =>
router.push(`/admin/app-information/business-field/${item.item.id}`)
}
style={{ marginHorizontal: 10, marginVertical: 5 }}
>
<Grid>
<Grid.Col span={2} style={{ alignItems: "center" }}>
<TextCustom bold>Aksi</TextCustom>
<Grid.Col span={8} style={{ alignSelf: "center" }}>
<StackCustom gap={"xs"}>
<TextCustom bold truncate>
{item?.item?.name || "-"}
</TextCustom>
</StackCustom>
</Grid.Col>
<Grid.Col span={4} style={{ alignItems: "center" }}>
<TextCustom bold>Status</TextCustom>
</Grid.Col>
<Grid.Col span={6}>
<TextCustom bold>Nama Bidang Bisnis</TextCustom>
<Grid.Col span={4} style={{ alignItems: "flex-end" }}>
<CenterCustom>
{item?.item?.active ? (
<BadgeCustom color="green">Aktif</BadgeCustom>
) : (
<BadgeCustom color="red">Tidak Aktif</BadgeCustom>
)}
</CenterCustom>
</Grid.Col>
</Grid>
<Divider />
{loadData ? (
<LoaderCustom />
) : _.isEmpty(listData) ? (
<TextCustom align="center">Tidak ada data</TextCustom>
) : (
<StackCustom>
{listData?.map((item: any, index: number) => (
<View key={index}>
<Grid>
<Grid.Col span={2} style={{ alignItems: "center" }}>
<ActionIcon
icon={
<FontAwesome5
name="edit"
size={ICON_SIZE_BUTTON}
color="black"
/>
}
onPress={() => {
router.push(
`/admin/app-information/business-field/${item.id}`
);
}}
/>
</Grid.Col>
<Grid.Col
span={4}
style={{ alignItems: "center", justifyContent: "center" }}
>
<CenterCustom>
<BadgeCustom
color={
item.active ? AccentColor.blue : AccentColor.blackgray
}
>
{item.active ? "Aktif" : "Tidak Aktif"}
</BadgeCustom>
</CenterCustom>
</Grid.Col>
<Grid.Col span={6} style={{ justifyContent: "center" }}>
<TextCustom>{item.name}</TextCustom>
</Grid.Col>
</Grid>
</View>
))}
</StackCustom>
)}
</StackCustom>
</AdminBasicBox>
</>
);
}

View File

@@ -1,119 +1,59 @@
import {
ActionIcon,
BadgeCustom,
CenterCustom,
Grid,
LoaderCustom,
StackCustom,
TextCustom,
TextCustom
} from "@/components";
import { AccentColor } from "@/constants/color-palet";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { apiAdminMasterBank } from "@/service/api-admin/api-master-admin";
import { FontAwesome5 } from "@expo/vector-icons";
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 AdminBasicBox from "@/components/_ShareComponent/Admin/AdminBasicBox";
import { router } from "expo-router";
export default function AdminAppInformation_Bank() {
const [listData, setListData] = useState<any | null>(null);
const [loadData, setLoadData] = useState(false);
useFocusEffect(
useCallback(() => {
loadMasterBank();
}, [])
);
const loadMasterBank = async () => {
try {
setLoadData(true);
const response = await apiAdminMasterBank();
setListData(response.data);
} catch (error) {
console.log("[ERROR LIST BANK]", error);
setListData([]);
} finally {
setLoadData(false);
}
interface BankProps {
item: {
id: string;
namaBank: string;
namaAkun: string;
norek: string;
isActive: boolean;
createdAt: string;
updatedAt: string;
};
}
export default function AdminAppInformation_Bank({
item,
}: {
item: BankProps;
}) {
return (
<>
<StackCustom>
<AdminBasicBox
onPress={() =>
router.push(`/admin/app-information/information-bank/${item.item.id}`)
}
style={{ marginHorizontal: 10, marginVertical: 5 }}
>
<Grid>
<Grid.Col span={3}>
<TextCustom bold align="center">
Aksi
</TextCustom>
<Grid.Col span={8}>
<StackCustom gap={"xs"}>
<TextCustom bold truncate>
{item?.item?.namaBank || "-"}
</TextCustom>
<TextCustom size={"small"} bold truncate color="gray">
{item?.item?.norek || "-"}
</TextCustom>
</StackCustom>
</Grid.Col>
<Grid.Col span={3}>
<TextCustom bold align="center">
Status
</TextCustom>
</Grid.Col>
<Grid.Col span={6}>
<TextCustom bold align="center">
Nama Bank
</TextCustom>
<Grid.Col span={4} style={{ alignItems: "flex-end" }}>
<CenterCustom>
{item?.item?.isActive ? (
<BadgeCustom color="green">Aktif</BadgeCustom>
) : (
<BadgeCustom color="red">Tidak Aktif</BadgeCustom>
)}
</CenterCustom>
</Grid.Col>
</Grid>
<Divider />
{loadData ? (
<LoaderCustom />
) : _.isEmpty(listData) ? (
<TextCustom align="center">Tidak ada data</TextCustom>
) : (
<StackCustom>
{listData?.map((item: any, index: number) => (
<View key={index}>
<Grid>
<Grid.Col span={3} style={{ alignItems: "center" }}>
<ActionIcon
icon={
<FontAwesome5
name="edit"
size={ICON_SIZE_BUTTON}
color="black"
/>
}
onPress={() => {
router.push(
`/admin/app-information/information-bank/${item.id}`
);
}}
/>
</Grid.Col>
<Grid.Col
span={3}
style={{ alignItems: "center", justifyContent: "center" }}
>
<CenterCustom>
<BadgeCustom
color={
item.isActive
? AccentColor.blue
: AccentColor.blackgray
}
>
{item.isActive ? "Aktif" : "Tidak Aktif"}
</BadgeCustom>
</CenterCustom>
</Grid.Col>
<Grid.Col span={6} style={{ justifyContent: "center" }}>
<TextCustom align="center">{item.namaBank}</TextCustom>
</Grid.Col>
</Grid>
</View>
))}
</StackCustom>
)}
</StackCustom>
</AdminBasicBox>
</>
);
}

View File

@@ -0,0 +1,153 @@
import { ScrollableCustom, StackCustom } from "@/components";
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
import { MainColor } from "@/constants/color-palet";
import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
import { createPaginationComponents } from "@/helpers/paginationHelpers";
import { usePagination } from "@/hooks/use-pagination";
import AdminAppInformation_BusinessFieldSection from "@/screens/Admin/App-Information/BusinessFieldSection";
import AdminAppInformation_Bank_Component from "@/screens/Admin/App-Information/InformationBankSection";
import { apiFetchAdminMasterAppInformation } from "@/service/api-admin/api-master-admin";
import { router, useFocusEffect } from "expo-router";
import { useCallback, useState } from "react";
import { Alert, RefreshControl } from "react-native";
export function Admin_ScreenAppInformation() {
const [activeCategory, setActiveCategory] = useState<string | null>("bank");
const [activePage, setActivePage] = useState<string>("Informasi Bank");
const pagination = usePagination({
fetchFunction: async (page) => {
return await apiFetchAdminMasterAppInformation({
category: activeCategory as string,
page: String(page),
});
},
pageSize: PAGINATION_DEFAULT_TAKE,
dependencies: [activeCategory],
onError: (error) => console.error("[ERROR] Fetch job by status:", error),
});
const { ListEmptyComponent, ListFooterComponent } =
createPaginationComponents({
loading: pagination.loading,
refreshing: pagination.refreshing,
listData: pagination.listData,
emptyMessage: `Tidak ada data ${activeCategory}`,
skeletonCount: PAGINATION_DEFAULT_TAKE,
skeletonHeight: 100,
});
const handlePress = (item: any) => {
setActiveCategory(item.value);
setActivePage(item.label);
// tambahkan logika lain seperti filter dsb.
};
useFocusEffect(
useCallback(() => {
pagination.onRefresh();
}, [activeCategory]),
);
const scrollComponent = (
<StackCustom>
<ScrollableCustom
data={listPage.map((e, i) => ({
id: i,
label: e.label,
value: e.value,
}))}
onButtonPress={handlePress}
activeId={activeCategory as any}
/>
<AdminComp_BoxTitle
title={activePage}
rightComponent={
<AdminActionIconPlus
onPress={() => {
if (activeCategory === "bank") {
router.push("/admin/app-information/information-bank/create");
} else if (activeCategory === "business") {
router.push("/admin/app-information/business-field/create");
} else if (activeCategory === "sticker") {
Alert.alert("Coming Soon", "Next Update");
// router.push("/admin/app-information/sticker/create");
}
}}
/>
}
/>
</StackCustom>
);
// const renderContent = () => {
// switch (activeCategory) {
// case "bank":
// return <AdminAppInformation_Bank_Component />;
// case "business":
// return <AdminAppInformation_BusinessFieldSection />;
// // case "sticker":
// // return <AdminAppInformation_StickerSection />;
// default:
// return <AdminAppInformation_Bank_Component />;
// }
// };
const renderItem = (item: any) => {
if (activeCategory === "bank") {
return <AdminAppInformation_Bank_Component key={item.id} item={item} />;
} else if (activeCategory === "business") {
return (
<AdminAppInformation_BusinessFieldSection key={item.id} item={item} />
);
} else {
return <AdminAppInformation_Bank_Component key={item.id} item={item} />;
}
};
return (
<NewWrapper
headerComponent={scrollComponent}
// ListHeaderComponent={
// }
refreshControl={
<RefreshControl
tintColor={MainColor.yellow}
colors={[MainColor.yellow]}
refreshing={pagination.refreshing}
onRefresh={pagination.onRefresh}
/>
}
onEndReached={pagination.loadMore}
ListEmptyComponent={ListEmptyComponent}
ListFooterComponent={ListFooterComponent}
hideFooter
// Data dan render
listData={pagination.listData}
renderItem={(item: any) => renderItem(item)}
/>
// {renderContent()}
// </NewWrapper>
);
}
const listPage = [
{
id: "1",
label: "Informasi Bank",
value: "bank",
},
{
id: "2",
label: "Bidang & Sub Bidang",
value: "business",
},
// {
// id: "3",
// label: "Stiker",
// value: "sticker",
// },
];

View File

@@ -0,0 +1,185 @@
/* eslint-disable react-hooks/exhaustive-deps */
import {
BadgeCustom,
BaseBox,
CenterCustom,
NewWrapper,
Spacing,
StackCustom,
TextCustom,
} from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import { GridSpan_NewComponent } from "@/components/_ShareComponent/GridSpan_NewComponent";
import { MainColor } from "@/constants/color-palet";
import {
ICON_SIZE_SMALL,
PAGINATION_DEFAULT_TAKE,
} from "@/constants/constans-value";
import { createPaginationComponents } from "@/helpers/paginationHelpers";
import { usePagination } from "@/hooks/use-pagination";
import { apiAdminMasterBusinessFieldById } from "@/service/api-admin/api-master-admin";
import { Ionicons } from "@expo/vector-icons";
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
import { useCallback, useState } from "react";
import { RefreshControl, View } from "react-native";
export function Admin_ScreenBusinessFieldDetail() {
const { id } = useLocalSearchParams();
const [bidang, setBidang] = useState<any | null>(null);
const pagination = usePagination({
fetchFunction: async (page) => {
return await apiAdminMasterBusinessFieldById({
category: "only-sub-bidang",
id: id as any,
page: String(page),
});
// Pastikan mengembalikan struktur data yang sesuai dengan yang diharapkan oleh usePagination
},
pageSize: PAGINATION_DEFAULT_TAKE,
dependencies: [id],
onError: (error) => {
console.log("Error fetching data sub bidang", error);
},
});
const { ListEmptyComponent, ListFooterComponent } =
createPaginationComponents({
loading: pagination.loading,
refreshing: pagination.refreshing,
listData: pagination.listData,
searchQuery: "",
emptyMessage: "Tidak ada data pengguna",
emptySearchMessage: "Tidak ada hasil pencarian",
skeletonCount: PAGINATION_DEFAULT_TAKE,
skeletonHeight: 100,
isInitialLoad: pagination.isInitialLoad,
});
useFocusEffect(
useCallback(() => {
onLoadBidang();
pagination.onRefresh();
}, [id]),
);
const onLoadBidang = async () => {
try {
const response = await apiAdminMasterBusinessFieldById({
id: id as string,
category: "all",
});
setBidang(response.data);
} catch (error) {
console.log("[ERROR]", error);
setBidang(null);
}
};
const renderHeader = () => (
<View>
<BaseBox
onPress={() =>
router.push(
`/admin/app-information/business-field/${id}/bidang-update`,
)
}
>
<StackCustom gap={"xs"}>
<GridSpan_NewComponent
span1={10}
span2={2}
text1={
<StackCustom>
<TextCustom bold size={"large"}>
{bidang?.bidang?.name}
</TextCustom>
{bidang?.bidang.active ? (
<BadgeCustom color="green">Aktif</BadgeCustom>
) : (
<BadgeCustom color="red">Tidak Aktif</BadgeCustom>
)}
</StackCustom>
}
text2={
<CenterCustom>
<Ionicons
name="caret-forward"
size={ICON_SIZE_SMALL}
color="white"
/>
</CenterCustom>
}
/>
</StackCustom>
</BaseBox>
<CenterCustom>
<TextCustom bold>Sub Bidang</TextCustom>
</CenterCustom>
<Spacing height={5} />
</View>
);
const renderItem = ({ item }: { item: any }) => (
<BaseBox
onPress={() =>
router.push(
`/admin/app-information/business-field/${item?.id}/sub-bidang-update`,
)
}
>
<StackCustom gap={"xs"}>
<GridSpan_NewComponent
span1={10}
span2={2}
text1={
<StackCustom>
<TextCustom bold size={"large"}>
{item.name}
</TextCustom>
{item?.isActive ? (
<BadgeCustom color="green">Aktif</BadgeCustom>
) : (
<BadgeCustom color="red">Tidak Aktif</BadgeCustom>
)}
</StackCustom>
}
text2={
<CenterCustom>
<Ionicons
name="caret-forward"
size={ICON_SIZE_SMALL}
color="white"
/>
</CenterCustom>
}
/>
</StackCustom>
</BaseBox>
);
return (
<>
<NewWrapper
listData={pagination.listData}
onEndReached={pagination.loadMore}
ListEmptyComponent={ListEmptyComponent}
ListFooterComponent={ListFooterComponent}
hideFooter
refreshControl={
<RefreshControl
refreshing={pagination.refreshing}
onRefresh={pagination.onRefresh}
tintColor={MainColor.yellow}
colors={[MainColor.yellow]}
/>
}
headerComponent={
<AdminBackButtonAntTitle title="Detail Bidang & Sub Bidang" />
}
ListHeaderComponent={renderHeader()}
renderItem={renderItem}
/>
</>
);
}

View File

@@ -5,20 +5,18 @@ import {
Grid,
SearchInput,
StackCustom,
TextCustom
TextCustom,
} from "@/components";
import AdminBasicBox from "@/components/_ShareComponent/Admin/AdminBasicBox";
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
import { MainColor } from "@/constants/color-palet";
import {
PAGINATION_DEFAULT_TAKE
} from "@/constants/constans-value";
import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
import { createPaginationComponents } from "@/helpers/paginationHelpers";
import { usePagination } from "@/hooks/use-pagination";
import { apiAdminUserAccessGetAll } from "@/service/api-admin/api-admin-user-access";
import { router } from "expo-router";
import { useState } from "react";
import { router, useFocusEffect } from "expo-router";
import { useCallback, useState } from "react";
import { RefreshControl } from "react-native";
export function Admin_ScreenUserAccess() {
@@ -54,6 +52,12 @@ export function Admin_ScreenUserAccess() {
isInitialLoad: pagination.isInitialLoad,
});
useFocusEffect(
useCallback(() => {
pagination.onRefresh();
}, []),
);
const rightComponent = () => {
return (
<>

View File

@@ -1,9 +1,11 @@
import { apiConfig } from "../api-config";
// ================== START MASTER BANK ================== //
export async function apiAdminMasterBank() {
export async function apiAdminMasterBank({ page = "1" }: { page?: string }) {
try {
const response = await apiConfig.get(`/mobile/admin/master/bank`);
const response = await apiConfig.get(
`/mobile/admin/master/bank?page=${page}`,
);
return response.data;
} catch (error) {
throw error;
@@ -51,9 +53,15 @@ export async function apiAdminMasterBankCreate({ data }: { data: any }) {
// ================== START BUSINNES FIELD ================== //
export async function apiAdminMasterBusinessField() {
export async function apiAdminMasterBusinessField({
page = "1",
}: {
page: string;
}) {
try {
const response = await apiConfig.get(`/mobile/admin/master/business-field`);
const response = await apiConfig.get(
`/mobile/admin/master/business-field?page=${page}`,
);
return response.data;
} catch (error) {
throw error;
@@ -64,16 +72,19 @@ export async function apiAdminMasterBusinessFieldById({
id,
subBidangId,
category,
page = "1"
}: {
id: string;
subBidangId?: string | null;
category: "bidang" | "sub-bidang" | "all";
category: "bidang" | "sub-bidang" | "all" | "only-sub-bidang"
page?: string
}) {
const queryCategory = category ? `?category=${category}` : "";
const querySubBidang = subBidangId ? `&subBidangId=${subBidangId}` : "";
const queryPage = page ? `&page=${page}` : "";
try {
const response = await apiConfig.get(
`/mobile/admin/master/business-field/${id}${queryCategory}${querySubBidang}`
`/mobile/admin/master/business-field/${id}${queryCategory}${querySubBidang}${queryPage}`,
);
return response.data;
} catch (error) {
@@ -95,7 +106,7 @@ export async function apiAdminMasterBusinessFieldUpdate({
`/mobile/admin/master/business-field/${id}?category=${category}`,
{
data: data,
}
},
);
return response.data;
} catch (error) {
@@ -113,7 +124,7 @@ export async function apiAdminMasterBusinessFieldCreate({
`/mobile/admin/master/business-field`,
{
data: data,
}
},
);
return response.data;
} catch (error) {
@@ -139,7 +150,7 @@ export async function apiEventCreateTypeOfEvent({ data }: { data: string }) {
`/mobile/admin/master/type-of-event`,
{
data: data,
}
},
);
return response.data;
} catch (error) {
@@ -150,7 +161,7 @@ export async function apiEventCreateTypeOfEvent({ data }: { data: string }) {
export async function apiAdminMasterTypeOfEventGetOne({ id }: { id: string }) {
try {
const response = await apiConfig.get(
`/mobile/admin/master/type-of-event/${id}`
`/mobile/admin/master/type-of-event/${id}`,
);
return response.data;
} catch (error) {
@@ -170,7 +181,7 @@ export async function apiAdminMasterTypeOfEventUpdate({
`/mobile/admin/master/type-of-event/${id}`,
{
data: data,
}
},
);
return response.data;
} catch (error) {
@@ -216,7 +227,7 @@ export async function apiAdminMasterDonationCategoryUpdate({
`/mobile/admin/master/donation/${id}`,
{
data: data,
}
},
);
return response.data;
} catch (error) {
@@ -240,3 +251,27 @@ export async function apiAdminMasterDonationCategoryCreate({
}
// ================== END DONATION ================== //
// ================== START FECTH APP INFORMATION ================== //
export async function apiFetchAdminMasterAppInformation({
page = "1",
category,
}: {
page: string;
category?: "bank" | "business" | string
}) {
if (category === "bank") {
const response = await apiAdminMasterBank({ page });
// TODO: implement bank logic
return response;
} else if (category === "business") {
const response = await apiAdminMasterBusinessField({ page });
// TODO: implement business logic
return response
} else {
throw new Error("Category is required");
}
}
// ================== END FECTH APP INFORMATION ================== //

View File

@@ -16,7 +16,7 @@ export const GStyles = StyleSheet.create({
// =============== Main Styles =============== //
container: {
flex: 1,
paddingInline: PADDING_MEDIUM,
paddingInline: PADDING_SMALL,
paddingTop: PADDING_EXTRA_SMALL,
paddingBottom: 5,
// paddingBlock: PADDING_EXTRA_SMALL,