assets and tier plans revamp

This commit is contained in:
rgrgogu
2026-08-01 17:44:12 +08:00
parent 4f738a691d
commit a34c6feb84
45 changed files with 2172 additions and 273 deletions
@@ -1,17 +1,16 @@
// modules/admin/pages/assets/ViewDocumentAsset.jsx
import { useParams, useNavigate } from "react-router-dom";
import { ArrowLeft, Lock, Globe, FileText, Download } from "lucide-react";
import { ArrowLeft, Lock, Globe, FileText } from "lucide-react";
import { useDateFormat } from "@/hooks/useDateFormat";
import { useAssetFetchState } from "@/hooks/useAssetFetchState";
import { useAssetPreviewSrc } from "@/hooks/useAssetPreviewSrc";
import { downloadAsset } from "@/utils/media.util";
import { Spinner } from "@/components/ui/spinner";
import { formatFileSize } from "@/utils/format.util";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { MediaFallback } from "@/components/generic/MediaFallback";
import FileZoomViewer from "@/components/generic/FileZoomViewer";
import AssetPageLoader from "@/components/generic/AssetLoader";
function MetaRow({ label, value }) {
@@ -32,7 +31,7 @@ export default function ViewDocumentAsset() {
const { fmtDateTime } = useDateFormat();
const { asset: selectedAsset, loading, notFound } = useAssetFetchState(assetId);
const { src: streamUrl } = useAssetPreviewSrc(selectedAsset, { scope: "admin" });
const { src: streamUrl, loading: previewLoading } = useAssetPreviewSrc(selectedAsset, { scope: "admin" });
if (loading) {
return <AssetPageLoader />;
@@ -48,7 +47,9 @@ export default function ViewDocumentAsset() {
}
const a = selectedAsset;
const canPreview = PREVIEWABLE.includes((a.extension ?? "").toLowerCase());
const ext = (a.extension ?? "").toLowerCase();
const canPreview = PREVIEWABLE.includes(ext);
const isPdf = ext === "pdf";
return (
<div className="max-w-7xl mx-auto px-4 py-6 space-y-6">
@@ -62,16 +63,22 @@ export default function ViewDocumentAsset() {
<h1 className="text-xl font-semibold truncate">{a.display_name ?? a.original_name}</h1>
<p className="text-sm text-muted-foreground">{a.mime_type}</p>
</div>
<Button variant="outline" size="sm" onClick={() => downloadAsset(a, { scope: "admin" })}>
<Download className="h-4 w-4" /> Download
</Button>
</div>
<div className="grid grid-cols-1 lg:grid-cols-5 gap-6">
{/* ── Document preview ── */}
<div className="lg:col-span-3">
{canPreview && streamUrl ? (
{isPdf ? (
<div className="rounded-lg border overflow-hidden">
<FileZoomViewer
src={streamUrl}
mimeType={a.mime_type}
fileName={a.display_name ?? a.original_name}
loading={previewLoading}
/>
</div>
) : canPreview && streamUrl ? (
<div className="rounded-lg border overflow-hidden bg-white" style={{ height: 600 }}>
<iframe
src={streamUrl}
@@ -96,7 +103,7 @@ export default function ViewDocumentAsset() {
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2">File Info</p>
<MetaRow label="Original Name" value={a.original_name} />
<MetaRow label="Extension" value={a.extension} />
<MetaRow label="File Size" value={a.file_size ? `${(a.file_size / 1024).toFixed(1)} KB` : null} />
<MetaRow label="File Size" value={formatFileSize(a.file_size)} />
<MetaRow label="MIME Type" value={a.mime_type} />
<Separator className="my-2" />
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2">Storage</p>