Alur pembayaran donasi

# feat
- Tampilan invoce
- Proses acc admin
- Transaksi berhasil
# Issue: Hitungan progres masih salah
This commit is contained in:
2024-01-08 13:56:14 +08:00
parent 4fc158bdc5
commit b4fe35e7d8
113 changed files with 2840 additions and 1274 deletions

View File

@@ -1,159 +0,0 @@
"use client";
import {
AspectRatio,
Box,
Divider,
Grid,
Group,
Image,
Pagination,
Paper,
Progress,
ScrollArea,
SimpleGrid,
Stack,
Table,
Text,
Title,
} from "@mantine/core";
import AdminDonasi_TombolKembali from "../component/tombol_kembali";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import {
IconClover,
IconMessageChatbot,
IconMoneybag,
} from "@tabler/icons-react";
import router from "next/router";
import moment from "moment";
export default function AdminDonasi_DetailPublish() {
return (
<>
<Stack>
<AdminDonasi_TombolKembali />
<SimpleGrid
cols={2}
spacing="lg"
breakpoints={[
{ maxWidth: "md", cols: 2, spacing: "md" },
{ maxWidth: "sm", cols: 1, spacing: "sm" },
{ maxWidth: "xs", cols: 1, spacing: "xs" },
]}
>
<TampilanDetailDonasi />
<TampilanListDonatur />
</SimpleGrid>
</Stack>
</>
);
}
function TampilanDetailDonasi() {
return (
<>
<Paper radius={"md"} bg={"blue.1"} p={"md"}>
<Stack>
<Stack>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image alt="Foto" src={"/aset/no-img.png"} />
</Paper>
</AspectRatio>
<Title order={4}>Judul Donasi</Title>
<Stack spacing={0}>
<Group position="apart">
<Stack spacing={0}>
<Text fz={12}>Dana dibutuhkan</Text>
<Title order={4} c="blue">
Rp. 50.000.000
</Title>
</Stack>
<Text fz={"xs"}>
Sisa hari{" "}
<Text span inherit fw={"bold"}>
100
</Text>{" "}
</Text>
</Group>
</Stack>
<Progress size={"lg"} value={50} />
{/* <Grid>
<Grid.Col
span={"auto"}
// onClick={() => router.push(RouterDonasi.donatur)}
>
<Stack align="center" spacing={"xs"}>
<Group>
<IconClover color="skyblue" />
<Text>50</Text>
</Group>
<Text>Donatur</Text>
</Stack>
</Grid.Col>
<Divider orientation="vertical" />
<Grid.Col
span={"auto"}
// onClick={() => router.push(RouterDonasi.kabar)}
>
<Stack spacing={"sm"} align="center">
<IconMessageChatbot color="skyblue" />
<Text>Kabar Terbaru</Text>
</Stack>
</Grid.Col>
<Divider orientation="vertical" />
<Grid.Col
span={"auto"}
// onClick={() => router.push(RouterDonasi.pencairan_dana)}
>
<Stack spacing={"sm"} align="center">
<IconMoneybag color="skyblue" />
<Text>Pencairan Dana</Text>
</Stack>
</Grid.Col>
</Grid> */}
</Stack>
</Stack>
</Paper>
</>
);
}
function TampilanListDonatur() {
const tableRows = Array(10)
.fill(0)
.map((e, i) => (
<tr key={i}>
<td>User {`${i + 1}`}</td>
<td>
Rp.{" "}
{`${new Intl.NumberFormat("id-ID", {
maximumFractionDigits: 10,
}).format(i + 100000)}`}
</td>
<td> {`${moment(Date.now()).format("ll")}`}</td>
</tr>
));
return (
<>
<Paper radius={"md"} bg={"cyan.1"} p={"md"}>
<Stack>
<Title order={4}>List Donatur</Title>
<ScrollArea h={300}>
<Table>
<thead>
<tr>
<th>Nama</th>
<th>Jumlah Donasi</th>
<th>Tanggal Donasi</th>
</tr>
</thead>
<tbody>{tableRows}</tbody>
</Table>
</ScrollArea>
</Stack>
</Paper>
</>
);
}

View File

@@ -1,17 +1,115 @@
"use client";
import { Button, Stack, Text } from "@mantine/core";
import { MODEL_DONASI } from "@/app_modules/donasi/model/interface";
import {
AspectRatio,
Button,
Divider,
Group,
Image,
Paper,
SimpleGrid,
Stack,
Text,
Title,
} from "@mantine/core";
import { useState } from "react";
import AdminDonasi_TombolKembali from "../component/tombol_kembali";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import TampilanRupiahDonasi from "@/app_modules/donasi/component/tampilan_rupiah";
export default function AdminDonasi_DetailReject({
closeModal,
dataReject,
}: {
closeModal: any;
dataReject: MODEL_DONASI;
}) {
const [donasi, setDonasi] = useState(dataReject);
return (
<>
<Stack>
<Text>Cooming Soon</Text>
<Button onClick={() => closeModal()}>close</Button>
<ButtonOnHeader />
<SimpleGrid
cols={2}
spacing="lg"
breakpoints={[
{ maxWidth: "md", cols: 2, spacing: "md" },
{ maxWidth: "sm", cols: 1, spacing: "sm" },
{ maxWidth: "xs", cols: 1, spacing: "xs" },
]}
>
<TampilanDetailDonasi donasi={donasi} />
<CatatanReject catatan={donasi.catatan} />
</SimpleGrid>
</Stack>
</>
);
}
function ButtonOnHeader() {
return (
<>
<Stack>
<Group position="apart">
<AdminDonasi_TombolKembali />
<Button radius={"xl"} bg={"orange"} color="orange">
Tambah catatan
</Button>
</Group>
<Divider />
</Stack>
</>
);
}
function TampilanDetailDonasi({ donasi }: { donasi: MODEL_DONASI }) {
return (
<>
<Paper radius={"md"} p={"md"}>
<Stack>
<Stack>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={RouterDonasi.api_gambar + `${donasi.imagesId}`}
/>
</Paper>
</AspectRatio>
<Stack spacing={0}>
<Title order={4}>{donasi.title}</Title>
<Text fz={"xs"}>
Durasi: {donasi.DonasiMaster_Durasi.name} hari
</Text>
</Stack>
<Stack spacing={0}>
<Group>
<Text fz={12}>Dana dibutuhkan</Text>
<Title order={4} c="blue">
<TampilanRupiahDonasi nominal={+donasi.target} />
</Title>
</Group>
<Group>
<Text fz={12}>Kategori</Text>
<Title order={4} c="blue">
{donasi.DonasiMaster_Ketegori.name}
</Title>
</Group>
</Stack>
</Stack>
</Stack>
</Paper>
</>
);
}
function CatatanReject({ catatan }: { catatan: string }) {
return (
<>
<Stack>
<Title order={6}>Alasan Penolakan</Title>
<Text>{catatan}</Text>
</Stack>
</>
);

View File

@@ -84,7 +84,7 @@ function ButtonOnHeader({ donasi }: { donasi: MODEL_DONASI }) {
(res) => {
if (res.status === 200) {
NotifBerhasil(res.message);
router.back()
router.back();
} else {
NotifGagal(res.message);
}

View File

@@ -0,0 +1,222 @@
"use client";
import {
AspectRatio,
Badge,
Box,
Button,
Center,
Divider,
Grid,
Group,
Image,
Pagination,
Paper,
Progress,
ScrollArea,
SimpleGrid,
Stack,
Table,
Text,
Title,
} from "@mantine/core";
import AdminDonasi_TombolKembali from "../../component/tombol_kembali";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import {
IconClover,
IconMessageChatbot,
IconMoneybag,
} from "@tabler/icons-react";
import router from "next/router";
import moment from "moment";
import {
MODEL_DONASI,
MODEL_DONASI_INVOICE,
} from "@/app_modules/donasi/model/interface";
import { useState } from "react";
import { RouterAdminDonasi } from "@/app/lib/router_hipmi/router_admin";
import TampilanRupiahDonasi from "@/app_modules/donasi/component/tampilan_rupiah";
import _ from "lodash";
import { useRouter } from "next/navigation";
import { useInterval, useShallowEffect } from "@mantine/hooks";
import { Donasi_getOneById } from "@/app_modules/donasi/fun/get/get_one_donasi_by_id";
export default function AdminDonasi_DetailPublish({
dataPublish,
listDonatur,
countDonatur,
}: {
dataPublish: MODEL_DONASI;
listDonatur: any[];
countDonatur: number;
}) {
const [donasi, setDonasi] = useState(dataPublish);
const [donatur, setDoanutur] = useState(listDonatur);
const interval = useInterval(() => reloadData(donasi.id), 5000);
useShallowEffect(() => {
interval.start();
}, []);
async function reloadData(donasiId: string) {
const data = await Donasi_getOneById(donasiId);
setDonasi(data as any)
return data;
}
return (
<>
{/* <pre>{JSON.stringify(donatur.map((e) => e), null, 2)}</pre> */}
<Stack>
<AdminDonasi_TombolKembali />
<TampilanDetailDonasi donasi={donasi} countDonatur={countDonatur} />
<TampilanListDonatur donatur={donatur} donasi={donasi} />
</Stack>
</>
);
}
function TampilanDetailDonasi({
donasi,
countDonatur,
}: {
donasi: MODEL_DONASI;
countDonatur: number;
}) {
return (
<>
<Paper radius={"md"} p={"md"}>
<Stack>
<Grid>
<Grid.Col span={6}>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={RouterDonasi.api_gambar + `${donasi.imagesId}`}
/>
</Paper>
</AspectRatio>
</Grid.Col>
<Grid.Col span={6}>
<Stack spacing={7}>
<Title order={4}>{donasi.title}</Title>
<Text fz={"xs"}>
Durasi: {donasi.DonasiMaster_Durasi.name} hari
</Text>
<Group>
<Text fz={12}>Dana dibutuhkan</Text>
<Title order={5} c="blue">
<TampilanRupiahDonasi nominal={+donasi.target} />
</Title>
</Group>
<Group>
<Text fz={12}>Kategori</Text>
<Title order={5} c="blue">
{donasi.DonasiMaster_Ketegori.name}
</Title>
</Group>
<Group>
<Text fz={12}>Total donatur</Text>
<Title order={5} c="blue">
{countDonatur}
</Title>
</Group>
<Group>
<Text fz={12}>Progres</Text>
<Title order={5} c="blue">
{donasi.progres} %
</Title>
</Group>
<Group>
<Text fz={12}>Dana terkumpul</Text>
<Title order={5} c="blue">
<TampilanRupiahDonasi nominal={+donasi.terkumpul} />
</Title>
</Group>
</Stack>
</Grid.Col>
</Grid>
</Stack>
</Paper>
</>
);
}
function TampilanListDonatur({
donatur,
donasi,
}: {
donatur: MODEL_DONASI_INVOICE[];
donasi: MODEL_DONASI;
}) {
const router = useRouter();
const tableRows = donatur.map((e, i) => (
<tr key={i}>
<td>{e.Author.username}</td>
<td>
<TampilanRupiahDonasi nominal={+e.nominal} />
</td>
<td> {`${moment(e.createdAt).format("ll")}`}</td>
<td>
<Center>
<Badge w={150} variant="dot">
{e.DonasiMaster_StatusInvoice.name}
</Badge>
</Center>
</td>
</tr>
));
return (
<>
<Paper radius={"md"} p={"md"}>
<Stack>
<Group position="apart">
<Title order={3}>Update List Donatur</Title>
<Button
radius={"xl"}
variant="outline"
onClick={() =>
router.push(RouterAdminDonasi.proses_transaksi + `${donasi.id}`)
}
>
Proses transaksi
</Button>
</Group>
{_.isEmpty(donatur) ? (
<Paper bg={"gray.1"} p={"xs"}>
<Center>BELUM ADA DONATUR</Center>
</Paper>
) : (
<Paper withBorder p={"xs"}>
<Table>
<thead>
<tr>
<th>Nama Donatur</th>
<th>Jumlah Donasi</th>
<th>Tanggal</th>
<th>
<Center>Status</Center>
</th>
{/* <th>
<Center>Aksi</Center>
</th> */}
</tr>
</thead>
<tbody>{tableRows}</tbody>
</Table>
</Paper>
)}
{/* <Group position="apart">
{[{ id: 1 }, { id: 2 },{ id: 3 }, { id: 4 }].map((e, i) => (
<Button key={i}>Status</Button>
))}
</Group> */}
</Stack>
</Paper>
</>
);
}

View File

@@ -0,0 +1,153 @@
"use client";
import {
ActionIcon,
Box,
Button,
Center,
Group,
HoverCard,
Paper,
Stack,
Table,
Text,
Title,
} from "@mantine/core";
import AdminDonasi_TombolKembali from "../../component/tombol_kembali";
import { MODEL_DONASI_INVOICE } from "@/app_modules/donasi/model/interface";
import { useState } from "react";
import moment from "moment";
import { IconQuestionMark } from "@tabler/icons-react";
import TampilanRupiahDonasi from "@/app_modules/donasi/component/tampilan_rupiah";
import { AdminDonasi_funUpdateStatusInvoice } from "../../fun/update/fun_update_status_invoice";
import { NotifBerhasil } from "@/app_modules/donasi/component/notifikasi/notif_berhasil";
import { NotifGagal } from "@/app_modules/donasi/component/notifikasi/notif_gagal";
import { AdminDonasi_getListStatusInvoiceProses } from "../../fun/get/get_list_status_invoice_proses";
import { AdminDonasi_funUpdateProgresDanTerkumpul } from "../../fun/update/fun_update_progres_dan_terkumpul";
export default function AdminDonasi_ProsesTransaksi({
listProses,
}: {
listProses: MODEL_DONASI_INVOICE[];
}) {
const [invoice, setInvoice] = useState<MODEL_DONASI_INVOICE[] | any[]>(
listProses
);
async function onClick(invoice: MODEL_DONASI_INVOICE) {
let nominal: number = +invoice.nominal;
let terkumpulSementaras: number = +invoice.Donasi.terkumpul;
const totalTerkumpul = terkumpulSementaras + nominal;
await AdminDonasi_funUpdateStatusInvoice(invoice.id, "1").then(
async (res) => {
if (res.status === 200) {
NotifBerhasil(res.message);
await AdminDonasi_funUpdateProgresDanTerkumpul(
invoice.Donasi.id,
totalTerkumpul
).then(async (res) => {
if (res.status === 200) {
await AdminDonasi_getListStatusInvoiceProses(
invoice.Donasi.id
).then((res) => {
setInvoice(res);
});
} else {
NotifGagal(res.message);
}
});
} else {
NotifGagal(res.message);
}
}
);
}
const rowTable = invoice.map((e) => (
<tr key={e.id}>
<td>{e.Author.username}</td>
<td>
<TampilanRupiahDonasi nominal={+e.nominal} />
</td>
<td>
<Center>{e.DonasiMaster_Bank.name}</Center>
</td>
<td>{`${moment(e.createdAt).format("ll")}`}</td>
<td>
<Center>
<Button
radius={"xl"}
variant="outline"
color="green"
onClick={() => onClick(e)}
>
Accept
</Button>
</Center>{" "}
</td>
</tr>
));
return (
<>
{/* <pre>{JSON.stringify(invoice, null, 2)}</pre> */}
<Stack>
<AdminDonasi_TombolKembali />
<Stack>
<HeaderPage />
<Paper p={"md"} withBorder>
<Table>
<thead>
<tr>
<th>Nama</th>
<th>Nominal</th>
<th>
<Center>Metode Pembayaran</Center>
</th>
<th>Tanggal</th>
<th>
<Center>Aksi</Center>
</th>
</tr>
</thead>
<tbody>{rowTable}</tbody>
</Table>
</Paper>
</Stack>
</Stack>
</>
);
}
function HeaderPage() {
return (
<>
<Group position="apart" px={"md"}>
<Title order={5}>Update Status Donatur</Title>
<Group position="left">
<HoverCard width={280} shadow="md">
<HoverCard.Target>
<ActionIcon bg={"gray.3"} radius={"xl"}>
<IconQuestionMark color="black" />
</ActionIcon>
</HoverCard.Target>
<HoverCard.Dropdown>
<Group spacing={4}>
<Text fz="sm">Sebelum melakukan aksi</Text>
<Text fz="sm" fw={"bold"} c={"green"}>
ACCEPT
</Text>
<Text fz={"sm"}>
Pastikan kembali transaksi donatur sesuai dengan mutasi pada
Bank tertuju
</Text>
</Group>
</HoverCard.Dropdown>
</HoverCard>
</Group>
</Group>
</>
);
}

View File

@@ -0,0 +1,13 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function AdminDonasi_funCountDonatur(donasiId: string) {
const donatur = await prisma.donasi_Invoice.count({
where: {
donasiId: donasiId
}
});
return donatur;
}

View File

@@ -0,0 +1,23 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function AdminDonasi_getListDonatur(donasiId: string) {
// console.log(donasiId)
const data = await prisma.donasi_Invoice.findMany({
where: {
donasiId: donasiId,
},
select: {
id: true,
nominal: true,
createdAt: true,
Author: true,
DonasiMaster_StatusInvoice: true
},
});
// console.log(data)
return data;
}

View File

@@ -0,0 +1,48 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function AdminDonasi_getListStatusInvoiceProses(donasiId: string) {
const dataStatus = await prisma.donasi_Invoice.findMany({
where: {
donasiId: donasiId,
donasiMaster_StatusInvoiceId: {
equals: "2",
},
},
select: {
id: true,
nominal: true,
createdAt: true,
Author: true,
Donasi: {
select: {
id: true,
title: true,
target: true,
active: true,
createdAt: true,
updatedAt: true,
publishTime: true,
catatan: true,
terkumpul: true,
authorId: true,
imagesId: true,
donasiMaster_KategoriId: true,
donasiMaster_DurasiId: true,
donasiMaster_StatusDonasiId: true,
Author: true,
imageDonasi: true,
CeritaDonasi: true,
DonasiMaster_Ketegori: true,
DonasiMaster_Durasi: true,
DonasiMaster_Status: true,
},
},
DonasiMaster_Bank: true,
DonasiMaster_StatusInvoice: true,
},
});
return dataStatus;
}

View File

@@ -15,6 +15,9 @@ export async function AdminDonasi_getById(id: string) {
createdAt: true,
updatedAt: true,
publishTime: true,
catatan: true,
progres: true,
terkumpul: true,
authorId: true,
imagesId: true,
donasiMaster_KategoriId: true,

View File

@@ -22,7 +22,7 @@ export async function AdminDonasi_funUpdateStatusPublish(
});
if (!data) return { status: 400, message: "Data tidak ditemukan" };
revalidatePath(RouterAdminDonasi.table_review);
revalidatePath("/dev/admin/donasi/table/review");
return {
status: 200,
message: "Status berhasil diganti",

View File

@@ -10,19 +10,18 @@ export async function AdminDonasi_funUpdateStatusReject(
statusId: string,
catatan: string
) {
const data = await prisma.donasi.update({
where: {
id: donasiId,
},
data: {
donasiMaster_StatusDonasiId: statusId,
catatan: catatan
catatan: catatan,
},
});
if (!data) return { status: 400, message: "Data tidak ditemukan" };
revalidatePath(RouterAdminDonasi.table_review);
revalidatePath("/dev/admin/donasi/table/review");
return {
status: 200,
message: "Status berhasil diganti",

View File

@@ -0,0 +1,38 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function AdminDonasi_funUpdateProgresDanTerkumpul(
donasiId: string,
terkumpul: number
) {
const danaTerkumpul = terkumpul.toString();
const update = await prisma.donasi.update({
where: {
id: donasiId,
},
data: {
terkumpul: danaTerkumpul,
},
});
if (!update) return { status: 400, message: "Update dana terkumpul gagal" };
let target: number = +update.target;
let totalTerkumpul = Number(update.terkumpul);
let progresSementarsa = Number(update.progres);
const progress = (totalTerkumpul / target) * 100;
const totalProgres = progresSementarsa + progress;
const updateProgres = await prisma.donasi.update({
where: { id: donasiId },
data: { progres: totalProgres.toString() },
});
if (!updateProgres) return { status: 400, message: "Update progres gagal" };
return {
status: 200,
message: "Berhasil update data donasi",
};
}

View File

@@ -0,0 +1,25 @@
"use server";
import prisma from "@/app/lib/prisma";
import { RouterAdminDonasi } from "@/app/lib/router_hipmi/router_admin";
import { revalidatePath } from "next/cache";
export async function AdminDonasi_funUpdateStatusInvoice(
invoiceId: string,
statusId: string
) {
const update = await prisma.donasi_Invoice.update({
where: {
id: invoiceId,
},
data: {
donasiMaster_StatusInvoiceId: statusId,
},
});
if (!update) return { status: 400, message: "Update gagal" };
revalidatePath("/dev/admin/donasi/detail/publish")
return {
status: 200,
message: "Update berhasil",
};
}

View File

@@ -1,10 +1,11 @@
import AdminDonasi_Main from "./main";
import AdminDonasi_TablePublish from "./table_status/table_publish";
import AdminDonasi_DetailPublish from "./detail_table/detail_publish";
import AdminDonasi_DetailPublish from "./detail_table/publish/detail_publish";
import AdminDonasi_TableReview from "./table_status/table_review";
import AdminDonasi_DetailReview from "./detail_table/detail_review";
import AdminDonasi_TableReject from "./table_status/table_reject";
import AdminDonasi_DetailReject from "./detail_table/detail_reject";
import AdminDonasi_ProsesTransaksi from "./detail_table/publish/proses_transaksi";
export {
AdminDonasi_Main,

View File

@@ -37,9 +37,7 @@ export default function AdminDonasi_TablePublish({
function TableStatus({ listPublish }: { listPublish: MODEL_DONASI[] }) {
const router = useRouter();
const [donasi, setDonasi] = useState(listPublish);
async function onClick() {
router.push(RouterAdminDonasi.detail_publish);
}
const TableRows = donasi.map((e, i) => (
<tr key={i}>
@@ -57,7 +55,7 @@ function TableStatus({ listPublish }: { listPublish: MODEL_DONASI[] }) {
leftIcon={<IconEyeCheck />}
radius={"xl"}
variant="outline"
onClick={onClick}
onClick={() => router.push(RouterAdminDonasi.detail_publish + `${e.id}`)}
>
Tampilkan
</Button>

View File

@@ -42,17 +42,6 @@ function TableStatus({ dataReject }: { dataReject: MODEL_DONASI[] }) {
const [opened, { open, close }] = useDisclosure(false);
const [donasi, setDonasi] = useState(dataReject);
function onClick() {
return (
<Modal opened={opened} onClose={close} centered withCloseButton={false}>
<Stack>
<Title order={6}>Alasan penolakan</Title>
<Text>{"test"}</Text>
</Stack>
</Modal>
);
}
const TableRows = donasi.map((e, i) => (
<tr key={i}>
<td>{e.title}</td>
@@ -61,7 +50,6 @@ function TableStatus({ dataReject }: { dataReject: MODEL_DONASI[] }) {
</td>
<td>{e.DonasiMaster_Ketegori.name}</td>
<td>{e.DonasiMaster_Durasi.name} hari</td>
<td>{e.catatan}</td>
<td>
<Center>
<Button
@@ -70,20 +58,33 @@ function TableStatus({ dataReject }: { dataReject: MODEL_DONASI[] }) {
leftIcon={<IconEyeCheck />}
radius={"xl"}
variant="outline"
onClick={() => {
onClick()
// onClick(e.catatan);
}}
onClick={() => router.push(RouterAdminDonasi.detail_reject + `${e.id}`)}
>
Tampilkan
</Button>
</Center>
{/* <ModalReject opened={opened} close={close} /> */}
</td>
</tr>
));
return (
<>
{donasi.map((e,i) => (
<Modal
key={e.id}
opened={opened}
onClose={close}
centered
withCloseButton={false}
>
<Stack>
<Title order={6}>Alasan penolakan</Title>
<Text>{i}</Text>
</Stack>
</Modal>
))}
<Box>
<Box bg={"red.1"} p={"xs"}>
<Title order={6} c={"red"}>
@@ -104,7 +105,6 @@ function TableStatus({ dataReject }: { dataReject: MODEL_DONASI[] }) {
<th>Target</th>
<th>Ketegori</th>
<th>Durasi</th>
<th>Catatan</th>
<th>
<Center>Lihat alasan</Center>
</th>
@@ -116,3 +116,16 @@ function TableStatus({ dataReject }: { dataReject: MODEL_DONASI[] }) {
</>
);
}
async function ModalReject(opened: any, close: any) {
return (
<>
<Modal opened={opened} onClose={close} centered withCloseButton={false}>
<Stack>
<Title order={6}>Alasan penolakan</Title>
<Text>{"test"}</Text>
</Stack>
</Modal>
</>
);
}

View File

@@ -0,0 +1,95 @@
"use client";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import {
SimpleGrid,
Box,
Stack,
Grid,
AspectRatio,
Paper,
Progress,
Divider,
Image,
Text,
} from "@mantine/core";
import router from "next/router";
import ComponentDonasi_TampilanHitungMundur from "./tampilan_hitung_mundur";
import TampilanRupiahDonasi from "./tampilan_rupiah";
import { MODEL_DONASI } from "../model/interface";
import { useViewportSize } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { useState } from "react";
export default function ComponentDonasi_BoxPublish({
dataDonasi,
path,
}: {
dataDonasi: MODEL_DONASI[];
path: string;
}) {
const { height, width } = useViewportSize();
const router = useRouter();
const [donasi, setDonasi] = useState(dataDonasi);
return (
<>
<SimpleGrid
cols={4}
spacing="lg"
breakpoints={[
{ maxWidth: "62rem", cols: 3, spacing: "md" },
{ maxWidth: "48rem", cols: 2, spacing: "sm" },
{ maxWidth: "36rem", cols: 1, spacing: "sm" },
]}
>
{donasi.map((e, i) => (
<Box
key={i}
onClick={
() => router.push(path + `${e.id}`)
// toast("Cooming soon")
}
>
<Stack>
<Grid>
<Grid.Col span={7}>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={RouterDonasi.api_gambar + `${e.imagesId}`}
radius={"md"}
/>
</Paper>
</AspectRatio>
</Grid.Col>
<Grid.Col span={5}>
<Stack spacing={"xs"}>
<Stack spacing={0}>
<Text fz={"sm"} fw={"bold"} lineClamp={2}>
{e.title}
</Text>
<ComponentDonasi_TampilanHitungMundur
durasi={e.DonasiMaster_Durasi.name}
publishTime={e.publishTime}
textSize={10}
/>
</Stack>
<Progress value={+e.progres} color="orange" />
<Stack spacing={0}>
<Text fz={"sm"}>Terkumpul</Text>
<Text fz={"sm"} fw={"bold"} c={"orange"} truncate>
<TampilanRupiahDonasi nominal={+e.terkumpul} />
</Text>
</Stack>
</Stack>
</Grid.Col>
</Grid>
{width > 575 ? "" : <Divider />}
</Stack>
</Box>
))}
</SimpleGrid>
</>
);
}

View File

@@ -0,0 +1,57 @@
"use client";
import { useRouter } from "next/navigation";
import { MODEL_DONASI } from "../../model/interface";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import {
Stack,
AspectRatio,
Paper,
Title,
Group,
Image,
Text,
} from "@mantine/core";
import TampilanRupiahDonasi from "../tampilan_rupiah";
export default function ComponentDonasi_DetailDataGalangDana({ donasi }: { donasi: MODEL_DONASI }) {
const router = useRouter();
return (
<>
<Stack>
<Stack>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={RouterDonasi.api_gambar + `${donasi.imagesId}`}
/>
</Paper>
</AspectRatio>
<Stack spacing={0}>
<Title order={4}>{donasi.title}</Title>
<Text fz={10}>
Durasi: {donasi.DonasiMaster_Durasi.name} hari
</Text>
</Stack>
<Stack spacing={0}>
<Group position="apart">
<Stack spacing={0}>
<Text fz={12}>Dana dibutuhkan</Text>
<Title order={4} c="blue">
<TampilanRupiahDonasi nominal={+donasi.target} />
</Title>
</Stack>
<Stack spacing={0}>
<Text fz={12}>Kategori</Text>
<Title order={4} c="blue">
{donasi.DonasiMaster_Ketegori.name}
</Title>
</Stack>
</Group>
</Stack>
</Stack>
</Stack>
</>
);
}

View File

@@ -7,7 +7,7 @@ import { Stack, Title, Paper, Group, ActionIcon, Text } from "@mantine/core";
import { IconCircleChevronRight } from "@tabler/icons-react";
import moment from "moment";
export default function ComponentCeritaPenggalangDanaDonasi({
export default function ComponentDonasi_CeritaPenggalangMain({
donasi,
}: {
donasi: MODEL_DONASI;
@@ -23,14 +23,14 @@ export default function ComponentCeritaPenggalangDanaDonasi({
<Text>{moment(donasi.createdAt).format("ll")}</Text>
<ActionIcon
variant="transparent"
onClick={() => router.push(RouterDonasi.cerita_penggalang + `${donasi.id}`)}
onClick={() =>
router.push(RouterDonasi.cerita_penggalang + `${donasi.id}`)
}
>
<IconCircleChevronRight />
</ActionIcon>
</Group>
<Text lineClamp={4}>
{donasi.CeritaDonasi.cerita}
</Text>
<Text lineClamp={4}>{donasi.CeritaDonasi.cerita}</Text>
{/* <Text c={"blue"}>Baca selengkapnya</Text> */}
</Stack>
</Paper>

View File

@@ -0,0 +1,118 @@
"use client";
import { useRouter } from "next/navigation";
import { MODEL_DONASI } from "../../model/interface";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import {
Stack,
AspectRatio,
Paper,
Title,
Group,
Progress,
Grid,
Divider,
Image,
Text,
} from "@mantine/core";
import {
IconClover,
IconMessageChatbot,
IconMoneybag,
} from "@tabler/icons-react";
import TampilanRupiahDonasi from "../tampilan_rupiah";
import ComponentDonasi_TampilanHitungMundur from "../tampilan_hitung_mundur";
export function ComponentDonasi_DetailDataMain({
donasi,
countDonatur,
}: {
donasi: MODEL_DONASI;
countDonatur: number;
}) {
const router = useRouter();
return (
<>
<Stack>
<Stack>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={RouterDonasi.api_gambar + `${donasi.imagesId}`}
/>
</Paper>
</AspectRatio>
<Stack spacing={0}>
<Title order={4}>{donasi.title}</Title>
<ComponentDonasi_TampilanHitungMundur
durasi={donasi.DonasiMaster_Durasi.name}
publishTime={donasi.publishTime}
/>
</Stack>
<Stack spacing={0}>
<Group position="apart" align="center" h={"100%"}>
<Stack spacing={0}>
<Text fz={12}>Dana terkumpul</Text>
<Title order={4} c="blue">
<TampilanRupiahDonasi nominal={+donasi.terkumpul} />
</Title>
<Group>
<Text fz={10}>Dari total</Text>{" "}
<TampilanRupiahDonasi
nominal={+donasi.target}
fontSize={10}
/>
</Group>
</Stack>
<Stack spacing={0}>
<Text fz={12}>Kategori</Text>
<Title order={4} c="blue">
{donasi.DonasiMaster_Ketegori.name}
</Title>
</Stack>
</Group>
</Stack>
<Progress value={+donasi.progres} animate />
<Grid>
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.donatur)}
>
<Stack align="center" spacing={"xs"}>
<Group>
<IconClover color="skyblue" />
<Title order={6} c={"blue"}>
{countDonatur}
</Title>
</Group>
<Text fz={"xs"}>Donatur</Text>
</Stack>
</Grid.Col>
<Divider orientation="vertical" />
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.kabar)}
>
<Stack spacing={"sm"} align="center">
<IconMessageChatbot color="skyblue" />
<Text fz={"xs"}>Kabar Terbaru</Text>
</Stack>
</Grid.Col>
<Divider orientation="vertical" />
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.pencairan_dana)}
>
<Stack spacing={"sm"} align="center">
<IconMoneybag color="skyblue" />
<Text fz={"xs"}>Pencairan Dana</Text>
</Stack>
</Grid.Col>
</Grid>
</Stack>
</Stack>
</>
);
}

View File

@@ -0,0 +1,50 @@
"use client"
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { MODEL_AUTHOR } from "@/app_modules/home/models/interface";
import { Stack, Title, Paper, Group, ActionIcon, Avatar, Text } from "@mantine/core";
import { IconCircleChevronRight } from "@tabler/icons-react";
import _ from "lodash";
import { useRouter } from "next/navigation";
import ComponentDonasi_NotedBox from "../noted_box";
export default function ComponentDonasi_InformasiPenggalangMain({ author }: { author: MODEL_AUTHOR}) {
const router = useRouter();
return (
<>
{/* <pre>{JSON.stringify(author, null, 2)}</pre> */}
<Stack spacing={"xs"}>
<Title order={4}>Informasi Penggalang Dana</Title>
<Paper p={"sm"} withBorder>
<Stack>
<Group position="apart">
<Title order={5}>Penggalang Dana</Title>
<ActionIcon
variant="transparent"
onClick={() => router.push(RouterDonasi.penggalang_dana + `${author.id}`)}
>
<IconCircleChevronRight />
</ActionIcon>
</Group>
<Group>
<Avatar radius={"xl"} variant="filled" bg={"blue"}>
{(() => {
const usr = author.username;
const splt = usr.split("");
const Up = _.upperCase(splt[0]);
return Up;
})()}
</Avatar>
<Text>{author.username}</Text>
</Group>
<ComponentDonasi_NotedBox
informasi="Semua dana yang terkumpul akan disalurkan ke penggalang dana,
kabar penyaluran dapat dilihat di halaman kabar terbaru."
/>
</Stack>
</Paper>
</Stack>
</>
);
}

View File

@@ -1,19 +1,29 @@
"use client";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { Footer, Center, Button } from "@mantine/core";
import { useAtom } from "jotai";
import { useRouter } from "next/navigation";
import { gs_proses_donasi } from "../global_state";
export default function ButtonDonasi() {
export default function ButtonDonasi({ donasiId }: { donasiId: string }) {
const router = useRouter();
const [prosesDonasi, setProsesDonasi] = useAtom(gs_proses_donasi);
async function onClick() {
setProsesDonasi({
...prosesDonasi,
bank: "",
nominal: "",
norek: "",
});
router.push(RouterDonasi.masukan_donasi + `${donasiId}`);
}
return (
<>
<Footer height={70} px={"md"} sx={{ borderStyle: "none" }}>
<Center h={70}>
<Button
w={"100%"}
radius={"xl"}
onClick={() => router.push(RouterDonasi.masukan_donasi)}
>
<Button w={"100%"} radius={"xl"} onClick={() => onClick()}>
Donasi
</Button>
</Center>

View File

@@ -7,6 +7,7 @@ import { useState } from "react";
export default function HeaderTamplateDonasi({
hideBack,
changeIconBack,
route,
route2,
title,
@@ -14,6 +15,7 @@ export default function HeaderTamplateDonasi({
bg,
}: {
hideBack?: boolean;
changeIconBack?: any
route?: any;
route2?: any;
title: string;
@@ -42,7 +44,7 @@ export default function HeaderTamplateDonasi({
}
}}
>
<IconChevronLeft />
{changeIconBack ? changeIconBack: <IconChevronLeft />}
</ActionIcon>
)}
<Title order={5}>{title}</Title>

View File

@@ -1,6 +1,6 @@
import { Center, Grid, Group, Paper, Text, Title } from "@mantine/core";
export default function BoxInformasiDonasi({
export default function ComponentDonasi_NotedBox({
informasi,
}: {
informasi: string;
@@ -9,10 +9,10 @@ export default function BoxInformasiDonasi({
<>
<Paper bg={"blue.3"} p={"sm"}>
<Group>
<Text fz={"xs"} fs={"italic"}>
<Text span inherit c={"red"}>* </Text>
<Text fz={"xs"} fs={"italic"}>
<Text span inherit c={"red"}>
*{" "}
</Text>
{informasi}
</Text>
</Group>

View File

@@ -0,0 +1,30 @@
"use client";
import { Text } from "@mantine/core";
import moment from "moment";
export default function ComponentDonasi_TampilanHitungMundur({
durasi,
publishTime,
textSize,
}: {
durasi: any;
publishTime: any;
textSize?: number
}) {
return (
<>
<Text fz={textSize? textSize: "xs"}>
Sisa hari{" "}
<Text span inherit fw={"bold"}>
{Number(durasi) -
moment(new Date()).diff(new Date(publishTime), "days") <=
0
? 0
: Number(durasi) -
moment(new Date()).diff(new Date(publishTime), "days")}
</Text>{" "}
</Text>
</>
);
}

View File

@@ -1,9 +1,9 @@
import { Text } from "@mantine/core";
export default function TampilanRupiahDonasi({nominal}: {nominal: number}) {
export default function TampilanRupiahDonasi({nominal, fontSize}: {nominal: number, fontSize?: number}) {
return (
<>
<Text>
<Text fz={ fontSize ? fontSize : "md"}>
Rp.{" "}
{new Intl.NumberFormat("id-ID", { maximumFractionDigits: 10 }).format(
nominal

View File

@@ -16,7 +16,7 @@ import { useAtom } from "jotai";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { gs_donasi_tabs_posting } from "../global_state";
import BoxInformasiDonasi from "../component/box_informasi";
import ComponentDonasi_NotedBox from "../component/noted_box";
import { MODEL_DONASI_TEMPORARY } from "../model/interface";
import _ from "lodash";
import toast from "react-simple-toasts";
@@ -77,7 +77,7 @@ export default function CreateCeritaPenggalangDonasi({
<>
<Stack spacing={"md"} px={"md"}>
{/* <pre>{JSON.stringify(dataTempo, null, 2)}</pre> */}
<BoxInformasiDonasi informasi="Ceritakan dengan jujur & benar mengapa Penggalanagn Dana ini harus diadakan!" />
<ComponentDonasi_NotedBox informasi="Ceritakan dengan jujur & benar mengapa Penggalanagn Dana ini harus diadakan!" />
<Textarea
autosize
minRows={2}

View File

@@ -20,7 +20,7 @@ import { IconCamera } from "@tabler/icons-react";
import { useAtom } from "jotai";
import { useRouter } from "next/navigation";
import BoxInformasiDonasi from "../component/box_informasi";
import ComponentDonasi_NotedBox from "../component/noted_box";
import { MODEL_DONASI_ALL_MASTER } from "../model/interface";
import { useState } from "react";
import { useShallowEffect } from "@mantine/hooks";
@@ -75,7 +75,7 @@ export default function CreateDonasi({
return (
<>
<Stack spacing={"md"} px={"md"}>
<BoxInformasiDonasi informasi="Lengkapi semua data di bawah untuk selanjutnya mengisi cerita Penggalangan Dana!" />
<ComponentDonasi_NotedBox informasi="Lengkapi semua data di bawah untuk selanjutnya mengisi cerita Penggalangan Dana!" />
<Select
label="Kategori"
placeholder="Pilih kategori penggalangan dana"

View File

@@ -1,159 +1,66 @@
"use client";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { ActionIcon, AspectRatio, Avatar, Divider, Grid, Group, Image, Paper, Progress, Stack, Text, Title } from "@mantine/core";
import { IconClover, IconMessageChatbot, IconMoneybag, IconCircleChevronRight } from "@tabler/icons-react";
import {
ActionIcon,
AspectRatio,
Avatar,
Divider,
Grid,
Group,
Image,
Paper,
Progress,
Stack,
Text,
Title,
} from "@mantine/core";
import {
IconClover,
IconMessageChatbot,
IconMoneybag,
IconCircleChevronRight,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import BoxInformasiDonasi from "../../component/box_informasi";
import ComponentDonasi_NotedBox from "../../component/noted_box";
import { useState } from "react";
import { MODEL_DONASI, MODEL_DONASI_INVOICE } from "../../model/interface";
import TampilanRupiahDonasi from "../../component/tampilan_rupiah";
import { ComponentDonasi_DetailDataMain } from "../../component/detail_main/detail_data_donasi";
import ComponentDonasi_InformasiPenggalangMain from "../../component/detail_main/informasi_penggalang";
import ComponentDonasi_CeritaPenggalangMain from "../../component/detail_main/cerita_penggalang";
export default function DetailDonasiSaya() {
export default function DetailDonasiSaya({
dataDonasi,
countDonatur,
}: {
dataDonasi: MODEL_DONASI_INVOICE;
countDonatur: number;
}) {
const [invoice, setInvoice] = useState(dataDonasi);
return (
<>
<Stack>
<Stack spacing={0}>
<Text>Donasi Saya:</Text>
<Title order={4} c={"blue"}>
Rp. 100.000
<TampilanRupiahDonasi nominal={+invoice.nominal} />
</Title>
</Stack>
<DetailDonasi/>
<InformasiPenggalangDana/>
<CeritaPenggalangDana/>
<ComponentDonasi_DetailDataMain
donasi={invoice.Donasi}
countDonatur={countDonatur}
/>
<ComponentDonasi_InformasiPenggalangMain
author={invoice.Donasi.Author}
/>
<ComponentDonasi_CeritaPenggalangMain donasi={invoice.Donasi} />
</Stack>
</>
);
}
function DetailDonasi() {
const router = useRouter();
return (
<>
<Stack>
<Stack>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image alt="Foto" src={"/aset/no-img.png"} />
</Paper>
</AspectRatio>
<Title order={4}>Judul Donasi</Title>
<Stack spacing={0}>
<Group position="apart">
<Stack spacing={0}>
<Text fz={12}>Dana dibutuhkan</Text>
<Title order={4} c="blue">
Rp. 50.000.000
</Title>
</Stack>
<Text fz={"xs"}>
Sisa hari{" "}
<Text span inherit fw={"bold"}>
100
</Text>{" "}
</Text>
</Group>
</Stack>
<Progress value={50} />
<Grid>
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.donatur)}
>
<Stack align="center" spacing={"xs"}>
<Group>
<IconClover color="skyblue" />
<Text>50</Text>
</Group>
<Text>Donatur</Text>
</Stack>
</Grid.Col>
<Divider orientation="vertical" />
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.kabar)}
>
<Stack spacing={"sm"} align="center">
<IconMessageChatbot color="skyblue" />
<Text>Kabar Terbaru</Text>
</Stack>
</Grid.Col>
<Divider orientation="vertical" />
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.pencairan_dana)}
>
<Stack spacing={"sm"} align="center">
<IconMoneybag color="skyblue" />
<Text>Pencairan Dana</Text>
</Stack>
</Grid.Col>
</Grid>
</Stack>
</Stack>
</>
);
}
function InformasiPenggalangDana() {
const router = useRouter();
return (
<>
<Stack spacing={"xs"}>
<Title order={4}>Informasi Penggalang Dana</Title>
<Paper p={"sm"} withBorder>
<Stack>
<Group position="apart">
<Title order={5}>Penggalang Dana</Title>
<ActionIcon
variant="transparent"
onClick={() => router.push(RouterDonasi.penggalang_dana)}
>
<IconCircleChevronRight />
</ActionIcon>
</Group>
<Group>
<Avatar radius={"xl"} variant="filled" bg={"blue"}>
U
</Avatar>
<Text>Username</Text>
</Group>
<BoxInformasiDonasi
informasi="Semua dana yang terkumpul akan disalurkan ke penggalang dana,
kabar penyaluran dapat dilihat di halaman kabar terbaru."
/>
</Stack>
</Paper>
</Stack>
</>
);
}
function CeritaPenggalangDana() {
const router = useRouter();
return (
<>
<Stack spacing={"xs"}>
<Title order={4}>Cerita Penggalang Dana</Title>
<Paper p={"sm"} withBorder>
<Stack>
<Group position="apart">
<Text>1 Des 2023</Text>
<ActionIcon
variant="transparent"
onClick={() => router.push(RouterDonasi.cerita_penggalang)}
>
<IconCircleChevronRight />
</ActionIcon>
</Group>
<Text lineClamp={4}>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat
doloremque perferendis laborum? Cupiditate sed consequatur quasi
doloremque, consequuntur libero? Vel nam esse fuga, sed et
repellat commodi nemo quia dignissimos?
</Text>
{/* <Text c={"blue"}>Baca selengkapnya</Text> */}
</Stack>
</Paper>
</Stack>
</>
);
}

View File

@@ -3,11 +3,12 @@
import { AppShell } from "@mantine/core"
import React from "react"
import HeaderTamplateDonasi from "../../component/header_tamplate"
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi"
export default function LayoutDetailDonasiSaya({children}: {children: React.ReactNode}){
return<>
<AppShell
header={<HeaderTamplateDonasi title="Detail Donasi Saya"/>}
header={<HeaderTamplateDonasi title="Detail Donasi Saya" route={RouterDonasi.main_donasi_saya} />}
>
{children}
</AppShell>

View File

@@ -24,17 +24,18 @@ import {
IconMessageChatbot,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import BoxInformasiDonasi from "../../component/box_informasi";
import ComponentDonasi_NotedBox from "../../component/noted_box";
import { useAtom } from "jotai";
import { gs_donasi_tabs_posting } from "../../global_state";
import { MODEL_DONASI } from "../../model/interface";
import { useState } from "react";
import TampilanRupiahDonasi from "../../component/tampilan_rupiah";
import ComponentCeritaPenggalangDanaDonasi from "../../component/detail_main/cerita_penggalang";
import ComponentDonasi_CeritaPenggalangMain from "../../component/detail_main/cerita_penggalang";
import { Donasi_funGantiStatus } from "../../fun/update/fun_ganti_status";
import { NotifBerhasil } from "../../component/notifikasi/notif_berhasil";
import { NotifPeringatan } from "../../component/notifikasi/notif_peringatan";
import { useShallowEffect } from "@mantine/hooks";
import ComponentDonasi_DetailDataGalangDana from "../../component/detail_galang_dana/detail_data_donasi";
export default function DetailDraftDonasi({
dataDonasi,
@@ -44,8 +45,8 @@ export default function DetailDraftDonasi({
return (
<>
<Stack spacing={"xl"}>
<DetailDonasi dataDonasi={dataDonasi} />
<ComponentCeritaPenggalangDanaDonasi donasi={dataDonasi} />
<ComponentDonasi_DetailDataGalangDana donasi={dataDonasi} />
<ComponentDonasi_CeritaPenggalangMain donasi={dataDonasi} />
<ButtonAjukanPenggalangan dataDonasi={dataDonasi} />
</Stack>
</>
@@ -86,47 +87,47 @@ function ButtonAjukanPenggalangan({
);
}
function DetailDonasi({ dataDonasi }: { dataDonasi: MODEL_DONASI }) {
const [donasi, setDonasi] = useState(dataDonasi);
useShallowEffect(() => {
setDonasi(dataDonasi);
}, [dataDonasi]);
return (
<>
<Stack>
<Stack>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={RouterDonasi.api_image + `${donasi.imageDonasi.url}`}
/>
</Paper>
</AspectRatio>
<Stack spacing={0}>
<Title order={4}>{donasi.title}</Title>
<Text fz={"xs"}>
Durasi: {donasi.DonasiMaster_Durasi.name} hari
</Text>
</Stack>
<Stack spacing={0}>
<Group position="apart">
<Stack spacing={0}>
<Text fz={12}>Dana dibutuhkan</Text>
<Title order={4} c="blue">
<TampilanRupiahDonasi nominal={+donasi.target} />
</Title>
</Stack>
<Stack spacing={0}>
<Text fz={12}>Kategori</Text>
<Title order={4} c="blue">
{donasi.DonasiMaster_Ketegori.name}
</Title>
</Stack>
</Group>
</Stack>
</Stack>
</Stack>
</>
);
}
// function DetailDonasi({ dataDonasi }: { dataDonasi: MODEL_DONASI }) {
// const [donasi, setDonasi] = useState(dataDonasi);
// useShallowEffect(() => {
// setDonasi(dataDonasi);
// }, [dataDonasi]);
// return (
// <>
// <Stack>
// <Stack>
// <AspectRatio ratio={16 / 9}>
// <Paper radius={"md"}>
// <Image
// alt="Foto"
// src={RouterDonasi.api_image + `${donasi.imageDonasi.url}`}
// />
// </Paper>
// </AspectRatio>
// <Stack spacing={0}>
// <Title order={4}>{donasi.title}</Title>
// <Text fz={"xs"}>
// Durasi: {donasi.DonasiMaster_Durasi.name} hari
// </Text>
// </Stack>
// <Stack spacing={0}>
// <Group position="apart">
// <Stack spacing={0}>
// <Text fz={12}>Dana dibutuhkan</Text>
// <Title order={4} c="blue">
// <TampilanRupiahDonasi nominal={+donasi.target} />
// </Title>
// </Stack>
// <Stack spacing={0}>
// <Text fz={12}>Kategori</Text>
// <Title order={4} c="blue">
// {donasi.DonasiMaster_Ketegori.name}
// </Title>
// </Stack>
// </Group>
// </Stack>
// </Stack>
// </Stack>
// </>
// );
// }

View File

@@ -9,9 +9,11 @@ import React from "react";
export default function LayoutCeritaPenggalangDonasi({
children,
statusDonasiId,
donasiId
}: {
children: React.ReactNode;
statusDonasiId: string;
donasiId: string
}) {
if (statusDonasiId !== "1") {
return (
@@ -27,7 +29,7 @@ export default function LayoutCeritaPenggalangDonasi({
return (
<AppShell
header={<HeaderTamplateDonasi title="Cerita Penggalang Dana" />}
footer={<ButtonDonasi />}
footer={<ButtonDonasi donasiId={donasiId}/>}
>
{children}
</AppShell>

View File

@@ -27,144 +27,25 @@ import {
IconMoneybag,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import BoxInformasiDonasi from "../../component/box_informasi";
import ComponentDonasi_NotedBox from "../../component/noted_box";
import { ComponentDonasi_DetailDataMain } from "../../component/detail_main/detail_data_donasi";
import { MODEL_DONASI } from "../../model/interface";
import ComponentDonasi_CeritaPenggalangMain from "../../component/detail_main/cerita_penggalang";
import ComponentDonasi_InformasiPenggalangMain from "../../component/detail_main/informasi_penggalang";
export default function DetailMainDonasi() {
export default function DetailMainDonasi({
dataDonasi,
countDonatur
}: {
dataDonasi: MODEL_DONASI;
countDonatur: number
}) {
return (
<>
<Stack spacing={40}>
<DetailDonasi />
<InformasiPenggalangDana />
<CeritaPenggalangDana />
</Stack>
</>
);
}
function DetailDonasi() {
const router = useRouter();
return (
<>
<Stack>
<Stack>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image alt="Foto" src={"/aset/no-img.png"} />
</Paper>
</AspectRatio>
<Title order={4}>Judul Donasi</Title>
<Stack spacing={0}>
<Group position="apart">
<Stack spacing={0}>
<Text fz={12}>Dana dibutuhkan</Text>
<Title order={4} c="blue">
Rp. 50.000.000
</Title>
</Stack>
<Text fz={"xs"}>Sisa hari <Text span inherit fw={"bold"}>100</Text> </Text>
</Group>
</Stack>
<Progress value={50} />
<Grid>
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.donatur)}
>
<Stack align="center" spacing={"xs"}>
<Group>
<IconClover color="skyblue" />
<Text>50</Text>
</Group>
<Text>Donatur</Text>
</Stack>
</Grid.Col>
<Divider orientation="vertical" />
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.kabar)}
>
<Stack spacing={"sm"} align="center">
<IconMessageChatbot color="skyblue" />
<Text>Kabar Terbaru</Text>
</Stack>
</Grid.Col>
<Divider orientation="vertical" />
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.pencairan_dana)}
>
<Stack spacing={"sm"} align="center">
<IconMoneybag color="skyblue" />
<Text>Pencairan Dana</Text>
</Stack>
</Grid.Col>
</Grid>
</Stack>
</Stack>
</>
);
}
function InformasiPenggalangDana() {
const router = useRouter();
return (
<>
<Stack spacing={"xs"}>
<Title order={4}>Informasi Penggalang Dana</Title>
<Paper p={"sm"} withBorder>
<Stack>
<Group position="apart">
<Title order={5}>Penggalang Dana</Title>
<ActionIcon
variant="transparent"
onClick={() => router.push(RouterDonasi.penggalang_dana)}
>
<IconCircleChevronRight />
</ActionIcon>
</Group>
<Group>
<Avatar radius={"xl"} variant="filled" bg={"blue"}>
U
</Avatar>
<Text>Username</Text>
</Group>
<BoxInformasiDonasi
informasi="Semua dana yang terkumpul akan disalurkan ke penggalang dana,
kabar penyaluran dapat dilihat di halaman kabar terbaru."
/>
</Stack>
</Paper>
</Stack>
</>
);
}
function CeritaPenggalangDana() {
const router = useRouter();
return (
<>
<Stack spacing={"xs"}>
<Title order={4}>Cerita Penggalang Dana</Title>
<Paper p={"sm"} withBorder>
<Stack>
<Group position="apart">
<Text>1 Des 2023</Text>
<ActionIcon
variant="transparent"
onClick={() => router.push(RouterDonasi.cerita_penggalang)}
>
<IconCircleChevronRight />
</ActionIcon>
</Group>
<Text lineClamp={4}>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat
doloremque perferendis laborum? Cupiditate sed consequatur quasi
doloremque, consequuntur libero? Vel nam esse fuga, sed et
repellat commodi nemo quia dignissimos?
</Text>
{/* <Text c={"blue"}>Baca selengkapnya</Text> */}
</Stack>
</Paper>
<ComponentDonasi_DetailDataMain donasi={dataDonasi} countDonatur={countDonatur} />
<ComponentDonasi_InformasiPenggalangMain author={dataDonasi.Author} />
<ComponentDonasi_CeritaPenggalangMain donasi={dataDonasi} />
</Stack>
</>
);

View File

@@ -7,14 +7,16 @@ import ButtonDonasi from "../../component/footer_button_donasi";
export default function LayoutDetailMainDonasi({
children,
donasiId
}: {
children: React.ReactNode;
donasiId: string
}) {
return (
<>
<AppShell
header={<HeaderTamplateDonasi title="Detail Donasi" />}
footer={<ButtonDonasi />}
footer={<ButtonDonasi donasiId={donasiId}/>}
>
{children}
</AppShell>

View File

@@ -1,93 +0,0 @@
"use client";
import {
Box,
Button,
Grid,
Group,
Paper,
Stack,
Text,
TextInput,
Title,
} from "@mantine/core";
import {
IconChevronRight,
IconMoodSmile,
IconMoodSmileBeam,
IconMoodSmileDizzy,
IconMoodXd,
} from "@tabler/icons-react";
export default function MasukanDonasi() {
const listNominal = [
{
id: 1,
nominal: 25000,
icon: <IconMoodSmile />,
},
{
id: 2,
nominal: 50000,
icon: <IconMoodSmileBeam />,
},
{
id: 3,
nominal: 75000,
icon: <IconMoodSmileDizzy />,
},
{
id: 4,
nominal: 10000,
icon: <IconMoodXd />,
},
];
return (
<>
<Stack>
<Box>
{listNominal.map((e) => (
<Paper
key={e.id}
withBorder
radius={"md"}
p={"sm"}
shadow="lg"
mb={"md"}
>
<Group position="apart">
<Group>
{e.icon}
<Title order={4}>
Rp.{" "}
{new Intl.NumberFormat("id-ID", {
maximumFractionDigits: 10,
}).format(e.nominal)}
</Title>
</Group>
<IconChevronRight />
</Group>
</Paper>
))}
</Box>
<Paper p={"sm"} withBorder shadow="lg">
<Stack>
<Text>Nominal Lainnya</Text>
<Grid>
<Grid.Col span={1}>
<Title order={4}>Rp.</Title>
</Grid.Col>
<Grid.Col span={11}>
<TextInput type="number" />
</Grid.Col>
</Grid>
<Text c={"gray"} fz={"xs"}>
Minimal Donasi Rp. 10.000
</Text>
</Stack>
</Paper>
<Button radius={"xl"}>Lanjutan Pembayaran</Button>
</Stack>
</>
);
}

View File

@@ -1,6 +1,6 @@
"use client";
import BoxInformasiDonasi from "@/app_modules/donasi/component/box_informasi";
import ComponentDonasi_NotedBox from "@/app_modules/donasi/component/noted_box";
import {
Avatar,
Button,
@@ -45,7 +45,7 @@ function BoxDanaDicarikan() {
<Text fz={"xs"}>Pencairan dana</Text>
</Grid.Col>
</Grid>
<BoxInformasiDonasi informasi=" Pencairan dana akan dilakukan oleh Admin HIPMI tanpa campur tangan
<ComponentDonasi_NotedBox informasi=" Pencairan dana akan dilakukan oleh Admin HIPMI tanpa campur tangan
pihak manapun, jika berita pencairan dana dibawah tidak sesuai
dengan kabar yang diberikan oleh PENGGALANG DANA. Maka pegguna lain
dapat melaporkannya pada Admin HIPMI !"/>

View File

@@ -1,6 +1,13 @@
"use client";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import ComponentDonasi_BoxPublish from "@/app_modules/donasi/component/box_publish";
import TampilanRupiahDonasi from "@/app_modules/donasi/component/tampilan_rupiah";
import {
MODEL_DONASI,
MODEL_DONASI_INFO_PENGGALANG,
} from "@/app_modules/donasi/model/interface";
import { MODEL_AUTHOR } from "@/app_modules/home/models/interface";
import {
AspectRatio,
Avatar,
@@ -27,23 +34,38 @@ import {
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import router from "next/router";
import { useState } from "react";
export default function PenggalangDanaDonasi({
dataPenggalang,
}: {
dataPenggalang: MODEL_DONASI_INFO_PENGGALANG;
}) {
const [value, setValue] = useState(dataPenggalang);
export default function PenggalangDanaDonasi() {
return (
<>
<Stack>
<InformasiPenggalang />
<DataPengganganDana />
<InformasiPenggalang value={value as any} />
<ComponentDonasi_BoxPublish
dataDonasi={value.Donasi}
path={RouterDonasi.detail_publish}
/>
</Stack>
</>
);
}
function InformasiPenggalang() {
function InformasiPenggalang({ value }: { value: MODEL_AUTHOR }) {
return (
<>
<Paper radius={"md"}>
<Stack bg={"gray.1"} p={"md"} spacing={"xl"} sx={{borderRadius: "10px"}}>
<Stack
bg={"gray.1"}
p={"md"}
spacing={"xl"}
sx={{ borderRadius: "10px" }}
>
<Stack align="center" spacing={0}>
<Paper
radius={"100%"}
@@ -60,7 +82,7 @@ function InformasiPenggalang() {
/>
</Center>
</Paper>
<Title order={3}>@Username</Title>
<Title order={3}>@{value.username}</Title>
</Stack>
<Stack>
<Group>
@@ -69,7 +91,7 @@ function InformasiPenggalang() {
</Group>
<Group>
<IconPhone />
<Text>+62 81x xxx xxx</Text>
<Text>+{value.nomor}</Text>
</Group>
<Group>
<IconBrandGmail />
@@ -82,13 +104,12 @@ function InformasiPenggalang() {
);
}
function DataPengganganDana() {
function DataPengganganDana({ donasi }: { donasi: MODEL_DONASI[] }) {
const router = useRouter();
const { height, width } = useViewportSize();
return (
<>
<Title order={5}>Peggalangan Dana Yang Dilakukan</Title>
<SimpleGrid
cols={4}
spacing="lg"
@@ -98,42 +119,43 @@ function DataPengganganDana() {
{ maxWidth: "36rem", cols: 1, spacing: "sm" },
]}
>
{Array(5)
.fill(0)
.map((e, i) => (
<Box key={i} onClick={() => router.push(RouterDonasi.detail_main)}>
<Stack>
<Grid>
<Grid.Col span={7}>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={"/aset/no-img.png"}
radius={"md"}
/>
</Paper>
</AspectRatio>
</Grid.Col>
<Grid.Col span={5}>
<Stack spacing={"xs"}>
<Text fz={"sm"} fw={"bold"} lineClamp={2}>
Judul Donasi Bisa Dilihat Disini Untuk Contoh
{donasi.map((e, i) => (
<Box
key={i}
onClick={() => router.push(RouterDonasi.detail_main + `${e.id}`)}
>
<Stack>
<Grid>
<Grid.Col span={7}>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={RouterDonasi.api_gambar + `${e.imagesId}`}
radius={"md"}
/>
</Paper>
</AspectRatio>
</Grid.Col>
<Grid.Col span={5}>
<Stack spacing={"xs"}>
<Text fz={"sm"} fw={"bold"} lineClamp={2}>
{e.title}
</Text>
<Progress value={50} color="orange" />
<Stack spacing={0}>
<Text fz={"sm"}>Terkumpul</Text>
<Text fz={"sm"} fw={"bold"} c={"orange"} truncate>
<TampilanRupiahDonasi nominal={+e.target} />
</Text>
<Progress value={50} color="orange" />
<Stack spacing={0}>
<Text fz={"sm"}>Terkumpul</Text>
<Text fz={"sm"} fw={"bold"} c={"orange"} truncate>
Rp. 100.000.000
</Text>
</Stack>
</Stack>
</Grid.Col>
</Grid>
{width > 575 ? "" : <Divider />}
</Stack>
</Box>
))}
</Stack>
</Grid.Col>
</Grid>
{width > 575 ? "" : <Divider />}
</Stack>
</Box>
))}
</SimpleGrid>
</>
);

View File

@@ -12,7 +12,7 @@ export default function LayoutPenggalangDanaDonasi({
return (
<>
<AppShell
header={<HeaderTamplateDonasi title="Informasu Penggalangan Dana" />}
header={<HeaderTamplateDonasi title="Informasi Penggalangan Dana" />}
// footer={<FooterDonasi />}
>
{children}

View File

@@ -22,146 +22,31 @@ import {
IconCircleChevronRight,
IconMessageChatbot,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import BoxInformasiDonasi from "../../component/box_informasi";
import { MODEL_DONASI } from "../../model/interface";
import { useState } from "react";
import ComponentDonasi_CeritaPenggalangMain from "../../component/detail_main/cerita_penggalang";
import { ComponentDonasi_DetailDataMain } from "../../component/detail_main/detail_data_donasi";
import _ from "lodash";
import ComponentDonasi_InformasiPenggalangMain from "../../component/detail_main/informasi_penggalang";
export default function DetailPublishDonasi() {
export default function DetailPublishDonasi({
dataPublish,
countDonatur
}: {
dataPublish: MODEL_DONASI;
countDonatur: number
}) {
const [donasi, setDonasi] = useState(dataPublish);
return (
<>
{/* <pre>{JSON.stringify(donasi,null,2)}</pre> */}
<Stack spacing={40}>
<DetailDonasi />
<InformasiPenggalangDana />
<CeritaPenggalangDana />
<ComponentDonasi_DetailDataMain donasi={donasi} countDonatur={countDonatur} />
<ComponentDonasi_InformasiPenggalangMain author={donasi.Author}/>
<ComponentDonasi_CeritaPenggalangMain donasi={donasi} />
</Stack>
</>
);
}
function DetailDonasi() {
const router = useRouter();
return (
<>
<Stack>
<Stack>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image alt="Foto" src={"/aset/no-img.png"} />
</Paper>
</AspectRatio>
<Title order={4}>Judul Donasi</Title>
<Stack spacing={0}>
<Group position="apart">
<Stack spacing={0}>
<Text fz={12}>Dana dibutuhkan</Text>
<Title order={4} c="blue">
Rp. 50.000.000
</Title>
</Stack>
<Text fz={"xs"}>Sisa hari <Text span inherit fw={"bold"}>100</Text> </Text>
</Group>
</Stack>
<Progress value={50} />
<Grid>
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.donatur)}
>
<Stack align="center" spacing={"xs"}>
<Group>
<IconClover color="skyblue" />
<Text>50</Text>
</Group>
<Text>Donatur</Text>
</Stack>
</Grid.Col>
<Divider orientation="vertical" />
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.kabar)}
>
<Stack spacing={"sm"} align="center">
<IconMessageChatbot color="skyblue" />
<Text>Kabar Terbaru</Text>
</Stack>
</Grid.Col>
<Divider orientation="vertical" />
<Grid.Col
span={"auto"}
onClick={() => router.push(RouterDonasi.pencairan_dana)}
>
<Stack spacing={"sm"} align="center">
<IconMoneybag color="skyblue" />
<Text>Pencairan Dana</Text>
</Stack>
</Grid.Col>
</Grid>
</Stack>
</Stack>
</>
);
}
function InformasiPenggalangDana() {
const router = useRouter();
return (
<>
<Stack spacing={"xs"}>
<Title order={4}>Informasi Penggalang Dana</Title>
<Paper p={"sm"} withBorder>
<Stack>
<Group position="apart">
<Title order={5}>Penggalang Dana</Title>
<ActionIcon
variant="transparent"
onClick={() => router.push(RouterDonasi.penggalang_dana)}
>
<IconCircleChevronRight />
</ActionIcon>
</Group>
<Group>
<Avatar radius={"xl"} variant="filled" bg={"blue"}>
U
</Avatar>
<Text>Username</Text>
</Group>
<BoxInformasiDonasi
informasi="Semua dana yang terkumpul akan disalurkan ke penggalang dana,
kabar penyaluran dapat dilihat di halaman kabar terbaru."
/>
</Stack>
</Paper>
</Stack>
</>
);
}
function CeritaPenggalangDana() {
const router = useRouter();
return (
<>
<Stack spacing={"xs"}>
<Title order={4}>Cerita Penggalang Dana</Title>
<Paper p={"sm"} withBorder>
<Stack>
<Group position="apart">
<Text>1 Des 2023</Text>
<ActionIcon
variant="transparent"
onClick={() => router.push(RouterDonasi.cerita_penggalang)}
>
<IconCircleChevronRight />
</ActionIcon>
</Group>
<Text lineClamp={4}>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat
doloremque perferendis laborum? Cupiditate sed consequatur quasi
doloremque, consequuntur libero? Vel nam esse fuga, sed et
repellat commodi nemo quia dignissimos?
</Text>
{/* <Text c={"blue"}>Baca selengkapnya</Text> */}
</Stack>
</Paper>
</Stack>
</>
);
}

View File

@@ -26,26 +26,54 @@ import {
IconMessageChatbot,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import BoxInformasiDonasi from "../../component/box_informasi";
import ComponentDonasi_NotedBox from "../../component/noted_box";
import { useAtom } from "jotai";
import { gs_donasi_tabs_posting } from "../../global_state";
import { useDisclosure } from "@mantine/hooks";
import { useState } from "react";
import { MODEL_DONASI } from "../../model/interface";
import { Donasi_funGantiStatus } from "../../fun/update/fun_ganti_status";
import { NotifBerhasil } from "../../component/notifikasi/notif_berhasil";
import { NotifGagal } from "../../component/notifikasi/notif_gagal";
import ComponentDonasi_CeritaPenggalangMain from "../../component/detail_main/cerita_penggalang";
import ComponentDonasi_DetailDataGalangDana from "../../component/detail_galang_dana/detail_data_donasi";
export default function DetailRejectDonasi() {
export default function DetailRejectDonasi({
dataReject,
}: {
dataReject: MODEL_DONASI;
}) {
const [donasi, setDonasi] = useState(dataReject);
return (
<>
<Stack spacing={"xl"}>
<AlasanPenolakan />
<DetailDonasi />
{/* <InformasiPenggalangDana /> */}
<CeritaPenggalangDana />
<ButtonAction />
<AlasanPenolakan catatan={donasi.catatan} />
<ComponentDonasi_DetailDataGalangDana donasi={donasi} />
<ComponentDonasi_CeritaPenggalangMain donasi={donasi} />
<ButtonAction donasiId={donasi.id} />
</Stack>
</>
);
}
function ButtonAction() {
function AlasanPenolakan({ catatan }: { catatan: string }) {
return (
<>
<Paper bg={"blue.1"} p={"sm"}>
<Title order={5}>Alasan penolakan</Title>
<Spoiler
maxHeight={50}
hideLabel="Sembunyikan"
showLabel="Selengkapnya"
>
{catatan}
</Spoiler>
</Paper>
</>
);
}
function ButtonAction({ donasiId }: { donasiId: string }) {
const [tabsPostingDonasi, setTabsPostingDonasi] = useAtom(
gs_donasi_tabs_posting
);
@@ -53,7 +81,14 @@ function ButtonAction() {
const [opened, { open, close }] = useDisclosure(false);
async function onCLick() {
router.push(RouterDonasi.main_galang_dana);
await Donasi_funGantiStatus(donasiId, "3").then((res) => {
if (res.status === 200) {
NotifBerhasil(res.message);
router.push(RouterDonasi.main_galang_dana);
} else {
NotifGagal(res.message);
}
});
setTabsPostingDonasi("Draft");
}
async function onDelete() {
@@ -68,19 +103,36 @@ function ButtonAction() {
bg={"orange"}
color="orange"
onClick={() => onCLick()}
compact
>
Ajukan Kembali
Edit Donasi
</Button>
<Button radius={"xl"} bg={"red"} color="red" onClick={() => open()}>
<Button
radius={"xl"}
bg={"red"}
color="red"
onClick={() => open()}
compact
>
Hapus Donasi
</Button>
</Group>
<Modal opened={opened} onClose={close} centered title="Yakin menghapus Penggalanagn Dana ini ?">
<Modal
opened={opened}
onClose={close}
centered
title="Yakin menghapus Penggalanagn Dana ini ?"
>
<Group position="center">
<Button radius={"xl"} variant="outline" onClick={close}>
Batal
</Button>
<Button radius={"xl"} variant="outline" color="red" onClick={() => onDelete()}>
<Button
radius={"xl"}
variant="outline"
color="red"
onClick={() => onDelete()}
>
Hapus
</Button>
</Group>
@@ -88,122 +140,3 @@ function ButtonAction() {
</>
);
}
function AlasanPenolakan() {
return (
<>
<Paper bg={"blue.1"} p={"sm"}>
<Title order={5}>Alasan penolakan</Title>
<Spoiler
maxHeight={50}
hideLabel="Sembunyikan"
showLabel="Selengkapnya"
>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Veniam id
explicabo accusantium consequatur natus ex nisi perferendis rem
deserunt illo exercitationem illum doloremque, maxime voluptatibus
nihil rerum provident et? Nobis.
</Spoiler>
</Paper>
</>
);
}
function DetailDonasi() {
const router = useRouter();
return (
<>
<Stack>
<Stack>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image alt="Foto" src={"/aset/no-img.png"} />
</Paper>
</AspectRatio>
<Title order={4}>Judul Donasi</Title>
<Stack spacing={0}>
<Group position="apart">
<Stack spacing={0}>
<Text fz={12}>Dana dibutuhkan</Text>
<Title order={4} c="blue">
Rp. 50.000.000
</Title>
</Stack>
<Stack spacing={0}>
<Text fz={12}>Kategori</Text>
<Title order={4} c="blue">
Kesehatan
</Title>
</Stack>
</Group>
</Stack>
</Stack>
</Stack>
</>
);
}
function InformasiPenggalangDana() {
const router = useRouter();
return (
<>
<Stack spacing={"xs"}>
<Title order={4}>Informasi Penggalang Dana</Title>
<Paper p={"sm"} withBorder>
<Stack>
<Group position="apart">
<Title order={5}>Penggalang Dana</Title>
<ActionIcon
variant="transparent"
onClick={() => router.push(RouterDonasi.penggalang_dana)}
>
<IconCircleChevronRight />
</ActionIcon>
</Group>
<Group>
<Avatar radius={"xl"} variant="filled" bg={"blue"}>
U
</Avatar>
<Text>Username</Text>
</Group>
<BoxInformasiDonasi
informasi="Semua dana yang terkumpul akan disalurkan ke penggalang dana,
kabar penyaluran dapat dilihat di halaman kabar terbaru."
/>
</Stack>
</Paper>
</Stack>
</>
);
}
function CeritaPenggalangDana() {
const router = useRouter();
return (
<>
<Stack spacing={"xs"}>
<Title order={4}>Cerita Penggalang Dana</Title>
<Paper p={"sm"} withBorder>
<Stack>
<Group position="apart">
<Text>1 Des 2023</Text>
<ActionIcon
variant="transparent"
onClick={() => router.push(RouterDonasi.cerita_penggalang)}
>
<IconCircleChevronRight />
</ActionIcon>
</Group>
<Text lineClamp={4}>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat
doloremque perferendis laborum? Cupiditate sed consequatur quasi
doloremque, consequuntur libero? Vel nam esse fuga, sed et
repellat commodi nemo quia dignissimos?
</Text>
{/* <Text c={"blue"}>Baca selengkapnya</Text> */}
</Stack>
</Paper>
</Stack>
</>
);
}

View File

@@ -24,16 +24,17 @@ import {
IconMessageChatbot,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import BoxInformasiDonasi from "../../component/box_informasi";
import ComponentDonasi_NotedBox from "../../component/noted_box";
import { useAtom } from "jotai";
import { gs_donasi_tabs_posting } from "../../global_state";
import { MODEL_DONASI } from "../../model/interface";
import { useState } from "react";
import TampilanRupiahDonasi from "../../component/tampilan_rupiah";
import ComponentCeritaPenggalangDanaDonasi from "../../component/detail_main/cerita_penggalang";
import ComponentDonasi_CeritaPenggalangMain from "../../component/detail_main/cerita_penggalang";
import { Donasi_funGantiStatus } from "../../fun/update/fun_ganti_status";
import { NotifPeringatan } from "../../component/notifikasi/notif_peringatan";
import { NotifBerhasil } from "../../component/notifikasi/notif_berhasil";
import ComponentDonasi_DetailDataGalangDana from "../../component/detail_galang_dana/detail_data_donasi";
export default function DetailReviewDonasi({
dataDonasi,
@@ -44,14 +45,13 @@ export default function DetailReviewDonasi({
return (
<>
<Stack spacing={"xl"}>
<DetailDonasi donasi={donasi} />
<ComponentCeritaPenggalangDanaDonasi donasi={donasi} />
<ComponentDonasi_DetailDataGalangDana donasi={donasi} />
<ComponentDonasi_CeritaPenggalangMain donasi={donasi} />
<ButtonBatalReview donasi={donasi} />
</Stack>
</>
);
}
function ButtonBatalReview({ donasi }: { donasi: MODEL_DONASI }) {
const router = useRouter();
const [tabsPostingDonasi, setTabsPostingDonasi] = useAtom(
@@ -78,44 +78,4 @@ function ButtonBatalReview({ donasi }: { donasi: MODEL_DONASI }) {
);
}
function DetailDonasi({ donasi }: { donasi: MODEL_DONASI }) {
const router = useRouter();
return (
<>
<Stack>
<Stack>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={RouterDonasi.api_gambar + `${donasi.imagesId}`}
/>
</Paper>
</AspectRatio>
<Stack spacing={0}>
<Title order={4}>{donasi.title}</Title>
<Text fz={"xs"}>
Durasi: {donasi.DonasiMaster_Durasi.name} hari
</Text>
</Stack>
<Stack spacing={0}>
<Group position="apart">
<Stack spacing={0}>
<Text fz={12}>Dana dibutuhkan</Text>
<Title order={4} c="blue">
<TampilanRupiahDonasi nominal={+donasi.target} />
</Title>
</Stack>
<Stack spacing={0}>
<Text fz={12}>Kategori</Text>
<Title order={4} c="blue">
{donasi.DonasiMaster_Ketegori.name}
</Title>
</Stack>
</Group>
</Stack>
</Stack>
</Stack>
</>
);
}

View File

@@ -0,0 +1,16 @@
"use server"
import prisma from "@/app/lib/prisma"
export async function Donasi_getCountDonatur(donasiId: string) {
const donatur = await prisma.donasi_Invoice.count({
where: {
donasiId: donasiId,
donasiMaster_StatusInvoiceId: {
equals: "1"
}
}
});
return donatur
}

View File

@@ -0,0 +1,23 @@
"use server";
import prisma from "@/app/lib/prisma";
import { revalidatePath } from "next/cache";
export async function Donasi_funCreateInvoice(data: any) {
const res = await prisma.donasi_Invoice.create({
data: {
donasiId: data.donasiId,
nominal: data.nominal,
donasiMaster_BankId: data.donasiMaster_BankId,
authorId: data.authorId
},
});
if (!res) return { status: 400, message: "Gagal membuat invoice" };
revalidatePath("/dev/donasi/main/donasi_saya")
return {
status: 200,
message: "Berhasil membuat invoice",
invoiceId: res.id
};
}

View File

@@ -0,0 +1,47 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function Donasi_getAuthorById(authorId: string) {
// console.log(authorId);
const data = await prisma.user.findFirst({
where: {
id: authorId,
},
select: {
id: true,
username: true,
nomor: true,
Donasi: {
where: {
donasiMaster_StatusDonasiId: "1",
},
select: {
id: true,
title: true,
target: true,
active: true,
createdAt: true,
updatedAt: true,
publishTime: true,
catatan: true,
authorId: true,
progres: true,
terkumpul: true,
imagesId: true,
donasiMaster_KategoriId: true,
donasiMaster_DurasiId: true,
donasiMaster_StatusDonasiId: true,
Author: true,
imageDonasi: true,
CeritaDonasi: true,
DonasiMaster_Ketegori: true,
DonasiMaster_Durasi: true,
DonasiMaster_Status: true,
},
},
},
});
return data;
}

View File

@@ -12,6 +12,7 @@ export default async function Donasi_getCeritaByDonasiId(donasiId: string) {
pembukaan: true,
cerita: true,
imageCeritaDonasi: true,
createdAt: true,
},
});
return data;

View File

@@ -18,6 +18,16 @@ export default async function Donasi_getByStatus(
authorId: authorId,
donasiMaster_StatusDonasiId: "1",
},
select: {
id: true,
title: true,
imagesId: true,
target: true,
publishTime: true,
DonasiMaster_Durasi: true,
terkumpul: true,
}
});
return getReview;
}
@@ -48,7 +58,19 @@ export default async function Donasi_getByStatus(
authorId: authorId,
donasiMaster_StatusDonasiId: "4",
},
select: {
id: true,
title: true,
imagesId: true,
target: true,
publishTime: true,
DonasiMaster_Durasi: true,
catatan: true,
}
});
return getReview;
}

View File

@@ -0,0 +1,40 @@
"use server";
import prisma from "@/app/lib/prisma";
import { tree } from "next/dist/build/templates/app-page";
export async function Donasi_getListBeranda() {
const data = await prisma.donasi.findMany({
orderBy: {
publishTime: "desc",
},
where: {
donasiMaster_StatusDonasiId: "1",
},
select: {
id: true,
title: true,
target: true,
active: true,
createdAt: true,
updatedAt: true,
publishTime: true,
catatan: true,
progres: true,
terkumpul: true,
authorId: true,
imagesId: true,
donasiMaster_KategoriId: true,
donasiMaster_DurasiId: true,
donasiMaster_StatusDonasiId: true,
Author: true,
imageDonasi: true,
CeritaDonasi: true,
DonasiMaster_Ketegori: true,
DonasiMaster_Durasi: true,
DonasiMaster_Status: true,
},
});
return data;
}

View File

@@ -0,0 +1,41 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function Donasi_getInvoiceByAuthorId(authorId: string) {
// console.log(authorId)
const data = await prisma.donasi_Invoice.findMany({
orderBy: {
createdAt: "desc"
},
where: {
authorId: authorId,
},
select: {
id: true,
nominal: true,
DonasiMaster_StatusInvoice: true,
donasiMaster_StatusInvoiceId: true,
Donasi: {
select: {
id: true,
title: true,
target: true,
progres: true,
authorId: true,
imagesId: true,
publishTime: true,
donasiMaster_KategoriId: true,
donasiMaster_DurasiId: true,
donasiMaster_StatusDonasiId: true,
imageDonasi: true,
DonasiMaster_Ketegori: true,
DonasiMaster_Durasi: true,
DonasiMaster_Status: true,
},
},
},
});
return data;
}

View File

@@ -0,0 +1,17 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function Donasi_getNamaBank(bankId: string) {
const data = await prisma.donasiMaster_Bank.findFirst({
where: {
id: bankId,
},
select: {
name: true,
norek: true,
},
});
return data;
}

View File

@@ -15,7 +15,10 @@ export async function Donasi_getOneById(donasiId: string) {
createdAt: true,
updatedAt: true,
publishTime: true,
catatan: true,
authorId: true,
progres: true,
terkumpul: true,
imagesId: true,
donasiMaster_KategoriId: true,
donasiMaster_DurasiId: true,

View File

@@ -0,0 +1,47 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function Donasi_getOneInvoiceById(invoiceId: string) {
const res = await prisma.donasi_Invoice.findFirst({
where: {
id: invoiceId,
},
select: {
id: true,
nominal: true,
donasiId: true,
donasiMaster_BankId: true,
donasiMaster_StatusInvoiceId: true,
Donasi: {
select: {
id: true,
title: true,
target: true,
active: true,
createdAt: true,
updatedAt: true,
publishTime: true,
catatan: true,
progres: true,
terkumpul: true,
authorId: true,
imagesId: true,
donasiMaster_KategoriId: true,
donasiMaster_DurasiId: true,
donasiMaster_StatusDonasiId: true,
Author: true,
imageDonasi: true,
CeritaDonasi: true,
DonasiMaster_Ketegori: true,
DonasiMaster_Durasi: true,
DonasiMaster_Status: true,
}
},
DonasiMaster_Bank: true,
DonasiMaster_StatusInvoice: true,
},
});
return res
}

View File

@@ -0,0 +1,8 @@
"use server"
import prisma from "@/app/lib/prisma"
export async function Donasi_getMasterBank() {
const data = await prisma.donasiMaster_Bank.findMany({})
return data
}

View File

@@ -4,6 +4,13 @@ import prisma from "@/app/lib/prisma";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { revalidatePath } from "next/cache";
/**
*
* @param donasiId | string
* @param statusId | string | 1 - 4
* @tutorial id_and_statusName | Publish "1", Review "2, Draft "3", Reject "4"
* @returns ganti status donasi
*/
export async function Donasi_funGantiStatus(
donasiId: string,
statusId: string

View File

@@ -0,0 +1,28 @@
"use server";
import prisma from "@/app/lib/prisma";
import { revalidatePath } from "next/cache";
export async function Donasi_funUpdateStatusInvoice(
invoiceId: string,
statusId: string
) {
// console.log(invoiceId, "invoice Id");
// console.log(status, "status");
const data = await prisma.donasi_Invoice.update({
where: {
id: invoiceId
},
data: {
donasiMaster_StatusInvoiceId: statusId
}
})
if(!data) return {status: 400, message: "Gagal memperbarui status transaksi"}
revalidatePath("dev/admin/donasi/detail/publish")
return {
status: 200,
message: "Berhasil memperbarui status transaksi",
}
}

View File

@@ -15,3 +15,9 @@ export const gs_donasi_tabs_posting = atomWithStorage<string | null>(
"gs_donasi_tabs_posting",
"Publish"
);
export const gs_proses_donasi = atomWithStorage("gs_nomi", {
nominal: "",
bank: "",
norek: "",
});

View File

@@ -7,8 +7,8 @@ import LayoutCreateDonasi from "./create/layout";
import PagePopUpCreateDonasi from "./page_pop_up/create";
import DetailMainDonasi from "./detail/detail_main";
import LayoutDetailMainDonasi from "./detail/detail_main/layout";
import MasukanDonasi from "./detail/detail_main/masukan_donasi";
import LayoutMasukanDonasi from "./detail/detail_main/masukan_donasi/layout";
import MasukanDonasi from "./proses_donasi/masukan_donasi";
import LayoutMasukanDonasi from "./proses_donasi/masukan_donasi/layout";
import DonaturDonasi from "./detail/detail_main/donatur";
import LayoutDonaturDonasi from "./detail/detail_main/donatur/layout";
import KabarDonasi from "./detail/detail_main/kabar";
@@ -40,6 +40,12 @@ import EditCeritaPenggalangDonasi from "./edit/edit_cerita_penggalang";
import LayoutEditCeritaPenggalangDonasi from "./edit/edit_cerita_penggalang/layout";
import DetailDonasiSaya from "./detail/detail_donasi_saya";
import LayoutDetailDonasiSaya from "./detail/detail_donasi_saya/layout";
import Donasi_MetodePembayaran from "./proses_donasi/metode_pembayaran";
import LayoutDonasi_MetodePembayaran from "./proses_donasi/metode_pembayaran/layout";
import Donasi_InvoiceProses from "./proses_donasi/invoice";
import LayoutDonasi_InvoiceProses from "./proses_donasi/invoice/layout";
import Donasi_ProsesTransaksi from "./proses_donasi/proses_transaksi";
import LayoutDonasi_ProsesTransaksi from "./proses_donasi/proses_transaksi/layout";
export {
MainDonasi,
@@ -84,4 +90,10 @@ export {
LayoutEditCeritaPenggalangDonasi,
DetailDonasiSaya,
LayoutDetailDonasiSaya,
Donasi_MetodePembayaran,
LayoutDonasi_MetodePembayaran,
Donasi_InvoiceProses,
LayoutDonasi_InvoiceProses,
Donasi_ProsesTransaksi,
LayoutDonasi_ProsesTransaksi,
};

View File

@@ -24,59 +24,19 @@ import {
} from "@mantine/core";
import { useViewportSize } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { MODEL_DONASI } from "../model/interface";
import { useState } from "react";
import ComponentDonasi_BoxPublish from "../component/box_publish";
export default function MainDonasi() {
const router = useRouter();
const { height, width } = useViewportSize();
export default function MainDonasi({
listDonasi,
}: {
listDonasi: MODEL_DONASI[];
}) {
return (
<>
<SimpleGrid
cols={4}
spacing="lg"
breakpoints={[
{ maxWidth: "62rem", cols: 3, spacing: "md" },
{ maxWidth: "48rem", cols: 2, spacing: "sm" },
{ maxWidth: "36rem", cols: 1, spacing: "sm" },
]}
>
{Array(5)
.fill(0)
.map((e, i) => (
<Box key={i} onClick={() => router.push(RouterDonasi.detail_main)}>
<Stack>
<Grid>
<Grid.Col span={7}>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={"/aset/no-img.png"}
radius={"md"}
/>
</Paper>
</AspectRatio>
</Grid.Col>
<Grid.Col span={5}>
<Stack spacing={"xs"}>
<Text fz={"sm"} fw={"bold"} lineClamp={2}>
Judul Donasi Bisa Dilihat Disini Untuk Contoh
</Text>
<Progress value={50} color="orange" />
<Stack spacing={0}>
<Text fz={"sm"}>Terkumpul</Text>
<Text fz={"sm"} fw={"bold"} c={"orange"} truncate>
Rp. 100.000.000
</Text>
</Stack>
</Stack>
</Grid.Col>
</Grid>
{width > 575 ? "" : <Divider />}
</Stack>
</Box>
))}
</SimpleGrid>
<ComponentDonasi_BoxPublish dataDonasi={listDonasi} path={RouterDonasi.detail_main}/>
</>
);
}

View File

@@ -22,12 +22,29 @@ import {
} from "@mantine/core";
import { useViewportSize } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { MODEL_DONASI_INVOICE } from "../model/interface";
import { useState } from "react";
import TampilanRupiahDonasi from "../component/tampilan_rupiah";
import ComponentDonasi_TampilanHitungMundur from "../component/tampilan_hitung_mundur";
import moment from "moment";
import toast from "react-simple-toasts";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import _ from "lodash";
export default function DonasiSayaDonasi() {
export default function DonasiSayaDonasi({
listInvoice,
}: {
listInvoice: MODEL_DONASI_INVOICE[];
}) {
const [invoice, setInvoice] = useState(listInvoice);
const router = useRouter();
const { height, width } = useViewportSize();
if (_.isEmpty(invoice))
return (
<>
<Center h={"80vh"}>Belum Ada Donasi</Center>
</>
);
return (
<>
<SimpleGrid
@@ -39,49 +56,103 @@ export default function DonasiSayaDonasi() {
{ maxWidth: "36rem", cols: 1, spacing: "sm" },
]}
>
{Array(5)
.fill(0)
.map((e, i) => (
<Box
key={i}
onClick={() =>
router.push(RouterDonasi.detail_donasi_saya)
}
>
<Stack>
<Grid>
<Grid.Col span={5}>
<Stack spacing={"xs"}>
<Text fz={"sm"} fw={"bold"} lineClamp={2}>
Judul Donasi Bisa Dilihat Disini Untuk Contoh
{invoice.map((e, i) => (
<Box
key={i}
onClick={() =>
onClick(router, e.donasiMaster_StatusInvoiceId, e.id, e.Donasi.id)
}
>
<Stack>
<Grid>
<Grid.Col span={5}>
<Stack spacing={5}>
<Stack spacing={0}>
<Text fz={"xs"} fw={"bold"} truncate>
{e.Donasi.title}
</Text>
<Progress value={50} color="orange" />
<ComponentDonasi_TampilanHitungMundur
durasi={e.Donasi.DonasiMaster_Durasi.name}
publishTime={e.Donasi.publishTime}
textSize={10}
/>
</Stack>
<Progress value={+e.Donasi.progres} color="orange" />
<Group position="apart">
<Stack spacing={0}>
<Text fz={"sm"}>Donasi Saya</Text>
<Text fz={"sm"} fw={"bold"} c={"orange"} truncate>
Rp. 25.000.000
<Text fz={10}>Donasi Saya</Text>
<Text fz={10} fw={"bold"} c={"orange"} truncate>
<TampilanRupiahDonasi nominal={+e.nominal} />
</Text>
</Stack>
</Stack>
</Grid.Col>
<Grid.Col span={7}>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={"/aset/no-img.png"}
radius={"md"}
/>
</Paper>
</AspectRatio>
</Grid.Col>
</Grid>
{width > 575 ? "" : <Divider />}
</Stack>
</Box>
))}
</Group>
<Badge size="xs" variant="dot">
<Text>{e.DonasiMaster_StatusInvoice.name}</Text>
</Badge>
</Stack>
</Grid.Col>
<Grid.Col span={7}>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={RouterDonasi.api_gambar + `${e.Donasi.imagesId}`}
radius={"md"}
/>
</Paper>
</AspectRatio>
</Grid.Col>
</Grid>
{width > 575 ? "" : <Divider />}
</Stack>
</Box>
))}
</SimpleGrid>
</>
);
}
function HitungMundur({
durasi,
publishTime,
}: {
durasi: string;
publishTime: Date;
}) {
return (
<>
<Stack spacing={0} align="center">
<Text fz={"xs"}>Sisa hari </Text>
<Text span inherit fw={"bold"} fz={"xs"}>
{Number(durasi) -
moment(new Date()).diff(new Date(publishTime), "days") <=
0
? 0
: Number(durasi) -
moment(new Date()).diff(new Date(publishTime), "days")}
</Text>
</Stack>
</>
);
}
async function onClick(
router: AppRouterInstance,
status: string,
invoiceId: string,
donasiId: string
) {
if (status === "1") {
return router.push(RouterDonasi.detail_donasi_saya + `${invoiceId}`);
} else {
if (status === "2") {
return router.push(RouterDonasi.proses_transaksi + `${invoiceId}`);
} else {
if (status === "3") {
return router.push(RouterDonasi.invoice + `${invoiceId}`);
} else {
toast("gagal");
}
}
}
}

View File

@@ -23,7 +23,17 @@ import { Warna } from "@/app/lib/warna";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import PostingDraftDonasi from "./galang_dana/draft";
export default function GalangDanaDonasi({listReview, listDraft}: {listReview: any, listDraft: any}) {
export default function GalangDanaDonasi({
listPublish,
listReview,
listDraft,
listReject
}: {
listPublish: any;
listReview: any;
listDraft: any;
listReject: any
}) {
const router = useRouter();
const [tabsPostingDonasi, setTabsPostingDonasi] = useAtom(
gs_donasi_tabs_posting
@@ -33,7 +43,7 @@ export default function GalangDanaDonasi({listReview, listDraft}: {listReview: a
{
id: 1,
value: "Publish",
path: <PostingPublishDonasi data={"1"} />,
path: <PostingPublishDonasi listPublish={listPublish} />,
color: "green",
},
{
@@ -51,7 +61,7 @@ export default function GalangDanaDonasi({listReview, listDraft}: {listReview: a
{
id: 4,
value: "Reject",
path: <PostingRejectDonasi data={"4"} />,
path: <PostingRejectDonasi listReject={listReject} />,
color: "red",
},
];
@@ -69,7 +79,7 @@ export default function GalangDanaDonasi({listReview, listDraft}: {listReview: a
Galang Dana
</Button>
</Affix>
<Stack >
<Stack>
<Tabs
color="orange"
variant="pills"
@@ -79,27 +89,27 @@ export default function GalangDanaDonasi({listReview, listDraft}: {listReview: a
onTabChange={setTabsPostingDonasi}
>
<Stack>
<Tabs.List grow>
{listPosting.map((e, i) => (
<Tabs.Tab
key={e.id}
value={e.value}
bg={tabsPostingDonasi === e.value ? e.color : "gray.1"}
>
<Text
c={tabsPostingDonasi === e.value ? "white" : "gray"}
fw={tabsPostingDonasi === e.value ? 900 : "normal"}
<Tabs.List grow>
{listPosting.map((e, i) => (
<Tabs.Tab
key={e.id}
value={e.value}
bg={tabsPostingDonasi === e.value ? e.color : "gray.1"}
>
{e.value}
</Text>
</Tabs.Tab>
<Text
c={tabsPostingDonasi === e.value ? "white" : "gray"}
fw={tabsPostingDonasi === e.value ? 900 : "normal"}
>
{e.value}
</Text>
</Tabs.Tab>
))}
</Tabs.List>
{listPosting.map((e, i) => (
<Tabs.Panel key={e.id} value={e.value} pt="xs">
{e.path}
</Tabs.Panel>
))}
</Tabs.List>
{listPosting.map((e, i) => (
<Tabs.Panel key={e.id} value={e.value} pt="xs">
{e.path}
</Tabs.Panel>
))}
</Stack>
</Tabs>
</Stack>

View File

@@ -21,64 +21,20 @@ import {
import { useViewportSize } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import toast from "react-simple-toasts";
import { MODEL_DONASI } from "../../model/interface";
import { useState } from "react";
import TampilanRupiahDonasi from "../../component/tampilan_rupiah";
import ComponentDonasi_TampilanHitungMundur from "../../component/tampilan_hitung_mundur";
import ComponentDonasi_BoxPublish from "../../component/box_publish";
export default function PostingPublishDonasi({ data }: { data: any }) {
const router = useRouter();
const { height, width } = useViewportSize();
export default function PostingPublishDonasi({
listPublish,
}: {
listPublish: MODEL_DONASI[];
}) {
return (
<>
<SimpleGrid
cols={4}
spacing="lg"
breakpoints={[
{ maxWidth: "62rem", cols: 3, spacing: "md" },
{ maxWidth: "48rem", cols: 2, spacing: "sm" },
{ maxWidth: "36rem", cols: 1, spacing: "sm" },
]}
>
{Array(5)
.fill(0)
.map((e, i) => (
<Box
key={i}
onClick={() =>
router.push(RouterDonasi.detail_publish)
// toast("Cooming soon")
}
>
<Stack>
<Grid>
<Grid.Col span={7}>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={"/aset/no-img.png"}
radius={"md"}
/>
</Paper>
</AspectRatio>
</Grid.Col>
<Grid.Col span={5}>
<Stack spacing={"xs"}>
<Text fz={"sm"} fw={"bold"} lineClamp={2}>
Judul Donasi Bisa Dilihat Disini Untuk Contoh
</Text>
<Progress value={50} color="orange" />
<Stack spacing={0}>
<Text fz={"sm"}>Terkumpul</Text>
<Text fz={"sm"} fw={"bold"} c={"orange"} truncate>
Rp. 100.000.000
</Text>
</Stack>
</Stack>
</Grid.Col>
</Grid>
{width > 575 ? "" : <Divider />}
</Stack>
</Box>
))}
</SimpleGrid>
<ComponentDonasi_BoxPublish dataDonasi={listPublish} path={RouterDonasi.detail_publish} />
</>
);
}

View File

@@ -19,15 +19,19 @@ import {
import { useViewportSize } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import toast from "react-simple-toasts";
import { MODEL_DONASI } from "../../model/interface";
import { useState } from "react";
export default function PostingRejectDonasi({ data }: { data: any }) {
export default function PostingRejectDonasi({
listReject,
}: {
listReject: MODEL_DONASI[];
}) {
const { height, width } = useViewportSize();
const router = useRouter()
const router = useRouter();
const [donasi, setDonasi] = useState(listReject)
return (
<>
<SimpleGrid
cols={4}
spacing="lg"
@@ -37,45 +41,44 @@ export default function PostingRejectDonasi({ data }: { data: any }) {
{ maxWidth: "36rem", cols: 1, spacing: "sm" },
]}
>
{Array(5)
.fill(0)
{donasi
.map((e, i) => (
<Box
key={i}
onClick={() =>
router.push(RouterDonasi.detail_reject)
}
>
<Stack>
<Grid>
<Grid.Col span={7}>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image alt="Foto" src={"/aset/no-img.png"} radius={"md"} />
</Paper>
</AspectRatio>
</Grid.Col>
<Grid.Col span={5}>
<Stack spacing={"xs"}>
<Text fz={"sm"} fw={"bold"} lineClamp={2}>
Judul Donasi Bisa Dilihat Disini Untuk Contoh
</Text>
<Stack spacing={0}>
<Text fz={"sm"} fw={"bold"}>Alasan ditolak</Text>
<Text fz={"sm"} lineClamp={2}>
Lorem ipsum dolor, sit amet consectetur adipisicing elit.
Expedita inventore rem iure praesentium delectus consectetur
alias, veniam, fugit in ab esse recusandae mollitia quasi
perferendis tenetur suscipit architecto saepe! Animi.
key={i}
onClick={() => router.push(RouterDonasi.detail_reject + `${e.id}`)}
>
<Stack>
<Grid>
<Grid.Col span={7}>
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
<Image
alt="Foto"
src={RouterDonasi.api_gambar + `${e.imagesId}`}
radius={"md"}
/>
</Paper>
</AspectRatio>
</Grid.Col>
<Grid.Col span={5}>
<Stack spacing={"xs"}>
<Text fz={"sm"} fw={"bold"} lineClamp={2}>
{e.title}
</Text>
<Stack spacing={0}>
<Text fz={"sm"} fw={"bold"}>
Alasan ditolak
</Text>
<Text fz={"sm"} lineClamp={2}>
{e.catatan}
</Text>
</Stack>
</Stack>
</Stack>
</Grid.Col>
</Grid>
{width > 575 ? "" : <Divider />}
</Stack>
</Box>
</Grid.Col>
</Grid>
{width > 575 ? "" : <Divider />}
</Stack>
</Box>
))}
</SimpleGrid>
</>

View File

@@ -1,4 +1,5 @@
import { MODEL_AUTHOR } from "@/app_modules/home/models/interface";
import { Model_Nama_Bank } from "@/app_modules/investasi/model/model_investasi";
import { MODEL_IMAGES } from "@/app_modules/models/interface";
export interface MODEL_DONASI {
@@ -10,7 +11,9 @@ export interface MODEL_DONASI {
updatedAt: Date;
imagesId: string;
publishTime: Date;
catatan: string,
catatan: string;
progres: string;
terkumpul: string
authorId: string;
donasiMaster_KategoriId: string;
donasiMaster_DurasiId: string;
@@ -31,8 +34,8 @@ export interface MODEL_CERITA_DONASI {
createdAt: Date;
updatedAt: Date;
imagesId: string;
imageCeritaDonasi: MODEL_IMAGES
donasiId: string
imageCeritaDonasi: MODEL_IMAGES;
donasiId: string;
}
export interface MODEL_DONASI_ALL_MASTER {
@@ -54,3 +57,43 @@ export interface MODEL_DONASI_TEMPORARY {
donasiMaster_KategoriId: string;
donasiMaster_DurasiId: string;
}
export interface MODEL_DONASI_INFO_PENGGALANG {
id: string;
username: string;
nomor: string;
Donasi: MODEL_DONASI[];
}
export interface MODEL_DONASI_INVOICE {
id: string;
nominal: string;
donasiId: string;
active: boolean;
createdAt: Date;
updatedAt: Date;
Author: MODEL_AUTHOR
authorId: string
donasiMaster_BankId: string;
donasiMaster_StatusInvoiceId: string;
Donasi: MODEL_DONASI;
DonasiMaster_Bank: MODEL_DONASI_NAMA_BANK;
DonasiMaster_StatusInvoice: MODEL_DONASI_ALL_MASTER;
}
export interface MODEL_DONASI_NAMA_BANK {
id: string;
name: string;
norek: string;
active: boolean;
createdAt: Date;
updatedAt: Date;
}
export interface MODEL_DONASI_ALL_MASTER {
id: string;
name: string;
active: boolean;
createdAt: Date;
updatedAt: Date;
}

View File

@@ -0,0 +1,168 @@
"use client";
import {
Box,
Button,
Center,
CopyButton,
Grid,
Group,
Paper,
Stack,
Text,
Title,
} from "@mantine/core";
import { useAtom } from "jotai";
import { gs_proses_donasi } from "../../global_state";
import { MODEL_DONASI, MODEL_DONASI_INVOICE } from "../../model/interface";
import { useState } from "react";
import TampilanRupiahDonasi from "../../component/tampilan_rupiah";
import ComponentDonasi_TampilanHitungMundur from "../../component/tampilan_hitung_mundur";
import { useRouter } from "next/navigation";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { Donasi_funUpdateStatusInvoice } from "../../fun/update/fun_update_status_invoice";
import { NotifBerhasil } from "../../component/notifikasi/notif_berhasil";
import { NotifGagal } from "../../component/notifikasi/notif_gagal";
export default function Donasi_InvoiceProses({
dataInvoice,
}: {
dataInvoice: MODEL_DONASI_INVOICE;
}) {
const [invoice, setDataInvoice] = useState(dataInvoice);
const router = useRouter();
return (
<>
<Stack spacing={"lg"}>
<Stack spacing={0}>
<Title order={5}>Mohon transfer ke rekening dibawah</Title>
<Group spacing={"xs"}>
<Text>untuk diteruskan ke </Text>
<Text fw={"bold"}>{invoice.Donasi.Author.username}</Text>
</Group>
</Stack>
<Paper p={"sm"} withBorder>
<Stack spacing={"md"}>
<Stack spacing={0}>
<Text>Bank {invoice.DonasiMaster_Bank.name}</Text>
<Text>PT. Himpunan Pengusaha Badung</Text>
</Stack>
<Paper bg={"gray.1"} p={"sm"} radius={"md"}>
<Grid>
<Grid.Col span={8}>
<Group position="left" align="center" h={"100%"}>
<Title order={4}>{invoice.DonasiMaster_Bank.norek}</Title>
</Group>
</Grid.Col>
<Grid.Col span={4}>
<Group position="right">
<CopyButton value={invoice.DonasiMaster_Bank.norek}>
{({ copied, copy }) => (
<Button
color={copied ? "teal" : "blue"}
variant="outline"
radius={"xl"}
onClick={copy}
>
{copied ? "Berhasil" : "Salin"}
</Button>
)}
</CopyButton>
</Group>
</Grid.Col>
</Grid>
</Paper>
</Stack>
</Paper>
<Paper p={"sm"} withBorder>
<Stack spacing={"md"}>
<Stack spacing={0}>
<Text>Jumlah transfer</Text>
</Stack>
<Paper bg={"gray.1"} p={"sm"} radius={"md"}>
<Grid>
<Grid.Col span={8}>
<Group position="left" align="center" h={"100%"}>
<Title order={4}>
<TampilanRupiahDonasi
nominal={+(+invoice.nominal + 2500)}
/>
</Title>
</Group>
</Grid.Col>
<Grid.Col span={4}>
<Group position="right">
<CopyButton value={"" + (+invoice.nominal + 2500)}>
{({ copied, copy }) => (
<Button
color={copied ? "teal" : "blue"}
variant="outline"
radius={"xl"}
onClick={copy}
>
{copied ? "Berhasil" : "Salin"}
</Button>
)}
</CopyButton>
</Group>
</Grid.Col>
</Grid>
</Paper>
<Text fz={"xs"} c={"gray"}>
Sudah termasuk biaya admin Rp. 2.500,-
</Text>
</Stack>
</Paper>
<Paper p={"sm"} withBorder>
<Stack>
<Text>Detail donasi</Text>
<Paper p={"md"} bg={"gray.2"}>
<Stack spacing={"lg"}>
<Stack spacing={"xs"}>
<Title order={4}>{invoice.Donasi.title}</Title>
<Stack spacing={0}>
<Group spacing={5}>
<Text>Kategori</Text>
<Title order={5}>
{invoice.Donasi.DonasiMaster_Ketegori.name}
</Title>
</Group>
<ComponentDonasi_TampilanHitungMundur
durasi={invoice.Donasi.DonasiMaster_Durasi.name}
publishTime={invoice.Donasi.publishTime}
textSize={16}
/>
</Stack>
</Stack>
</Stack>
</Paper>
</Stack>
</Paper>
<Button
radius={"xl"}
bg={"orange"}
color="orange"
onClick={() => onClick(router, invoice.id)}
>
Saya Sudah Transfer
</Button>
</Stack>
</>
);
}
async function onClick(router: AppRouterInstance, invoiceId: string) {
await Donasi_funUpdateStatusInvoice(invoiceId, "2").then((res) => {
if (res.status === 200) {
NotifBerhasil(res.message);
router.push(RouterDonasi.proses_transaksi + `${invoiceId}`);
} else {
NotifGagal(res.message);
}
});
}

View File

@@ -0,0 +1,44 @@
"use client";
import { ActionIcon, AppShell, Group, Header, Title } from "@mantine/core";
import React from "react";
import HeaderTamplateDonasi from "../../component/header_tamplate";
import { IconChevronLeft, IconX } from "@tabler/icons-react";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { gs_donasi_hot_menu } from "../../global_state";
import { useAtom } from "jotai";
import { title } from "process";
import { useRouter } from "next/navigation";
export default function LayoutDonasi_InvoiceProses({
children,
}: {
children: React.ReactNode;
}) {
const router = useRouter();
const [donasiHotMenu, setDonasiHotMenu] = useAtom(gs_donasi_hot_menu);
async function onClick() {
setDonasiHotMenu(2);
router.push(RouterDonasi.main_donasi_saya);
}
return (
<>
<AppShell
header={
<Header height={50} sx={{ borderStyle: "none" }}>
<Group h={50} position="apart" px={"md"}>
<ActionIcon variant="transparent" onClick={() => onClick()}>
<IconX />
</ActionIcon>
<Title order={5}>Invoice</Title>
<ActionIcon disabled variant="transparent"></ActionIcon>
</Group>
</Header>
}
>
{children}
</AppShell>
</>
);
}

View File

@@ -0,0 +1,123 @@
"use client";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import {
Box,
Button,
Grid,
Group,
NumberInput,
Paper,
Stack,
Text,
TextInput,
Title,
} from "@mantine/core";
import {
IconChevronRight,
IconMoodSmile,
IconMoodSmileBeam,
IconMoodSmileDizzy,
IconMoodXd,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { NotifPeringatan } from "../../component/notifikasi/notif_peringatan";
import { useAtom } from "jotai";
import { gs_proses_donasi } from "../../global_state";
const listNominal = [
{
id: 1,
jumlah: 25000,
icon: <IconMoodSmile />,
},
{
id: 2,
jumlah: 50000,
icon: <IconMoodSmileBeam />,
},
{
id: 3,
jumlah: 75000,
icon: <IconMoodSmileDizzy />,
},
{
id: 4,
jumlah: 100000,
icon: <IconMoodXd />,
},
];
export default function MasukanDonasi({ donasiId }: { donasiId: string }) {
const router = useRouter();
const [nominal, setNominal] = useState(0);
const [prosesDonasi, setProsesDonasi] = useAtom(gs_proses_donasi);
async function onProses(nominal: number) {
if (nominal === 0) return NotifPeringatan("Masukan Nominal");
if (nominal < 10000)
return NotifPeringatan("Mohon maaf, Minimal donasi Rp. 10.000");
setProsesDonasi({
...prosesDonasi,
nominal: "" + nominal,
});
router.push(RouterDonasi.metode_pembayaran + `${donasiId}`);
}
return (
<>
<Stack>
<Box>
{listNominal.map((e) => (
<Paper
key={e.id}
withBorder
radius={"md"}
p={"sm"}
shadow="lg"
mb={"md"}
onClick={() => onProses(e.jumlah)}
>
<Group position="apart">
<Group>
{e.icon}
<Title order={4}>
Rp.{" "}
{new Intl.NumberFormat("id-ID", {
maximumFractionDigits: 10,
}).format(e.jumlah)}
</Title>
</Group>
<IconChevronRight />
</Group>
</Paper>
))}
</Box>
<Paper p={"sm"} withBorder shadow="lg">
<Stack>
<Text>Nominal Lainnya</Text>
<Grid>
<Grid.Col span={1}>
<Title order={4}>Rp.</Title>
</Grid.Col>
<Grid.Col span={11}>
<NumberInput
min={0}
type="number"
onChange={(val: number) => setNominal(val)}
/>
</Grid.Col>
</Grid>
<Text c={"gray"} fz={"xs"}>
Minimal Donasi Rp. 10.000
</Text>
</Stack>
</Paper>
<Button radius={"xl"} onClick={() => onProses(nominal)}>
Lanjutan Pembayaran
</Button>
</Stack>
</>
);
}

View File

@@ -2,7 +2,7 @@
import { AppShell } from "@mantine/core";
import React from "react";
import HeaderTamplateDonasi from "../../../component/header_tamplate";
import HeaderTamplateDonasi from "../../component/header_tamplate";
export default function LayoutMasukanDonasi({
children,

View File

@@ -0,0 +1,103 @@
"use client";
import { useAtom } from "jotai";
import { gs_proses_donasi } from "../../global_state";
import { Box, Button, Group, Paper, Radio, Stack, Title } from "@mantine/core";
import { IconChevronRight } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { useState } from "react";
import { Model_Nama_Bank } from "@/app_modules/investasi/model/model_investasi";
import { Donasi_getNamaBank } from "../../fun/get/get_nama_bank";
import { Donasi_funCreateInvoice } from "../../fun/create/fun_create_invoice";
import { NotifBerhasil } from "../../component/notifikasi/notif_berhasil";
import { NotifGagal } from "../../component/notifikasi/notif_gagal";
const listBank = [
{
id: "1",
norek: "345678765",
bank: "BCA",
},
{
id: "2",
norek: "4565435",
bank: "BRI",
},
{
id: "3",
norek: "423533424565",
bank: "BNI",
},
{
id: "4",
norek: "8765423",
bank: "MANDIRI",
},
];
export default function Donasi_MetodePembayaran({
listBank,
donasiId,
authorId
}: {
listBank: Model_Nama_Bank[];
donasiId: string;
authorId: string
}) {
const router = useRouter();
const [prosesDonasi, setProsesDonasi] = useAtom(gs_proses_donasi);
const [pilihBank, setPilihBank] = useState("1");
const [bank, setBank] = useState(listBank);
async function onProses() {
const body = {
donasiId: donasiId,
donasiMaster_BankId: pilihBank,
nominal: prosesDonasi.nominal,
authorId: authorId
};
// console.log(body)
await Donasi_funCreateInvoice(body).then((res) => {
if (res.status === 200) {
NotifBerhasil(res.message);
router.push(RouterDonasi.invoice + `${res.invoiceId}`);
setProsesDonasi({
...prosesDonasi,
nominal: "",
});
} else {
NotifGagal(res.message);
}
});
}
return (
<>
<Stack>
{/* <pre>{JSON.stringify(prosesDonasi, null, 2)}</pre> */}
<Radio.Group value={pilihBank} onChange={setPilihBank} withAsterisk>
{bank.map((e) => (
<Paper
key={e.id}
withBorder
radius={"md"}
p={"sm"}
shadow="lg"
mb={"xs"}
>
<Radio value={e.id} label={<Title order={6}>{e.name}</Title>} />
</Paper>
))}
</Radio.Group>
<Button radius={"xl"} onClick={() => onProses()}>
Pilih
</Button>
</Stack>
</>
);
}

View File

@@ -0,0 +1,17 @@
"use client"
import HeaderTamplateDonasi from "@/app_modules/donasi/component/header_tamplate"
import { AppShell } from "@mantine/core"
import React from "react"
export default function LayoutDonasi_MetodePembayaran({children}: {children: React.ReactNode}){
return<>
<AppShell
header={<HeaderTamplateDonasi title="Pilih Metode Pembayaran"/>}
>
{children}
</AppShell>
</>
}

View File

@@ -0,0 +1,74 @@
"use client";
import {
Avatar,
Box,
Button,
Center,
CopyButton,
Grid,
Group,
Loader,
Paper,
Stack,
Title,
} from "@mantine/core";
import invoice from "../invoice";
import { MODEL_DONASI_INVOICE } from "../../model/interface";
import { useState } from "react";
import { useInterval, useShallowEffect } from "@mantine/hooks";
import { redirect, useRouter } from "next/navigation";
import { Donasi_getOneInvoiceById } from "../../fun/get/get_one_invoice_by_id";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { useAtom } from "jotai";
import { gs_donasi_hot_menu } from "../../global_state";
export default function Donasi_ProsesTransaksi({
dataInvoice,
}: {
dataInvoice: MODEL_DONASI_INVOICE;
}) {
const [invoice, setInvoice] = useState(dataInvoice);
const [hotMenu, setHotMenu] = useAtom(gs_donasi_hot_menu);
const interval = useInterval(
() =>
reloadData(invoice.id).then((res) =>
setInvoice(res as MODEL_DONASI_INVOICE)
),
5000
);
useShallowEffect(() => {
interval.start();
}, [invoice.id]);
function reloadData(invoiceId: string) {
const res = Donasi_getOneInvoiceById(invoiceId);
return res;
}
if (invoice.donasiMaster_StatusInvoiceId === "1") {
redirect(RouterDonasi.detail_donasi_saya + `${invoice.id}`);
}
return (
<>
<Paper p={"sm"} withBorder>
<Stack spacing={"md"}>
<Paper bg={"gray.1"} p={"sm"} radius={"md"}>
<Stack align="center" justify="center">
<Title order={6}>Admin sedang memproses transaksimu</Title>
<Paper radius={1000} w={100} h={100}>
<Center h={"100%"}>
<Loader size={"lg"} color="orange" variant="bars" />
</Center>
</Paper>
<Title order={6}>Mohon menunggu !</Title>
</Stack>
</Paper>
</Stack>
</Paper>
</>
);
}

View File

@@ -0,0 +1,42 @@
"use client";
import { ActionIcon, AppShell, Group, Header, Title } from "@mantine/core";
import React from "react";
import HeaderTamplateDonasi from "../../component/header_tamplate";
import { IconX } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { useAtom } from "jotai";
import { gs_donasi_hot_menu } from "../../global_state";
export default function LayoutDonasi_ProsesTransaksi({
children,
}: {
children: React.ReactNode;
}) {
const router = useRouter();
const [donasiHotMenu, setDonasiHotMenu] = useAtom(gs_donasi_hot_menu);
async function onClick() {
setDonasiHotMenu(2);
router.push(RouterDonasi.main_donasi_saya);
}
return (
<>
<AppShell
header={
<Header height={50} sx={{ borderStyle: "none" }}>
<Group h={50} position="apart" px={"md"}>
<ActionIcon variant="transparent" onClick={() => onClick()}>
<IconX />
</ActionIcon>
<Title order={5}>Proses Transaksi</Title>
<ActionIcon disabled variant="transparent"></ActionIcon>
</Group>
</Header>
}
>
{children}
</AppShell>
</>
);
}