feat: move top donate to dedicated card
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import posthog from "posthog-js";
|
import posthog from "posthog-js";
|
||||||
import { useEffect } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useEllipsisVisible } from "react-hook-text-overflow";
|
import { useEllipsisVisible } from "react-hook-text-overflow";
|
||||||
import { DataTable } from "@/components/tantable";
|
import { DataTable } from "@/components/tantable";
|
||||||
import { SimpleTooltip } from "@/components/tooltip";
|
import { SimpleTooltip } from "@/components/tooltip";
|
||||||
@@ -27,6 +27,7 @@ import type { donations } from "@/lib/db/schema";
|
|||||||
import { sse } from "@/lib/db/sse-endpoints";
|
import { sse } from "@/lib/db/sse-endpoints";
|
||||||
import { ActionButton } from "../../../../components/action-button";
|
import { ActionButton } from "../../../../components/action-button";
|
||||||
import { getImage, reloadWidget, resendPopup, testPopup } from "./api";
|
import { getImage, reloadWidget, resendPopup, testPopup } from "./api";
|
||||||
|
import { formatDistanceToNow } from "date-fns";
|
||||||
|
|
||||||
const columns: ColumnDef<typeof donations.$inferSelect>[] = [
|
const columns: ColumnDef<typeof donations.$inferSelect>[] = [
|
||||||
{ accessorKey: "name", header: "ชื่อ", meta: { className: "w-50 truncate" } },
|
{ accessorKey: "name", header: "ชื่อ", meta: { className: "w-50 truncate" } },
|
||||||
@@ -103,63 +104,110 @@ const columns: ColumnDef<typeof donations.$inferSelect>[] = [
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
cell(row) {
|
cell(row) {
|
||||||
return (
|
return <ActionRow row={row.row.original} filler />;
|
||||||
<div className="flex gap-1">
|
|
||||||
<SimpleTooltip text="แสดง Popup อีกครั้ง">
|
|
||||||
<ActionButton
|
|
||||||
variant="outline"
|
|
||||||
size="icon-sm"
|
|
||||||
action={() => {
|
|
||||||
posthog.capture("donation_admin_resend", {
|
|
||||||
id: row.row.original.id,
|
|
||||||
});
|
|
||||||
return resendPopup(row.row.original.id);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MessageCircleWarning />
|
|
||||||
</ActionButton>
|
|
||||||
</SimpleTooltip>
|
|
||||||
{row.row.original.uid ? (
|
|
||||||
<SimpleTooltip text="ก็อบ UID">
|
|
||||||
<ActionButton
|
|
||||||
size="icon-sm"
|
|
||||||
action={() =>
|
|
||||||
navigator.clipboard.writeText(row.row.original.uid!)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Copy />
|
|
||||||
</ActionButton>
|
|
||||||
</SimpleTooltip>
|
|
||||||
) : (
|
|
||||||
<div className="size-8" />
|
|
||||||
)}
|
|
||||||
{row.row.original.image && (
|
|
||||||
<SimpleTooltip text="เปิดภาพ">
|
|
||||||
<ActionButton
|
|
||||||
size="icon-sm"
|
|
||||||
variant="outline"
|
|
||||||
action={async () => {
|
|
||||||
await getImage(row.row.original.id).then((blob) => {
|
|
||||||
const url = URL.createObjectURL(blob);
|
|
||||||
|
|
||||||
const tab = window.open("about:blank", "_blank");
|
|
||||||
if (tab) {
|
|
||||||
tab.location.href = url;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ImageIcon />
|
|
||||||
</ActionButton>
|
|
||||||
</SimpleTooltip>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
meta: { className: "w-27 p-0" },
|
meta: { className: "w-27 p-0" },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function ActionRow({
|
||||||
|
row,
|
||||||
|
filler,
|
||||||
|
}: {
|
||||||
|
row: typeof donations.$inferSelect;
|
||||||
|
filler?: boolean;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="flex gap-1">
|
||||||
|
<SimpleTooltip text="แสดง Popup อีกครั้ง">
|
||||||
|
<ActionButton
|
||||||
|
variant="outline"
|
||||||
|
size="icon-sm"
|
||||||
|
action={() => {
|
||||||
|
posthog.capture("donation_admin_resend", {
|
||||||
|
id: row.id,
|
||||||
|
});
|
||||||
|
return resendPopup(row.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MessageCircleWarning />
|
||||||
|
</ActionButton>
|
||||||
|
</SimpleTooltip>
|
||||||
|
{row.uid ? (
|
||||||
|
<SimpleTooltip text="ก็อบ UID">
|
||||||
|
<ActionButton
|
||||||
|
size="icon-sm"
|
||||||
|
action={() => navigator.clipboard.writeText(row.uid!)}
|
||||||
|
>
|
||||||
|
<Copy />
|
||||||
|
</ActionButton>
|
||||||
|
</SimpleTooltip>
|
||||||
|
) : filler ? (
|
||||||
|
<div className="size-8" />
|
||||||
|
) : undefined}
|
||||||
|
{row.image && (
|
||||||
|
<SimpleTooltip text="เปิดภาพ">
|
||||||
|
<ActionButton
|
||||||
|
size="icon-sm"
|
||||||
|
variant="outline"
|
||||||
|
action={async () => {
|
||||||
|
await getImage(row.id).then((blob) => {
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
const tab = window.open("about:blank", "_blank");
|
||||||
|
if (tab) {
|
||||||
|
tab.location.href = url;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ImageIcon />
|
||||||
|
</ActionButton>
|
||||||
|
</SimpleTooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TopRow({ row }: { row?: typeof donations.$inferSelect }) {
|
||||||
|
const [time, setTime] = useState("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!row) return setTime("");
|
||||||
|
function update() {
|
||||||
|
setTime(`${formatDistanceToNow(row!.created)} ago`);
|
||||||
|
}
|
||||||
|
const interval = setInterval(update, 1000);
|
||||||
|
update();
|
||||||
|
return () => clearTimeout(interval);
|
||||||
|
}, [row]);
|
||||||
|
return (
|
||||||
|
<div className="flex w-full gap-2 p-1">
|
||||||
|
{row ? (
|
||||||
|
<div className="flex flex-10 flex-col rounded-lg border bg-card/50 py-1 pr-1 pl-2">
|
||||||
|
<div className="flex justify-between text-xl">
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<span className="font-semibold">{row.name}</span>
|
||||||
|
<span className="opacity-70">{row.amount}฿</span>
|
||||||
|
</div>
|
||||||
|
<span className="pr-1 opacity-70">{time}</span>
|
||||||
|
</div>
|
||||||
|
<div className="min-h-20">{row.message}</div>
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<ActionRow row={row} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex-10 items-center justify-center rounded-lg border bg-card/50 px-2 py-1">
|
||||||
|
<span>No donation yet</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* <div className="flex-1 rounded-lg border bg-card/50 px-2 py-1">Hi</div>
|
||||||
|
<div className="flex-1 rounded-lg border bg-card/50 px-2 py-1">Hi</div> */}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function DonateAdminPage({
|
export function DonateAdminPage({
|
||||||
data,
|
data,
|
||||||
}: {
|
}: {
|
||||||
@@ -171,10 +219,11 @@ export function DonateAdminPage({
|
|||||||
<BitcoinIcon size={32} />
|
<BitcoinIcon size={32} />
|
||||||
โดเนททั้งหมด
|
โดเนททั้งหมด
|
||||||
</span>
|
</span>
|
||||||
|
<TopRow row={data[0]} />
|
||||||
<DataTable
|
<DataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
emptyDescription="No donation came in yet."
|
emptyDescription="No donation came in yet."
|
||||||
data={data}
|
data={data.slice(1)}
|
||||||
className="max-h-[calc(100vh-93px)] w-full overflow-y-auto bg-black/25 backdrop-blur-sm"
|
className="max-h-[calc(100vh-93px)] w-full overflow-y-auto bg-black/25 backdrop-blur-sm"
|
||||||
></DataTable>
|
></DataTable>
|
||||||
<DonateWatcher />
|
<DonateWatcher />
|
||||||
|
|||||||
Reference in New Issue
Block a user