feat(admin): image thumbnails in lists + template image/demo fields

- AdminThumb: reusable thumbnail (raster + SVG via <img>, dashed fallback on
  empty/broken)
- AdminResource: ColumnDef gains type:"image" → renders thumbnails in tables
- image thumbnail columns for categories, slides, home-events, internal routes;
  categories icon field now multiline (accepts raw SVG markup)
- TemplatesAdmin: cover image / mini-demo / demo / full-demo upload fields
  (backed by existing container image/demo fields) + thumbnail column in the list

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-02 23:23:52 +03:30
parent 24aa4c51a4
commit b47314fcab
4 changed files with 76 additions and 6 deletions
+3 -1
View File
@@ -3,6 +3,7 @@
import { useCallback, useEffect, useState, type ReactNode } from "react";
import { FileUploadField } from "@/components/admin/FileUploadField";
import { AdminThumb } from "@/components/admin/AdminThumb";
export interface FieldDef {
key: string;
@@ -17,6 +18,7 @@ export interface FieldDef {
export interface ColumnDef {
key: string;
label: string;
type?: "text" | "image";
render?: (row: Record<string, unknown>) => ReactNode;
}
@@ -162,7 +164,7 @@ export function AdminResource({ config }: { config: ResourceConfig }) {
<tr key={String(row[idKey] ?? i)} className="border-b border-[#161a2e] hover:bg-[#12152a]">
{config.columns.map((c) => (
<td key={c.key} className="px-4 py-3 text-gray-200">
{c.render ? c.render(row) : formatCell(row[c.key])}
{c.render ? c.render(row) : c.type === "image" ? <AdminThumb src={row[c.key]} /> : formatCell(row[c.key])}
</td>
))}
{(config.canEdit || config.canDelete || config.rowActions) && (