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

@@ -24,6 +24,7 @@ model User {
Investasi Investasi[]
TransaksiInvestasi TransaksiInvestasi[]
Donasi Donasi[]
Donasi_Invoice Donasi_Invoice[]
}
model MasterUserRole {
@@ -74,6 +75,7 @@ model Images {
Donasi Donasi?
CeritaDonasi Donasi_Cerita[]
Donasi_TemporaryCreate Donasi_TemporaryCreate[]
Donasi_Kabar Donasi_Kabar[]
}
model Katalog {
@@ -282,6 +284,8 @@ model Donasi {
updatedAt DateTime @updatedAt
publishTime DateTime?
catatan String?
progres String? @default("0")
terkumpul String? @default("0")
Author User? @relation(fields: [authorId], references: [id])
authorId String?
@@ -294,6 +298,8 @@ model Donasi {
donasiMaster_DurasiId String?
DonasiMaster_Status DonasiMaster_StatusDonasi? @relation(fields: [donasiMaster_StatusDonasiId], references: [id])
donasiMaster_StatusDonasiId String? @default("2")
Donasi_Invoice Donasi_Invoice[]
Donasi_Kabar Donasi_Kabar[]
}
model Donasi_TemporaryCreate {
@@ -353,3 +359,55 @@ model DonasiMaster_StatusDonasi {
updatedAt DateTime @updatedAt
Donasi Donasi[]
}
model DonasiMaster_Bank {
id String @id @default(cuid())
name String
norek String
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Donasi_Invoice Donasi_Invoice[]
}
model DonasiMaster_StatusInvoice {
id String @id @default(cuid())
name String
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Donasi_Invoice Donasi_Invoice[]
}
model Donasi_Invoice {
id String @id @default(cuid())
nominal String
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Donasi Donasi? @relation(fields: [donasiId], references: [id])
donasiId String?
DonasiMaster_Bank DonasiMaster_Bank? @relation(fields: [donasiMaster_BankId], references: [id])
donasiMaster_BankId String?
DonasiMaster_StatusInvoice DonasiMaster_StatusInvoice? @relation(fields: [donasiMaster_StatusInvoiceId], references: [id])
donasiMaster_StatusInvoiceId String? @default("3")
Author User? @relation(fields: [authorId], references: [id])
authorId String?
}
model Donasi_Kabar {
id String @id @default(cuid())
title String
deskripsi String
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Donasi Donasi? @relation(fields: [donasiId], references: [id])
donasiId String?
ImagesKabar Images? @relation(fields: [imagesId], references: [id])
imagesId String?
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -13,6 +13,8 @@ import userSeeder from "../../../bin/seeder/user_seeder.json";
import donasi_status from "../../../bin/seeder/donasi/master_status.json";
import donasi_kategori from "../../../bin/seeder/donasi/master_kategori.json";
import donasi_durasi from "../../../bin/seeder/donasi/master_durasi.json";
import donasi_namaBank from "../../../bin/seeder/donasi/master_bank.json"
import donasi_status_invoice from "../../../bin/seeder/donasi/master_status_invoice.json"
export async function GET(req: Request) {
const dev = new URL(req.url).searchParams.get("dev");
@@ -229,6 +231,39 @@ export async function GET(req: Request) {
});
}
for (let i of donasi_namaBank) {
await prisma.donasiMaster_Bank.upsert({
where: {
id: i.id,
},
create: {
id: i.id,
name: i.name,
norek: i.norek,
},
update: {
id: i.id,
name: i.name,
norek: i.norek,
},
});
}
for (let d of donasi_status_invoice) {
await prisma.donasiMaster_StatusInvoice.upsert({
where: {
id: d.id,
},
create: {
id: d.id,
name: d.name,
},
update: {
name: d.name,
},
});
}
return NextResponse.json({ success: true });
}

View File

@@ -0,0 +1,17 @@
import { AdminDonasi_DetailPublish } from "@/app_modules/admin/donasi";
import { AdminDonasi_funCountDonatur } from "@/app_modules/admin/donasi/fun/count/fun_count_donatur";
import { AdminDonasi_getListDonatur } from "@/app_modules/admin/donasi/fun/get/get_list_donatur_by_id";
import { AdminDonasi_getById } from "@/app_modules/admin/donasi/fun/get/get_one_by_id";
export default async function Page({params}: {params: {id: string}}) {
const dataPublish = await AdminDonasi_getById(params.id)
const listDonatur = await AdminDonasi_getListDonatur(params.id)
const countDonatur = await AdminDonasi_funCountDonatur(params.id)
return (
<>
<AdminDonasi_DetailPublish dataPublish={dataPublish as any} listDonatur={listDonatur} countDonatur={countDonatur} />
</>
);
}

View File

@@ -1,9 +0,0 @@
import { AdminDonasi_DetailPublish } from "@/app_modules/admin/donasi";
export default async function Page() {
return (
<>
<AdminDonasi_DetailPublish />
</>
);
}

View File

@@ -0,0 +1,12 @@
import { AdminDonasi_DetailReject } from "@/app_modules/admin/donasi";
import { AdminDonasi_getById } from "@/app_modules/admin/donasi/fun/get/get_one_by_id";
export default async function Page({ params }: { params: { id: string } }) {
const dataReject = await AdminDonasi_getById(params.id);
return (
<>
<AdminDonasi_DetailReject dataReject={dataReject as any} />
</>
);
}

View File

@@ -0,0 +1,11 @@
import AdminDonasi_ProsesTransaksi from "@/app_modules/admin/donasi/detail_table/publish/proses_transaksi";
import { AdminDonasi_getListStatusInvoiceProses } from "@/app_modules/admin/donasi/fun/get/get_list_status_invoice_proses";
export default async function Page({params}: {params: {id: string}}) {
let donasiId = params.id
const listProses = await AdminDonasi_getListStatusInvoiceProses(donasiId)
return <AdminDonasi_ProsesTransaksi listProses={listProses as any}/>
}

View File

@@ -13,7 +13,7 @@ export default async function Layout({
const statusDonasiId = dataDonasi?.donasiMaster_StatusDonasiId;
return (
<>
<LayoutCeritaPenggalangDonasi statusDonasiId={statusDonasiId as string}>
<LayoutCeritaPenggalangDonasi statusDonasiId={statusDonasiId as string} donasiId={dataDonasi?.id as string}>
{children}
</LayoutCeritaPenggalangDonasi>
</>

View File

@@ -0,0 +1,17 @@
import { DetailDonasiSaya } from "@/app_modules/donasi";
import { Donasi_getCountDonatur } from "@/app_modules/donasi/fun/count/get_count_donatur";
import { Donasi_getOneById } from "@/app_modules/donasi/fun/get/get_one_donasi_by_id";
import { Donasi_getOneInvoiceById } from "@/app_modules/donasi/fun/get/get_one_invoice_by_id";
export default async function Page({ params }: { params: { id: string } }) {
let invoiceId = params.id;
const dataDonasi = await Donasi_getOneInvoiceById(invoiceId);
const countDonatur= await Donasi_getCountDonatur(dataDonasi?.donasiId as any)
return (
<>
<DetailDonasiSaya dataDonasi={dataDonasi as any} countDonatur={countDonatur} />
</>
);
}

View File

@@ -1,7 +0,0 @@
import { DetailDonasiSaya } from "@/app_modules/donasi";
export default async function Page() {
return<>
<DetailDonasiSaya/>
</>
}

View File

@@ -3,12 +3,14 @@ import React from "react";
export default async function Layout({
children,
params
}: {
children: React.ReactNode;
params: {id: string}
}) {
return (
<>
<LayoutDetailMainDonasi>{children}</LayoutDetailMainDonasi>
<LayoutDetailMainDonasi donasiId={params.id}>{children}</LayoutDetailMainDonasi>
</>
);
}

View File

@@ -0,0 +1,16 @@
import { DetailMainDonasi } from "@/app_modules/donasi";
import { Donasi_getCountDonatur } from "@/app_modules/donasi/fun/count/get_count_donatur";
import { Donasi_getOneById } from "@/app_modules/donasi/fun/get/get_one_donasi_by_id";
export default async function Page({ params }: { params: { id: string } }) {
let donasiId = params.id;
const dataDonasi = await Donasi_getOneById(donasiId);
const countDonatur = await Donasi_getCountDonatur(donasiId)
return (
<>
<DetailMainDonasi dataDonasi={dataDonasi as any} countDonatur={countDonatur} />
</>
);
}

View File

@@ -1,9 +0,0 @@
import { DetailMainDonasi } from "@/app_modules/donasi";
export default async function Page() {
return (
<>
<DetailMainDonasi />
</>
);
}

View File

@@ -0,0 +1,14 @@
import { DetailPublishDonasi } from "@/app_modules/donasi";
import { Donasi_getCountDonatur } from "@/app_modules/donasi/fun/count/get_count_donatur";
import { Donasi_getOneById } from "@/app_modules/donasi/fun/get/get_one_donasi_by_id";
export default async function Page({ params }: { params: { id: string } }) {
const dataPublish = await Donasi_getOneById(params.id);
const countDonatur= await Donasi_getCountDonatur(params.id)
return (
<>
<DetailPublishDonasi dataPublish={dataPublish as any} countDonatur={countDonatur} />
</>
);
}

View File

@@ -1,7 +0,0 @@
import { DetailPublishDonasi } from "@/app_modules/donasi";
export default async function Page() {
return<>
<DetailPublishDonasi/>
</>
}

View File

@@ -0,0 +1,11 @@
import { DetailRejectDonasi } from "@/app_modules/donasi";
import { Donasi_getOneById } from "@/app_modules/donasi/fun/get/get_one_donasi_by_id";
export default async function Page({params}: {params: {id: string}}) {
let donasiId= params.id
const dataReject = await Donasi_getOneById(donasiId)
return<>
<DetailRejectDonasi dataReject={dataReject as any}/>
</>
}

View File

@@ -1,7 +0,0 @@
import { DetailRejectDonasi } from "@/app_modules/donasi";
export default async function Page() {
return<>
<DetailRejectDonasi/>
</>
}

View File

@@ -1,5 +1,8 @@
import { MainDonasi } from "@/app_modules/donasi";
import { Donasi_getListBeranda } from "@/app_modules/donasi/fun/get/get_list_beranda";
export default async function Page() {
return <MainDonasi/>
const listDonasi = await Donasi_getListBeranda()
// console.log(listDonasi)
return <MainDonasi listDonasi={listDonasi as any}/>
}

View File

@@ -1,5 +1,10 @@
import { DonasiSayaDonasi } from "@/app_modules/donasi";
import { Donasi_getInvoiceByAuthorId } from "@/app_modules/donasi/fun/get/get_list_invoice_by_author_id";
import { getToken_UserId } from "@/app_modules/fun/get_user_token";
export default async function Page() {
return <DonasiSayaDonasi/>
}
const authorId = await getToken_UserId();
const listInvoice = await Donasi_getInvoiceByAuthorId(authorId);
return <DonasiSayaDonasi listInvoice={listInvoice as any} />;
}

View File

@@ -4,14 +4,16 @@ import { getToken_UserId } from "@/app_modules/fun/get_user_token";
export default async function Page() {
const authorId = await getToken_UserId();
const listPublish = await Donasi_getByStatus(authorId, "1")
const listReview = await Donasi_getByStatus(authorId, "2");
const listDraft = await Donasi_getByStatus(authorId, "3");
const listReject = await Donasi_getByStatus(authorId, "4")
// console.log(listReview)
return (
<>
<PostingDonasi listReview={listReview} listDraft={listDraft} />
<PostingDonasi listPublish={listPublish} listReview={listReview} listDraft={listDraft} listReject={listReject} />
</>
);
}

View File

@@ -1,5 +0,0 @@
import { MasukanDonasi } from "@/app_modules/donasi";
export default async function Page() {
return <MasukanDonasi/>
}

View File

@@ -0,0 +1,13 @@
import { PenggalangDanaDonasi } from "@/app_modules/donasi";
import { Donasi_getAuthorById } from "@/app_modules/donasi/fun/get/get_author_by_id";
export default async function Page({ params }: { params: { id: string } }) {
let authorId = params.id;
const dataPenggalang = await Donasi_getAuthorById(authorId);
return (
<>
<PenggalangDanaDonasi dataPenggalang={dataPenggalang as any} />
</>
);
}

View File

@@ -1,10 +0,0 @@
import { PenggalangDanaDonasi } from "@/app_modules/donasi";
export default async function Page() {
return (
<>
<PenggalangDanaDonasi />
</>
);
}

View File

@@ -0,0 +1,8 @@
import { LayoutDonasi_InvoiceProses } from "@/app_modules/donasi";
import React from "react";
export default async function Layout({children}: {children: React.ReactNode}) {
return<>
<LayoutDonasi_InvoiceProses>{children}</LayoutDonasi_InvoiceProses>
</>
}

View File

@@ -0,0 +1,11 @@
import { Donasi_InvoiceProses } from "@/app_modules/donasi";
import { Donasi_getOneById } from "@/app_modules/donasi/fun/get/get_one_donasi_by_id";
import { Donasi_getOneInvoiceById } from "@/app_modules/donasi/fun/get/get_one_invoice_by_id";
export default async function Page({ params }: { params: { id: string } }) {
let invoiceId = params.id;
const dataInvoice = await Donasi_getOneInvoiceById(invoiceId);
return <Donasi_InvoiceProses dataInvoice={dataInvoice as any} />;
}

View File

@@ -0,0 +1,6 @@
import { MasukanDonasi } from "@/app_modules/donasi";
export default async function Page({params}: {params : {id: string}}) {
let donasiId = params.id
return <MasukanDonasi donasiId={donasiId}/>
}

View File

@@ -0,0 +1,8 @@
import { LayoutDonasi_MetodePembayaran } from "@/app_modules/donasi";
import React from "react";
export default async function Layout({children}: {children: React.ReactNode}) {
return<>
<LayoutDonasi_MetodePembayaran>{children}</LayoutDonasi_MetodePembayaran>
</>
}

View File

@@ -0,0 +1,13 @@
import { Donasi_MetodePembayaran } from "@/app_modules/donasi";
import { Donasi_getMasterBank } from "@/app_modules/donasi/fun/master/get_bank";
import { getToken_UserId } from "@/app_modules/fun/get_user_token";
export default async function Page({params}: {params: {id: string}}) {
let donasiId= params.id
const listBank = await Donasi_getMasterBank()
const authorId = await getToken_UserId()
return<>
<Donasi_MetodePembayaran listBank={listBank} donasiId={donasiId} authorId={authorId}/>
</>
}

View File

@@ -0,0 +1,8 @@
import { LayoutDonasi_ProsesTransaksi } from "@/app_modules/donasi";
import React from "react";
export default async function Layout({children}:{children: React.ReactNode}) {
return<>
<LayoutDonasi_ProsesTransaksi>{children}</LayoutDonasi_ProsesTransaksi>
</>
}

View File

@@ -0,0 +1,13 @@
import { Donasi_ProsesTransaksi } from "@/app_modules/donasi";
import { Donasi_getOneInvoiceById } from "@/app_modules/donasi/fun/get/get_one_invoice_by_id";
export default async function Page({params}: {params: {id: string}}) {
// console.log(params.id)
const dataInvoice = await Donasi_getOneInvoiceById(params.id)
// console.log(dataInvoice)
return (
<>
<Donasi_ProsesTransaksi dataInvoice={dataInvoice as any} />
</>
);
}

View File

@@ -23,8 +23,13 @@ export const RouterAdminDonasi = {
// detail
detail_publish: "/dev/admin/donasi/detail/publish",
detail_publish: "/dev/admin/donasi/detail/publish/",
detail_review: "/dev/admin/donasi/detail/review/",
detail_reject: "/dev/admin/donasi/detail/reject/",
// proses
proses_transaksi: "/dev/admin/donasi/proses_transaksi/"
};

View File

@@ -23,20 +23,28 @@ export const RouterDonasi = {
page_pop_up_create: "/dev/donasi/page_pop_up/create",
//detail
detail_main: "/dev/donasi/detail/detail_main",
detail_main: "/dev/donasi/detail/detail_main/",
detail_kabar: "/dev/donasi/detail/detail_kabar",
detail_publish: "/dev/donasi/detail/detail_publish",
detail_publish: "/dev/donasi/detail/detail_publish/",
detail_review: "/dev/donasi/detail/detail_review/",
detail_draft: "/dev/donasi/detail/detail_draft/",
detail_reject: "/dev/donasi/detail/detail_reject",
detail_donasi_saya: "/dev/donasi/detail/detail_donasi_saya",
detail_reject: "/dev/donasi/detail/detail_reject/",
detail_donasi_saya: "/dev/donasi/detail/detail_donasi_saya/",
//alur donasi
masukan_donasi: "/dev/donasi/masukan_donasi",
donatur: "/dev/donasi/donatur",
kabar: "/dev/donasi/kabar",
pencairan_dana: "/dev/donasi/pencairan_dana",
penggalang_dana: "/dev/donasi/penggalang_dana",
penggalang_dana: "/dev/donasi/penggalang_dana/",
cerita_penggalang: "/dev/donasi/cerita_penggalang/",
list_kabar: "/dev/donasi/list_kabar",
// proses donasi
masukan_donasi: "/dev/donasi/proses_donasi/masukan_donasi/",
metode_pembayaran: "/dev/donasi/proses_donasi/metode_pembayaran/",
invoice: "/dev/donasi/proses_donasi/invoice/",
proses_transaksi: "/dev/donasi/proses_donasi/proses_transaksi/",
};

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} />
</>
);
}

Some files were not shown because too many files have changed in this diff Show More