feat(admin): separate platform CRUD from CMS, add entity selector macro
Some checks failed
Some checks failed
- Move platforms menu from CMS to Platform Admin section with create/edit - Add platform create page, API endpoint, and service method - Remove CMS-specific content from platform list and detail pages - Create shared entity_selector + entity_selected_badge Jinja macros - Create entity-selector.js generalizing store-selector.js for any entity - Add Tom Select merchant filter to stores page with localStorage persistence - Migrate store-products page to use shared macros (remove 53 lines of duped CSS) - Fix broken icons: puzzle→puzzle-piece, building-storefront→store, language→translate, server→cube Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
134
app/modules/tenancy/static/admin/js/platform-create.js
Normal file
134
app/modules/tenancy/static/admin/js/platform-create.js
Normal file
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Platform Create - Alpine.js Component
|
||||
*
|
||||
* Handles platform creation for multi-platform CMS.
|
||||
*/
|
||||
|
||||
const platformCreateLog = window.LogConfig.createLogger('PLATFORM_CREATE');
|
||||
|
||||
function platformCreate() {
|
||||
return {
|
||||
// Inherit base layout functionality from init-alpine.js
|
||||
...data(),
|
||||
|
||||
// Page identification
|
||||
currentPage: 'platform-create',
|
||||
|
||||
// State
|
||||
saving: false,
|
||||
error: null,
|
||||
|
||||
// Language editing
|
||||
currentLang: 'fr',
|
||||
languageNames: {
|
||||
fr: 'Fran\u00e7ais',
|
||||
de: 'Deutsch',
|
||||
en: 'English',
|
||||
lb: 'L\u00ebtzebuergesch',
|
||||
},
|
||||
|
||||
// Form data
|
||||
formData: {
|
||||
code: '',
|
||||
name: '',
|
||||
description_translations: { fr: '', de: '', en: '', lb: '' },
|
||||
domain: '',
|
||||
path_prefix: '',
|
||||
default_language: 'fr',
|
||||
supported_languages: ['fr', 'de', 'en', 'lb'],
|
||||
is_active: true,
|
||||
is_public: true,
|
||||
},
|
||||
|
||||
errors: {},
|
||||
|
||||
// Available languages
|
||||
availableLanguages: [
|
||||
{ code: 'fr', name: 'French' },
|
||||
{ code: 'de', name: 'German' },
|
||||
{ code: 'en', name: 'English' },
|
||||
{ code: 'lb', name: 'Luxembourgish' },
|
||||
],
|
||||
|
||||
// Lifecycle
|
||||
async init() {
|
||||
platformCreateLog.info('=== PLATFORM CREATE PAGE INITIALIZING ===');
|
||||
|
||||
// Duplicate initialization guard
|
||||
if (window._platformCreateInitialized) {
|
||||
platformCreateLog.warn('Platform create page already initialized, skipping...');
|
||||
return;
|
||||
}
|
||||
window._platformCreateInitialized = true;
|
||||
|
||||
platformCreateLog.info('=== PLATFORM CREATE PAGE INITIALIZATION COMPLETE ===');
|
||||
},
|
||||
|
||||
async handleSubmit() {
|
||||
this.saving = true;
|
||||
this.error = null;
|
||||
this.errors = {};
|
||||
|
||||
try {
|
||||
// Sync base description from default language translation
|
||||
const defaultLang = this.formData.default_language || 'fr';
|
||||
const baseDesc = this.formData.description_translations[defaultLang] || '';
|
||||
|
||||
const payload = {
|
||||
code: this.formData.code,
|
||||
name: this.formData.name,
|
||||
description: baseDesc || null,
|
||||
description_translations: this.formData.description_translations,
|
||||
domain: this.formData.domain || null,
|
||||
path_prefix: this.formData.path_prefix || null,
|
||||
default_language: this.formData.default_language,
|
||||
supported_languages: this.formData.supported_languages,
|
||||
is_active: this.formData.is_active,
|
||||
is_public: this.formData.is_public,
|
||||
};
|
||||
|
||||
const response = await apiClient.post('/admin/platforms', payload);
|
||||
|
||||
platformCreateLog.info(`Created platform: ${response.code}`);
|
||||
|
||||
// Redirect to the new platform's detail page
|
||||
window.location.href = `/admin/platforms/${response.code}`;
|
||||
} catch (err) {
|
||||
platformCreateLog.error('Error creating platform:', err);
|
||||
this.error = err.message || 'Failed to create platform';
|
||||
|
||||
// Handle validation errors
|
||||
if (err.details) {
|
||||
this.errors = err.details;
|
||||
}
|
||||
} finally {
|
||||
this.saving = false;
|
||||
}
|
||||
},
|
||||
|
||||
// Helper Methods
|
||||
isLanguageSupported(code) {
|
||||
return this.formData.supported_languages.includes(code);
|
||||
},
|
||||
|
||||
toggleLanguage(code) {
|
||||
const index = this.formData.supported_languages.indexOf(code);
|
||||
if (index > -1) {
|
||||
// Don't allow removing the last language
|
||||
if (this.formData.supported_languages.length > 1) {
|
||||
this.formData.supported_languages.splice(index, 1);
|
||||
// Switch tab if the removed language was active
|
||||
if (this.currentLang === code) {
|
||||
this.currentLang = this.formData.supported_languages[0];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.formData.supported_languages.push(code);
|
||||
// Initialize empty translation for new language
|
||||
if (!this.formData.description_translations[code]) {
|
||||
this.formData.description_translations[code] = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user