@actuate-media/cms-admin 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js +148 -2
- package/dist/AdminRoot.js.map +1 -1
- package/dist/__tests__/components/posts-badges.test.d.ts +2 -0
- package/dist/__tests__/components/posts-badges.test.d.ts.map +1 -0
- package/dist/__tests__/components/posts-badges.test.js +68 -0
- package/dist/__tests__/components/posts-badges.test.js.map +1 -0
- package/dist/__tests__/layout/sidebar-posts.test.d.ts +2 -0
- package/dist/__tests__/layout/sidebar-posts.test.d.ts.map +1 -0
- package/dist/__tests__/layout/sidebar-posts.test.js +162 -0
- package/dist/__tests__/layout/sidebar-posts.test.js.map +1 -0
- package/dist/__tests__/lib/page-editor-service.test.d.ts +2 -0
- package/dist/__tests__/lib/page-editor-service.test.d.ts.map +1 -0
- package/dist/__tests__/lib/page-editor-service.test.js +137 -0
- package/dist/__tests__/lib/page-editor-service.test.js.map +1 -0
- package/dist/__tests__/lib/pages-service.test.d.ts +2 -0
- package/dist/__tests__/lib/pages-service.test.d.ts.map +1 -0
- package/dist/__tests__/lib/pages-service.test.js +140 -0
- package/dist/__tests__/lib/pages-service.test.js.map +1 -0
- package/dist/__tests__/lib/post-editor-service.test.d.ts +2 -0
- package/dist/__tests__/lib/post-editor-service.test.d.ts.map +1 -0
- package/dist/__tests__/lib/post-editor-service.test.js +185 -0
- package/dist/__tests__/lib/post-editor-service.test.js.map +1 -0
- package/dist/__tests__/lib/posts-service.test.d.ts +2 -0
- package/dist/__tests__/lib/posts-service.test.d.ts.map +1 -0
- package/dist/__tests__/lib/posts-service.test.js +244 -0
- package/dist/__tests__/lib/posts-service.test.js.map +1 -0
- package/dist/__tests__/views/posts-list-view.test.d.ts +2 -0
- package/dist/__tests__/views/posts-list-view.test.d.ts.map +1 -0
- package/dist/__tests__/views/posts-list-view.test.js +98 -0
- package/dist/__tests__/views/posts-list-view.test.js.map +1 -0
- package/dist/actuate-admin.css +1 -1
- package/dist/components/pages/tag-badges.d.ts +21 -0
- package/dist/components/pages/tag-badges.d.ts.map +1 -0
- package/dist/components/pages/tag-badges.js +56 -0
- package/dist/components/pages/tag-badges.js.map +1 -0
- package/dist/components/posts/badges.d.ts +25 -0
- package/dist/components/posts/badges.d.ts.map +1 -0
- package/dist/components/posts/badges.js +123 -0
- package/dist/components/posts/badges.js.map +1 -0
- package/dist/components/posts/icons.d.ts +12 -0
- package/dist/components/posts/icons.d.ts.map +1 -0
- package/dist/components/posts/icons.js +26 -0
- package/dist/components/posts/icons.js.map +1 -0
- package/dist/layout/Layout.js +36 -8
- package/dist/layout/Layout.js.map +1 -1
- package/dist/layout/Sidebar.d.ts +9 -0
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Sidebar.js +100 -48
- package/dist/layout/Sidebar.js.map +1 -1
- package/dist/lib/page-editor-service.d.ts +45 -0
- package/dist/lib/page-editor-service.d.ts.map +1 -0
- package/dist/lib/page-editor-service.js +153 -0
- package/dist/lib/page-editor-service.js.map +1 -0
- package/dist/lib/pages-service.d.ts +143 -0
- package/dist/lib/pages-service.d.ts.map +1 -0
- package/dist/lib/pages-service.js +444 -0
- package/dist/lib/pages-service.js.map +1 -0
- package/dist/lib/post-editor-service.d.ts +57 -0
- package/dist/lib/post-editor-service.d.ts.map +1 -0
- package/dist/lib/post-editor-service.js +234 -0
- package/dist/lib/post-editor-service.js.map +1 -0
- package/dist/lib/posts-service.d.ts +73 -0
- package/dist/lib/posts-service.d.ts.map +1 -0
- package/dist/lib/posts-service.js +245 -0
- package/dist/lib/posts-service.js.map +1 -0
- package/dist/lib/preview-link.d.ts +32 -0
- package/dist/lib/preview-link.d.ts.map +1 -0
- package/dist/lib/preview-link.js +40 -0
- package/dist/lib/preview-link.js.map +1 -0
- package/dist/router/index.d.ts +1 -0
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +9 -1
- package/dist/router/index.js.map +1 -1
- package/dist/views/Dashboard.d.ts.map +1 -1
- package/dist/views/Dashboard.js +14 -3
- package/dist/views/Dashboard.js.map +1 -1
- package/dist/views/Pages/PageTagManager.d.ts +14 -0
- package/dist/views/Pages/PageTagManager.d.ts.map +1 -0
- package/dist/views/Pages/PageTagManager.js +145 -0
- package/dist/views/Pages/PageTagManager.js.map +1 -0
- package/dist/views/Pages/PagesListView.d.ts +18 -0
- package/dist/views/Pages/PagesListView.d.ts.map +1 -0
- package/dist/views/Pages/PagesListView.js +287 -0
- package/dist/views/Pages/PagesListView.js.map +1 -0
- package/dist/views/Posts/NewPostPicker.d.ts +16 -0
- package/dist/views/Posts/NewPostPicker.d.ts.map +1 -0
- package/dist/views/Posts/NewPostPicker.js +59 -0
- package/dist/views/Posts/NewPostPicker.js.map +1 -0
- package/dist/views/Posts/NewPostTypeInstructions.d.ts +18 -0
- package/dist/views/Posts/NewPostTypeInstructions.d.ts.map +1 -0
- package/dist/views/Posts/NewPostTypeInstructions.js +147 -0
- package/dist/views/Posts/NewPostTypeInstructions.js.map +1 -0
- package/dist/views/Posts/PostTypesView.d.ts +26 -0
- package/dist/views/Posts/PostTypesView.d.ts.map +1 -0
- package/dist/views/Posts/PostTypesView.js +52 -0
- package/dist/views/Posts/PostTypesView.js.map +1 -0
- package/dist/views/Posts/PostsListView.d.ts +25 -0
- package/dist/views/Posts/PostsListView.d.ts.map +1 -0
- package/dist/views/Posts/PostsListView.js +239 -0
- package/dist/views/Posts/PostsListView.js.map +1 -0
- package/dist/views/Posts/post-type-presets.d.ts +32 -0
- package/dist/views/Posts/post-type-presets.d.ts.map +1 -0
- package/dist/views/Posts/post-type-presets.js +72 -0
- package/dist/views/Posts/post-type-presets.js.map +1 -0
- package/dist/views/page-builder/Widgets.d.ts +13 -0
- package/dist/views/page-builder/Widgets.d.ts.map +1 -0
- package/dist/views/page-builder/Widgets.js +15 -0
- package/dist/views/page-builder/Widgets.js.map +1 -0
- package/dist/views/page-editor/AddSectionModal.d.ts +20 -0
- package/dist/views/page-editor/AddSectionModal.d.ts.map +1 -0
- package/dist/views/page-editor/AddSectionModal.js +22 -0
- package/dist/views/page-editor/AddSectionModal.js.map +1 -0
- package/dist/views/page-editor/EditorCanvas.d.ts +18 -0
- package/dist/views/page-editor/EditorCanvas.d.ts.map +1 -0
- package/dist/views/page-editor/EditorCanvas.js +64 -0
- package/dist/views/page-editor/EditorCanvas.js.map +1 -0
- package/dist/views/page-editor/EditorTopBar.d.ts +30 -0
- package/dist/views/page-editor/EditorTopBar.d.ts.map +1 -0
- package/dist/views/page-editor/EditorTopBar.js +42 -0
- package/dist/views/page-editor/EditorTopBar.js.map +1 -0
- package/dist/views/page-editor/PagePreview.d.ts +13 -0
- package/dist/views/page-editor/PagePreview.d.ts.map +1 -0
- package/dist/views/page-editor/PagePreview.js +37 -0
- package/dist/views/page-editor/PagePreview.js.map +1 -0
- package/dist/views/page-editor/PageSectionEditor.d.ts +16 -0
- package/dist/views/page-editor/PageSectionEditor.d.ts.map +1 -0
- package/dist/views/page-editor/PageSectionEditor.js +272 -0
- package/dist/views/page-editor/PageSectionEditor.js.map +1 -0
- package/dist/views/page-editor/PageSettingsModal.d.ts +12 -0
- package/dist/views/page-editor/PageSettingsModal.d.ts.map +1 -0
- package/dist/views/page-editor/PageSettingsModal.js +52 -0
- package/dist/views/page-editor/PageSettingsModal.js.map +1 -0
- package/dist/views/page-editor/SectionInspector.d.ts +17 -0
- package/dist/views/page-editor/SectionInspector.d.ts.map +1 -0
- package/dist/views/page-editor/SectionInspector.js +98 -0
- package/dist/views/page-editor/SectionInspector.js.map +1 -0
- package/dist/views/page-editor/SectionsPanel.d.ts +15 -0
- package/dist/views/page-editor/SectionsPanel.d.ts.map +1 -0
- package/dist/views/page-editor/SectionsPanel.js +43 -0
- package/dist/views/page-editor/SectionsPanel.js.map +1 -0
- package/dist/views/page-editor/ValidationSummary.d.ts +9 -0
- package/dist/views/page-editor/ValidationSummary.d.ts.map +1 -0
- package/dist/views/page-editor/ValidationSummary.js +10 -0
- package/dist/views/page-editor/ValidationSummary.js.map +1 -0
- package/dist/views/page-editor/section-icons.d.ts +4 -0
- package/dist/views/page-editor/section-icons.d.ts.map +1 -0
- package/dist/views/page-editor/section-icons.js +20 -0
- package/dist/views/page-editor/section-icons.js.map +1 -0
- package/dist/views/page-editor/section-types.d.ts +11 -0
- package/dist/views/page-editor/section-types.d.ts.map +1 -0
- package/dist/views/page-editor/section-types.js +10 -0
- package/dist/views/page-editor/section-types.js.map +1 -0
- package/dist/views/page-editor/sections/ArticleBodySection.d.ts +13 -0
- package/dist/views/page-editor/sections/ArticleBodySection.d.ts.map +1 -0
- package/dist/views/page-editor/sections/ArticleBodySection.js +23 -0
- package/dist/views/page-editor/sections/ArticleBodySection.js.map +1 -0
- package/dist/views/page-editor/sections/AuthorBioSection.d.ts +8 -0
- package/dist/views/page-editor/sections/AuthorBioSection.d.ts.map +1 -0
- package/dist/views/page-editor/sections/AuthorBioSection.js +21 -0
- package/dist/views/page-editor/sections/AuthorBioSection.js.map +1 -0
- package/dist/views/page-editor/sections/ByTheNumbersSection.d.ts +5 -0
- package/dist/views/page-editor/sections/ByTheNumbersSection.d.ts.map +1 -0
- package/dist/views/page-editor/sections/ByTheNumbersSection.js +10 -0
- package/dist/views/page-editor/sections/ByTheNumbersSection.js.map +1 -0
- package/dist/views/page-editor/sections/CtaBannerSection.d.ts +5 -0
- package/dist/views/page-editor/sections/CtaBannerSection.d.ts.map +1 -0
- package/dist/views/page-editor/sections/CtaBannerSection.js +10 -0
- package/dist/views/page-editor/sections/CtaBannerSection.js.map +1 -0
- package/dist/views/page-editor/sections/FeatureHighlightSection.d.ts +5 -0
- package/dist/views/page-editor/sections/FeatureHighlightSection.d.ts.map +1 -0
- package/dist/views/page-editor/sections/FeatureHighlightSection.js +18 -0
- package/dist/views/page-editor/sections/FeatureHighlightSection.js.map +1 -0
- package/dist/views/page-editor/sections/GallerySection.d.ts +6 -0
- package/dist/views/page-editor/sections/GallerySection.d.ts.map +1 -0
- package/dist/views/page-editor/sections/GallerySection.js +17 -0
- package/dist/views/page-editor/sections/GallerySection.js.map +1 -0
- package/dist/views/page-editor/sections/HeroBannerSection.d.ts +5 -0
- package/dist/views/page-editor/sections/HeroBannerSection.d.ts.map +1 -0
- package/dist/views/page-editor/sections/HeroBannerSection.js +11 -0
- package/dist/views/page-editor/sections/HeroBannerSection.js.map +1 -0
- package/dist/views/page-editor/sections/MissionSection.d.ts +6 -0
- package/dist/views/page-editor/sections/MissionSection.d.ts.map +1 -0
- package/dist/views/page-editor/sections/MissionSection.js +12 -0
- package/dist/views/page-editor/sections/MissionSection.js.map +1 -0
- package/dist/views/page-editor/sections/PullQuoteSection.d.ts +6 -0
- package/dist/views/page-editor/sections/PullQuoteSection.d.ts.map +1 -0
- package/dist/views/page-editor/sections/PullQuoteSection.js +13 -0
- package/dist/views/page-editor/sections/PullQuoteSection.js.map +1 -0
- package/dist/views/page-editor/sections/RelatedPostsSection.d.ts +12 -0
- package/dist/views/page-editor/sections/RelatedPostsSection.d.ts.map +1 -0
- package/dist/views/page-editor/sections/RelatedPostsSection.js +23 -0
- package/dist/views/page-editor/sections/RelatedPostsSection.js.map +1 -0
- package/dist/views/page-editor/sections/SectionRenderer.d.ts +22 -0
- package/dist/views/page-editor/sections/SectionRenderer.d.ts.map +1 -0
- package/dist/views/page-editor/sections/SectionRenderer.js +52 -0
- package/dist/views/page-editor/sections/SectionRenderer.js.map +1 -0
- package/dist/views/page-editor/sections/index.d.ts +14 -0
- package/dist/views/page-editor/sections/index.d.ts.map +1 -0
- package/dist/views/page-editor/sections/index.js +12 -0
- package/dist/views/page-editor/sections/index.js.map +1 -0
- package/dist/views/page-editor/sections/parts.d.ts +55 -0
- package/dist/views/page-editor/sections/parts.d.ts.map +1 -0
- package/dist/views/page-editor/sections/parts.js +60 -0
- package/dist/views/page-editor/sections/parts.js.map +1 -0
- package/dist/views/page-editor/viewports.d.ts +14 -0
- package/dist/views/page-editor/viewports.d.ts.map +1 -0
- package/dist/views/page-editor/viewports.js +12 -0
- package/dist/views/page-editor/viewports.js.map +1 -0
- package/dist/views/post-editor/PostEditorCanvas.d.ts +21 -0
- package/dist/views/post-editor/PostEditorCanvas.d.ts.map +1 -0
- package/dist/views/post-editor/PostEditorCanvas.js +58 -0
- package/dist/views/post-editor/PostEditorCanvas.js.map +1 -0
- package/dist/views/post-editor/PostFieldsModal.d.ts +12 -0
- package/dist/views/post-editor/PostFieldsModal.d.ts.map +1 -0
- package/dist/views/post-editor/PostFieldsModal.js +53 -0
- package/dist/views/post-editor/PostFieldsModal.js.map +1 -0
- package/dist/views/post-editor/PostHeader.d.ts +15 -0
- package/dist/views/post-editor/PostHeader.d.ts.map +1 -0
- package/dist/views/post-editor/PostHeader.js +27 -0
- package/dist/views/post-editor/PostHeader.js.map +1 -0
- package/dist/views/post-editor/PostHeaderPanel.d.ts +11 -0
- package/dist/views/post-editor/PostHeaderPanel.d.ts.map +1 -0
- package/dist/views/post-editor/PostHeaderPanel.js +21 -0
- package/dist/views/post-editor/PostHeaderPanel.js.map +1 -0
- package/dist/views/post-editor/PostPreview.d.ts +14 -0
- package/dist/views/post-editor/PostPreview.d.ts.map +1 -0
- package/dist/views/post-editor/PostPreview.js +53 -0
- package/dist/views/post-editor/PostPreview.js.map +1 -0
- package/dist/views/post-editor/PostSectionEditor.d.ts +17 -0
- package/dist/views/post-editor/PostSectionEditor.d.ts.map +1 -0
- package/dist/views/post-editor/PostSectionEditor.js +290 -0
- package/dist/views/post-editor/PostSectionEditor.js.map +1 -0
- package/dist/views/post-editor/PostTemplateEditor.d.ts +9 -0
- package/dist/views/post-editor/PostTemplateEditor.d.ts.map +1 -0
- package/dist/views/post-editor/PostTemplateEditor.js +144 -0
- package/dist/views/post-editor/PostTemplateEditor.js.map +1 -0
- package/package.json +2 -2
- package/src/AdminRoot.tsx +213 -2
- package/src/__tests__/components/posts-badges.test.tsx +77 -0
- package/src/__tests__/layout/sidebar-posts.test.ts +179 -0
- package/src/__tests__/lib/page-editor-service.test.ts +173 -0
- package/src/__tests__/lib/pages-service.test.ts +157 -0
- package/src/__tests__/lib/post-editor-service.test.ts +215 -0
- package/src/__tests__/lib/posts-service.test.ts +279 -0
- package/src/__tests__/views/posts-list-view.test.ts +110 -0
- package/src/components/pages/tag-badges.tsx +104 -0
- package/src/components/posts/badges.tsx +170 -0
- package/src/components/posts/icons.ts +40 -0
- package/src/layout/Layout.tsx +66 -10
- package/src/layout/Sidebar.tsx +116 -50
- package/src/lib/page-editor-service.ts +233 -0
- package/src/lib/pages-service.ts +599 -0
- package/src/lib/post-editor-service.ts +342 -0
- package/src/lib/posts-service.ts +366 -0
- package/src/lib/preview-link.ts +63 -0
- package/src/router/index.ts +10 -1
- package/src/views/Dashboard.tsx +15 -3
- package/src/views/Pages/PageTagManager.tsx +436 -0
- package/src/views/Pages/PagesListView.tsx +944 -0
- package/src/views/Posts/NewPostPicker.tsx +147 -0
- package/src/views/Posts/NewPostTypeInstructions.tsx +344 -0
- package/src/views/Posts/PostTypesView.tsx +194 -0
- package/src/views/Posts/PostsListView.tsx +869 -0
- package/src/views/Posts/post-type-presets.ts +105 -0
- package/src/views/page-builder/Widgets.tsx +44 -0
- package/src/views/page-editor/AddSectionModal.tsx +56 -0
- package/src/views/page-editor/EditorCanvas.tsx +127 -0
- package/src/views/page-editor/EditorTopBar.tsx +233 -0
- package/src/views/page-editor/PagePreview.tsx +96 -0
- package/src/views/page-editor/PageSectionEditor.tsx +476 -0
- package/src/views/page-editor/PageSettingsModal.tsx +154 -0
- package/src/views/page-editor/SectionInspector.tsx +599 -0
- package/src/views/page-editor/SectionsPanel.tsx +270 -0
- package/src/views/page-editor/ValidationSummary.tsx +53 -0
- package/src/views/page-editor/section-icons.ts +33 -0
- package/src/views/page-editor/section-types.ts +27 -0
- package/src/views/page-editor/sections/ArticleBodySection.tsx +57 -0
- package/src/views/page-editor/sections/AuthorBioSection.tsx +61 -0
- package/src/views/page-editor/sections/ByTheNumbersSection.tsx +41 -0
- package/src/views/page-editor/sections/CtaBannerSection.tsx +29 -0
- package/src/views/page-editor/sections/FeatureHighlightSection.tsx +63 -0
- package/src/views/page-editor/sections/GallerySection.tsx +54 -0
- package/src/views/page-editor/sections/HeroBannerSection.tsx +44 -0
- package/src/views/page-editor/sections/MissionSection.tsx +22 -0
- package/src/views/page-editor/sections/PullQuoteSection.tsx +27 -0
- package/src/views/page-editor/sections/RelatedPostsSection.tsx +55 -0
- package/src/views/page-editor/sections/SectionRenderer.tsx +102 -0
- package/src/views/page-editor/sections/index.ts +13 -0
- package/src/views/page-editor/sections/parts.tsx +113 -0
- package/src/views/page-editor/viewports.ts +25 -0
- package/src/views/post-editor/PostEditorCanvas.tsx +123 -0
- package/src/views/post-editor/PostFieldsModal.tsx +196 -0
- package/src/views/post-editor/PostHeader.tsx +87 -0
- package/src/views/post-editor/PostHeaderPanel.tsx +107 -0
- package/src/views/post-editor/PostPreview.tsx +114 -0
- package/src/views/post-editor/PostSectionEditor.tsx +506 -0
- package/src/views/post-editor/PostTemplateEditor.tsx +347 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo, useState } from 'react';
|
|
4
|
+
import { ArrowLeft, Check, Copy, Sparkles } from 'lucide-react';
|
|
5
|
+
import { toast } from 'sonner';
|
|
6
|
+
import { resolvePostTypeIcon } from '../../components/posts/icons.js';
|
|
7
|
+
import { paletteFor } from '../../components/posts/badges.js';
|
|
8
|
+
import { POST_TYPE_PRESETS } from './post-type-presets.js';
|
|
9
|
+
/**
|
|
10
|
+
* /posts/types/new — Quick Post Type gallery + snippet generator.
|
|
11
|
+
*
|
|
12
|
+
* Two ways to start:
|
|
13
|
+
* 1. Pick a Quick Post Type preset (Case Studies, News, Portfolio,
|
|
14
|
+
* Events, Team) — pre-fills the form and tailored extra fields.
|
|
15
|
+
* 2. Fill the form from scratch.
|
|
16
|
+
*
|
|
17
|
+
* Either way the page emits a paste-ready `actuate.config.ts` snippet.
|
|
18
|
+
*
|
|
19
|
+
* Why this isn't a runtime form-driven CRUD:
|
|
20
|
+
* Collections in ActuateCMS are file-defined in `actuate.config.ts`.
|
|
21
|
+
* Writing to that file at runtime would require either a parallel
|
|
22
|
+
* DB-only post-type model that duplicates the Collection concept, or
|
|
23
|
+
* mutating a source file on disk — which breaks Vercel's read-only
|
|
24
|
+
* serverless filesystem and any immutable deploy model. So we
|
|
25
|
+
* generate the snippet and the developer commits + redeploys. Same
|
|
26
|
+
* model Sanity, Keystone, and Payload use for code-defined schemas.
|
|
27
|
+
*/
|
|
28
|
+
const SLUG_RE = /^[a-z][a-z0-9-]*$/;
|
|
29
|
+
const ICON_OPTIONS = [
|
|
30
|
+
{ value: 'file-text', label: 'Document' },
|
|
31
|
+
{ value: 'briefcase', label: 'Briefcase' },
|
|
32
|
+
{ value: 'newspaper', label: 'Newspaper' },
|
|
33
|
+
{ value: 'book', label: 'Book' },
|
|
34
|
+
{ value: 'folder', label: 'Folder' },
|
|
35
|
+
{ value: 'layers', label: 'Layers' },
|
|
36
|
+
{ value: 'image', label: 'Image' },
|
|
37
|
+
{ value: 'calendar', label: 'Calendar' },
|
|
38
|
+
{ value: 'users', label: 'People' },
|
|
39
|
+
{ value: 'help', label: 'Help' },
|
|
40
|
+
];
|
|
41
|
+
const BLANK_DRAFT = {
|
|
42
|
+
slug: '',
|
|
43
|
+
singular: '',
|
|
44
|
+
plural: '',
|
|
45
|
+
color: 'purple',
|
|
46
|
+
icon: 'file-text',
|
|
47
|
+
description: '',
|
|
48
|
+
extraFields: [],
|
|
49
|
+
};
|
|
50
|
+
export function NewPostTypeInstructions({ onNavigate }) {
|
|
51
|
+
const [draft, setDraft] = useState(BLANK_DRAFT);
|
|
52
|
+
const [activePreset, setActivePreset] = useState(null);
|
|
53
|
+
const [copied, setCopied] = useState(false);
|
|
54
|
+
const snippet = useMemo(() => renderSnippet(draft), [draft]);
|
|
55
|
+
const slugValid = SLUG_RE.test(draft.slug);
|
|
56
|
+
const applyPreset = (preset) => {
|
|
57
|
+
setActivePreset(preset.key);
|
|
58
|
+
setDraft({
|
|
59
|
+
slug: preset.slug,
|
|
60
|
+
singular: preset.singular,
|
|
61
|
+
plural: preset.plural,
|
|
62
|
+
color: preset.color,
|
|
63
|
+
icon: preset.icon,
|
|
64
|
+
description: preset.description,
|
|
65
|
+
extraFields: preset.extraFields,
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
// Manual edits clear the active-preset highlight but keep any
|
|
69
|
+
// preset-seeded extra fields (the user may still want them).
|
|
70
|
+
const patchDraft = (patch) => {
|
|
71
|
+
setActivePreset(null);
|
|
72
|
+
setDraft((d) => ({ ...d, ...patch }));
|
|
73
|
+
};
|
|
74
|
+
const copy = async () => {
|
|
75
|
+
try {
|
|
76
|
+
await navigator.clipboard.writeText(snippet);
|
|
77
|
+
setCopied(true);
|
|
78
|
+
toast.success('Snippet copied to clipboard');
|
|
79
|
+
setTimeout(() => setCopied(false), 1800);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
toast.error('Copy failed — select the snippet manually');
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
return (_jsxs("div", { className: "mx-auto flex h-full max-w-3xl flex-col gap-6 p-4 sm:p-6", children: [_jsxs("button", { type: "button", onClick: () => onNavigate('/posts/types'), className: "text-muted-foreground hover:text-foreground inline-flex w-fit items-center gap-1.5 text-sm transition-colors", children: [_jsx(ArrowLeft, { className: "h-3.5 w-3.5", "aria-hidden": true }), "Back to Post Types"] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "text-foreground text-xl font-medium tracking-tight sm:text-2xl", children: "Add a Post Type" }), _jsxs("p", { className: "text-muted-foreground text-sm", children: ["Post Types are content models defined in", ' ', _jsx("code", { className: "font-mono", children: "actuate.config.ts" }), ". Start from a quick template or fill in the details below, then paste the generated snippet into your config and redeploy."] })] }), _jsxs("section", { "aria-labelledby": "quick-types-heading", className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(Sparkles, { className: "text-muted-foreground h-3.5 w-3.5", "aria-hidden": true }), _jsx("h2", { id: "quick-types-heading", className: "text-foreground text-sm font-medium", children: "Quick start" })] }), _jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5", children: POST_TYPE_PRESETS.map((preset) => {
|
|
86
|
+
const palette = paletteFor(preset.color);
|
|
87
|
+
const Icon = resolvePostTypeIcon(preset.icon);
|
|
88
|
+
const selected = activePreset === preset.key;
|
|
89
|
+
return (_jsxs("button", { type: "button", onClick: () => applyPreset(preset), "aria-pressed": selected, className: `focus-visible:ring-ring flex flex-col items-start gap-2 rounded-xl border p-3 text-left shadow-sm transition-colors focus:outline-none focus-visible:ring-2 ${selected
|
|
90
|
+
? 'border-primary bg-primary/5'
|
|
91
|
+
: 'border-border bg-card hover:border-primary/40 hover:bg-accent'}`, children: [_jsx("span", { className: `inline-flex h-8 w-8 items-center justify-center rounded-lg ${palette.bg} ${palette.text}`, children: _jsx(Icon, { className: "h-4 w-4", "aria-hidden": true }) }), _jsx("span", { className: "text-foreground text-sm leading-tight font-medium", children: preset.label })] }, preset.key));
|
|
92
|
+
}) })] }), _jsxs("div", { className: "bg-card border-border grid grid-cols-1 gap-4 rounded-xl border p-5 shadow-sm sm:grid-cols-2", children: [_jsx(Field, { label: "Slug", htmlFor: "pt-slug", error: draft.slug && !slugValid ? 'lowercase letters, numbers, and dashes only' : null, children: _jsx("input", { id: "pt-slug", value: draft.slug, onChange: (e) => patchDraft({ slug: e.target.value.trim() }), className: "border-border bg-background text-foreground focus:border-primary focus:ring-primary/30 w-full rounded-lg border px-3 py-1.5 text-sm focus:ring-2 focus:outline-none", placeholder: "reviews" }) }), _jsx(Field, { label: "Singular label", htmlFor: "pt-singular", children: _jsx("input", { id: "pt-singular", value: draft.singular, onChange: (e) => patchDraft({ singular: e.target.value }), className: "border-border bg-background text-foreground focus:border-primary focus:ring-primary/30 w-full rounded-lg border px-3 py-1.5 text-sm focus:ring-2 focus:outline-none", placeholder: "Review" }) }), _jsx(Field, { label: "Plural label", htmlFor: "pt-plural", children: _jsx("input", { id: "pt-plural", value: draft.plural, onChange: (e) => patchDraft({ plural: e.target.value }), className: "border-border bg-background text-foreground focus:border-primary focus:ring-primary/30 w-full rounded-lg border px-3 py-1.5 text-sm focus:ring-2 focus:outline-none", placeholder: "Reviews" }) }), _jsx(Field, { label: "Description", htmlFor: "pt-desc", children: _jsx("input", { id: "pt-desc", value: draft.description, onChange: (e) => patchDraft({ description: e.target.value }), className: "border-border bg-background text-foreground focus:border-primary focus:ring-primary/30 w-full rounded-lg border px-3 py-1.5 text-sm focus:ring-2 focus:outline-none", placeholder: "Product reviews and editorial pieces." }) }), _jsx(Field, { label: "Accent color", htmlFor: "pt-color", children: _jsxs("select", { id: "pt-color", value: draft.color, onChange: (e) => patchDraft({ color: e.target.value }), className: "border-border bg-background text-foreground focus:border-primary focus:ring-primary/30 w-full rounded-lg border px-3 py-1.5 text-sm focus:ring-2 focus:outline-none", children: [_jsx("option", { value: "purple", children: "Purple" }), _jsx("option", { value: "green", children: "Green" }), _jsx("option", { value: "orange", children: "Orange" }), _jsx("option", { value: "blue", children: "Blue" }), _jsx("option", { value: "red", children: "Red" }), _jsx("option", { value: "pink", children: "Pink" })] }) }), _jsx(Field, { label: "Icon", htmlFor: "pt-icon", children: _jsx("select", { id: "pt-icon", value: draft.icon, onChange: (e) => patchDraft({ icon: e.target.value }), className: "border-border bg-background text-foreground focus:border-primary focus:ring-primary/30 w-full rounded-lg border px-3 py-1.5 text-sm focus:ring-2 focus:outline-none", children: ICON_OPTIONS.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) }) })] }), _jsxs("div", { children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsxs("h2", { className: "text-foreground text-sm font-medium", children: ["Add to ", _jsx("code", { className: "font-mono", children: "actuate.config.ts" })] }), _jsxs("button", { type: "button", onClick: copy, disabled: !slugValid, className: "border-border bg-background text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40", children: [copied ? (_jsx(Check, { className: "h-3.5 w-3.5", "aria-hidden": true })) : (_jsx(Copy, { className: "h-3.5 w-3.5", "aria-hidden": true })), copied ? 'Copied' : 'Copy snippet'] })] }), _jsx("pre", { className: "border-border bg-muted text-foreground overflow-x-auto rounded-lg border p-4 text-xs leading-relaxed", children: _jsx("code", { children: snippet }) }), _jsx("p", { className: "text-muted-foreground mt-3 text-xs", children: "After adding the snippet and redeploying, the new type will appear in the Posts area tabs and on this Post Types page automatically." })] })] }));
|
|
93
|
+
}
|
|
94
|
+
function Field({ label, htmlFor, error, children, }) {
|
|
95
|
+
return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: htmlFor, className: "text-foreground text-sm font-medium", children: label }), children, error ? _jsx("span", { className: "text-destructive text-xs", children: error }) : null] }));
|
|
96
|
+
}
|
|
97
|
+
export function renderSnippet(draft) {
|
|
98
|
+
const safeSlug = draft.slug || 'new-type';
|
|
99
|
+
const extraFieldsBlock = draft.extraFields.length > 0
|
|
100
|
+
? '\n // type-specific fields\n' +
|
|
101
|
+
draft.extraFields.map((line) => ` ${line}`).join('\n') +
|
|
102
|
+
'\n'
|
|
103
|
+
: '';
|
|
104
|
+
return `// Add this entry to the \`collections\` map in actuate.config.ts:
|
|
105
|
+
collections: {
|
|
106
|
+
// …existing collections,
|
|
107
|
+
'${safeSlug}': {
|
|
108
|
+
slug: '${safeSlug}',
|
|
109
|
+
labels: {
|
|
110
|
+
singular: '${escapeString(draft.singular || 'Entry')}',
|
|
111
|
+
plural: '${escapeString(draft.plural || 'Entries')}',
|
|
112
|
+
},
|
|
113
|
+
type: 'post',
|
|
114
|
+
urlPrefix: '${safeSlug}',
|
|
115
|
+
admin: {
|
|
116
|
+
group: 'Posts',
|
|
117
|
+
icon: '${draft.icon}',
|
|
118
|
+
color: '${draft.color}',
|
|
119
|
+
description: '${escapeString(draft.description)}',
|
|
120
|
+
},
|
|
121
|
+
fields: {
|
|
122
|
+
title: { type: 'text', label: 'Title', required: true },
|
|
123
|
+
slug: { type: 'slug', label: 'Slug', from: 'title' },
|
|
124
|
+
excerpt: { type: 'text', label: 'Excerpt' },
|
|
125
|
+
featuredImage: { type: 'media', label: 'Featured Image' },
|
|
126
|
+
body: { type: 'richText', label: 'Body' },
|
|
127
|
+
status: {
|
|
128
|
+
type: 'select',
|
|
129
|
+
label: 'Status',
|
|
130
|
+
options: [
|
|
131
|
+
{ label: 'Draft', value: 'draft' },
|
|
132
|
+
{ label: 'Published', value: 'published' },
|
|
133
|
+
{ label: 'Scheduled', value: 'scheduled' },
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
publishDate: { type: 'date', label: 'Publish Date', includeTime: true },
|
|
137
|
+
metaTitle: { type: 'text', label: 'SEO Title' },
|
|
138
|
+
metaDescription: { type: 'text', label: 'SEO Description' },
|
|
139
|
+
${extraFieldsBlock} },
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
`;
|
|
143
|
+
}
|
|
144
|
+
function escapeString(input) {
|
|
145
|
+
return input.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=NewPostTypeInstructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NewPostTypeInstructions.js","sourceRoot":"","sources":["../../../src/views/Posts/NewPostTypeInstructions.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post Types — card grid that mirrors the reference screenshot. Each
|
|
3
|
+
* card surfaces:
|
|
4
|
+
* - colored top border (accent)
|
|
5
|
+
* - icon badge in upper-left
|
|
6
|
+
* - title + description
|
|
7
|
+
* - footer row: post count · field count · URL base
|
|
8
|
+
*
|
|
9
|
+
* Cards open the per-collection settings (`/collections/:slug/settings`
|
|
10
|
+
* in the existing admin) when clicked. The dashed "+ New Post Type"
|
|
11
|
+
* card routes to /posts/types/new where users get instructions for
|
|
12
|
+
* adding a new collection to the config file.
|
|
13
|
+
*
|
|
14
|
+
* Why no in-app create/edit flow yet:
|
|
15
|
+
* Collections are file-defined (actuate.config.ts). Writing to that
|
|
16
|
+
* file at runtime would require a parallel data model and break the
|
|
17
|
+
* read-only deploy invariant on serverless platforms. v2 of this
|
|
18
|
+
* surface will introduce a DB-overlay for visual metadata (icon /
|
|
19
|
+
* color / description) — schema stays in code.
|
|
20
|
+
*/
|
|
21
|
+
interface PostTypesViewProps {
|
|
22
|
+
onNavigate: (path: string) => void;
|
|
23
|
+
}
|
|
24
|
+
export declare function PostTypesView({ onNavigate }: PostTypesViewProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=PostTypesView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostTypesView.d.ts","sourceRoot":"","sources":["../../../src/views/Posts/PostTypesView.tsx"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,UAAU,kBAAkB;IAC1B,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC;AAED,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,EAAE,kBAAkB,2CAkE/D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { LayoutTemplate, Plus } from 'lucide-react';
|
|
5
|
+
import { fetchPosts } from '../../lib/posts-service.js';
|
|
6
|
+
import { paletteFor } from '../../components/posts/badges.js';
|
|
7
|
+
import { resolvePostTypeIcon } from '../../components/posts/icons.js';
|
|
8
|
+
export function PostTypesView({ onNavigate }) {
|
|
9
|
+
const [types, setTypes] = useState([]);
|
|
10
|
+
const [loading, setLoading] = useState(true);
|
|
11
|
+
const [error, setError] = useState(null);
|
|
12
|
+
const [refreshToken, setRefreshToken] = useState(0);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
let cancelled = false;
|
|
15
|
+
setLoading(true);
|
|
16
|
+
setError(null);
|
|
17
|
+
fetchPosts({ pageSize: 1 })
|
|
18
|
+
.then((res) => {
|
|
19
|
+
if (cancelled)
|
|
20
|
+
return;
|
|
21
|
+
setTypes(res.types);
|
|
22
|
+
setLoading(false);
|
|
23
|
+
})
|
|
24
|
+
.catch((err) => {
|
|
25
|
+
if (cancelled)
|
|
26
|
+
return;
|
|
27
|
+
setError(err instanceof Error ? err.message : 'Failed to load Post Types');
|
|
28
|
+
setLoading(false);
|
|
29
|
+
});
|
|
30
|
+
return () => {
|
|
31
|
+
cancelled = true;
|
|
32
|
+
};
|
|
33
|
+
}, [refreshToken]);
|
|
34
|
+
return (_jsxs("div", { className: "flex h-full flex-col gap-6 p-4 sm:p-6", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "text-foreground text-xl font-medium tracking-tight sm:text-2xl", children: "Post Types" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Define content models and their fields. All types share the same default fields." })] }), loading && _jsx(CardGridSkeleton, {}), !loading && error && (_jsxs("div", { className: "border-border bg-card rounded-xl border p-8 text-center", children: [_jsx("div", { className: "text-foreground mb-2 text-sm font-medium", children: error }), _jsx("button", { type: "button", onClick: () => setRefreshToken((t) => t + 1), className: "text-primary text-sm hover:underline", children: "Try again" })] })), !loading && !error && (_jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4", children: [types.map((t) => (_jsx(PostTypeCard, { type: t, onClick: () => onNavigate(`/posts/types/${t.slug}/edit`), onEditTemplate: () => onNavigate(`/posts/types/${t.slug}/template`) }, t.slug))), _jsx(NewPostTypeCard, { onClick: () => onNavigate('/posts/types/new') })] }))] }));
|
|
35
|
+
}
|
|
36
|
+
// ─── PostTypeCard ────────────────────────────────────────────────────
|
|
37
|
+
function PostTypeCard({ type, onClick, onEditTemplate, }) {
|
|
38
|
+
const palette = paletteFor(type.accentColor);
|
|
39
|
+
const Icon = resolvePostTypeIcon(type.icon);
|
|
40
|
+
// Tailwind needs the exact class string at build time — derive the
|
|
41
|
+
// top-border color from the palette's `border` token directly so it
|
|
42
|
+
// stays in sync with the badge color.
|
|
43
|
+
const topBorderClass = palette.border;
|
|
44
|
+
return (_jsxs("div", { className: "bg-card border-border relative flex flex-col gap-3 overflow-hidden rounded-xl border p-5 shadow-sm transition-shadow hover:shadow-md", children: [_jsx("span", { "aria-hidden": true, className: `absolute inset-x-0 top-0 h-1 ${topBorderClass}` }), _jsxs("button", { type: "button", onClick: onClick, "aria-label": `Manage ${type.name} posts`, className: "focus-visible:ring-ring -m-1 flex flex-col gap-3 rounded-lg p-1 text-left focus:outline-none focus-visible:ring-2", children: [_jsxs("div", { className: "flex items-center gap-3 pt-2", children: [_jsx("span", { className: `inline-flex h-9 w-9 items-center justify-center rounded-lg ${palette.bg} ${palette.text}`, children: _jsx(Icon, { className: "h-4 w-4", "aria-hidden": true }) }), _jsx("h2", { className: "text-foreground text-base leading-tight font-medium", children: type.name })] }), _jsx("p", { className: "text-muted-foreground line-clamp-2 text-sm", children: type.description ?? 'No description provided.' })] }), _jsxs("div", { className: "border-border mt-auto flex flex-wrap items-center gap-x-4 gap-y-1 border-t pt-3 text-xs", children: [_jsxs("span", { className: "text-foreground font-medium tabular-nums", children: [type.postCount, " ", _jsx("span", { className: "text-muted-foreground font-normal", children: "posts" })] }), _jsxs("span", { className: "text-foreground font-medium tabular-nums", children: [type.fieldCount, " ", _jsx("span", { className: "text-muted-foreground font-normal", children: "fields" })] }), _jsx("span", { className: "text-muted-foreground ml-auto truncate font-mono", children: type.urlBase })] }), _jsxs("button", { type: "button", onClick: onEditTemplate, className: "border-border text-foreground hover:bg-accent focus-visible:ring-ring inline-flex items-center justify-center gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs font-medium transition-colors focus:outline-none focus-visible:ring-2", children: [_jsx(LayoutTemplate, { className: "h-3.5 w-3.5", "aria-hidden": true }), "Edit template"] })] }));
|
|
45
|
+
}
|
|
46
|
+
function NewPostTypeCard({ onClick }) {
|
|
47
|
+
return (_jsxs("button", { type: "button", onClick: onClick, "aria-label": "New Post Type", className: "border-border text-muted-foreground hover:text-foreground hover:border-primary/50 hover:bg-primary/5 focus-visible:ring-ring flex min-h-[170px] flex-col items-center justify-center gap-2 rounded-xl border-2 border-dashed bg-transparent p-5 transition-colors focus:outline-none focus-visible:ring-2", children: [_jsx("span", { className: "bg-muted text-muted-foreground inline-flex h-9 w-9 items-center justify-center rounded-full", children: _jsx(Plus, { className: "h-4 w-4", "aria-hidden": true }) }), _jsx("span", { className: "text-sm font-medium", children: "New Post Type" })] }));
|
|
48
|
+
}
|
|
49
|
+
function CardGridSkeleton() {
|
|
50
|
+
return (_jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4", children: Array.from({ length: 4 }).map((_, i) => (_jsxs("div", { className: "bg-card border-border min-h-[170px] animate-pulse rounded-xl border p-5", children: [_jsx("div", { className: "bg-muted mb-3 h-9 w-9 rounded-lg" }), _jsx("div", { className: "bg-muted mb-2 h-4 w-1/2 rounded" }), _jsx("div", { className: "bg-muted h-3 w-3/4 rounded" })] }, i))) }));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=PostTypesView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostTypesView.js","sourceRoot":"","sources":["../../../src/views/Posts/PostTypesView.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All Posts management surface — table with type tabs, controls row,
|
|
3
|
+
* sortable headers, bulk actions, pagination. Data flows through the
|
|
4
|
+
* posts-service so swapping to a server endpoint later only touches
|
|
5
|
+
* the service file.
|
|
6
|
+
*
|
|
7
|
+
* Routing:
|
|
8
|
+
* - Row click → /posts/{postTypeId}/{postId}/edit (the section-based Post
|
|
9
|
+
* editor, seeded from the post type's template).
|
|
10
|
+
* - "Manage types" → /posts/types.
|
|
11
|
+
* - "+ New Post" lives in the top bar (computePageActions); the page
|
|
12
|
+
* itself doesn't render that button.
|
|
13
|
+
*/
|
|
14
|
+
interface PostsListViewProps {
|
|
15
|
+
onNavigate: (path: string) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function PostsListView({ onNavigate }: PostsListViewProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
/**
|
|
19
|
+
* Return up to 7 page-control entries: a sliding window around the
|
|
20
|
+
* current page with ellipsis markers. Keeps the footer narrow even on
|
|
21
|
+
* collections with hundreds of pages.
|
|
22
|
+
*/
|
|
23
|
+
export declare function pageNumbers(current: number, total: number): Array<number | '…'>;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=PostsListView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostsListView.d.ts","sourceRoot":"","sources":["../../../src/views/Posts/PostsListView.tsx"],"names":[],"mappings":"AAgCA;;;;;;;;;;;;GAYG;AAEH,UAAU,kBAAkB;IAC1B,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC;AAOD,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,EAAE,kBAAkB,2CA2U/D;AAmdD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAU/E"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Search, Settings, Trash2, X, } from 'lucide-react';
|
|
5
|
+
import { toast } from 'sonner';
|
|
6
|
+
import { bulkDeletePosts, bulkUpdatePosts, fetchPosts, } from '../../lib/posts-service.js';
|
|
7
|
+
import { PostStatusBadge, PostTypeBadge, SeoScoreIndicator, paletteFor, } from '../../components/posts/badges.js';
|
|
8
|
+
import { ConfirmDialog } from '../../components/ui/ConfirmDialog.js';
|
|
9
|
+
const PAGE_SIZE = 10;
|
|
10
|
+
export function PostsListView({ onNavigate }) {
|
|
11
|
+
const [activeType, setActiveType] = useState('all');
|
|
12
|
+
const [search, setSearch] = useState('');
|
|
13
|
+
const [debouncedSearch, setDebouncedSearch] = useState('');
|
|
14
|
+
const [status, setStatus] = useState('all');
|
|
15
|
+
const [author, setAuthor] = useState('all');
|
|
16
|
+
const [sortBy, setSortBy] = useState('date');
|
|
17
|
+
const [dir, setDir] = useState('desc');
|
|
18
|
+
const [page, setPage] = useState(1);
|
|
19
|
+
const [selected, setSelected] = useState(new Set());
|
|
20
|
+
const [data, setData] = useState(null);
|
|
21
|
+
const [loading, setLoading] = useState(true);
|
|
22
|
+
const [error, setError] = useState(null);
|
|
23
|
+
const [refreshToken, setRefreshToken] = useState(0);
|
|
24
|
+
const [pendingBulk, setPendingBulk] = useState(null);
|
|
25
|
+
const debounceTimer = useRef(null);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (debounceTimer.current)
|
|
28
|
+
clearTimeout(debounceTimer.current);
|
|
29
|
+
debounceTimer.current = setTimeout(() => {
|
|
30
|
+
setDebouncedSearch(search.trim());
|
|
31
|
+
setPage(1);
|
|
32
|
+
}, 250);
|
|
33
|
+
return () => {
|
|
34
|
+
if (debounceTimer.current)
|
|
35
|
+
clearTimeout(debounceTimer.current);
|
|
36
|
+
};
|
|
37
|
+
}, [search]);
|
|
38
|
+
// Re-fetch when any input that affects the result set changes.
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
let cancelled = false;
|
|
41
|
+
setLoading(true);
|
|
42
|
+
setError(null);
|
|
43
|
+
fetchPosts({
|
|
44
|
+
postType: activeType,
|
|
45
|
+
status,
|
|
46
|
+
author,
|
|
47
|
+
search: debouncedSearch,
|
|
48
|
+
sortBy,
|
|
49
|
+
sortDirection: dir,
|
|
50
|
+
page,
|
|
51
|
+
pageSize: PAGE_SIZE,
|
|
52
|
+
})
|
|
53
|
+
.then((res) => {
|
|
54
|
+
if (cancelled)
|
|
55
|
+
return;
|
|
56
|
+
setData(res);
|
|
57
|
+
setLoading(false);
|
|
58
|
+
})
|
|
59
|
+
.catch((err) => {
|
|
60
|
+
if (cancelled)
|
|
61
|
+
return;
|
|
62
|
+
setError(err instanceof Error ? err.message : 'Failed to load posts');
|
|
63
|
+
setLoading(false);
|
|
64
|
+
});
|
|
65
|
+
return () => {
|
|
66
|
+
cancelled = true;
|
|
67
|
+
};
|
|
68
|
+
}, [activeType, status, author, debouncedSearch, sortBy, dir, page, refreshToken]);
|
|
69
|
+
// Whenever the active type tab changes, reset paging to page 1.
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
setPage(1);
|
|
72
|
+
setSelected(new Set());
|
|
73
|
+
}, [activeType, debouncedSearch, status, author]);
|
|
74
|
+
const total = data?.total ?? 0;
|
|
75
|
+
const totalAll = useMemo(() => (data?.types ?? []).reduce((sum, t) => sum + t.postCount, 0), [data?.types]);
|
|
76
|
+
const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE));
|
|
77
|
+
const posts = data?.posts ?? [];
|
|
78
|
+
const types = data?.types ?? [];
|
|
79
|
+
const authors = data?.authors ?? [];
|
|
80
|
+
const handleSort = useCallback((field) => {
|
|
81
|
+
if (sortBy === field) {
|
|
82
|
+
setDir(dir === 'asc' ? 'desc' : 'asc');
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
setSortBy(field);
|
|
86
|
+
setDir(field === 'date' || field === 'seo' ? 'desc' : 'asc');
|
|
87
|
+
}
|
|
88
|
+
}, [sortBy, dir]);
|
|
89
|
+
const clearFilters = () => {
|
|
90
|
+
setSearch('');
|
|
91
|
+
setStatus('all');
|
|
92
|
+
setAuthor('all');
|
|
93
|
+
setActiveType('all');
|
|
94
|
+
setPage(1);
|
|
95
|
+
};
|
|
96
|
+
const filtersAreActive = debouncedSearch !== '' || status !== 'all' || author !== 'all' || activeType !== 'all';
|
|
97
|
+
// ─── Selection / bulk actions ─────────────────────────────────────
|
|
98
|
+
const toggleOne = (id) => setSelected((s) => {
|
|
99
|
+
const next = new Set(s);
|
|
100
|
+
if (next.has(id))
|
|
101
|
+
next.delete(id);
|
|
102
|
+
else
|
|
103
|
+
next.add(id);
|
|
104
|
+
return next;
|
|
105
|
+
});
|
|
106
|
+
const allOnPageSelected = posts.length > 0 && posts.every((p) => selected.has(p.id));
|
|
107
|
+
const toggleAllOnPage = (checked) => setSelected((s) => {
|
|
108
|
+
const next = new Set(s);
|
|
109
|
+
if (checked)
|
|
110
|
+
for (const p of posts)
|
|
111
|
+
next.add(p.id);
|
|
112
|
+
else
|
|
113
|
+
for (const p of posts)
|
|
114
|
+
next.delete(p.id);
|
|
115
|
+
return next;
|
|
116
|
+
});
|
|
117
|
+
const selectedPosts = useMemo(() => posts.filter((p) => selected.has(p.id)), [posts, selected]);
|
|
118
|
+
const runBulkUpdate = async (target) => {
|
|
119
|
+
const ids = selectedPosts.map((p) => ({ postTypeId: p.postTypeId, id: p.id }));
|
|
120
|
+
if (ids.length === 0)
|
|
121
|
+
return;
|
|
122
|
+
const verb = target === 'PUBLISHED' ? 'Publishing' : 'Updating';
|
|
123
|
+
const promise = bulkUpdatePosts(ids, { status: target });
|
|
124
|
+
toast.promise(promise, {
|
|
125
|
+
loading: `${verb} ${ids.length} post${ids.length === 1 ? '' : 's'}…`,
|
|
126
|
+
success: (r) => `${r.ok} updated${r.failed ? `, ${r.failed} failed` : ''}`,
|
|
127
|
+
error: 'Bulk update failed',
|
|
128
|
+
});
|
|
129
|
+
await promise;
|
|
130
|
+
setSelected(new Set());
|
|
131
|
+
setRefreshToken((t) => t + 1);
|
|
132
|
+
};
|
|
133
|
+
const runBulkDelete = async () => {
|
|
134
|
+
const ids = selectedPosts.map((p) => ({ postTypeId: p.postTypeId, id: p.id }));
|
|
135
|
+
if (ids.length === 0)
|
|
136
|
+
return;
|
|
137
|
+
const promise = bulkDeletePosts(ids);
|
|
138
|
+
toast.promise(promise, {
|
|
139
|
+
loading: `Deleting ${ids.length} post${ids.length === 1 ? '' : 's'}…`,
|
|
140
|
+
success: (r) => `${r.ok} deleted${r.failed ? `, ${r.failed} failed` : ''}`,
|
|
141
|
+
error: 'Bulk delete failed',
|
|
142
|
+
});
|
|
143
|
+
await promise;
|
|
144
|
+
setSelected(new Set());
|
|
145
|
+
setRefreshToken((t) => t + 1);
|
|
146
|
+
};
|
|
147
|
+
// ─── Render ───────────────────────────────────────────────────────
|
|
148
|
+
return (_jsxs("div", { className: "flex h-full flex-col gap-4 p-4 sm:p-6", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "text-foreground text-xl font-medium tracking-tight sm:text-2xl", children: "Posts" }), _jsxs("p", { className: "text-muted-foreground text-sm", children: [totalAll, " total post", totalAll === 1 ? '' : 's', " across all types"] })] }), _jsx(TypeTabs, { types: types, totalAll: totalAll, active: activeType, onChange: setActiveType }), _jsx(ControlsRow, { search: search, onSearchChange: setSearch, status: status, onStatusChange: (s) => {
|
|
149
|
+
setStatus(s);
|
|
150
|
+
setPage(1);
|
|
151
|
+
}, author: author, onAuthorChange: (a) => {
|
|
152
|
+
setAuthor(a);
|
|
153
|
+
setPage(1);
|
|
154
|
+
}, authors: authors, resultCount: total, onManageTypes: () => onNavigate('/posts/types') }), selected.size > 0 && (_jsx(BulkActionBar, { count: selected.size, onClear: () => setSelected(new Set()), onPublish: () => runBulkUpdate('PUBLISHED'), onDraft: () => runBulkUpdate('DRAFT'), onDelete: () => setPendingBulk('delete') })), _jsxs("div", { className: "bg-card border-border overflow-hidden rounded-xl border shadow-sm", children: [_jsxs("table", { className: "w-full table-fixed", role: "table", "aria-label": "Posts", children: [_jsxs("colgroup", { children: [_jsx("col", { style: { width: '40px' } }), _jsx("col", {}), _jsx("col", { style: { width: '140px' } }), _jsx("col", { style: { width: '180px' } }), _jsx("col", { style: { width: '130px' } }), _jsx("col", { style: { width: '120px' } }), _jsx("col", { style: { width: '90px' } })] }), _jsx("thead", { className: "border-border bg-muted/40 border-b", children: _jsxs("tr", { className: "text-muted-foreground text-xs", children: [_jsx("th", { scope: "col", className: "px-3 py-2.5 text-left", children: _jsx("input", { type: "checkbox", "aria-label": "Select all posts on this page", checked: allOnPageSelected, onChange: (e) => toggleAllOnPage(e.target.checked), className: "border-border accent-primary rounded" }) }), _jsx("th", { scope: "col", className: "px-3 py-2.5 text-left", children: _jsx(SortHeader, { label: "Title", field: "title", current: sortBy, dir: dir, onSort: handleSort }) }), _jsx("th", { scope: "col", className: "px-3 py-2.5 text-left", children: _jsx(SortHeader, { label: "Type", field: "type", current: sortBy, dir: dir, onSort: handleSort }) }), _jsx("th", { scope: "col", className: "px-3 py-2.5 text-left", children: _jsx(SortHeader, { label: "Author", field: "author", current: sortBy, dir: dir, onSort: handleSort }) }), _jsx("th", { scope: "col", className: "px-3 py-2.5 text-left", children: _jsx(SortHeader, { label: "Status", field: "status", current: sortBy, dir: dir, onSort: handleSort }) }), _jsx("th", { scope: "col", className: "px-3 py-2.5 text-left", children: _jsx(SortHeader, { label: "Date", field: "date", current: sortBy, dir: dir, onSort: handleSort }) }), _jsx("th", { scope: "col", className: "px-3 py-2.5 text-left", children: _jsx(SortHeader, { label: "SEO", field: "seo", current: sortBy, dir: dir, onSort: handleSort }) })] }) }), _jsxs("tbody", { children: [loading && posts.length === 0 && _jsx(LoadingRows, {}), !loading && error && (_jsx("tr", { children: _jsxs("td", { colSpan: 7, className: "px-3 py-12 text-center", children: [_jsx("div", { className: "text-foreground mb-2 text-sm font-medium", children: error }), _jsx("button", { onClick: () => setRefreshToken((t) => t + 1), className: "text-primary text-sm hover:underline", children: "Try again" })] }) })), !loading && !error && posts.length === 0 && (_jsx(EmptyRow, { filtersActive: filtersAreActive, onClear: clearFilters, onNewPost: () => onNavigate('/posts/new') })), !loading &&
|
|
155
|
+
!error &&
|
|
156
|
+
posts.map((p) => (_jsx(PostRow, { post: p, selected: selected.has(p.id), onSelect: () => toggleOne(p.id), onOpen: () => onNavigate(`/posts/${p.postTypeId}/${p.id}/edit`) }, p.id)))] })] }), _jsx(PaginationFooter, { page: page, totalPages: totalPages, total: total, pageSize: PAGE_SIZE, onPage: setPage })] }), _jsx(ConfirmDialog, { open: pendingBulk === 'delete', title: `Delete ${selected.size} post${selected.size === 1 ? '' : 's'}?`, description: "This moves the selected posts to trash. They can be restored from the per-type list for 30 days.", confirmLabel: "Delete", destructive: true, onClose: () => setPendingBulk(null), onConfirm: () => {
|
|
157
|
+
void runBulkDelete();
|
|
158
|
+
} })] }));
|
|
159
|
+
}
|
|
160
|
+
// ─── Sub-components ──────────────────────────────────────────────────
|
|
161
|
+
function SortHeader({ label, field, current, dir, onSort, }) {
|
|
162
|
+
const active = current === field;
|
|
163
|
+
const ariaSort = active ? (dir === 'asc' ? 'ascending' : 'descending') : 'none';
|
|
164
|
+
return (_jsxs("button", { type: "button", onClick: () => onSort(field), "aria-sort": ariaSort, className: `hover:text-foreground inline-flex items-center gap-1 text-xs font-medium tracking-wider uppercase transition-colors ${active ? 'text-foreground' : 'text-muted-foreground'}`, children: [_jsx("span", { children: label }), active &&
|
|
165
|
+
(dir === 'asc' ? (_jsx(ChevronUp, { className: "h-3 w-3", "aria-hidden": true })) : (_jsx(ChevronDown, { className: "h-3 w-3", "aria-hidden": true })))] }));
|
|
166
|
+
}
|
|
167
|
+
function TypeTabs({ types, totalAll, active, onChange, }) {
|
|
168
|
+
return (_jsxs("div", { role: "tablist", "aria-label": "Filter posts by type", className: "border-border flex flex-wrap items-center gap-1 border-b pb-px", children: [_jsx(TabPill, { label: "All Posts", count: totalAll, active: active === 'all', onClick: () => onChange('all') }), types.map((t) => (_jsx(TabPill, { label: t.name, count: t.postCount, active: active === t.slug, onClick: () => onChange(t.slug) }, t.slug)))] }));
|
|
169
|
+
}
|
|
170
|
+
function TabPill({ label, count, active, onClick, }) {
|
|
171
|
+
return (_jsxs("button", { type: "button", role: "tab", "aria-selected": active, onClick: onClick, className: `relative inline-flex items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors ${active
|
|
172
|
+
? 'bg-primary/10 text-primary'
|
|
173
|
+
: 'text-muted-foreground hover:text-foreground hover:bg-accent'}`, children: [_jsx("span", { children: label }), _jsx("span", { className: `rounded-full px-1.5 text-xs tabular-nums ${active ? 'bg-primary/15 text-primary' : 'bg-muted text-muted-foreground'}`, children: count })] }));
|
|
174
|
+
}
|
|
175
|
+
function ControlsRow({ search, onSearchChange, status, onStatusChange, author, onAuthorChange, authors, resultCount, onManageTypes, }) {
|
|
176
|
+
return (_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("div", { className: "relative max-w-sm flex-1", children: [_jsx(Search, { className: "text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2", "aria-hidden": true }), _jsx("input", { type: "search", value: search, onChange: (e) => onSearchChange(e.target.value), "aria-label": "Search posts", placeholder: "Search posts\u2026", className: "border-border bg-card text-foreground placeholder:text-muted-foreground focus:border-primary focus:ring-primary/30 w-full rounded-lg border py-2 pr-3 pl-9 text-sm shadow-sm focus:ring-2 focus:outline-none" })] }), _jsx(FilterSelect, { label: "Status", value: status, onChange: (v) => onStatusChange(v), options: [
|
|
177
|
+
{ value: 'all', label: 'All' },
|
|
178
|
+
{ value: 'PUBLISHED', label: 'Published' },
|
|
179
|
+
{ value: 'DRAFT', label: 'Draft' },
|
|
180
|
+
{ value: 'SCHEDULED', label: 'Scheduled' },
|
|
181
|
+
] }), _jsx(FilterSelect, { label: "Author", value: author, onChange: onAuthorChange, options: [
|
|
182
|
+
{ value: 'all', label: 'All' },
|
|
183
|
+
...authors.map((a) => ({ value: a.id, label: a.name })),
|
|
184
|
+
] }), _jsxs("div", { className: "ml-auto flex items-center gap-3", children: [_jsxs("button", { type: "button", onClick: onManageTypes, className: "border-border bg-background text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors", children: [_jsx(Settings, { className: "h-3.5 w-3.5", "aria-hidden": true }), "Manage types"] }), _jsxs("span", { className: "text-muted-foreground text-sm tabular-nums", children: [resultCount, " ", resultCount === 1 ? 'result' : 'results'] })] })] }));
|
|
185
|
+
}
|
|
186
|
+
function FilterSelect({ label, value, onChange, options, }) {
|
|
187
|
+
return (_jsxs("label", { className: "text-foreground inline-flex items-center gap-1.5 text-sm", children: [_jsxs("span", { className: "text-muted-foreground", children: [label, ":"] }), _jsx("select", { value: value, onChange: (e) => onChange(e.target.value), className: "border-border bg-card text-foreground focus:border-primary focus:ring-primary/30 rounded-lg border px-2.5 py-1.5 text-sm shadow-sm focus:ring-2 focus:outline-none", children: options.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) })] }));
|
|
188
|
+
}
|
|
189
|
+
function BulkActionBar({ count, onClear, onPublish, onDraft, onDelete, }) {
|
|
190
|
+
return (_jsxs("div", { className: "border-primary/30 bg-primary/5 flex items-center gap-2 rounded-lg border px-4 py-2", children: [_jsxs("span", { className: "text-foreground text-sm font-medium", children: [count, " selected"] }), _jsx("div", { className: "bg-border h-4 w-px", "aria-hidden": true }), _jsx("button", { type: "button", onClick: onPublish, className: "text-foreground hover:bg-accent rounded-md px-2 py-1 text-sm transition-colors", children: "Publish" }), _jsx("button", { type: "button", onClick: onDraft, className: "text-foreground hover:bg-accent rounded-md px-2 py-1 text-sm transition-colors", children: "Move to draft" }), _jsxs("button", { type: "button", onClick: onDelete, className: "text-destructive hover:bg-destructive/10 inline-flex items-center gap-1 rounded-md px-2 py-1 text-sm transition-colors", children: [_jsx(Trash2, { className: "h-3.5 w-3.5", "aria-hidden": true }), "Delete"] }), _jsxs("button", { type: "button", onClick: onClear, className: "text-muted-foreground hover:text-foreground ml-auto inline-flex items-center gap-1 rounded-md px-2 py-1 text-sm transition-colors", children: [_jsx(X, { className: "h-3.5 w-3.5", "aria-hidden": true }), "Clear"] })] }));
|
|
191
|
+
}
|
|
192
|
+
function PostRow({ post, selected, onSelect, onOpen, }) {
|
|
193
|
+
const p = paletteFor(post.postTypeAccentColor);
|
|
194
|
+
return (_jsxs("tr", { className: `border-border hover:bg-muted/30 group border-b transition-colors last:border-b-0 ${selected ? 'bg-primary/5' : ''}`, children: [_jsx("td", { className: "px-3 py-3", onClick: (e) => e.stopPropagation(), children: _jsx("input", { type: "checkbox", "aria-label": `Select "${post.title}"`, checked: selected, onChange: onSelect, className: "border-border accent-primary rounded" }) }), _jsx("td", { className: "px-3 py-3", children: _jsxs("button", { type: "button", onClick: onOpen, className: "flex w-full items-center gap-3 text-left", children: [_jsx("span", { "aria-hidden": true, className: `block h-9 w-9 shrink-0 rounded-md ${p.bg.split(' ')[0]}` }), _jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "text-foreground group-hover:text-primary block truncate text-sm font-medium", children: post.title }), _jsxs("span", { className: "text-muted-foreground block truncate text-xs", children: ["/", post.postTypeId, "/", post.slug || '—'] })] })] }) }), _jsx("td", { className: "px-3 py-3", children: _jsx(PostTypeBadge, { label: post.postTypeName, color: post.postTypeAccentColor }) }), _jsx("td", { className: "px-3 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { "aria-hidden": true, className: "bg-muted text-muted-foreground inline-flex h-7 w-7 items-center justify-center rounded-full text-[11px] font-semibold", children: post.authorInitials }), _jsx("span", { className: "text-foreground truncate text-sm", children: post.authorName })] }) }), _jsx("td", { className: "px-3 py-3", children: _jsx(PostStatusBadge, { status: post.status }) }), _jsx("td", { className: "text-muted-foreground px-3 py-3 text-sm tabular-nums", children: formatDateShort(post.updatedDate) }), _jsx("td", { className: "px-3 py-3", children: _jsx(SeoScoreIndicator, { score: post.seoScore }) })] }));
|
|
195
|
+
}
|
|
196
|
+
function LoadingRows() {
|
|
197
|
+
const rows = Array.from({ length: 8 });
|
|
198
|
+
return (_jsx(_Fragment, { children: rows.map((_, i) => (_jsx("tr", { className: "border-border border-b last:border-b-0", children: Array.from({ length: 7 }).map((__, j) => (_jsx("td", { className: "px-3 py-3", children: _jsx("div", { className: "bg-muted h-4 w-full animate-pulse rounded" }) }, j))) }, i))) }));
|
|
199
|
+
}
|
|
200
|
+
function EmptyRow({ filtersActive, onClear, onNewPost, }) {
|
|
201
|
+
return (_jsx("tr", { children: _jsxs("td", { colSpan: 7, className: "px-3 py-16 text-center", children: [_jsx("div", { className: "text-foreground mb-2 text-sm font-medium", children: filtersActive ? 'No posts match the current filters.' : 'No posts yet.' }), _jsx("div", { className: "text-muted-foreground mb-4 text-sm", children: filtersActive
|
|
202
|
+
? 'Try clearing the search or filters above.'
|
|
203
|
+
: 'Create your first post to get started.' }), filtersActive ? (_jsx("button", { type: "button", onClick: onClear, className: "text-primary text-sm hover:underline", children: "Clear filters" })) : (_jsx("button", { type: "button", onClick: onNewPost, className: "bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 rounded-lg px-3.5 py-1.5 text-sm font-medium shadow-sm transition-colors", children: "New Post" }))] }) }));
|
|
204
|
+
}
|
|
205
|
+
function PaginationFooter({ page, totalPages, total, pageSize, onPage, }) {
|
|
206
|
+
const start = total === 0 ? 0 : (page - 1) * pageSize + 1;
|
|
207
|
+
const end = Math.min(total, page * pageSize);
|
|
208
|
+
return (_jsxs("div", { className: "border-border flex items-center justify-between border-t px-4 py-3 text-sm", children: [_jsxs("span", { className: "text-muted-foreground tabular-nums", children: [start, "\u2013", end, " of ", total, " post", total === 1 ? '' : 's'] }), _jsxs("nav", { className: "flex items-center gap-1", "aria-label": "Posts pagination", children: [_jsx("button", { type: "button", onClick: () => onPage(Math.max(1, page - 1)), disabled: page === 1, "aria-label": "Previous page", className: "border-border bg-background text-foreground hover:bg-accent inline-flex h-8 w-8 items-center justify-center rounded-md border transition-colors disabled:cursor-not-allowed disabled:opacity-40", children: _jsx(ChevronLeft, { className: "h-4 w-4", "aria-hidden": true }) }), pageNumbers(page, totalPages).map((p, idx) => p === '…' ? (_jsx("span", { "aria-hidden": true, className: "text-muted-foreground inline-flex h-8 w-8 items-center justify-center text-sm", children: "\u2026" }, `gap-${idx}`)) : (_jsx("button", { type: "button", onClick: () => onPage(p), "aria-current": p === page ? 'page' : undefined, className: `inline-flex h-8 w-8 items-center justify-center rounded-md text-sm tabular-nums transition-colors ${p === page
|
|
209
|
+
? 'bg-primary text-primary-foreground'
|
|
210
|
+
: 'border-border bg-background text-foreground hover:bg-accent border'}`, children: p }, p))), _jsx("button", { type: "button", onClick: () => onPage(Math.min(totalPages, page + 1)), disabled: page === totalPages, "aria-label": "Next page", className: "border-border bg-background text-foreground hover:bg-accent inline-flex h-8 w-8 items-center justify-center rounded-md border transition-colors disabled:cursor-not-allowed disabled:opacity-40", children: _jsx(ChevronRight, { className: "h-4 w-4", "aria-hidden": true }) })] })] }));
|
|
211
|
+
}
|
|
212
|
+
// ─── Helpers ─────────────────────────────────────────────────────────
|
|
213
|
+
function formatDateShort(input) {
|
|
214
|
+
const d = new Date(input);
|
|
215
|
+
if (Number.isNaN(d.getTime()))
|
|
216
|
+
return '—';
|
|
217
|
+
return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Return up to 7 page-control entries: a sliding window around the
|
|
221
|
+
* current page with ellipsis markers. Keeps the footer narrow even on
|
|
222
|
+
* collections with hundreds of pages.
|
|
223
|
+
*/
|
|
224
|
+
export function pageNumbers(current, total) {
|
|
225
|
+
if (total <= 7)
|
|
226
|
+
return Array.from({ length: total }, (_, i) => i + 1);
|
|
227
|
+
const out = [1];
|
|
228
|
+
const start = Math.max(2, current - 1);
|
|
229
|
+
const end = Math.min(total - 1, current + 1);
|
|
230
|
+
if (start > 2)
|
|
231
|
+
out.push('…');
|
|
232
|
+
for (let i = start; i <= end; i++)
|
|
233
|
+
out.push(i);
|
|
234
|
+
if (end < total - 1)
|
|
235
|
+
out.push('…');
|
|
236
|
+
out.push(total);
|
|
237
|
+
return out;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=PostsListView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostsListView.js","sourceRoot":"","sources":["../../../src/views/Posts/PostsListView.tsx"],"names":[],"mappings":"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"}
|