refactor: standardize admin templates with shared macros

Migrate all admin templates to use standardized components:
- Use tabs macros (tabs_nav, tab_button) for tab navigation
- Use number_stepper for quantity/numeric inputs
- Use headers macros for consistent page layouts
- Use modals macros for dialog components

Affected pages: dashboard, settings, logs, content-pages, companies,
vendors, users, imports, marketplace, code-quality, and more.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-07 17:04:43 +01:00
parent 2ec150e8a5
commit bb2e5fd260
31 changed files with 261 additions and 1290 deletions

View File

@@ -1,34 +1,29 @@
{# app/templates/admin/content-page-edit.html #}
{% extends "admin/base.html" %}
{% from 'shared/macros/alerts.html' import loading_state, error_state, alert_dynamic %}
{% from 'shared/macros/headers.html' import page_header_flex, back_button, action_button %}
{% from 'shared/macros/inputs.html' import number_stepper %}
{% block title %}{% if page_id %}Edit{% else %}Create{% endif %} Content Page{% endblock %}
{% block alpine_data %}contentPageEditor({{ page_id if page_id else 'null' }}){% endblock %}
{% block content %}
<!-- Page Header -->
{# Dynamic title/subtitle and save button text based on create vs edit mode #}
<div class="flex items-center justify-between my-6">
<div>
<h2 class="text-2xl font-semibold text-gray-700 dark:text-gray-200">
<span x-text="pageId ? 'Edit Content Page' : 'Create Content Page'"></span>
</h2>
<h2 class="text-2xl font-semibold text-gray-700 dark:text-gray-200" x-text="pageId ? 'Edit Content Page' : 'Create Content Page'"></h2>
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1">
<span x-show="!pageId">Create a new platform default or vendor-specific page</span>
<span x-show="pageId">Modify an existing content page</span>
</p>
</div>
<div class="flex gap-2">
<a
href="/admin/content-pages"
class="flex items-center px-4 py-2 text-sm font-medium leading-5 text-gray-700 dark:text-gray-200 transition-colors duration-150 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg hover:border-gray-400 dark:hover:border-gray-500 focus:outline-none focus:shadow-outline-purple"
>
<span x-html="$icon('arrow-left', 'w-4 h-4 mr-2')"></span>
Back to List
</a>
<div class="flex items-center space-x-3">
{{ back_button('/admin/content-pages', 'Back to List') }}
<button
@click="savePage()"
:disabled="saving"
class="flex items-center px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple disabled:opacity-50 disabled:cursor-not-allowed"
class="flex items-center px-4 py-2 text-sm font-medium leading-5 transition-colors duration-150 border rounded-lg focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed text-white bg-purple-600 border-transparent hover:bg-purple-700 focus:shadow-outline-purple"
>
<span x-show="!saving" x-html="$icon('check', 'w-4 h-4 mr-2')"></span>
<span x-show="saving" x-html="$icon('spinner', 'w-4 h-4 mr-2')"></span>
@@ -37,28 +32,11 @@
</div>
</div>
<!-- Loading State -->
<div x-show="loading" class="text-center py-12">
<span x-html="$icon('spinner', 'inline w-8 h-8 text-purple-600')"></span>
<p class="mt-2 text-gray-600 dark:text-gray-400">Loading page...</p>
</div>
{{ loading_state('Loading page...') }}
<!-- Error State -->
<div x-show="error && !loading" class="mb-6 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg flex items-start">
<span x-html="$icon('exclamation', 'w-5 h-5 mr-3 mt-0.5 flex-shrink-0')"></span>
<div>
<p class="font-semibold">Error</p>
<p class="text-sm" x-text="error"></p>
</div>
</div>
{{ error_state('Error', show_condition='error && !loading') }}
<!-- Success Message -->
<div x-show="successMessage" x-transition class="mb-6 p-4 bg-green-100 border border-green-400 text-green-700 rounded-lg flex items-start">
<span x-html="$icon('check-circle', 'w-5 h-5 mr-3 mt-0.5 flex-shrink-0')"></span>
<div>
<p class="font-semibold" x-text="successMessage"></p>
</div>
</div>
{{ alert_dynamic(type='success', message_var='successMessage', show_condition='successMessage') }}
<!-- Main Form -->
<div x-show="!loading" class="bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden">
@@ -217,12 +195,7 @@
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Display Order
</label>
<input
type="number"
x-model.number="form.display_order"
min="0"
class="w-full px-3 py-2 text-gray-700 dark:text-gray-300 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:border-purple-500 dark:bg-gray-700"
>
{{ number_stepper(model='form.display_order', min=0, max=100, step=1, label='Display Order') }}
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Lower = first</p>
</div>