feat: add SQL query tool, platform debug, loyalty settings, and multi-module improvements
Some checks failed
CI / ruff (push) Successful in 14s
CI / pytest (push) Failing after 50m12s
CI / validate (push) Successful in 25s
CI / dependency-scanning (push) Successful in 32s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped

- Add admin SQL query tool with saved queries, schema explorer presets,
  and collapsible category sections (dev_tools module)
- Add platform debug tool for admin diagnostics
- Add loyalty settings page with owner-only access control
- Fix loyalty settings owner check (use currentUser instead of window.__userData)
- Replace HTTPException with AuthorizationException in loyalty routes
- Expand loyalty module with PIN service, Apple Wallet, program management
- Improve store login with platform detection and multi-platform support
- Update billing feature gates and subscription services
- Add store platform sync improvements and remove is_primary column
- Add unit tests for loyalty (PIN, points, stamps, program services)
- Update i18n translations across dev_tools locales

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 20:08:07 +01:00
parent a77a8a3a98
commit 319900623a
77 changed files with 5341 additions and 401 deletions

View File

@@ -374,44 +374,56 @@
</div>
</div>
{# Step checklist #}
<div class="divide-y divide-gray-100 dark:divide-gray-700">
<template x-for="step in steps" :key="step.key">
<a :href="step.route"
class="flex items-center px-6 py-3 hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors group">
{# Completion indicator #}
<div class="flex-shrink-0 mr-4">
<template x-if="step.completed">
<div class="w-6 h-6 rounded-full bg-green-100 dark:bg-green-900 flex items-center justify-center">
<svg class="w-4 h-4 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
</div>
</template>
{# Non-owner message #}
<template x-if="!isOwner">
<div class="px-6 py-4 text-center">
<p class="text-sm text-gray-600 dark:text-gray-400">
<span x-html="$icon('information-circle', 'inline w-5 h-5 mr-1 text-gray-400')"></span>
Contact your administrator to complete platform setup.
</p>
</div>
</template>
{# Step checklist (owners only) #}
<template x-if="isOwner">
<div class="divide-y divide-gray-100 dark:divide-gray-700">
<template x-for="step in steps" :key="step.key">
<a :href="step.route"
class="flex items-center px-6 py-3 hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors group">
{# Completion indicator #}
<div class="flex-shrink-0 mr-4">
<template x-if="step.completed">
<div class="w-6 h-6 rounded-full bg-green-100 dark:bg-green-900 flex items-center justify-center">
<svg class="w-4 h-4 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
</div>
</template>
<template x-if="!step.completed">
<div class="w-6 h-6 rounded-full border-2 border-gray-300 dark:border-gray-600 group-hover:border-purple-400 transition-colors"></div>
</template>
</div>
{# Step icon + text #}
<div class="flex-shrink-0 mr-3">
<span x-html="$icon(step.icon, 'w-5 h-5 text-gray-400 dark:text-gray-500')" class="block"></span>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm font-medium text-gray-900 dark:text-white"
:class="{ 'line-through text-gray-400 dark:text-gray-500': step.completed }"
x-text="t(step.title_key)"></p>
<p class="text-xs text-gray-500 dark:text-gray-400 truncate"
x-text="t(step.description_key)"></p>
</div>
{# Arrow #}
<template x-if="!step.completed">
<div class="w-6 h-6 rounded-full border-2 border-gray-300 dark:border-gray-600 group-hover:border-purple-400 transition-colors"></div>
<svg class="w-4 h-4 text-gray-400 group-hover:text-purple-500 transition-colors flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
</template>
</div>
{# Step icon + text #}
<div class="flex-shrink-0 mr-3">
<span x-html="$icon(step.icon, 'w-5 h-5 text-gray-400 dark:text-gray-500')" class="block"></span>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm font-medium text-gray-900 dark:text-white"
:class="{ 'line-through text-gray-400 dark:text-gray-500': step.completed }"
x-text="t(step.title_key)"></p>
<p class="text-xs text-gray-500 dark:text-gray-400 truncate"
x-text="t(step.description_key)"></p>
</div>
{# Arrow #}
<template x-if="!step.completed">
<svg class="w-4 h-4 text-gray-400 group-hover:text-purple-500 transition-colors flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
</template>
</a>
</template>
</div>
</a>
</template>
</div>
</template>
</div>
{% endmacro %}