feat: add platform assignment to user and vendor creation forms

User create page:
- When role=admin, show super admin toggle
- If not super admin, show platform multi-select
- Admin users created via /api/v1/admin/admin-users endpoint
- Vendor users created via existing /admin/users endpoint

Vendor create page:
- Add platform selection section
- Vendors can be assigned to multiple platforms on creation
- Update VendorCreate schema to accept platform_ids
- Update AdminService.create_vendor() to create VendorPlatform records

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-24 19:49:40 +01:00
parent 300f49c5a1
commit 3cbe7e2979
6 changed files with 241 additions and 13 deletions

View File

@@ -81,6 +81,7 @@
</span>
<select
x-model="formData.role"
@change="onRoleChange()"
:disabled="saving"
class="block w-full mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray form-select"
>
@@ -88,9 +89,62 @@
<option value="admin">Admin</option>
</select>
<span class="text-xs text-gray-600 dark:text-gray-400 mt-1">
Vendor: Can own companies and manage stores. Admin: Full platform access.
Vendor: Can own companies and manage stores. Admin: Platform management access.
</span>
</label>
<!-- Admin-specific options -->
<template x-if="formData.role === 'admin'">
<div class="mt-4 p-4 bg-purple-50 dark:bg-purple-900/20 rounded-lg border border-purple-200 dark:border-purple-800">
<h4 class="text-sm font-medium text-purple-800 dark:text-purple-300 mb-3">Admin Settings</h4>
<!-- Super Admin Toggle -->
<label class="flex items-center mb-4">
<input
type="checkbox"
x-model="formData.is_super_admin"
:disabled="saving"
class="w-4 h-4 text-purple-600 border-gray-300 rounded focus:ring-purple-500 dark:border-gray-600 dark:bg-gray-700"
>
<span class="ml-2 text-sm text-gray-700 dark:text-gray-300">
Super Admin
</span>
</label>
<p class="text-xs text-gray-600 dark:text-gray-400 mb-4 -mt-2 ml-6">
Super admins have access to all platforms and can manage other admins.
</p>
<!-- Platform Assignment (only if not super admin) -->
<template x-if="!formData.is_super_admin">
<div>
<label class="block text-sm">
<span class="text-gray-700 dark:text-gray-400">
Assigned Platforms <span class="text-red-600">*</span>
</span>
<div class="mt-2 space-y-2 max-h-48 overflow-y-auto">
<template x-for="platform in platforms" :key="platform.id">
<label class="flex items-center p-2 rounded hover:bg-purple-100 dark:hover:bg-purple-900/30 cursor-pointer">
<input
type="checkbox"
:value="platform.id"
x-model="formData.platform_ids"
:disabled="saving"
class="w-4 h-4 text-purple-600 border-gray-300 rounded focus:ring-purple-500 dark:border-gray-600 dark:bg-gray-700"
>
<span class="ml-2 text-sm text-gray-700 dark:text-gray-300" x-text="platform.name"></span>
<span class="ml-2 text-xs text-gray-500 dark:text-gray-400" x-text="'(' + platform.code + ')'"></span>
</label>
</template>
</div>
<p x-show="platforms.length === 0" class="text-sm text-gray-500 dark:text-gray-400 mt-2">
No platforms available. Create a platform first.
</p>
<span x-show="errors.platform_ids" class="text-xs text-red-600 dark:text-red-400 mt-1" x-text="errors.platform_ids"></span>
</label>
</div>
</template>
</div>
</template>
</div>
<!-- Right Column: Personal Info -->

View File

@@ -166,6 +166,44 @@
</div>
</div>
<!-- Platform Selection Section -->
<div class="mb-6 pt-6 border-t border-gray-200 dark:border-gray-700">
<h3 class="mb-4 text-lg font-semibold text-gray-700 dark:text-gray-200">Platform Access</h3>
<div class="p-4 mb-4 bg-blue-50 border border-blue-200 rounded-lg dark:bg-gray-700 dark:border-gray-600">
<p class="text-sm text-blue-800 dark:text-blue-300">
<span x-html="$icon('information-circle', 'w-4 h-4 inline mr-1')"></span>
Select which platforms this vendor should have access to. Each platform can have different settings and features.
</p>
</div>
<div class="space-y-2 max-h-48 overflow-y-auto">
<template x-for="platform in platforms" :key="platform.id">
<label class="flex items-center p-3 rounded-lg border border-gray-200 dark:border-gray-600 hover:bg-purple-50 dark:hover:bg-purple-900/20 cursor-pointer transition-colors">
<input
type="checkbox"
:value="platform.id"
x-model="formData.platform_ids"
class="w-4 h-4 text-purple-600 border-gray-300 rounded focus:ring-purple-500 dark:border-gray-600 dark:bg-gray-700"
>
<div class="ml-3 flex-1">
<span class="text-sm font-medium text-gray-700 dark:text-gray-300" x-text="platform.name"></span>
<span class="ml-2 text-xs text-gray-500 dark:text-gray-400" x-text="'(' + platform.code + ')'"></span>
</div>
<template x-if="platform.description">
<span class="text-xs text-gray-500 dark:text-gray-400" x-text="platform.description"></span>
</template>
</label>
</template>
</div>
<p x-show="platforms.length === 0" class="text-sm text-gray-500 dark:text-gray-400 mt-2">
No platforms available. Create a platform first.
</p>
<p x-show="formData.platform_ids.length === 0 && platforms.length > 0" class="text-xs text-amber-600 dark:text-amber-400 mt-2">
<span x-html="$icon('exclamation-triangle', 'w-4 h-4 inline mr-1')"></span>
Select at least one platform for the vendor to be accessible.
</p>
</div>
<!-- Marketplace URLs Section (Optional) -->
<div class="mb-6 pt-6 border-t border-gray-200 dark:border-gray-700">
<h3 class="mb-4 text-lg font-semibold text-gray-700 dark:text-gray-200">Marketplace URLs (Optional)</h3>