Refactor portfolio admin and views
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { PortfolioAssetKind, PortfolioSectionType } from "@prisma/client";
|
||||
import { PortfolioSectionType } from "@prisma/client";
|
||||
import { z } from "zod";
|
||||
|
||||
import { mediaFieldInputSchema } from "./media-validation";
|
||||
@@ -10,6 +10,7 @@ const requiredText = (label: string) =>
|
||||
.min(1, `${label} is required.`);
|
||||
|
||||
const optionalTrimmedText = z.string().trim().optional().transform((value) => value ?? "");
|
||||
const portfolioProjectViewModes = ["GRID", "STORY", "CASE_STUDY"] as const;
|
||||
|
||||
export const categoryInputSchema = z.object({
|
||||
id: z.string().trim().optional(),
|
||||
@@ -83,7 +84,7 @@ export const sectionInputSchema = z
|
||||
|
||||
export const assetInputSchema = z.object({
|
||||
id: z.string().trim().optional(),
|
||||
kind: z.nativeEnum(PortfolioAssetKind),
|
||||
kind: z.literal("IMAGE"),
|
||||
filePath: optionalTrimmedText,
|
||||
fileFieldName: optionalTrimmedText,
|
||||
media: mediaFieldInputSchema.optional(),
|
||||
@@ -98,6 +99,7 @@ export const projectInputSchema = z.object({
|
||||
categoryId: requiredText("Project categoryId"),
|
||||
slug: requiredText("Project slug")
|
||||
.regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Project slug must be lowercase and hyphenated."),
|
||||
viewMode: z.enum(portfolioProjectViewModes).default("GRID"),
|
||||
titleAr: requiredText("Project titleAr"),
|
||||
titleEn: requiredText("Project titleEn"),
|
||||
titleDe: requiredText("Project titleDe"),
|
||||
|
||||
+24
-1
@@ -1,4 +1,10 @@
|
||||
import type { Category, PortfolioAsset, PortfolioProject, PortfolioSection } from "@prisma/client";
|
||||
import type {
|
||||
Category,
|
||||
PortfolioAsset,
|
||||
PortfolioProject,
|
||||
PortfolioProjectViewMode,
|
||||
PortfolioSection,
|
||||
} from "@prisma/client";
|
||||
|
||||
import { getPortfolioMediaBindings } from "@/lib/media";
|
||||
import type { AppLocale } from "@/lib/locale";
|
||||
@@ -42,6 +48,7 @@ type ProjectRecord = Pick<
|
||||
PortfolioProject,
|
||||
| "id"
|
||||
| "slug"
|
||||
| "viewMode"
|
||||
| "titleAr"
|
||||
| "titleEn"
|
||||
| "titleDe"
|
||||
@@ -99,6 +106,7 @@ export type PortfolioAssetView = {
|
||||
export type PortfolioProjectView = {
|
||||
id: string;
|
||||
slug: string;
|
||||
viewMode: PortfolioProjectViewMode;
|
||||
title: LocalizedContent;
|
||||
summary: LocalizedContent;
|
||||
clientName: string;
|
||||
@@ -116,6 +124,20 @@ export type PortfolioProjectView = {
|
||||
assets: PortfolioAssetView[];
|
||||
};
|
||||
|
||||
export function resolvePortfolioProjectViewMode(
|
||||
value: string | null | undefined,
|
||||
): PortfolioProjectViewMode {
|
||||
switch (value) {
|
||||
case "STORY":
|
||||
return "STORY";
|
||||
case "CASE_STUDY":
|
||||
return "CASE_STUDY";
|
||||
case "GRID":
|
||||
default:
|
||||
return "GRID";
|
||||
}
|
||||
}
|
||||
|
||||
function mapLocalizedContent(record: Record<string, unknown>, prefix: string): LocalizedContent {
|
||||
return {
|
||||
ar: String(record[`${prefix}Ar`] ?? ""),
|
||||
@@ -174,6 +196,7 @@ function mapProject(
|
||||
return {
|
||||
id: record.id,
|
||||
slug: record.slug,
|
||||
viewMode: resolvePortfolioProjectViewMode(record.viewMode),
|
||||
title: mapLocalizedContent(record, "title"),
|
||||
summary: mapLocalizedContent(record, "summary"),
|
||||
clientName: record.clientName,
|
||||
|
||||
Reference in New Issue
Block a user