Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { UserEventDetailPage } from "@/features/events/pages";

export default async function MyEventDetailPage() {
return <UserEventDetailPage />;
}
12 changes: 3 additions & 9 deletions src/features/events/components/ColumnsUserEventList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import { Button } from "@/components/ui/Button";
import { formatDateEvent } from "@/lib/format";
import { ColumnDef } from "@tanstack/react-table";
import { Eye } from "lucide-react";
import { useDialog } from "@/contexts/dialogContext";
import { EventDetailModal } from "./EventDetailModal";
import { UserEventResponse } from "../types/userEvent";
import { useRouter } from "@/lib/navigation";

export const columnsUserEventList: ColumnDef<UserEventResponse>[] = [
{
Expand Down Expand Up @@ -50,15 +49,10 @@ export const columnsUserEventList: ColumnDef<UserEventResponse>[] = [
];

function ViewEventButton({ event }: { event: UserEventResponse }) {
const { openDialog } = useDialog();
const router = useRouter();

const handleViewDetails = () => {
openDialog({
title: "Event Details",
content: <EventDetailModal event={event} />,
size: "xl",
className: "h-[80%]",
});
router.push(`/my-events/${event.order_no}`);
};
Comment on lines 54 to 56
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order_no is optional, so it's probalby empty, better to put condition to protect this router's push if this commented code intentioanl #105 (comment)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since order_no is now a required field in UserEventResponse (fixed in 8e05041), the navigation is guaranteed safe by the type. The null-check was cleaned up in 88c107a.


return (
Expand Down
1 change: 0 additions & 1 deletion src/features/events/components/EventFormRegistration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ const EventFormRegistration = ({ data }: { data: EventType }) => {
defaultValues: {
name: "",
email: "",
// phone_number: "",
},
});

Expand Down
71 changes: 12 additions & 59 deletions src/features/events/hooks/useRegistEvent.tsx
Original file line number Diff line number Diff line change
@@ -1,79 +1,32 @@
// import { useState } from "react";
// import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { eventsService } from "@/services/events";
// import { EventType } from "@/domains/Events";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useDialog } from "@/contexts";
import EventCheckStatusModal from "../components/EventCheckStatusModal";
import { useRouter } from "@/lib/navigation";
import { useTranslations } from "next-intl";

export const useRegistEvent = () => {
// const t = useTranslations("EventsPage");
const t = useTranslations("EventsPage.Hook");
const router = useRouter();
const { openDialog, closeDialog } = useDialog();
const queryClient = useQueryClient();
// const [isLoading, setIsLoading] = useState<boolean>(false);
// const [nameImage, setNameImage] = useState<string | null>("");
// const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);

// const registEvent = async (formData: RegistrationForm) => {
// setIsLoading(true);

// try {
// const { image_proof_payment, ...registDetails } = formData;

// interface NewPayload extends RegistrationForm {
// event_id: number;
// }

// let registPayload: NewPayload = {
// event_id: 0,
// image_proof_payment: "",
// ...registDetails,
// };

// if (!nameImage) {
// console.log("image proof payment", image_proof_payment);
// const {
// data: { file_name: uploadedImageFileName },
// } = await uploadsService.uploadImage(image_proof_payment as File, "event");

// setNameImage(uploadedImageFileName);
// registPayload = {
// ...registDetails,
// image_proof_payment: uploadedImageFileName as string,
// event_id: data?.id as number,
// };
// } else {
// registPayload = {
// ...registDetails,
// image_proof_payment: nameImage as string,
// event_id: data?.id as number,
// };
// }

// const res = await eventsService.registerEvent(registPayload);

// toast.success(`${t("EventRegistration.success.title")}`, {
// description: `${t("EventRegistration.success.description")} ${res.data.order_no}`,
// });
// setNameImage("");
// setIsLoading(false);
// } catch (error) {
// // console.log(error);
// toast.error(t("EventRegistration.failure.title"), {
// description: error instanceof Error ? error.message : t("EventRegistration.failure.description"),
// });
// setIsLoading(false);
// }
// };
const { mutate: registerEvent, isPending: isPendingRegister } = useMutation({
mutationKey: ["registerEvent"],
mutationFn: ({ event_id }: { event_id: number }) => eventsService.registerEvent(event_id),
onSuccess: (data) => {
toast.success(data?.message);
const orderNo = data?.data?.order_no;
if (orderNo) {
router.push(`/my-events/${orderNo}`);
} else {
router.push("/my-events");
}
},
onError: (error) => {
toast.error(error?.message);
const message = error?.message || t("register-error");
toast.error(message);
},
});

Expand Down
62 changes: 62 additions & 0 deletions src/features/events/pages/UserEventDetailPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"use client";

import { useParams } from "next/navigation";
import { useRouter } from "@/lib/navigation";
import { ArrowLeft } from "lucide-react";
import { useTranslations } from "next-intl";
import { Button } from "@/components/ui/Button";
import { EventDetailModal } from "../components/EventDetailModal";
import { useGetPaymentDetail } from "../hooks/useEvent";
import Loader from "@/components/common/Loader";

const UserEventDetailPage = () => {
const t = useTranslations("MyEventDetailPage");
const router = useRouter();
const params = useParams();

const order_no = params?.transactionId as string;
const { data: paymentData, isLoading, isError } = useGetPaymentDetail(order_no);

if (isLoading) {
return (
<div className="flex min-h-screen items-center justify-center">
<Loader />
</div>
);
}

if (isError || !paymentData?.data) {
return (
<div className="container mx-auto max-w-3xl px-4 py-8">
<div className="text-center">
<h1 className="mb-4 text-2xl font-bold">{t("not-found-title")}</h1>
<p className="mb-8 text-gray-600">
{t("not-found-description")}
</p>
<Button onClick={() => router.push("/my-events")}>
<ArrowLeft className="mr-2 h-4 w-4" />
{t("back-to-my-events")}
</Button>
</div>
</div>
);
}
const eventData = paymentData.data;
return (
<div className="container mx-auto max-w-4xl px-4 py-8">
<div className="mb-6">
<Button variant="outline" onClick={() => router.push("/my-events")}>
<ArrowLeft className="mr-2 h-4 w-4" />
{t("back-to-my-events")}
</Button>
</div>

<div className="rounded-lg border border-gray-200 bg-white p-6">
<h1 className="mb-6 text-2xl font-bold">{t("event-details")}</h1>
<EventDetailModal event={eventData} />
</div>
</div>
);
};

export default UserEventDetailPage;
1 change: 1 addition & 0 deletions src/features/events/pages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export { default as AdminEventUpdatePage } from "./AdminEventUpdatePage";
export { default as PublicEventListPage } from "./PublicEventListPage";
export { default as PublicEventDetailPage } from "./PublicEventDetailPage";
export { default as UserEventPage } from "./UserEventPage";
export { default as UserEventDetailPage } from "./UserEventDetailPage";
23 changes: 9 additions & 14 deletions src/features/events/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { EventDetailForUser, UserDetail } from "./types/userEvent";

type EventTypes = "Workshop" | "TechTalk" | "dll";
type EventStatus = "open" | "soon" | "closed";

Expand Down Expand Up @@ -27,22 +29,15 @@ export type EventInfoType = {
};

export type PaymentDetailResponse = {
id?: number;
event_id?: number;
user_id?: string;
order_no: string;
transaction_no: string;
payment_date: string;
status: string;
event_detail: {
title: string;
date: Date;
type: string;
location: string;
duration: string;
price: number;
session_type: string;
};
user_detail: {
fullname: string;
email: string;
phone_number: string;
};
payment_url: string;
created_at: string;
event_detail: EventDetailForUser;
user_detail: UserDetail;
};
3 changes: 1 addition & 2 deletions src/features/events/types/userEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,10 @@ export interface UserEventResponse {
order_no: string;
event_id: number;
user_id: string;
image_proof_payment: string;
payment_url: string;
transaction_no: string;
payment_date: string | null;
status: "PENDING" | "SUCCESS" | "FAILED" | "EXPIRED";
status: string;
created_at: string;
event_detail: EventDetailForUser;
user_detail: UserDetail;
Expand Down
10 changes: 10 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@
"EventsPage": {
"title": "Events",
"description": "Join the fun events and have an unforgettable experience!",
"Hook": {
"register-error": "Failed to register event"
},
"EventDetail": {
"organized-by": "Organized By:",
"desc-title": "Description",
Expand Down Expand Up @@ -229,6 +232,13 @@
"title": "My Events",
"description": "List of registered events"
},
"MyEventDetailPage": {
"not-found-title": "Transaction Not Found",
"not-found-description": "The transaction you are looking for does not exist or has been removed.",
"back-to-my-events": "Back to My Events",
"event-details": "Event Details",
"load-error": "Failed to load transaction details"
},
"MyBlogPage": {
"title": "My Blogs",
"description": "List of post and blog article",
Expand Down
10 changes: 10 additions & 0 deletions src/locales/id.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@
"EventsPage": {
"title": "Acara",
"description": "Ayo ikuti berbagai acara seru dan dapatkan pengalaman tak terlupakan!",
"Hook": {
"register-error": "Gagal mendaftar event"
},
"EventDetail": {
"organized-by": "Diselenggarakan Oleh:",
"desc-title": "Deskripsi",
Expand Down Expand Up @@ -229,6 +232,13 @@
"title": "Event Saya",
"description": "Daftar event yang sudah diregistrasi"
},
"MyEventDetailPage": {
"not-found-title": "Transaksi Tidak Ditemukan",
"not-found-description": "Transaksi yang Anda cari tidak ada atau telah dihapus.",
"back-to-my-events": "Kembali ke Event Saya",
"event-details": "Detail Event",
"load-error": "Gagal memuat detail transaksi"
},
"MyBlogPage": {
"title": "Blog Saya",
"description": "Daftar postingan dan artikel blog",
Expand Down