diff --git a/app/templates/shared/macros/headers.html b/app/templates/shared/macros/headers.html index ee197eea..ab7a1351 100644 --- a/app/templates/shared/macros/headers.html +++ b/app/templates/shared/macros/headers.html @@ -220,3 +220,204 @@ {% endmacro %} + + +{# + Refresh Button + ============== + A button with loading state for refresh actions. + + Parameters: + - loading_var: Alpine.js variable for loading state (default: 'loading') + - onclick: Alpine.js click handler (default: 'refresh()') + - label: Button label (default: 'Refresh') + - loading_label: Label while loading (default: 'Loading...') + - variant: 'primary' | 'secondary' (default: 'primary') +#} +{% macro refresh_button(loading_var='loading', onclick='refresh()', label='Refresh', loading_label='Loading...', variant='primary') %} +{% set variants = { + 'primary': 'text-white bg-purple-600 border-transparent hover:bg-purple-700 focus:shadow-outline-purple', + 'secondary': 'text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700 focus:shadow-outline-gray' +} %} + +{% endmacro %} + + +{# + Action Button (with loading) + ============================ + A generic action button with loading state. + + Parameters: + - label: Button label + - loading_label: Label while loading + - loading_var: Alpine.js variable for loading state + - onclick: Alpine.js click handler + - icon: Button icon (default: 'check') + - variant: 'primary' | 'secondary' | 'danger' (default: 'primary') +#} +{% macro action_button(label, loading_label, loading_var, onclick, icon='check', variant='primary') %} +{% set variants = { + 'primary': 'text-white bg-purple-600 border-transparent hover:bg-purple-700 focus:shadow-outline-purple', + 'secondary': 'text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700 focus:shadow-outline-gray', + 'danger': 'text-white bg-red-600 border-transparent hover:bg-red-700 focus:shadow-outline-red' +} %} + +{% endmacro %} + + +{# + Back Button + =========== + A simple back navigation button. + + Parameters: + - url: Back URL + - label: Button label (default: 'Back') +#} +{% macro back_button(url, label='Back') %} + + + {{ label }} + +{% endmacro %} + + +{# + Page Header (Flexible) + ====================== + A flexible page header that accepts custom content via caller(). + Use this when you need custom action buttons or dynamic content. + + Parameters: + - title: Page title (static string) + - title_var: Alpine.js variable for dynamic title (use instead of title) + - subtitle: Page subtitle (static string) + - subtitle_var: Alpine.js variable for dynamic subtitle + - subtitle_show: Alpine.js condition for showing subtitle (e.g., 'user') + + Usage: + {% call page_header_flex(title='Dashboard') %} + {{ refresh_button() }} + {% endcall %} + + {% call page_header_flex(title_var="user?.name || 'User'", subtitle_show='user') %} + {{ back_button('/admin/users') }} + {% endcall %} +#} +{% macro page_header_flex(title=none, title_var=none, subtitle=none, subtitle_var=none, subtitle_show=none) %} +
+
+ {% if title_var %} +

+ {% else %} +

{{ title }}

+ {% endif %} + {% if subtitle_var %} +

+ {% elif subtitle %} +

{{ subtitle }}

+ {% endif %} +
+
+ {{ caller() }} +
+
+{% endmacro %} + + +{# + Page Header (with Refresh) + ========================== + A common pattern: static header with refresh button. + + Parameters: + - title: Page title + - subtitle: Page subtitle (optional) + - loading_var: Alpine.js variable for loading state (default: 'loading') + - refresh_action: Alpine.js refresh action (default: 'refresh()') +#} +{% macro page_header_refresh(title, subtitle=none, loading_var='loading', refresh_action='refresh()') %} +
+
+

{{ title }}

+ {% if subtitle %} +

{{ subtitle }}

+ {% endif %} +
+
+ {{ refresh_button(loading_var=loading_var, onclick=refresh_action) }} +
+
+{% endmacro %} + + +{# + Detail Page Header + ================== + Common pattern for detail pages with dynamic title and back button. + + Parameters: + - title_var: Alpine.js expression for title (e.g., "user?.name || 'User Details'") + - subtitle_template: Jinja template string for subtitle (rendered as-is) + - subtitle_show: Alpine.js condition for showing subtitle + - back_url: URL for back button + - back_label: Back button label (default: 'Back') +#} +{% macro detail_page_header(title_var, back_url, subtitle_show=none, back_label='Back') %} +
+
+

+ {% if caller is defined %} +

+ {{ caller() }} +

+ {% endif %} +
+ {{ back_button(back_url, back_label) }} +
+{% endmacro %} + + +{# + Edit Page Header + ================ + Common pattern for edit pages with static title, dynamic subtitle, and back button. + + Parameters: + - title: Static title (e.g., 'Edit Vendor') + - subtitle_var: Alpine.js expression for subtitle parts + - subtitle_show: Alpine.js condition for showing subtitle + - back_url: URL for back button + - back_label: Back button label (default: 'Back') +#} +{% macro edit_page_header(title, back_url, subtitle_show=none, back_label='Back') %} +
+
+

{{ title }}

+ {% if caller is defined %} +

+ {{ caller() }} +

+ {% endif %} +
+ {{ back_button(back_url, back_label) }} +
+{% endmacro %} diff --git a/app/templates/shared/macros/modals.html b/app/templates/shared/macros/modals.html index 6dddcf01..71e59d2a 100644 --- a/app/templates/shared/macros/modals.html +++ b/app/templates/shared/macros/modals.html @@ -6,12 +6,12 @@ Usage: {% from 'shared/macros/modals.html' import modal, confirm_modal, form_modal %} - {# Basic modal #} + Basic modal: {% call modal('editModal', 'Edit User', 'isEditModalOpen') %}

Modal content here

{% endcall %} - {# Confirmation modal #} + Confirmation modal: {{ confirm_modal('deleteModal', 'Delete User', 'Are you sure?', 'deleteUser()', 'isDeleteModalOpen') }} Required Alpine.js: @@ -475,3 +475,139 @@ {% endmacro %} + + +{# + Job Details Modal + ================= + A mobile-friendly modal for displaying import job details. + Used in marketplace and imports admin pages. + + Parameters: + - show_var: Alpine.js variable controlling visibility (default: 'showJobModal') + - job_var: Alpine.js variable containing the job data (default: 'selectedJob') + - close_action: Alpine.js action to close modal (default: 'closeJobModal()') + - get_vendor_name: Function to get vendor name from ID (default: 'getVendorName') + - show_created_by: Whether to show Created By field (default: false) + + Required Alpine.js state: + - showJobModal: boolean + - selectedJob: object with job data + - closeJobModal(): function to close and clear + - getVendorName(id): function to resolve vendor name + - formatDate(date): function to format dates +#} +{% macro job_details_modal(show_var='showJobModal', job_var='selectedJob', close_action='closeJobModal()', get_vendor_name='getVendorName', show_created_by=false) %} +
+
+ {# Modal Header #} +
+

+ Import Job Details +

+ +
+ + {# Modal Content #} +
+
+
+

Job ID

+

+
+
+

Vendor

+

+
+
+

Marketplace

+

+
+
+

Status

+ + +
+
+

Source URL

+

+
+
+

Imported

+

+
+
+

Updated

+

+
+
+

Errors

+

+
+
+

Total Processed

+

+
+
+

Started At

+

+
+
+

Completed At

+

+
+ {% if show_created_by %} +
+

Created By

+

+
+ {% endif %} +
+ + {# Error Details #} +
+

Error Details

+
+

+                
+
+
+ + {# Modal Footer #} +
+ +
+
+
+{% endmacro %}