From 19d3a9a6c7846ca5f0657b8a1582e9ed613b8b85 Mon Sep 17 00:00:00 2001 From: bagasbanuna Date: Wed, 15 Apr 2026 15:02:00 +0800 Subject: [PATCH] feat: Refactor super-admin screens to OS_Wrapper pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create screens/Admin/Super-Admin/ScreenSuperAdmin.tsx * Migrate from ViewWrapper to OS_Wrapper * Add usePagination hook for pagination & skeleton loading * Add AdminBasicBox for card layout (same as user-access) * Add pull-to-refresh & infinite scroll support - Create screens/Admin/Super-Admin/ScreenSuperAdminDetail.tsx * Migrate from ViewWrapper to OS_Wrapper * Add useAuth hook for user validation * Add pull-to-refresh support - Simplify route files: * app/(application)/admin/super-admin/index.tsx → 4 lines * app/(application)/admin/super-admin/[id]/index.tsx → 4 lines Co-authored-by: Qwen-Coder --- .../admin/super-admin/[id]/index.tsx | 130 +-------------- app/(application)/admin/super-admin/index.tsx | 149 +----------------- .../Admin/Super-Admin/ScreenSuperAdmin.tsx | 122 ++++++++++++++ .../Super-Admin/ScreenSuperAdminDetail.tsx | 148 +++++++++++++++++ 4 files changed, 276 insertions(+), 273 deletions(-) create mode 100644 screens/Admin/Super-Admin/ScreenSuperAdmin.tsx create mode 100644 screens/Admin/Super-Admin/ScreenSuperAdminDetail.tsx diff --git a/app/(application)/admin/super-admin/[id]/index.tsx b/app/(application)/admin/super-admin/[id]/index.tsx index 0aaa08c..945e1c5 100644 --- a/app/(application)/admin/super-admin/[id]/index.tsx +++ b/app/(application)/admin/super-admin/[id]/index.tsx @@ -1,129 +1,5 @@ -/* 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"; +import { Admin_ScreenSuperAdminDetail } from "@/screens/Admin/Super-Admin/ScreenSuperAdminDetail"; -export default function SuperAdminDetail() { - const { id } = useLocalSearchParams(); - const [data, setData] = useState(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", - category: "role", - }); - - 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 ( - <> - } - footerComponent={ - data && ( - - - {data?.masterUserRoleId === "2" - ? "Hapus akses admin" - : "Tambah sebagai admin"} - - - ) - } - > - {loadData ? ( - - ) : ( - - {listData(data && data)?.map((item: any, index: number) => ( - {item?.label}} - rightItem={{item?.value}} - /> - ))} - - )} - - - ); +export default function AdminSuperAdminDetail() { + return ; } - -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}`) || "-", - }, -]; diff --git a/app/(application)/admin/super-admin/index.tsx b/app/(application)/admin/super-admin/index.tsx index 6dde028..fa85df2 100644 --- a/app/(application)/admin/super-admin/index.tsx +++ b/app/(application)/admin/super-admin/index.tsx @@ -1,148 +1,5 @@ -/* 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 { Admin_ScreenSuperAdmin } from "@/screens/Admin/Super-Admin/ScreenSuperAdmin"; -import { router, useFocusEffect } from "expo-router"; -import _ from "lodash"; -import { useCallback, useState } from "react"; - -export default function SuperAdmin_ListUser() { - const [listData, setListData] = useState(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 ( - <> - setSearch(text)} - /> - - ); - }; - - return ( - <> - - } - > - - Aksi - - } - component2={ - - Username - - } - component3={ - - Role - - } - /> - - - - - {_.isEmpty(listData) ? ( - - Tidak ada data - - ) : ( - listData?.map((item: any, index: number) => ( - - - router.push(`/admin/super-admin/${item?.id}`) - } - name="open" - size={ICON_SIZE_XLARGE} - color={MainColor.yellow} - /> - - - // - // router.push(`/admin/super-admin/${item?.id}`) - // } - // > - // Detail - // - } - component2={ - - {item?.username || "-"} - - } - component3={ - - {item?.masterUserRoleId === "2" ? ( - Admin - ) : ( - - User - - )} - - } - style3={{ alignItems: "center", justifyContent: "center" }} - /> - )) - )} - - - - ); +export default function AdminSuperAdmin() { + return ; } diff --git a/screens/Admin/Super-Admin/ScreenSuperAdmin.tsx b/screens/Admin/Super-Admin/ScreenSuperAdmin.tsx new file mode 100644 index 0000000..c1d1a76 --- /dev/null +++ b/screens/Admin/Super-Admin/ScreenSuperAdmin.tsx @@ -0,0 +1,122 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +import { + BadgeCustom, + CenterCustom, + Grid, + OS_Wrapper, + SearchInput, + StackCustom, + TextCustom, +} from "@/components"; +import AdminBasicBox from "@/components/_ShareComponent/Admin/AdminBasicBox"; +import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; +import { AccentColor, 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 { apiAdminUserAccessGetAll } from "@/service/api-admin/api-admin-user-access"; +import { Ionicons } from "@expo/vector-icons"; +import { router, useFocusEffect } from "expo-router"; +import { useCallback, useState } from "react"; +import { RefreshControl } from "react-native"; + +export function Admin_ScreenSuperAdmin() { + const [search, setSearch] = useState(""); + + const pagination = usePagination({ + fetchFunction: async (page, searchQuery) => { + return await apiAdminUserAccessGetAll({ + search: searchQuery || "", + category: "all-role", + page: String(page), + }); + }, + pageSize: PAGINATION_DEFAULT_TAKE, + searchQuery: search, + dependencies: [], + onError: (error) => { + console.log("Error fetching super admin data", error); + }, + }); + + const { ListEmptyComponent, ListFooterComponent } = + createPaginationComponents({ + loading: pagination.loading, + refreshing: pagination.refreshing, + listData: pagination.listData, + searchQuery: search, + emptyMessage: "Tidak ada data pengguna", + emptySearchMessage: "Tidak ada hasil pencarian", + skeletonCount: PAGINATION_DEFAULT_TAKE, + skeletonHeight: 100, + isInitialLoad: pagination.isInitialLoad, + }); + + useFocusEffect( + useCallback(() => { + pagination.onRefresh(); + }, []), + ); + + const rightComponent = () => { + return ( + setSearch(text)} + /> + ); + }; + + const renderItem = ({ item, index }: { item: any; index: number }) => ( + router.push(`/admin/super-admin/${item?.id}`)} + style={{ marginHorizontal: 10, marginVertical: 5 }} + > + + + + + {item?.username || "-"} + + + + + + {item?.masterUserRoleId === "2" ? ( + Admin + ) : ( + User + )} + + + + + ); + + return ( + + } + refreshControl={ + + } + renderItem={renderItem} + listData={pagination.listData} + onEndReached={pagination.loadMore} + ListEmptyComponent={ListEmptyComponent} + ListFooterComponent={ListFooterComponent} + hideFooter + /> + ); +} diff --git a/screens/Admin/Super-Admin/ScreenSuperAdminDetail.tsx b/screens/Admin/Super-Admin/ScreenSuperAdminDetail.tsx new file mode 100644 index 0000000..e70bd70 --- /dev/null +++ b/screens/Admin/Super-Admin/ScreenSuperAdminDetail.tsx @@ -0,0 +1,148 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +import { + BoxButtonOnFooter, + ButtonCustom, + LoaderCustom, + OS_Wrapper, + StackCustom, + TextCustom, +} from "@/components"; +import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; +import GridTwoView from "@/components/_ShareComponent/GridTwoView"; +import { useAuth } from "@/hooks/use-auth"; +import { + apiAdminUserAccessGetById, + apiAdminUserAccessUpdateStatus, +} from "@/service/api-admin/api-admin-user-access"; +import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; +import { useCallback, useState } from "react"; +import { RefreshControl } from "react-native"; +import Toast from "react-native-toast-message"; + +export function Admin_ScreenSuperAdminDetail() { + const { user } = useAuth(); + const { id } = useLocalSearchParams(); + const [data, setData] = useState(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 () => { + if (!user?.id) { + Toast.show({ + type: "error", + text1: "User tidak ditemukan", + }); + return; + } + + try { + setLoading(true); + const response = await apiAdminUserAccessUpdateStatus({ + id: id as string, + role: data?.masterUserRoleId === "2" ? "user" : "admin", + category: "role", + }); + + 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 ( + <> + } + footerComponent={ + data && ( + + + {data?.masterUserRoleId === "2" + ? "Hapus akses admin" + : "Tambah sebagai admin"} + + + ) + } + refreshControl={ + + } + > + {loadData ? ( + + ) : ( + + {listData(data && data)?.map((item: any, index: number) => ( + {item?.label}} + rightItem={{item?.value}} + /> + ))} + + )} + + + ); +} + +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}`) || "-", + }, +];