Files
orion/app/templates/admin/test-vendors-users-migration.html
Samir Boulahtit bb2e5fd260 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>
2025-12-07 17:04:43 +01:00

207 lines
11 KiB
HTML

{# app/templates/admin/test-vendors-users-migration.html #}
{% extends 'admin/base.html' %}
{% from 'shared/macros/headers.html' import page_header %}
{% block title %}Vendors & Users Migration Testing{% endblock %}
{% block content %}
<div x-data="migrationTest()" x-init="init()">
{{ page_header('Vendors & Users Migration Testing', subtitle='Comprehensive test suite for verifying the Jinja2 migration') }}
{# Status Cards #}
<div class="grid gap-6 mb-8 md:grid-cols-2 xl:grid-cols-4">
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div class="p-3 mr-4 text-purple-500 bg-purple-100 rounded-full dark:text-purple-100 dark:bg-purple-500">
<span x-html="$icon('badge-check', 'w-5 h-5')"></span>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">Dashboard</p>
<p class="text-lg font-semibold text-green-600 dark:text-green-400">Complete</p>
</div>
</div>
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div class="p-3 mr-4 text-orange-500 bg-orange-100 rounded-full dark:text-orange-100 dark:bg-orange-500">
<span x-html="$icon('building-storefront', 'w-5 h-5')"></span>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">Vendors List</p>
<p class="text-lg font-semibold" :class="vendorsStatus === 'Complete' ? 'text-green-600 dark:text-green-400' : 'text-yellow-600 dark:text-yellow-400'" x-text="vendorsStatus">Testing</p>
</div>
</div>
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div class="p-3 mr-4 text-blue-500 bg-blue-100 rounded-full dark:text-blue-100 dark:bg-blue-500">
<span x-html="$icon('pencil-square', 'w-5 h-5')"></span>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">Vendor Edit</p>
<p class="text-lg font-semibold" :class="editStatus === 'Complete' ? 'text-green-600 dark:text-green-400' : 'text-yellow-600 dark:text-yellow-400'" x-text="editStatus">Testing</p>
</div>
</div>
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div class="p-3 mr-4 text-green-500 bg-green-100 rounded-full dark:text-green-100 dark:bg-green-500">
<span x-html="$icon('user-group', 'w-5 h-5')"></span>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">Users Page</p>
<p class="text-lg font-semibold" :class="usersStatus === 'Complete' ? 'text-green-600 dark:text-green-400' : 'text-yellow-600 dark:text-yellow-400'" x-text="usersStatus">Testing</p>
</div>
</div>
</div>
{# Quick Actions #}
<div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800">
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Quick Actions</h4>
<div class="flex flex-wrap gap-3">
<a href="{{ url_for('admin:vendors_list') }}" class="flex items-center px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-orange-600 border border-transparent rounded-lg hover:bg-orange-700 focus:outline-none">
<span x-html="$icon('building-storefront', 'w-4 h-4 mr-2')"></span>
Go to Vendors List
</a>
<a href="{{ url_for('admin:users_list') }}" class="flex items-center px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-green-600 border border-transparent rounded-lg hover:bg-green-700 focus:outline-none">
<span x-html="$icon('user-group', 'w-4 h-4 mr-2')"></span>
Go to Users Page
</a>
<a href="{{ url_for('admin:dashboard') }}" 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">
<span x-html="$icon('home', 'w-4 h-4 mr-2')"></span>
Go to Dashboard
</a>
</div>
{# Progress Bar #}
<div class="mt-4">
<div class="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700">
<div class="bg-green-600 h-2.5 rounded-full transition-all duration-300" :style="'width: ' + progress + '%'"></div>
</div>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400" x-text="progress + '% Complete - ' + checkedCount + '/' + totalChecks + ' checks passed'"></p>
</div>
</div>
{# Test Section: Vendors List #}
<div class="px-4 py-3 mb-6 bg-white rounded-lg shadow-md dark:bg-gray-800 border-l-4 border-orange-500">
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">
Test 1: Vendors List Page
<span class="ml-2 px-2 py-1 text-xs font-semibold text-red-700 bg-red-100 rounded-full dark:bg-red-700 dark:text-red-100">High Priority</span>
</h4>
<p class="mb-4 text-sm text-gray-600 dark:text-gray-400">Tests the vendor LIST functionality using adminVendors() function.</p>
<div class="space-y-2 mb-4">
<template x-for="(item, index) in vendorChecks" :key="index">
<label class="flex items-center p-2 rounded hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer">
<input type="checkbox" x-model="item.checked" @change="updateProgress()" class="w-4 h-4 text-purple-600 form-checkbox focus:ring-purple-500">
<span class="ml-3 text-sm text-gray-700 dark:text-gray-300" :class="{ 'line-through text-gray-400': item.checked }" x-text="item.label"></span>
</label>
</template>
</div>
<div class="p-3 bg-green-50 dark:bg-green-900/20 rounded-lg border-l-3 border-green-500">
<p class="text-sm font-medium text-green-700 dark:text-green-400">Expected: adminVendors() works with ApiClient, Logger, Utils</p>
</div>
</div>
{# Test Section: Users Page #}
<div class="px-4 py-3 mb-6 bg-white rounded-lg shadow-md dark:bg-gray-800 border-l-4 border-green-500">
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">
Test 2: Users Page
<span class="ml-2 px-2 py-1 text-xs font-semibold text-yellow-700 bg-yellow-100 rounded-full dark:bg-yellow-700 dark:text-yellow-100">Medium Priority</span>
</h4>
<p class="mb-4 text-sm text-gray-600 dark:text-gray-400">Tests the users page created with adminUsers() function.</p>
<div class="space-y-2 mb-4">
<template x-for="(item, index) in userChecks" :key="index">
<label class="flex items-center p-2 rounded hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer">
<input type="checkbox" x-model="item.checked" @change="updateProgress()" class="w-4 h-4 text-purple-600 form-checkbox focus:ring-purple-500">
<span class="ml-3 text-sm text-gray-700 dark:text-gray-300" :class="{ 'line-through text-gray-400': item.checked }" x-text="item.label"></span>
</label>
</template>
</div>
<div class="p-3 bg-green-50 dark:bg-green-900/20 rounded-lg border-l-3 border-green-500">
<p class="text-sm font-medium text-green-700 dark:text-green-400">Expected: adminUsers() follows same pattern as vendors list</p>
</div>
</div>
{# Console Panel #}
<div class="px-4 py-3 bg-gray-800 rounded-lg shadow-md">
<div class="flex items-center justify-between mb-3">
<h4 class="text-lg font-semibold text-gray-200">Test Console</h4>
<button @click="logs = []" class="px-3 py-1 text-xs text-gray-400 border border-gray-600 rounded hover:bg-gray-700">Clear</button>
</div>
<div class="h-48 overflow-y-auto font-mono text-sm">
<template x-for="(log, index) in logs" :key="index">
<div class="py-1 border-b border-gray-700">
<span class="text-gray-500" x-text="log.time"></span>
<span :class="log.level === 'success' ? 'text-green-400' : log.level === 'error' ? 'text-red-400' : 'text-blue-400'" x-text="log.message"></span>
</div>
</template>
<div x-show="logs.length === 0" class="text-gray-500">No logs yet. Start testing!</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
function migrationTest() {
return {
...data(),
currentPage: 'testing',
vendorsStatus: 'Testing',
editStatus: 'Testing',
usersStatus: 'Testing',
progress: 0,
checkedCount: 0,
totalChecks: 0,
logs: [],
vendorChecks: [
{ label: 'Navigate to /admin/vendors - Page loads without errors', checked: false },
{ label: 'Check console - No JavaScript errors', checked: false },
{ label: 'Verify Alpine.js function - adminVendors() is called', checked: false },
{ label: '4 stat cards display in a grid', checked: false },
{ label: 'Table displays with correct headers', checked: false },
{ label: 'Status badges show correctly (Verified/Pending)', checked: false },
{ label: 'Action buttons (View, Edit, Delete) work', checked: false },
],
userChecks: [
{ label: 'Navigate to /admin/users - Page loads without errors', checked: false },
{ label: 'Alpine.js adminUsers() function works', checked: false },
{ label: '4 stat cards display (Total, Active, Admins, Vendors)', checked: false },
{ label: 'Users table displays correctly', checked: false },
{ label: 'Role badges display (admin/vendor/customer)', checked: false },
{ label: 'Status badges show (Active/Inactive)', checked: false },
{ label: 'Action buttons work (View, Edit, Toggle Status)', checked: false },
],
init() {
this.totalChecks = this.vendorChecks.length + this.userChecks.length;
this.log('Migration Test Suite Ready', 'success');
this.log('Follow the test sections to verify migration', 'info');
},
updateProgress() {
const vendorChecked = this.vendorChecks.filter(c => c.checked).length;
const userChecked = this.userChecks.filter(c => c.checked).length;
this.checkedCount = vendorChecked + userChecked;
this.progress = Math.round((this.checkedCount / this.totalChecks) * 100);
// Update section status
if (vendorChecked === this.vendorChecks.length) {
this.vendorsStatus = 'Complete';
this.log('Vendors list tests completed!', 'success');
}
if (userChecked === this.userChecks.length) {
this.usersStatus = 'Complete';
this.log('Users page tests completed!', 'success');
}
},
log(message, level = 'info') {
const time = new Date().toLocaleTimeString();
this.logs.push({ time: `[${time}]`, message, level });
}
};
}
</script>
{% endblock %}