try to deploy

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-07-13 21:27:56 +08:00
parent bfc4b9fc67
commit b1805cfe4d
87 changed files with 798 additions and 718 deletions
+12
View File
@@ -28,6 +28,11 @@ const ALLOWED_DOCUMENT_EXTENSIONS = new Set([
"zip", "json", "rtf", "txt", "csv", "md",
]);
// Matches asset_upload.middleware.js on the backend — rejecting an oversized
// file here means the queue shows a clear "invalid" reason instantly instead
// of a job that uploads for a while and then fails with a generic error.
export const MAX_ASSET_FILE_SIZE = 500 * 1024 * 1024; // 500 MB
export function fileExtension(filename = "") {
const dot = filename.lastIndexOf(".");
return dot > 0 ? filename.slice(dot + 1).toLowerCase() : "";
@@ -35,6 +40,13 @@ export function fileExtension(filename = "") {
// { ok: true } or { ok: false, reason }
export function validateAssetFile(file) {
if (file.size > MAX_ASSET_FILE_SIZE) {
return {
ok: false,
reason: `File exceeds the ${MAX_ASSET_FILE_SIZE / (1024 * 1024)} MB size limit.`,
};
}
const mime = file.type || "";
if (mime.startsWith("image/") || mime.startsWith("video/") || mime.startsWith("audio/")) {
+25 -14
View File
@@ -75,6 +75,10 @@ export const BADGE_STYLES = {
// ── Asset — is_public ─────────────────────────
"true": "bg-emerald-100 text-emerald-700 border-emerald-200",
"false": "bg-zinc-100 text-zinc-600 border-zinc-200",
// ── Generic boolean labels (BOOLEAN_FIELD_LABELS) ─────────
"Yes": "bg-emerald-100 text-emerald-700 border-emerald-200",
"No": "bg-zinc-100 text-zinc-600 border-zinc-200",
};
function EnumBadge({ value }) {
@@ -94,24 +98,28 @@ export function formatDate(value) {
catch { return value; }
}
// Human-readable labels for boolean-backed enum fields — [falseLabel, trueLabel].
// Shared by renderCell (table cells) and ColumnFilter (filter dropdown), so a
// "true"/"false" boolean column never surfaces its raw value to the admin.
export const BOOLEAN_FIELD_LABELS = {
is_active: ["Not Active", "Active"],
is_verified: ["Not Verified", "Verified"],
is_public: ["Private", "Public"],
is_banned: ["Not Banned", "Banned"],
is_required: ["No", "Yes"],
};
function renderCell(attr, value) {
if (value === null || value === undefined || value === "") {
return <span className="text-muted-foreground/40">-</span>;
}
switch (attr.type) {
case "enum":
if (attr.field === "is_active")
return <EnumBadge value={value ? "Active" : "Not Active"} />;
else if (attr.field === "is_verified")
return <EnumBadge value={value ? "Verified" : "Not Verified"} />;
else if (attr.field === "is_public")
return <EnumBadge value={value ? "Public" : "Private"} />;
else if (attr.field === "is_banned")
return <EnumBadge value={value ? "Banned" : "Not Banned"} />;
else
return <EnumBadge value={value} />;
case "enum": {
const boolLabels = BOOLEAN_FIELD_LABELS[attr.field];
if (boolLabels) return <EnumBadge value={boolLabels[value ? 1 : 0]} />;
return <EnumBadge value={value} />;
}
case "date": return <span className="text-xs text-muted-foreground">{formatDate(value)}</span>;
case "number": return <span className="font-mono text-xs font-semibold text-muted-foreground">{value}</span>;
default: return <span className="text-sm">{value}</span>;
@@ -131,13 +139,16 @@ export function ColumnFilter({ column, attr }) {
// ENUM (AUTO APPLY)
// ─────────────────────────────────────────────
if (attr.type === "enum") {
const boolLabels = BOOLEAN_FIELD_LABELS[attr.field];
const choiceLabel = (c) => boolLabels ? boolLabels[c === "true" ? 1 : 0] : c;
return (
<Select
value={inputValue || "__all__"}
onValueChange={(v) => {
const value = v === "__all__" ? "" : v;
setInputValue(value);
column.setFilterValue(value);
column.setFilterValue(value);
}}
>
<SelectTrigger className="h-7 text-xs w-full">
@@ -148,7 +159,7 @@ export function ColumnFilter({ column, attr }) {
<SelectItem value="__all__">All</SelectItem>
{attr.options?.choices?.map((c) => (
<SelectItem key={c} value={c}>
{c}
{choiceLabel(c)}
</SelectItem>
))}
</SelectContent>