add: Admin Event detail screen dan komponen pendukung
Deskripsi: Menambahkan halaman detail event pada admin panel dengan status parameter Menambahkan beberapa komponen UI untuk menampilkan detail event, drawer informasi, dan QR Code Update konfigurasi aplikasi dan iOS project Perbaikan pada halaman verifikasi authentication Update dokumentasi prompt untuk Qwen File yang diubah: Modified app.config.js app/(application)/admin/event/[id]/[status]/index.tsx docs/prompt-for-qwen-code.md ios/HIPMIBadungConnect.xcodeproj/project.pbxproj ios/HIPMIBadungConnect/Info.plist screens/Authentication/VerificationView.tsx New Admin Event Components screens/Admin/Event/BoxEventDetail.tsx screens/Admin/Event/EventDetailDrawer.tsx screens/Admin/Event/EventDetailQRCode.tsx screens/Admin/Event/ScreenEventDetail.tsx ### No Issue
This commit is contained in:
85
screens/Admin/Event/BoxEventDetail.tsx
Normal file
85
screens/Admin/Event/BoxEventDetail.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import { BadgeCustom, BaseBox, Spacing, StackCustom, TextCustom } from "@/components";
|
||||
import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8";
|
||||
import { colorBadgeStatus } from "@/utils/colorBadge";
|
||||
import { dateTimeView } from "@/utils/dateTimeView";
|
||||
import _ from "lodash";
|
||||
|
||||
interface EventDetailData {
|
||||
Author?: {
|
||||
username?: string;
|
||||
};
|
||||
title?: string;
|
||||
lokasi?: string;
|
||||
EventMaster_TipeAcara?: {
|
||||
name?: string;
|
||||
};
|
||||
tanggal?: string;
|
||||
tanggalSelesai?: string;
|
||||
deskripsi?: string;
|
||||
catatan?: string;
|
||||
}
|
||||
|
||||
interface BoxEventDetailProps {
|
||||
data: EventDetailData | null;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export function BoxEventDetail({ data, status }: BoxEventDetailProps) {
|
||||
const listData = [
|
||||
{
|
||||
label: "Pembuat Event",
|
||||
value: data?.Author?.username || "-",
|
||||
},
|
||||
{
|
||||
label: "Judul Event",
|
||||
value: data?.title || "-",
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: data ? (
|
||||
<BadgeCustom color={colorBadgeStatus({ status })}>
|
||||
{_.startCase(status)}
|
||||
</BadgeCustom>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "Lokasi",
|
||||
value: data?.lokasi || "-",
|
||||
},
|
||||
{
|
||||
label: "Tipe Acara",
|
||||
value: data?.EventMaster_TipeAcara?.name || "-",
|
||||
},
|
||||
{
|
||||
label: "Mulai Event",
|
||||
value: data?.tanggal ? dateTimeView({ date: data.tanggal }) : "-",
|
||||
},
|
||||
{
|
||||
label: "Event Berakhir",
|
||||
value: data?.tanggalSelesai
|
||||
? dateTimeView({ date: data.tanggalSelesai })
|
||||
: "-",
|
||||
},
|
||||
{
|
||||
label: "Deskripsi",
|
||||
value: data?.deskripsi || "-",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
{listData.map((item, i) => (
|
||||
<GridSpan_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
<Spacing />
|
||||
</BaseBox>
|
||||
);
|
||||
}
|
||||
37
screens/Admin/Event/EventDetailDrawer.tsx
Normal file
37
screens/Admin/Event/EventDetailDrawer.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { DrawerCustom, MenuDrawerDynamicGrid } from "@/components";
|
||||
import { IconList } from "@/components/_Icon/IconComponent";
|
||||
import { router } from "expo-router";
|
||||
|
||||
interface EventDetailDrawerProps {
|
||||
isVisible: boolean;
|
||||
onClose: () => void;
|
||||
eventId: string;
|
||||
}
|
||||
|
||||
export function EventDetailDrawer({
|
||||
isVisible,
|
||||
onClose,
|
||||
eventId,
|
||||
}: EventDetailDrawerProps) {
|
||||
return (
|
||||
<DrawerCustom
|
||||
isVisible={isVisible}
|
||||
closeDrawer={onClose}
|
||||
height={"auto"}
|
||||
>
|
||||
<MenuDrawerDynamicGrid
|
||||
data={[
|
||||
{
|
||||
label: "Daftar Peserta",
|
||||
icon: <IconList />,
|
||||
path: `/admin/event/${eventId}/list-of-participants`,
|
||||
},
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
onClose();
|
||||
router.push(item.path as any);
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
);
|
||||
}
|
||||
26
screens/Admin/Event/EventDetailQRCode.tsx
Normal file
26
screens/Admin/Event/EventDetailQRCode.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { BaseBox, LoaderCustom, Spacing, StackCustom, TextCustom } from "@/components";
|
||||
import QRCode from "react-native-qrcode-svg";
|
||||
|
||||
interface EventDetailQRCodeProps {
|
||||
qrValue: string;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
export function EventDetailQRCode({ qrValue, isLoading }: EventDetailQRCodeProps) {
|
||||
return (
|
||||
<BaseBox>
|
||||
<StackCustom style={{ alignItems: "center" }}>
|
||||
<TextCustom bold>QR Code Event</TextCustom>
|
||||
{isLoading ? (
|
||||
<LoaderCustom />
|
||||
) : (
|
||||
<QRCode
|
||||
value={qrValue}
|
||||
size={200}
|
||||
/>
|
||||
)}
|
||||
</StackCustom>
|
||||
<Spacing />
|
||||
</BaseBox>
|
||||
);
|
||||
}
|
||||
163
screens/Admin/Event/ScreenEventDetail.tsx
Normal file
163
screens/Admin/Event/ScreenEventDetail.tsx
Normal file
@@ -0,0 +1,163 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { ActionIcon, AlertDefaultSystem } from "@/components";
|
||||
import { IconDot } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||
import ReportBox from "@/components/Box/ReportBox";
|
||||
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { funUpdateStatusEvent } from "@/screens/Admin/Event/funUpdateStatus";
|
||||
import { apiAdminEventById } from "@/service/api-admin/api-admin-event";
|
||||
import { DEEP_LINK_URL } from "@/service/api-config";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import Toast from "react-native-toast-message";
|
||||
import { BoxEventDetail } from "./BoxEventDetail";
|
||||
import { EventDetailDrawer } from "./EventDetailDrawer";
|
||||
import { EventDetailQRCode } from "./EventDetailQRCode";
|
||||
|
||||
export function Admin_ScreenEventDetail() {
|
||||
const { user } = useAuth();
|
||||
const { id, status } = useLocalSearchParams();
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
const [data, setData] = useState<any | null>(null);
|
||||
const [loadData, setLoadData] = useState(false);
|
||||
|
||||
const deepLinkURL = `${DEEP_LINK_URL}/event/${id}/confirmation?userId=${user?.id}`;
|
||||
const deepLinkURLDEV = `${DEEP_LINK_URL}/--/event/${id}/confirmation?userId=${user?.id}`;
|
||||
const isDevLink =
|
||||
process.env.NODE_ENV === "development" ? deepLinkURLDEV : deepLinkURL;
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id]),
|
||||
);
|
||||
|
||||
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 rightComponent = (
|
||||
<ActionIcon
|
||||
icon={<IconDot size={ICON_SIZE_BUTTON} />}
|
||||
onPress={() => {
|
||||
setOpenDrawer(true);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
const handlerSubmit = async () => {
|
||||
try {
|
||||
const response = await funUpdateStatusEvent({
|
||||
id: id as string,
|
||||
changeStatus: "publish",
|
||||
data: { catatan: "", senderId: user?.id as string },
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
const headerComponent = useMemo(
|
||||
() => (
|
||||
<AdminBackButtonAntTitle
|
||||
title={`Detail Data`}
|
||||
rightComponent={
|
||||
status === "publish" || status === "history"
|
||||
? rightComponent
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
),
|
||||
[status],
|
||||
);
|
||||
|
||||
const footerComponent = useMemo(() => {
|
||||
if (status === "review") {
|
||||
return (
|
||||
<AdminButtonReview
|
||||
onPublish={() => {
|
||||
AlertDefaultSystem({
|
||||
title: "Publish",
|
||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressRight: () => handlerSubmit(),
|
||||
});
|
||||
}}
|
||||
onReject={() => {
|
||||
router.push(`/admin/event/${id}/reject-input?status=${status}`);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (status === "reject") {
|
||||
return (
|
||||
<AdminButtonReject
|
||||
title="Tambah Catatan"
|
||||
onReject={() => {
|
||||
router.push(`/admin/event/${id}/reject-input?status=${status}`);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [status, id]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<NewWrapper
|
||||
headerComponent={headerComponent}
|
||||
footerComponent={footerComponent}
|
||||
>
|
||||
<BoxEventDetail data={data} status={status as string} />
|
||||
|
||||
{data?.catatan && (status === "reject" || status === "review") && (
|
||||
<ReportBox text={data.catatan} />
|
||||
)}
|
||||
|
||||
{(status === "publish" || status === "history") && (
|
||||
<EventDetailQRCode qrValue={isDevLink} isLoading={loadData} />
|
||||
)}
|
||||
</NewWrapper>
|
||||
|
||||
<EventDetailDrawer
|
||||
isVisible={openDrawer}
|
||||
onClose={() => setOpenDrawer(false)}
|
||||
eventId={id as string}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user