Event
Fix: - UI: status, detail status, delete button, detail utama, tampilan utama - Semua terintergrasi ke API mobile ### No Issue
This commit is contained in:
@@ -1,9 +1,36 @@
|
|||||||
|
import { LoaderCustom, TextCustom } from "@/components";
|
||||||
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
||||||
import FloatingButton from "@/components/Button/FloatingButton";
|
import FloatingButton from "@/components/Button/FloatingButton";
|
||||||
import Event_BoxPublishSection from "@/screens/Event/BoxPublishSection";
|
import Event_BoxPublishSection from "@/screens/Event/BoxPublishSection";
|
||||||
import { router } from "expo-router";
|
import { apiEventGetAll } from "@/service/api-client/api-event";
|
||||||
|
import { dateTimeView } from "@/utils/dateTimeView";
|
||||||
|
import { router, useFocusEffect } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function EventBeranda() {
|
export default function EventBeranda() {
|
||||||
|
const [listData, setListData] = useState([]);
|
||||||
|
const [isLoadData, setIsLoadData] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadData = async () => {
|
||||||
|
try {
|
||||||
|
setIsLoadData(true);
|
||||||
|
const response = await apiEventGetAll();
|
||||||
|
// console.log("Response", JSON.stringify(response.data, null, 2));
|
||||||
|
setListData(response.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
} finally {
|
||||||
|
setIsLoadData(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ViewWrapper
|
<ViewWrapper
|
||||||
hideFooter
|
hideFooter
|
||||||
@@ -11,13 +38,24 @@ export default function EventBeranda() {
|
|||||||
<FloatingButton onPress={() => router.push("/event/create")} />
|
<FloatingButton onPress={() => router.push("/event/create")} />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{Array.from({ length: 10 }).map((_, index) => (
|
{isLoadData ? (
|
||||||
|
<LoaderCustom />
|
||||||
|
) : _.isEmpty(listData) ? (
|
||||||
|
<TextCustom align="center">Belum ada event</TextCustom>
|
||||||
|
) : (
|
||||||
|
listData.map((item: any, index) => (
|
||||||
<Event_BoxPublishSection
|
<Event_BoxPublishSection
|
||||||
key={index}
|
key={index}
|
||||||
id={index.toString()}
|
href={`/event/${item.id}/publish`}
|
||||||
href={`/event/${index}/publish`}
|
data={item}
|
||||||
|
rightComponentAvatar={
|
||||||
|
<TextCustom>
|
||||||
|
{dateTimeView({ date: item?.tanggal, withoutTime: true })}
|
||||||
|
</TextCustom>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
))}
|
))
|
||||||
|
)}
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export default function EventEdit() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateDate = () => {
|
const validateDate = async () => {
|
||||||
if (
|
if (
|
||||||
data?.title === "" ||
|
data?.title === "" ||
|
||||||
data?.lokasi === "" ||
|
data?.lokasi === "" ||
|
||||||
@@ -92,7 +92,8 @@ export default function EventEdit() {
|
|||||||
text1: "Info",
|
text1: "Info",
|
||||||
text2: "Lengkapi semua data",
|
text2: "Lengkapi semua data",
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const startDate = new Date(selectedDate as any);
|
const startDate = new Date(selectedDate as any);
|
||||||
@@ -104,12 +105,17 @@ export default function EventEdit() {
|
|||||||
text1: "Info",
|
text1: "Info",
|
||||||
text2: "Ubah tanggal berakhirnya event",
|
text2: "Ubah tanggal berakhirnya event",
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlerSubmit = async () => {
|
const handlerSubmit = async () => {
|
||||||
validateDate();
|
const isValid = await validateDate();
|
||||||
|
if (!isValid) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const newData = {
|
const newData = {
|
||||||
|
|||||||
@@ -1,23 +1,42 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
DotButton,
|
DotButton,
|
||||||
DrawerCustom,
|
DrawerCustom,
|
||||||
MenuDrawerDynamicGrid,
|
MenuDrawerDynamicGrid,
|
||||||
Spacing,
|
Spacing,
|
||||||
ViewWrapper
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { IMenuDrawerItem } from "@/components/_Interface/types";
|
import { IMenuDrawerItem } from "@/components/_Interface/types";
|
||||||
import LeftButtonCustom from "@/components/Button/BackButton";
|
import LeftButtonCustom from "@/components/Button/BackButton";
|
||||||
import Event_BoxDetailPublishSection from "@/screens/Event/BoxDetailPublishSection";
|
import Event_BoxDetailPublishSection from "@/screens/Event/BoxDetailPublishSection";
|
||||||
import { menuDrawerPublishEvent } from "@/screens/Event/menuDrawerPublish";
|
import { menuDrawerPublishEvent } from "@/screens/Event/menuDrawerPublish";
|
||||||
|
import { apiEventGetOne } from "@/service/api-client/api-event";
|
||||||
import { router, Stack, useLocalSearchParams } from "expo-router";
|
import { router, Stack, useLocalSearchParams } from "expo-router";
|
||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Alert } from "react-native";
|
import { Alert } from "react-native";
|
||||||
|
|
||||||
export default function EventDetailPublish() {
|
export default function EventDetailPublish() {
|
||||||
const { id } = useLocalSearchParams();
|
const { id } = useLocalSearchParams();
|
||||||
const [openDrawer, setOpenDrawer] = useState(false);
|
const [openDrawer, setOpenDrawer] = useState(false);
|
||||||
|
|
||||||
|
const [data, setData] = useState();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
async function onLoadData() {
|
||||||
|
try {
|
||||||
|
const response = await apiEventGetOne({ id: id as string });
|
||||||
|
if (response.success) {
|
||||||
|
setData(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@@ -44,19 +63,19 @@ export default function EventDetailPublish() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ViewWrapper>
|
<ViewWrapper>
|
||||||
<Event_BoxDetailPublishSection footerButton={footerButton} />
|
<Event_BoxDetailPublishSection data={data} footerButton={footerButton} />
|
||||||
<Spacing />
|
<Spacing />
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
|
|
||||||
<DrawerCustom
|
<DrawerCustom
|
||||||
isVisible={openDrawer}
|
isVisible={openDrawer}
|
||||||
closeDrawer={() => setOpenDrawer(false)}
|
closeDrawer={() => setOpenDrawer(false)}
|
||||||
height={250}
|
height={"auto"}
|
||||||
>
|
>
|
||||||
<MenuDrawerDynamicGrid
|
<MenuDrawerDynamicGrid
|
||||||
data={menuDrawerPublishEvent({ id: id as string })}
|
data={menuDrawerPublishEvent({ id: id as string })}
|
||||||
columns={4}
|
columns={4}
|
||||||
onPressItem={handlePress}
|
// onPressItem={handlePress}
|
||||||
/>
|
/>
|
||||||
</DrawerCustom>
|
</DrawerCustom>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ImageSourcePropType } from "react-native";
|
|
||||||
import Divider from "../Divider/Divider";
|
import Divider from "../Divider/Divider";
|
||||||
import Grid from "../Grid/GridCustom";
|
import Grid from "../Grid/GridCustom";
|
||||||
import AvatarCustom from "../Image/AvatarCustom";
|
import AvatarComp from "../Image/AvatarComp";
|
||||||
import TextCustom from "../Text/TextCustom";
|
import TextCustom from "../Text/TextCustom";
|
||||||
|
|
||||||
const AvatarUsernameAndOtherComponent = ({
|
const AvatarUsernameAndOtherComponent = ({
|
||||||
@@ -12,7 +11,7 @@ const AvatarUsernameAndOtherComponent = ({
|
|||||||
withBottomLine = false,
|
withBottomLine = false,
|
||||||
}: {
|
}: {
|
||||||
avatarHref?: string;
|
avatarHref?: string;
|
||||||
avatar?: ImageSourcePropType;
|
avatar?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
rightComponent?: React.ReactNode;
|
rightComponent?: React.ReactNode;
|
||||||
withBottomLine?: boolean;
|
withBottomLine?: boolean;
|
||||||
@@ -21,7 +20,7 @@ const AvatarUsernameAndOtherComponent = ({
|
|||||||
<>
|
<>
|
||||||
<Grid containerStyle={{ zIndex: 10 }}>
|
<Grid containerStyle={{ zIndex: 10 }}>
|
||||||
<Grid.Col span={2}>
|
<Grid.Col span={2}>
|
||||||
<AvatarCustom source={avatar} href={avatarHref as any} />
|
<AvatarComp fileId={avatar} href={avatarHref as any} size="base" />
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col
|
<Grid.Col
|
||||||
span={rightComponent ? 6 : 10}
|
span={rightComponent ? 6 : 10}
|
||||||
|
|||||||
@@ -1,21 +1,50 @@
|
|||||||
import {
|
import { AvatarUsernameAndOtherComponent, BaseBox, BoxWithHeaderSection, Grid, StackCustom, TextCustom } from "@/components";
|
||||||
BaseBox,
|
import { dateTimeView } from "@/utils/dateTimeView";
|
||||||
Grid,
|
|
||||||
StackCustom,
|
|
||||||
TextCustom
|
|
||||||
} from "@/components";
|
|
||||||
|
|
||||||
export default function Event_BoxDetailPublishSection({
|
export default function Event_BoxDetailPublishSection({
|
||||||
|
data,
|
||||||
footerButton,
|
footerButton,
|
||||||
}: {
|
}: {
|
||||||
|
data?: any;
|
||||||
footerButton?: React.ReactNode;
|
footerButton?: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
|
const listData = [
|
||||||
|
{
|
||||||
|
title: "Lokasi",
|
||||||
|
value: data?.lokasi || "-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Tipe Acara",
|
||||||
|
value: data?.EventMaster_TipeAcara?.name || "-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Tanggal Mulai",
|
||||||
|
value: dateTimeView({ date: data?.tanggal }) || "-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Tanggal Berakhir",
|
||||||
|
value: dateTimeView({ date: data?.tanggalSelesai }) || "-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Deskripsi",
|
||||||
|
value: data?.deskripsi || "-",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
console.log("DATA >> ", JSON.stringify(data, null, 2));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<BaseBox>
|
<BoxWithHeaderSection>
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
|
<AvatarUsernameAndOtherComponent
|
||||||
|
avatarHref={`/profile/${data?.Author?.Profile?.id}`}
|
||||||
|
name={data?.Author?.username || "-"}
|
||||||
|
avatar={data?.Author?.Profile?.imageId || ""}
|
||||||
|
/>
|
||||||
|
|
||||||
<TextCustom bold align="center" size="xlarge">
|
<TextCustom bold align="center" size="xlarge">
|
||||||
Judul event publish
|
{data?.title || "-"}
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
{listData.map((item, index) => (
|
{listData.map((item, index) => (
|
||||||
<Grid key={index}>
|
<Grid key={index}>
|
||||||
@@ -28,34 +57,9 @@ export default function Event_BoxDetailPublishSection({
|
|||||||
</Grid>
|
</Grid>
|
||||||
))}
|
))}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BoxWithHeaderSection>
|
||||||
|
|
||||||
{footerButton}
|
{footerButton}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
|
||||||
{
|
|
||||||
title: "Lokasi",
|
|
||||||
value:
|
|
||||||
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Consectetur eveniet ab eum ducimus tempore a quia deserunt quisquam. Tempora, atque. Aperiam minima asperiores dicta perferendis quis adipisci, dolore optio porro!",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Tipe Acara",
|
|
||||||
value: "Workshop",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Tanggal Mulai",
|
|
||||||
value: "Senin, 18 Juli 2025, 10:00 WIB",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Tanggal Berakhir",
|
|
||||||
value: "Selasa, 19 Juli 2025, 12:00 WIB",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Deskripsi",
|
|
||||||
value:
|
|
||||||
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Consectetur eveniet ab eum ducimus tempore a quia deserunt quisquam. Tempora, atque. Aperiam minima asperiores dicta perferendis quis adipisci, dolore optio porro!",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -7,21 +7,15 @@ import {
|
|||||||
import { Href } from "expo-router";
|
import { Href } from "expo-router";
|
||||||
|
|
||||||
export default function Event_BoxPublishSection({
|
export default function Event_BoxPublishSection({
|
||||||
id,
|
|
||||||
title,
|
|
||||||
username,
|
|
||||||
description,
|
|
||||||
href,
|
href,
|
||||||
|
data,
|
||||||
|
|
||||||
// Avatar
|
// Avatar
|
||||||
sourceAvatar,
|
sourceAvatar,
|
||||||
rightComponentAvatar,
|
rightComponentAvatar,
|
||||||
}: {
|
}: {
|
||||||
id: string;
|
|
||||||
title?: string;
|
|
||||||
username?: string;
|
|
||||||
description?: string;
|
|
||||||
href: Href;
|
href: Href;
|
||||||
|
data?: any;
|
||||||
|
|
||||||
// Avatar
|
// Avatar
|
||||||
sourceAvatar?: string;
|
sourceAvatar?: string;
|
||||||
@@ -32,18 +26,15 @@ export default function Event_BoxPublishSection({
|
|||||||
<BoxWithHeaderSection href={href}>
|
<BoxWithHeaderSection href={href}>
|
||||||
<StackCustom gap={"xs"}>
|
<StackCustom gap={"xs"}>
|
||||||
<AvatarUsernameAndOtherComponent
|
<AvatarUsernameAndOtherComponent
|
||||||
avatarHref={`/profile/${id}`}
|
avatarHref={`/profile/${data?.Author?.Profile?.id}`}
|
||||||
name={username || "Lorem ipsum dolor sit"}
|
name={data?.Author?.username || "-"}
|
||||||
rightComponent={rightComponentAvatar}
|
rightComponent={rightComponentAvatar}
|
||||||
avatar={sourceAvatar as any}
|
avatar={data?.Author?.Profile?.imageId || ""}
|
||||||
/>
|
/>
|
||||||
<TextCustom truncate bold>
|
<TextCustom truncate bold>
|
||||||
{title || "Lorem ipsum dolor sit"}
|
{data?.title || "-"}
|
||||||
</TextCustom>
|
|
||||||
<TextCustom truncate={2}>
|
|
||||||
{description ||
|
|
||||||
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro sed doloremque tempora soluta. Dolorem ex quidem ipsum tempora, ipsa, obcaecati quia suscipit numquam, voluptates commodi porro impedit natus quos doloremque!"}
|
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
|
<TextCustom truncate={2}>{data?.deskripsi || "-"}</TextCustom>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BoxWithHeaderSection>
|
</BoxWithHeaderSection>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { AlertDefaultSystem, ButtonCustom, Grid } from "@/components";
|
import { AlertDefaultSystem, ButtonCustom, Grid } from "@/components";
|
||||||
import { apiEventUpdateStatus } from "@/service/api-client/api-event";
|
import {
|
||||||
|
apiEventDelete,
|
||||||
|
apiEventUpdateStatus,
|
||||||
|
} from "@/service/api-client/api-event";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
@@ -118,9 +121,26 @@ export default function Event_ButtonStatusSection({
|
|||||||
message: "Apakah Anda yakin ingin menghapus data ini?",
|
message: "Apakah Anda yakin ingin menghapus data ini?",
|
||||||
textLeft: "Batal",
|
textLeft: "Batal",
|
||||||
textRight: "Hapus",
|
textRight: "Hapus",
|
||||||
onPressRight: () => {
|
onPressRight: async () => {
|
||||||
console.log("Hapus");
|
try {
|
||||||
|
const response = await apiEventDelete({ id: id });
|
||||||
|
if (response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: response.message,
|
||||||
|
});
|
||||||
router.back();
|
router.back();
|
||||||
|
} else {
|
||||||
|
Toast.show({
|
||||||
|
type: "info",
|
||||||
|
text1: "Info",
|
||||||
|
text2: response.message,
|
||||||
|
});
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -62,3 +62,23 @@ export async function apiEventUpdateData({ id, data }: { id: string; data: any }
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function apiEventDelete({ id }: { id: string }) {
|
||||||
|
try {
|
||||||
|
const response = await apiConfig.delete(`/mobile/event/${id}`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function apiEventGetAll() {
|
||||||
|
try {
|
||||||
|
const response = await apiConfig.get(`/mobile/event`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -7,6 +7,8 @@ export const dateTimeView = ({
|
|||||||
date: any;
|
date: any;
|
||||||
withoutTime?: boolean;
|
withoutTime?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const newDate = dayjs(date).format(`DD-MM-YYYY, ${withoutTime ? "" : "HH:mm"}`);
|
const newDate = dayjs(date).format(
|
||||||
|
`DD-MM-YYYY ${withoutTime ? "" : ", HH:mm"}`
|
||||||
|
);
|
||||||
return newDate;
|
return newDate;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user