# Event Join
## feat - Join event - History semua event dan event saya ### No Issuue
This commit is contained in:
1
src/app/admin/layout.tsx
Normal file
1
src/app/admin/layout.tsx
Normal file
@@ -0,0 +1 @@
|
||||
#! apa
|
||||
@@ -1,11 +1,14 @@
|
||||
import { AdminEvent_Main } from "@/app_modules/admin/event";
|
||||
import AdminEvent_funCountByStatusId from "@/app_modules/admin/event/fun/count/fun_count_event_by_status_id";
|
||||
import { AdminEvent_funCountTipeAcara } from "@/app_modules/admin/event/fun/count/fun_count_tipe_acara";
|
||||
|
||||
export default async function Page() {
|
||||
const countPublish = await AdminEvent_funCountByStatusId("1");
|
||||
const countReview = await AdminEvent_funCountByStatusId("2");
|
||||
const countDraft = await AdminEvent_funCountByStatusId("3");
|
||||
const countReject = await AdminEvent_funCountByStatusId("4");
|
||||
const countTipeAcara = await AdminEvent_funCountTipeAcara()
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -14,6 +17,7 @@ export default async function Page() {
|
||||
countReview={countReview as number}
|
||||
countDraft={countDraft as number}
|
||||
countReject={countReject as number}
|
||||
countTipeAcara={countTipeAcara as number}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
14
src/app/dev/event/detail/riwayat/[id]/layout.tsx
Normal file
14
src/app/dev/event/detail/riwayat/[id]/layout.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { LayoutEvent_DetailRiwayat } from "@/app_modules/event";
|
||||
import React from "react";
|
||||
|
||||
export default async function Layout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<LayoutEvent_DetailRiwayat>{children}</LayoutEvent_DetailRiwayat>
|
||||
</>
|
||||
);
|
||||
}
|
||||
24
src/app/dev/event/detail/riwayat/[id]/page.tsx
Normal file
24
src/app/dev/event/detail/riwayat/[id]/page.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
import { Event_DetailRiwayat } from "@/app_modules/event";
|
||||
import { Event_countTotalPesertaById } from "@/app_modules/event/fun/count/count_total_peserta_by_id";
|
||||
import { Event_CekUserJoinById } from "@/app_modules/event/fun/get/cek_user_join_by_id";
|
||||
import { Event_getListPesertaById } from "@/app_modules/event/fun/get/get_list_peserta_by_id";
|
||||
import { Event_getOneById } from "@/app_modules/event/fun/get/get_one_by_id";
|
||||
import { User_getUserId } from "@/app_modules/fun_global/get_user_token";
|
||||
|
||||
export default async function Page({ params }: { params: { id: string } }) {
|
||||
let eventId = params.id;
|
||||
const dataEvent = await Event_getOneById(eventId);
|
||||
const listPeserta = await Event_getListPesertaById(eventId);
|
||||
const totalPeserta = await Event_countTotalPesertaById(eventId);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Event_DetailRiwayat
|
||||
dataEvent={dataEvent as any}
|
||||
listPeserta={listPeserta as any}
|
||||
totalPeserta={totalPeserta as any}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { Event_History } from "@/app_modules/event";
|
||||
|
||||
export default async function Page({ params }: { params: { id: string } }) {
|
||||
let eventId = params.id;
|
||||
console.log(eventId);
|
||||
return <Event_History />;
|
||||
}
|
||||
19
src/app/dev/event/main/riwayat/page.tsx
Normal file
19
src/app/dev/event/main/riwayat/page.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Event_Riwayat } from "@/app_modules/event";
|
||||
import { Event_getListRiwayatSaya } from "@/app_modules/event/fun/get/get_list_riwayat_saya";
|
||||
import { Event_getListSemuaRiwayat } from "@/app_modules/event/fun/get/get_list_semua_riwayat";
|
||||
import { Event_getOneById } from "@/app_modules/event/fun/get/get_one_by_id";
|
||||
import { User_getUserId } from "@/app_modules/fun_global/get_user_token";
|
||||
|
||||
export default async function Page({ params }: { params: { id: string } }) {
|
||||
let eventId = params.id;
|
||||
const authorId = await User_getUserId();
|
||||
const dataSemuaRiwayat = await Event_getListSemuaRiwayat();
|
||||
const dataRiwayatSaya = await Event_getListRiwayatSaya(authorId);
|
||||
|
||||
return (
|
||||
<Event_Riwayat
|
||||
dataSemuaRiwayat={dataSemuaRiwayat as any}
|
||||
dataRiwayatSaya={dataRiwayatSaya as any}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -11,6 +11,7 @@ export default async function Page() {
|
||||
|
||||
return (
|
||||
<Event_StatusPage
|
||||
authorId={authorId}
|
||||
listPublish={listPublish}
|
||||
listReview={listReview}
|
||||
listDraft={listDraft}
|
||||
|
||||
@@ -4,7 +4,7 @@ export const RouterEvent = {
|
||||
beranda: "/dev/event/main/beranda",
|
||||
status_page: "/dev/event/main/status_page",
|
||||
kontribusi: "/dev/event/main/kontribusi",
|
||||
history: "/dev/event/main/history",
|
||||
riwayat: "/dev/event/main/riwayat",
|
||||
|
||||
// status
|
||||
status_publish: "/dev/event/main/status_page/publish",
|
||||
@@ -25,4 +25,5 @@ export const RouterEvent = {
|
||||
detail_review: "/dev/event/detail/review/",
|
||||
detail_draft: "/dev/event/detail/draft/",
|
||||
detail_reject: "/dev/event/detail/reject/",
|
||||
detail_riwayat: "/dev/event/detail/riwayat/",
|
||||
};
|
||||
|
||||
5
src/app_modules/admin/event/create/tipe_acara.tsx
Normal file
5
src/app_modules/admin/event/create/tipe_acara.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
"use client"
|
||||
|
||||
export default function AdminEvent_CreateTipeAcara(){
|
||||
|
||||
}
|
||||
22
src/app_modules/admin/event/detail/tipe_acara.tsx
Normal file
22
src/app_modules/admin/event/detail/tipe_acara.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Stack } from "@mantine/core";
|
||||
import ComponentAdminDonasi_TombolKembali from "../../donasi/component/tombol_kembali";
|
||||
import ComponentAdminGlobal_HeaderTamplate from "../../component/header_tamplate";
|
||||
|
||||
export default function AdminEvent_DetailTipeAcara() {
|
||||
return (
|
||||
<>
|
||||
<Stack>
|
||||
<ComponentAdminGlobal_HeaderTamplate name="Event" />
|
||||
<ComponentAdminDonasi_TombolKembali />
|
||||
<DetailTipeAcara/>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function DetailTipeAcara(){
|
||||
return <>
|
||||
|
||||
disiin tipe nya
|
||||
</>
|
||||
}
|
||||
@@ -12,6 +12,9 @@ export default async function AdminEvent_funCountByStatusId(statusId: string) {
|
||||
const count = await prisma.event.count({
|
||||
where: {
|
||||
eventMaster_StatusId: "1",
|
||||
tanggal: {
|
||||
gte: new Date
|
||||
}
|
||||
},
|
||||
});
|
||||
return count;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
"use server"
|
||||
|
||||
import prisma from "@/app/lib/prisma"
|
||||
|
||||
export async function AdminEvent_funCountTipeAcara() {
|
||||
const data = await prisma.eventMaster_TipeAcara.count({})
|
||||
return data
|
||||
}
|
||||
@@ -6,10 +6,14 @@ export async function AdminEvent_getListTableByStatusId(statudId: string) {
|
||||
if (statudId === "1") {
|
||||
const getPublish = await prisma.event.findMany({
|
||||
orderBy: {
|
||||
updatedAt: "desc",
|
||||
tanggal: "desc",
|
||||
},
|
||||
where: {
|
||||
eventMaster_StatusId: "1",
|
||||
tanggal: {
|
||||
gte: new Date
|
||||
}
|
||||
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
|
||||
@@ -2,10 +2,12 @@ import AdminEvent_Main from "./main";
|
||||
import AdminEvent_TableReview from "./table_status/table_review";
|
||||
import AdminEvent_TablePublish from "./table_status/table_publish";
|
||||
import AdminEvent_TableReject from "./table_status/table_reject";
|
||||
import AdminEvent_DetailTipeAcara from "./detail/tipe_acara";
|
||||
|
||||
export {
|
||||
AdminEvent_Main,
|
||||
AdminEvent_TableReview,
|
||||
AdminEvent_TablePublish,
|
||||
AdminEvent_TableReject,
|
||||
AdminEvent_DetailTipeAcara,
|
||||
};
|
||||
|
||||
@@ -18,20 +18,22 @@ import { IconChevronsRight } from "@tabler/icons-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import ComponentAdminGlobal_HeaderTamplate from "../../component/header_tamplate";
|
||||
|
||||
|
||||
export default function AdminEvent_Main({
|
||||
countPublish,
|
||||
countReview,
|
||||
countDraft,
|
||||
countReject,
|
||||
countTipeAcara,
|
||||
}: {
|
||||
countPublish: number;
|
||||
countReview: number;
|
||||
countDraft: number;
|
||||
countReject: number;
|
||||
countTipeAcara: number;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const listBox = [
|
||||
|
||||
const listStatus = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Publish",
|
||||
@@ -61,10 +63,29 @@ export default function AdminEvent_Main({
|
||||
color: "red",
|
||||
},
|
||||
];
|
||||
|
||||
const listBox2 = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Riwayat Event",
|
||||
// jumlah: countPublish,
|
||||
path: RouterAdminEvent.table_publish,
|
||||
color: "gray",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Kategori",
|
||||
// jumlah: countPublish,
|
||||
path: RouterAdminEvent.table_publish,
|
||||
color: "green",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack spacing={"xl"}>
|
||||
<ComponentAdminGlobal_HeaderTamplate name="Event"/>
|
||||
<ComponentAdminGlobal_HeaderTamplate name="Event" />
|
||||
|
||||
<SimpleGrid
|
||||
cols={4}
|
||||
spacing="lg"
|
||||
@@ -74,7 +95,7 @@ export default function AdminEvent_Main({
|
||||
{ maxWidth: "36rem", cols: 1, spacing: "sm" },
|
||||
]}
|
||||
>
|
||||
{listBox.map((e, i) => (
|
||||
{listStatus.map((e, i) => (
|
||||
<Paper
|
||||
key={i}
|
||||
bg={`${e.color}.2`}
|
||||
@@ -101,6 +122,25 @@ export default function AdminEvent_Main({
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
<Paper
|
||||
shadow="md"
|
||||
radius="md"
|
||||
p="md"
|
||||
bg={"gray.3"}
|
||||
// w={{ lg: "62rem", md: "48rem", sm: "36rem" }}
|
||||
w={300}
|
||||
>
|
||||
<Group position="apart">
|
||||
<ActionIcon disabled variant="transparent"></ActionIcon>
|
||||
<Stack align="center" spacing={0}>
|
||||
<Text>Tipe Acara</Text>
|
||||
<Title>{countTipeAcara}</Title>
|
||||
</Stack>
|
||||
<ActionIcon radius={"xl"} onClick={() => router.push("")}>
|
||||
<IconChevronsRight color="gray" />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import AdminMain from "./main/view";
|
||||
import AdminLayout from "./main/layout";
|
||||
import SplashDashboardAdmin from "./splash";
|
||||
import SplashDashboardAdmin from "../splash/splash";
|
||||
|
||||
export { AdminMain, AdminLayout, SplashDashboardAdmin };
|
||||
|
||||
@@ -50,16 +50,16 @@ export default function Donasi_NotifPage({
|
||||
<Stack>
|
||||
<Group position="apart">
|
||||
<Text fw={"bold"} truncate>
|
||||
{e.Donasi_Kabar.title}
|
||||
{e.Donasi_Kabar?.title}
|
||||
</Text>
|
||||
<Text fz={"xs"}>{moment(e.createdAt).format("ll")}</Text>
|
||||
</Group>
|
||||
<Stack spacing={0}>
|
||||
<Text lineClamp={2}>{e.Donasi_Kabar.deskripsi}</Text>
|
||||
<Text lineClamp={2}>{e.Donasi_Kabar?.deskripsi}</Text>
|
||||
<Text
|
||||
c={"blue"}
|
||||
onClick={() =>
|
||||
onClick(router as any, e.Donasi_Kabar.id, e.id)
|
||||
onClick(router as any, e.Donasi_Kabar?.id, e.id)
|
||||
}
|
||||
>
|
||||
Buka Kabar
|
||||
|
||||
@@ -22,7 +22,7 @@ export default function ComponentEvent_DetailData({
|
||||
<>
|
||||
<Paper withBorder p={"md"} shadow="lg">
|
||||
<Stack px={"sm"}>
|
||||
<Title order={4}>{data ? data.title : null}</Title>
|
||||
<Title order={4}>{data ? data?.title : null}</Title>
|
||||
<Grid>
|
||||
<Grid.Col span={4}>
|
||||
<Text fw={"bold"} fz={"sm"}>
|
||||
@@ -31,7 +31,7 @@ export default function ComponentEvent_DetailData({
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}>:</Grid.Col>
|
||||
<Grid.Col span={"auto"}>
|
||||
<Text>{data ? data.lokasi : null}</Text>
|
||||
<Text>{data ? data?.lokasi : null}</Text>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Grid>
|
||||
@@ -42,7 +42,7 @@ export default function ComponentEvent_DetailData({
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}>:</Grid.Col>
|
||||
<Grid.Col span={"auto"}>
|
||||
<Text>{data ? data.EventMaster_TipeAcara.name : null}</Text>
|
||||
<Text>{data ? data.EventMaster_TipeAcara?.name : null}</Text>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Grid>
|
||||
@@ -72,7 +72,7 @@ export default function ComponentEvent_DetailData({
|
||||
maxHeight={50}
|
||||
showLabel="Lihat banyak"
|
||||
>
|
||||
{data ? data.deskripsi : null}
|
||||
{data ? data?.deskripsi : null}
|
||||
</Spoiler>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
@@ -25,7 +25,7 @@ import { useAtom } from "jotai";
|
||||
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { gs_event_status } from "../global_state";
|
||||
import { gs_event_hotMenu, gs_event_status } from "../global_state";
|
||||
import { MODEL_DEFAULT_MASTER } from "@/app_modules/model_global/interface";
|
||||
import { Event_funCreate } from "../fun/create/fun_create";
|
||||
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
|
||||
@@ -41,6 +41,8 @@ export default function Event_Create({
|
||||
const router = useRouter();
|
||||
const [tabsStatus, setTabsStatus] = useAtom(gs_event_status);
|
||||
const [listTipe, setListTipe] = useState(listTipeAcara);
|
||||
const [hotMenu, setHotMenu] = useAtom(gs_event_hotMenu);
|
||||
|
||||
|
||||
const [value, setValue] = useState({
|
||||
title: "",
|
||||
@@ -120,7 +122,7 @@ export default function Event_Create({
|
||||
<Button
|
||||
radius={"xl"}
|
||||
mt={"xl"}
|
||||
onClick={() => onSave(router, setTabsStatus, value)}
|
||||
onClick={() => onSave(router, setTabsStatus, value, setHotMenu)}
|
||||
>
|
||||
Simpan
|
||||
</Button>
|
||||
@@ -132,12 +134,14 @@ export default function Event_Create({
|
||||
async function onSave(
|
||||
router: AppRouterInstance,
|
||||
setTabsStatus: any,
|
||||
value: any
|
||||
value: any,
|
||||
setHotMenu: any
|
||||
) {
|
||||
await Event_funCreate(value).then((res) => {
|
||||
if (res.status === 201) {
|
||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
||||
setTabsStatus("Review");
|
||||
setHotMenu(1)
|
||||
router.push(RouterEvent.status_page);
|
||||
} else {
|
||||
ComponentGlobal_NotifikasiGagal(res.message);
|
||||
|
||||
76
src/app_modules/event/detail/riwayat/index.tsx
Normal file
76
src/app_modules/event/detail/riwayat/index.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
Button,
|
||||
Center,
|
||||
Divider,
|
||||
Grid,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import ComponentEvent_DetailData from "../../component/detail/detail_data";
|
||||
import { MODEL_EVENT, MODEL_EVENT_PESERTA } from "../../model/interface";
|
||||
import _ from "lodash";
|
||||
import { Event_funJoinEvent } from "../../fun/create/fun_join_event";
|
||||
import { useState } from "react";
|
||||
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil";
|
||||
import { Event_getListPesertaById } from "../../fun/get/get_list_peserta_by_id";
|
||||
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
|
||||
import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header";
|
||||
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
|
||||
import ComponentEvent_DetailMainData from "../../component/detail/detail_main";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Event_countTotalPesertaById } from "../../fun/count/count_total_peserta_by_id";
|
||||
import ComponentEvent_ListPeserta from "../../component/detail/list_peserta";
|
||||
|
||||
export default function Event_DetailRiwayat({
|
||||
dataEvent,
|
||||
listPeserta,
|
||||
totalPeserta,
|
||||
}: {
|
||||
dataEvent: MODEL_EVENT;
|
||||
listPeserta: MODEL_EVENT_PESERTA[];
|
||||
totalPeserta: number;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [total, setTotal] = useState(totalPeserta);
|
||||
const [peserta, setPeserta] = useState(listPeserta);
|
||||
return (
|
||||
<>
|
||||
<Stack spacing={"lg"}>
|
||||
<ComponentEvent_DetailMainData data={dataEvent} />
|
||||
<ComponentEvent_ListPeserta listPeserta={listPeserta} total={total} />
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
async function onJoin(
|
||||
userId: string,
|
||||
eventId: string,
|
||||
setPeserta: any,
|
||||
setTotal: any
|
||||
) {
|
||||
const body = {
|
||||
userId: userId,
|
||||
eventId: eventId,
|
||||
};
|
||||
|
||||
await Event_funJoinEvent(body as any).then(async (res) => {
|
||||
if (res.status === 200) {
|
||||
await Event_getListPesertaById(eventId).then(async (val) => {
|
||||
await Event_countTotalPesertaById(eventId).then((ttl) => {
|
||||
setPeserta(val);
|
||||
setTotal(ttl);
|
||||
ComponentGlobal_NotifikasiBerhasil(res.message, 2000);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ComponentGlobal_NotifikasiGagal(res.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
19
src/app_modules/event/detail/riwayat/layout.tsx
Normal file
19
src/app_modules/event/detail/riwayat/layout.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
"use client";
|
||||
|
||||
import { AppShell } from "@mantine/core";
|
||||
import React from "react";
|
||||
import ComponentEvent_HeaderTamplate from "../../component/header_tamplate";
|
||||
|
||||
export default function LayoutEvent_DetailRiwayat({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<AppShell header={<ComponentEvent_HeaderTamplate title="Detail Riwayat" />}>
|
||||
{children}
|
||||
</AppShell>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -5,9 +5,15 @@ import prisma from "@/app/lib/prisma";
|
||||
export async function Event_getByStatusId(statusId: string, authorId: string) {
|
||||
if (statusId === "1") {
|
||||
const data = await prisma.event.findMany({
|
||||
orderBy: {
|
||||
tanggal: "desc",
|
||||
},
|
||||
where: {
|
||||
eventMaster_StatusId: "1",
|
||||
authorId: authorId,
|
||||
tanggal: {
|
||||
gte: new Date(),
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
@@ -20,6 +26,9 @@ export async function Event_getByStatusId(statusId: string, authorId: string) {
|
||||
}
|
||||
if (statusId === "2") {
|
||||
const data = await prisma.event.findMany({
|
||||
orderBy: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
where: {
|
||||
eventMaster_StatusId: "2",
|
||||
authorId: authorId,
|
||||
|
||||
34
src/app_modules/event/fun/get/get_list_riwayat_saya.ts
Normal file
34
src/app_modules/event/fun/get/get_list_riwayat_saya.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/app/lib/prisma";
|
||||
import _ from "lodash";
|
||||
|
||||
export async function Event_getListRiwayatSaya(authorId: string) {
|
||||
const data = await prisma.event.findMany({
|
||||
orderBy: {
|
||||
tanggal: "desc",
|
||||
},
|
||||
where: {
|
||||
authorId: authorId,
|
||||
eventMaster_StatusId: "1",
|
||||
tanggal: {
|
||||
lte: new Date(),
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
tanggal: true,
|
||||
deskripsi: true,
|
||||
active: true,
|
||||
authorId: true,
|
||||
Author: {
|
||||
select: {
|
||||
Profile: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
33
src/app_modules/event/fun/get/get_list_semua_riwayat.ts
Normal file
33
src/app_modules/event/fun/get/get_list_semua_riwayat.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/app/lib/prisma";
|
||||
import _ from "lodash";
|
||||
|
||||
export async function Event_getListSemuaRiwayat() {
|
||||
const data = await prisma.event.findMany({
|
||||
orderBy: {
|
||||
tanggal: "desc",
|
||||
},
|
||||
where: {
|
||||
eventMaster_StatusId: "1",
|
||||
tanggal: {
|
||||
lte: new Date(),
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
tanggal: true,
|
||||
deskripsi: true,
|
||||
active: true,
|
||||
authorId: true,
|
||||
Author: {
|
||||
select: {
|
||||
Profile: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -6,4 +6,5 @@ export const gs_event_hotMenu = atomWithStorage("gs_event_hotMenu", 0)
|
||||
* @param status | "Publish", "Review", "Draft", "Reject"
|
||||
* @type string
|
||||
*/
|
||||
export const gs_event_status = atomWithStorage<string | any>("gs_status_event", "Publish")
|
||||
export const gs_event_status = atomWithStorage<string | any>("gs_status_event", "Publish")
|
||||
export const gs_event_riwayat = atomWithStorage<string | any>("gs_event_riwayat", "Semua")
|
||||
@@ -19,7 +19,9 @@ import Event_DetailMain from "./detail/main_detail";
|
||||
import LayoutEvent_DetailMain from "./detail/main_detail/layout";
|
||||
import Event_DetailKontribusi from "./detail/kontribusi";
|
||||
import LayoutEvent_DetailKontribusi from "./detail/kontribusi/layout";
|
||||
import Event_History from "./main/history";
|
||||
import Event_Riwayat from "./main/riwayat";
|
||||
import Event_DetailRiwayat from "./detail/riwayat";
|
||||
import LayoutEvent_DetailRiwayat from "./detail/riwayat/layout";
|
||||
|
||||
export {
|
||||
Event_SplashScreen,
|
||||
@@ -43,5 +45,7 @@ export {
|
||||
LayoutEvent_DetailMain,
|
||||
Event_DetailKontribusi,
|
||||
LayoutEvent_DetailKontribusi,
|
||||
Event_History,
|
||||
Event_Riwayat ,
|
||||
Event_DetailRiwayat ,
|
||||
LayoutEvent_DetailRiwayat ,
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { RouterEvent } from "@/app/lib/router_hipmi/router_event";
|
||||
import {
|
||||
Affix,
|
||||
Avatar,
|
||||
Badge,
|
||||
Box,
|
||||
@@ -17,6 +18,7 @@ import {
|
||||
Stack,
|
||||
Text,
|
||||
Title,
|
||||
rem,
|
||||
} from "@mantine/core";
|
||||
import moment from "moment";
|
||||
import { useRouter } from "next/navigation";
|
||||
@@ -25,6 +27,8 @@ import { MODEL_EVENT } from "../model/interface";
|
||||
import ComponentEvent_BoxListStatus from "../component/box_list_status";
|
||||
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
|
||||
import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header";
|
||||
import _ from "lodash";
|
||||
import { IconCirclePlus } from "@tabler/icons-react";
|
||||
|
||||
export default function Event_Beranda({
|
||||
dataEvent,
|
||||
@@ -32,42 +36,72 @@ export default function Event_Beranda({
|
||||
dataEvent: MODEL_EVENT[];
|
||||
}) {
|
||||
const router = useRouter();
|
||||
|
||||
// if (_.isEmpty(dataEvent))
|
||||
// return (
|
||||
// <Center h={"80vh"}>
|
||||
// <Text fw={"bold"} fz={"sm"}>
|
||||
// Tidak Ada Event
|
||||
// </Text>
|
||||
// </Center>
|
||||
// );
|
||||
return (
|
||||
<>
|
||||
{dataEvent.map((e, i) => (
|
||||
<Card key={e.id} shadow="lg" radius={"md"} withBorder mb={"sm"}>
|
||||
<Card.Section px={"sm"} pt={"sm"}>
|
||||
<ComponentGlobal_AuthorNameOnHeader
|
||||
profileId={e.Author.Profile.id}
|
||||
imagesId={e.Author.Profile.imagesId}
|
||||
authorName={e.Author.Profile.name}
|
||||
/>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
p={"sm"}
|
||||
onClick={() => router.push(RouterEvent.detail_main + e.id)}
|
||||
>
|
||||
<Stack>
|
||||
<Grid>
|
||||
<Grid.Col span={8}>
|
||||
<Title order={6} truncate>
|
||||
{e.title}
|
||||
</Title>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4}>
|
||||
<Text fz={"sm"} truncate>
|
||||
{moment(e.tanggal).format("ll")}
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
{/* <Affix position={{ bottom: rem(100), right: rem(20) }}>
|
||||
<Button
|
||||
radius={"xl"}
|
||||
color="blue"
|
||||
leftIcon={<IconCirclePlus />}
|
||||
onClick={() => router.push(RouterEvent.create)}
|
||||
>
|
||||
<Text fz={"sm"}> Tambah Event</Text>
|
||||
</Button>
|
||||
</Affix> */}
|
||||
|
||||
<Text fz={"sm"} lineClamp={2}>
|
||||
{e.deskripsi}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Card.Section>
|
||||
</Card>
|
||||
))}
|
||||
{_.isEmpty(dataEvent) ? (
|
||||
<Center h={"80vh"}>
|
||||
<Text fw={"bold"} fz={"sm"}>
|
||||
Tidak Ada Event
|
||||
</Text>
|
||||
</Center>
|
||||
) : (
|
||||
<Box>
|
||||
{dataEvent.map((e, i) => (
|
||||
<Card key={e.id} shadow="lg" radius={"md"} withBorder mb={"sm"}>
|
||||
<Card.Section px={"sm"} pt={"sm"}>
|
||||
<ComponentGlobal_AuthorNameOnHeader
|
||||
profileId={e.Author.Profile.id}
|
||||
imagesId={e.Author.Profile.imagesId}
|
||||
authorName={e.Author.Profile.name}
|
||||
/>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
p={"sm"}
|
||||
onClick={() => router.push(RouterEvent.detail_main + e.id)}
|
||||
>
|
||||
<Stack>
|
||||
<Grid>
|
||||
<Grid.Col span={8}>
|
||||
<Title order={6} truncate>
|
||||
{e.title}
|
||||
</Title>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4}>
|
||||
<Text fz={"sm"} truncate>
|
||||
{moment(e.tanggal).format("ll")}
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
|
||||
<Text fz={"sm"} lineClamp={2}>
|
||||
{e.deskripsi}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Card.Section>
|
||||
</Card>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
"use client"
|
||||
|
||||
export default function Event_History(){
|
||||
return<>
|
||||
ini history
|
||||
|
||||
</>
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
Avatar,
|
||||
Box,
|
||||
Card,
|
||||
Center,
|
||||
Flex,
|
||||
Grid,
|
||||
Group,
|
||||
@@ -21,6 +22,7 @@ import { RouterEvent } from "@/app/lib/router_hipmi/router_event";
|
||||
import { MODEL_EVENT_PESERTA } from "../../model/interface";
|
||||
import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header";
|
||||
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
|
||||
import _ from "lodash";
|
||||
|
||||
export default function Event_Kontribusi({
|
||||
listKontribusi,
|
||||
@@ -42,6 +44,15 @@ export default function Event_Kontribusi({
|
||||
},
|
||||
];
|
||||
|
||||
if (_.isEmpty(listKontribusi))
|
||||
return (
|
||||
<Center h={"80vh"}>
|
||||
<Text fw={"bold"} fz={"sm"}>
|
||||
Tidak Ada Kontribusi
|
||||
</Text>
|
||||
</Center>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* <pre>{JSON.stringify(listKontribusi, null,2)}</pre> */}
|
||||
@@ -56,7 +67,9 @@ export default function Event_Kontribusi({
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
p={"sm"}
|
||||
onClick={() => router.push(RouterEvent.detail_kontribusi + e.Event.id)}
|
||||
onClick={() =>
|
||||
router.push(RouterEvent.detail_kontribusi + e.Event.id)
|
||||
}
|
||||
>
|
||||
<Stack>
|
||||
<Grid>
|
||||
@@ -77,18 +90,19 @@ export default function Event_Kontribusi({
|
||||
</Text> */}
|
||||
|
||||
<Group position="center">
|
||||
{e.Event.Event_Peserta.map((val) => (
|
||||
<Box key={val.id}>
|
||||
<Avatar
|
||||
size={"lg"}
|
||||
radius={"xl"}
|
||||
sx={{ borderStyle: "solid", borderWidth: "0.5px" }}
|
||||
src={
|
||||
RouterProfile.api_foto_profile + val.User.Profile.imagesId
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
))}
|
||||
{e.Event.Event_Peserta.map((val) => (
|
||||
<Box key={val.id}>
|
||||
<Avatar
|
||||
size={"lg"}
|
||||
radius={"xl"}
|
||||
sx={{ borderStyle: "solid", borderWidth: "0.5px" }}
|
||||
src={
|
||||
RouterProfile.api_foto_profile +
|
||||
val.User.Profile.imagesId
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
))}
|
||||
</Group>
|
||||
</Stack>
|
||||
</Card.Section>
|
||||
|
||||
@@ -55,10 +55,10 @@ export default function LayoutEvent_Main({
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
name: "History",
|
||||
path: RouterEvent.history,
|
||||
name: "Riwayat",
|
||||
path: RouterEvent.riwayat,
|
||||
icon: <IconHistory />,
|
||||
}
|
||||
},
|
||||
];
|
||||
return (
|
||||
<>
|
||||
@@ -71,6 +71,19 @@ export default function LayoutEvent_Main({
|
||||
}
|
||||
footer={
|
||||
<Footer height={70} bg={"dark"} sx={{ borderTop: "px solid blue" }}>
|
||||
<Center>
|
||||
<ActionIcon
|
||||
sx={{ zIndex: 1, position: "absolute" }}
|
||||
mt={-5}
|
||||
size={"xl"}
|
||||
radius={"xl"}
|
||||
variant="transparent"
|
||||
bg={"white"}
|
||||
onClick={() => router.push(RouterEvent.create)}
|
||||
>
|
||||
<IconCirclePlus color="#347aeb" size={40} />
|
||||
</ActionIcon>
|
||||
</Center>
|
||||
<Grid>
|
||||
{listFooter.map((e, i) => (
|
||||
<Grid.Col
|
||||
|
||||
74
src/app_modules/event/main/riwayat/index.tsx
Normal file
74
src/app_modules/event/main/riwayat/index.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
"use client";
|
||||
|
||||
import { RouterEvent } from "@/app/lib/router_hipmi/router_event";
|
||||
import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header";
|
||||
import { Card, Stack, Grid, Title, Text, Center, Tabs } from "@mantine/core";
|
||||
import moment from "moment";
|
||||
|
||||
import { MODEL_EVENT } from "../../model/interface";
|
||||
import _ from "lodash";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import Event_SemuaRiwayat from "./semua";
|
||||
import Event_RiwayatSaya from "./saya";
|
||||
import { useAtom } from "jotai";
|
||||
import { gs_event_riwayat } from "../../global_state";
|
||||
|
||||
export default function Event_Riwayat({
|
||||
dataSemuaRiwayat,
|
||||
dataRiwayatSaya
|
||||
}: {
|
||||
dataSemuaRiwayat: MODEL_EVENT[];
|
||||
dataRiwayatSaya: MODEL_EVENT[]
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [tabsRiwayat, setTabsRiwayat] = useAtom(gs_event_riwayat)
|
||||
|
||||
const listTabs = [
|
||||
{
|
||||
id: 1,
|
||||
label: "Semua Riwayat",
|
||||
value: "Semua",
|
||||
path: <Event_SemuaRiwayat data={dataSemuaRiwayat as any} />,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
label: "Riwayat Saya",
|
||||
value: "Saya",
|
||||
path: <Event_RiwayatSaya data={dataRiwayatSaya as any}/>,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tabs
|
||||
defaultValue={"Semua"}
|
||||
variant="pills"
|
||||
radius={"xl"}
|
||||
onTabChange={setTabsRiwayat}
|
||||
value={tabsRiwayat}
|
||||
>
|
||||
<Stack>
|
||||
<Tabs.List grow>
|
||||
{listTabs.map((e) => (
|
||||
<Tabs.Tab
|
||||
key={e.id}
|
||||
value={e.value}
|
||||
bg={tabsRiwayat === e.value ? "blue" : "gray.1"}
|
||||
fw={tabsRiwayat === e.value ? "bold" : "normal"}
|
||||
>
|
||||
{e.label}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs.List>
|
||||
{listTabs.map((e) => (
|
||||
<Tabs.Panel key={e.id} value={e.value}>
|
||||
{e.path}
|
||||
</Tabs.Panel>
|
||||
))}
|
||||
</Stack>
|
||||
</Tabs>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
61
src/app_modules/event/main/riwayat/saya.tsx
Normal file
61
src/app_modules/event/main/riwayat/saya.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
"use client";
|
||||
|
||||
import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header";
|
||||
import { Card, Stack, Grid, Title, Text, Center } from "@mantine/core";
|
||||
import moment from "moment";
|
||||
import { MODEL_EVENT } from "../../model/interface";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { RouterEvent } from "@/app/lib/router_hipmi/router_event";
|
||||
import _ from "lodash";
|
||||
|
||||
export default function Event_RiwayatSaya({ data }: { data: MODEL_EVENT[] }) {
|
||||
const router = useRouter();
|
||||
|
||||
if (_.isEmpty(data))
|
||||
return (
|
||||
<Center h={"80vh"}>
|
||||
<Text fw={"bold"} fz={"sm"}>
|
||||
Tidak Ada Event
|
||||
</Text>
|
||||
</Center>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{data.map((e, i) => (
|
||||
<Card key={e.id} shadow="lg" radius={"md"} withBorder mb={"sm"}>
|
||||
<Card.Section px={"sm"} pt={"sm"}>
|
||||
<ComponentGlobal_AuthorNameOnHeader
|
||||
profileId={e.Author.Profile.id}
|
||||
imagesId={e.Author.Profile.imagesId}
|
||||
authorName={e.Author.Profile.name}
|
||||
/>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
p={"sm"}
|
||||
onClick={() => router.push(RouterEvent.detail_riwayat + e.id)}
|
||||
>
|
||||
<Stack>
|
||||
<Grid>
|
||||
<Grid.Col span={8}>
|
||||
<Title order={6} truncate>
|
||||
{e.title}
|
||||
</Title>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4}>
|
||||
<Text fz={"sm"} truncate>
|
||||
{moment(e.tanggal).format("ll")}
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
|
||||
<Text fz={"sm"} lineClamp={2}>
|
||||
{e.deskripsi}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Card.Section>
|
||||
</Card>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
62
src/app_modules/event/main/riwayat/semua.tsx
Normal file
62
src/app_modules/event/main/riwayat/semua.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
"use client";
|
||||
|
||||
import { RouterEvent } from "@/app/lib/router_hipmi/router_event";
|
||||
import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header";
|
||||
import { Card, Stack, Grid, Title, Text, Center } from "@mantine/core";
|
||||
import moment from "moment";
|
||||
|
||||
import { MODEL_EVENT } from "../../model/interface";
|
||||
import { useRouter } from "next/navigation";
|
||||
import _ from "lodash";
|
||||
|
||||
export default function Event_SemuaRiwayat({ data }: { data: MODEL_EVENT[] }) {
|
||||
const router = useRouter();
|
||||
|
||||
if (_.isEmpty(data))
|
||||
return (
|
||||
<Center h={"80vh"}>
|
||||
<Text fw={"bold"} fz={"sm"}>
|
||||
Tidak Ada Event
|
||||
</Text>
|
||||
</Center>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{data.map((e, i) => (
|
||||
<Card key={e.id} shadow="lg" radius={"md"} withBorder mb={"sm"}>
|
||||
<Card.Section px={"sm"} pt={"sm"}>
|
||||
<ComponentGlobal_AuthorNameOnHeader
|
||||
profileId={e.Author.Profile.id}
|
||||
imagesId={e.Author.Profile.imagesId}
|
||||
authorName={e.Author.Profile.name}
|
||||
/>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
p={"sm"}
|
||||
onClick={() => router.push(RouterEvent.detail_riwayat + e.id)}
|
||||
>
|
||||
<Stack>
|
||||
<Grid>
|
||||
<Grid.Col span={8}>
|
||||
<Title order={6} truncate>
|
||||
{e.title}
|
||||
</Title>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4}>
|
||||
<Text fz={"sm"} truncate>
|
||||
{moment(e.tanggal).format("ll")}
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
|
||||
<Text fz={"sm"} lineClamp={2}>
|
||||
{e.deskripsi}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Card.Section>
|
||||
</Card>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -14,11 +14,13 @@ import Event_StatusReject from "./reject";
|
||||
import { MODEL_EVENT } from "../../model/interface";
|
||||
|
||||
export default function Event_StatusPage({
|
||||
authorId,
|
||||
listPublish,
|
||||
listReview,
|
||||
listDraft,
|
||||
listReject,
|
||||
}: {
|
||||
authorId: string
|
||||
listPublish: any;
|
||||
listReview: any;
|
||||
listDraft: any;
|
||||
@@ -34,7 +36,7 @@ export default function Event_StatusPage({
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
path: <Event_StatusReview listReview={listReview} />,
|
||||
path: <Event_StatusReview listReview={listReview} authorId={authorId} />,
|
||||
value: "Review",
|
||||
},
|
||||
{
|
||||
@@ -50,16 +52,7 @@ export default function Event_StatusPage({
|
||||
];
|
||||
return (
|
||||
<>
|
||||
<Affix position={{ bottom: rem(100), right: rem(20) }}>
|
||||
<Button
|
||||
radius={"xl"}
|
||||
color="blue"
|
||||
leftIcon={<IconCirclePlus />}
|
||||
onClick={() => router.push(RouterEvent.create)}
|
||||
>
|
||||
Tambah Event
|
||||
</Button>
|
||||
</Affix>
|
||||
|
||||
|
||||
<Tabs
|
||||
color="blue"
|
||||
|
||||
@@ -28,7 +28,6 @@ export default function Event_StatusPublish({
|
||||
.map((e, i) => (
|
||||
<Box key={e.id}>
|
||||
<ComponentEvent_BoxListStatus data={e} path={RouterEvent.detail_publish}/>
|
||||
|
||||
</Box>
|
||||
))}
|
||||
</>
|
||||
|
||||
@@ -8,15 +8,29 @@ import { MODEL_EVENT } from "../../model/interface";
|
||||
import { useState } from "react";
|
||||
import ComponentEvent_BoxListStatus from "../../component/box_list_status";
|
||||
import _ from "lodash";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
import { Event_getByStatusId } from "../../fun/get/get_event_by_status_id";
|
||||
|
||||
export default function Event_StatusReview({
|
||||
listReview,
|
||||
authorId,
|
||||
}: {
|
||||
listReview: MODEL_EVENT[];
|
||||
authorId: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [data, setData] = useState(listReview);
|
||||
|
||||
if (_.isEmpty(listReview))
|
||||
useShallowEffect(() => {
|
||||
setTimeout(() => loadData(authorId), 1000)
|
||||
}, []);
|
||||
|
||||
async function loadData(authorId: string) {
|
||||
const res : any = await Event_getByStatusId("2", authorId);
|
||||
setData(res);
|
||||
}
|
||||
|
||||
if (_.isEmpty(data))
|
||||
return (
|
||||
<Center h={"50vh"} fz={"sm"} fw={"bold"}>
|
||||
Tidak Ada Event
|
||||
@@ -24,7 +38,7 @@ export default function Event_StatusReview({
|
||||
);
|
||||
return (
|
||||
<>
|
||||
{listReview.map((e, i) => (
|
||||
{data.map((e, i) => (
|
||||
<Box key={e.id}>
|
||||
<ComponentEvent_BoxListStatus
|
||||
data={e}
|
||||
|
||||
0
src/app_modules_admin/main/index.ts
Normal file
0
src/app_modules_admin/main/index.ts
Normal file
5
src/app_modules_admin/main/layout.tsx
Normal file
5
src/app_modules_admin/main/layout.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
"use client"
|
||||
|
||||
export default function Admin_Layout(){
|
||||
|
||||
}
|
||||
2
src/app_modules_admin/main/main_dashboard/index.tsx
Normal file
2
src/app_modules_admin/main/main_dashboard/index.tsx
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
Reference in New Issue
Block a user