Add headless CMS for official site content management
Integrate article and page management into the Laravel admin dashboard
to serve as a headless CMS for the Next.js frontend (usher-site).
Backend:
- 7 migrations: article_categories, article_tags, articles, pivots, attachments, pages
- 5 models with relationships: Article, ArticleCategory, ArticleTag, ArticleAttachment, Page
- 4 admin controllers: articles (with publish/archive/pin), categories, tags, pages
- Admin views with EasyMDE markdown editor, multi-select categories/tags
- Navigation section "官網管理" in admin sidebar
API (v1):
- GET /api/v1/articles (filtered by type, category, tag, search; paginated)
- GET /api/v1/articles/{slug} (with related articles)
- GET /api/v1/categories
- GET /api/v1/pages/{slug} (with children)
- GET /api/v1/homepage (aggregated homepage data)
- Attachment download endpoint
- CORS configured for usher.org.tw, vercel.app, localhost:3000
Content migration:
- ImportHugoContent command: imports Hugo markdown files as articles/pages
- Successfully imported 27 articles, 17 categories, 11 tags, 9 pages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,8 @@
|
||||
|
||||
<!-- Scripts -->
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
|
||||
@stack('styles')
|
||||
</head>
|
||||
<body class="font-sans antialiased bg-gray-50 text-slate-900 transition-colors duration-300 dark:bg-slate-900 dark:text-slate-100">
|
||||
<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:z-50 focus:p-4 focus:bg-white focus:text-black focus:outline-none focus:ring-2 focus:ring-indigo-500">
|
||||
@@ -35,5 +37,7 @@
|
||||
{{ $slot }}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@stack('scripts')
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
文件
|
||||
</x-nav-link>
|
||||
|
||||
@if(Auth::user() && (Auth::user()->hasRole(['admin', 'membership_manager', 'finance_accountant', 'finance_cashier', 'staff']) || Auth::user()->canAny(['view_finance_documents', 'view_incomes', 'view_accounting_transactions', 'manage_system_settings'])))
|
||||
@if(Auth::user() && (Auth::user()->hasRole(['admin', 'membership_manager', 'finance_accountant', 'finance_cashier', 'staff']) || Auth::user()->canAny(['view_finance_documents', 'view_incomes', 'view_accounting_transactions', 'manage_system_settings', 'view_articles', 'view_pages'])))
|
||||
<div class="hidden sm:flex sm:items-center">
|
||||
<x-dropdown align="right" width="48">
|
||||
<x-slot name="trigger">
|
||||
@@ -97,6 +97,23 @@
|
||||
文件管理
|
||||
</x-dropdown-link>
|
||||
@endhasrole
|
||||
@can('view_articles')
|
||||
<div class="border-t border-gray-200 dark:border-gray-600 my-1"></div>
|
||||
<div class="px-4 py-1 text-xs font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider">官網管理</div>
|
||||
<x-dropdown-link :href="route('admin.articles.index')">
|
||||
文章管理
|
||||
</x-dropdown-link>
|
||||
@endcan
|
||||
@can('view_pages')
|
||||
<x-dropdown-link :href="route('admin.pages.index')">
|
||||
頁面管理
|
||||
</x-dropdown-link>
|
||||
@endcan
|
||||
@can('view_articles')
|
||||
<x-dropdown-link :href="route('admin.article-categories.index')">
|
||||
文章分類
|
||||
</x-dropdown-link>
|
||||
@endcan
|
||||
@can('manage_system_settings')
|
||||
<x-dropdown-link :href="route('admin.settings.general')">
|
||||
系統設定
|
||||
@@ -170,7 +187,7 @@
|
||||
文件
|
||||
</x-responsive-nav-link>
|
||||
|
||||
@if(Auth::user() && (Auth::user()->hasRole(['admin', 'membership_manager', 'finance_accountant', 'finance_cashier', 'staff']) || Auth::user()->canAny(['view_finance_documents', 'view_incomes', 'view_accounting_transactions', 'manage_system_settings'])))
|
||||
@if(Auth::user() && (Auth::user()->hasRole(['admin', 'membership_manager', 'finance_accountant', 'finance_cashier', 'staff']) || Auth::user()->canAny(['view_finance_documents', 'view_incomes', 'view_accounting_transactions', 'manage_system_settings', 'view_articles', 'view_pages'])))
|
||||
<div class="pt-2 pb-1 border-t border-gray-200 dark:border-gray-700 mt-2">
|
||||
<div class="px-4 text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
||||
管理
|
||||
@@ -233,6 +250,26 @@
|
||||
文件管理
|
||||
</x-responsive-nav-link>
|
||||
@endhasrole
|
||||
@can('view_articles')
|
||||
<div class="pt-2 pb-1 border-t border-gray-200 dark:border-gray-700 mt-2">
|
||||
<div class="px-4 text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
||||
官網管理
|
||||
</div>
|
||||
</div>
|
||||
<x-responsive-nav-link :href="route('admin.articles.index')" :active="request()->routeIs('admin.articles.*')">
|
||||
文章管理
|
||||
</x-responsive-nav-link>
|
||||
@endcan
|
||||
@can('view_pages')
|
||||
<x-responsive-nav-link :href="route('admin.pages.index')" :active="request()->routeIs('admin.pages.*')">
|
||||
頁面管理
|
||||
</x-responsive-nav-link>
|
||||
@endcan
|
||||
@can('view_articles')
|
||||
<x-responsive-nav-link :href="route('admin.article-categories.index')" :active="request()->routeIs('admin.article-categories.*')">
|
||||
文章分類
|
||||
</x-responsive-nav-link>
|
||||
@endcan
|
||||
@can('manage_system_settings')
|
||||
<x-responsive-nav-link :href="route('admin.settings.general')" :active="request()->routeIs('admin.settings.*')">
|
||||
系統設定
|
||||
|
||||
Reference in New Issue
Block a user