setLibraryQuery(event.target.value)}
- className="pl-9"
+ value={query}
+ onChange={(event) => setQuery(event.target.value)}
placeholder="Search media"
+ className="pl-9"
/>
-
- {visibleLibraryOptions.length > 0 ? (
- visibleLibraryOptions.map((option) => {
- const isActive = option.id === value.assetId;
+
+ {visibleOptions.map((option) => {
+ const isActive = option.id === value.assetId;
- return (
-
-
- ) : null}
- {previewUrl ? (
- value.kind === "IMAGE" ? (
-
-
-
- ) : (
-
- {previewUrl}
-
- )
- ) : null}
+
+ setOpen(false)}>
+ Close
+
+
+
+
);
}
diff --git a/components/root/portfolio-categories-manager.tsx b/components/root/portfolio-categories-manager.tsx
index 574c4fd..630174d 100644
--- a/components/root/portfolio-categories-manager.tsx
+++ b/components/root/portfolio-categories-manager.tsx
@@ -2,7 +2,16 @@
import { useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
-import { FileText, FolderPlus, Hash, Layers3, Pencil, Text, Trash2 } from "lucide-react";
+import {
+ FileText,
+ FolderPlus,
+ Hash,
+ Layers3,
+ Pencil,
+ Sparkles,
+ Text,
+ Trash2,
+} from "lucide-react";
import type { deleteCategoryAction, upsertCategoryAction } from "@/app/root/portfolio/actions";
import { StatsCard } from "@/components/dashboard/stats-card";
@@ -23,35 +32,48 @@ import {
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
+import { Separator } from "@/components/ui/separator";
import { Textarea } from "@/components/ui/textarea";
import type { PortfolioCategoryView } from "@/lib/portfolio";
const locales = [
- { key: "Ar", lowerKey: "ar" as const, label: "Arabic" },
- { key: "En", lowerKey: "en" as const, label: "English" },
- { key: "De", lowerKey: "de" as const, label: "German" },
+ { key: "Ar", label: "Arabic" },
+ { key: "En", label: "English" },
+ { key: "De", label: "German" },
] as const;
const copy = {
- addCategory: "Kategorie hinzufuegen",
- saveCategory: "Kategorie speichern",
- save: "Speichern",
- delete: "Loeschen",
- active: "Aktiv",
- sortOrder: "Sortierung",
- projects: "Projekte",
- description: "Beschreibung",
- currentCategories: "Aktuelle Kategorien",
- modalDescription: "Neue Kategorie direkt im Popup anlegen.",
- editDescription: "Kategorie im Popup aendern oder loeschen.",
- empty: "Noch keine Kategorien vorhanden.",
- deleteBlocked: "Loeschen erst moeglich, wenn keine Projekte mehr zugeordnet sind.",
- editCategory: "Kategorie bearbeiten",
+ addCategory: "Add Category",
+ saveCategory: "Save Category",
+ save: "Save",
+ delete: "Delete",
+ active: "Active",
+ sortOrder: "Sort Order",
+ projects: "Projects",
+ description: "Description",
+ currentCategories: "Current Categories",
+ modalDescription: "Create a new category with a faster flow for basics, localization, and status.",
+ editDescription: "Update category content, change status, or remove the category if it has no assigned projects.",
+ empty: "No categories yet.",
+ deleteBlocked: "Delete becomes available only when no projects are assigned.",
+ editCategory: "Edit Category",
};
type CategoryAction = typeof upsertCategoryAction;
type CategoryDeleteAction = typeof deleteCategoryAction;
+type CategoryFormValues = {
+ slug?: string;
+ sortOrder?: number;
+ isActive?: boolean;
+ nameAr?: string;
+ nameEn?: string;
+ nameDe?: string;
+ descriptionAr?: string;
+ descriptionEn?: string;
+ descriptionDe?: string;
+};
+
type PortfolioCategoriesManagerProps = {
categories: Array
;
activeCount: number;
@@ -65,64 +87,134 @@ function CategoryLocaleFields({
values,
}: {
idPrefix: string;
- values?: {
- nameAr?: string;
- nameEn?: string;
- nameDe?: string;
- descriptionAr?: string;
- descriptionEn?: string;
- descriptionDe?: string;
- };
+ values?: CategoryFormValues;
}) {
return (
-
- {locales.map((locale) => {
- const nameKey = `name${locale.key}` as const;
- const descriptionKey = `description${locale.key}` as const;
+
+
+
Localized Content
+
+ Keep names and descriptions ready in all supported locales.
+
+
- return (
-
-
+
+ {locales.map((locale) => {
+ const nameKey = `name${locale.key}` as const;
+ const descriptionKey = `description${locale.key}` as const;
+
+ return (
+
{locale.label}
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
- );
- })}
+
+ );
+ })}
+
);
}
+function CategoryForm({
+ formId,
+ action,
+ values,
+ categoryId,
+}: {
+ formId: string;
+ action: CategoryAction;
+ values?: CategoryFormValues;
+ categoryId?: string;
+}) {
+ return (
+
+ );
+}
+
function EditCategoryDialog({
category,
open,
@@ -136,6 +228,8 @@ function EditCategoryDialog({
saveCategoryAction: CategoryAction;
removeCategoryAction: CategoryDeleteAction;
}) {
+ const formId = `portfolio-category-form-${category.id}`;
+
return (