Some checks failed
Logo URL is required by Google Wallet API for LoyaltyClass creation. Added validation across all three program edit screens (admin, merchant, store) with a helpful hint explaining the requirement. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
155 lines
5.8 KiB
JavaScript
155 lines
5.8 KiB
JavaScript
// app/modules/loyalty/static/admin/js/loyalty-program-edit.js
|
|
// noqa: js-006 - async init pattern is safe, loadData has try/catch
|
|
|
|
const loyaltyProgramEditLog = window.LogConfig.loggers.loyaltyProgramEdit || window.LogConfig.createLogger('loyaltyProgramEdit');
|
|
|
|
function adminLoyaltyProgramEdit() {
|
|
return {
|
|
...data(),
|
|
...createProgramFormMixin(),
|
|
currentPage: 'loyalty-programs',
|
|
|
|
merchantId: null,
|
|
merchant: null,
|
|
programId: null,
|
|
|
|
loading: false,
|
|
error: null,
|
|
|
|
get backUrl() {
|
|
return `/admin/loyalty/merchants/${this.merchantId}`;
|
|
},
|
|
|
|
async init() {
|
|
loyaltyProgramEditLog.info('=== ADMIN PROGRAM EDIT PAGE INITIALIZING ===');
|
|
if (window._adminProgramEditInitialized) return;
|
|
window._adminProgramEditInitialized = true;
|
|
|
|
// Extract merchant ID from URL: /admin/loyalty/merchants/{id}/program
|
|
const pathParts = window.location.pathname.split('/');
|
|
const merchantsIndex = pathParts.indexOf('merchants');
|
|
if (merchantsIndex !== -1 && pathParts[merchantsIndex + 1]) {
|
|
this.merchantId = parseInt(pathParts[merchantsIndex + 1]);
|
|
}
|
|
|
|
if (!this.merchantId) {
|
|
this.error = 'Invalid merchant ID';
|
|
loyaltyProgramEditLog.error('Could not extract merchant ID from URL');
|
|
return;
|
|
}
|
|
|
|
loyaltyProgramEditLog.info('Merchant ID:', this.merchantId);
|
|
await this.loadData();
|
|
loyaltyProgramEditLog.info('=== ADMIN PROGRAM EDIT PAGE INITIALIZATION COMPLETE ===');
|
|
},
|
|
|
|
async loadData() {
|
|
this.loading = true;
|
|
this.error = null;
|
|
|
|
try {
|
|
// Load merchant info and program data in parallel
|
|
await Promise.all([
|
|
this.loadMerchant(),
|
|
this.loadProgram()
|
|
]);
|
|
} catch (error) {
|
|
loyaltyProgramEditLog.error('Failed to load data:', error);
|
|
this.error = error.message || 'Failed to load data';
|
|
} finally {
|
|
this.loading = false;
|
|
}
|
|
},
|
|
|
|
async loadMerchant() {
|
|
const response = await apiClient.get(`/admin/merchants/${this.merchantId}`);
|
|
if (response) {
|
|
this.merchant = response;
|
|
loyaltyProgramEditLog.info('Merchant loaded:', this.merchant.name);
|
|
}
|
|
},
|
|
|
|
async loadProgram() {
|
|
try {
|
|
const response = await apiClient.get(`/admin/loyalty/merchants/${this.merchantId}/stats`);
|
|
|
|
if (response && response.program) {
|
|
const program = response.program;
|
|
this.programId = program.id;
|
|
this.isNewProgram = false;
|
|
this.populateSettings(program);
|
|
loyaltyProgramEditLog.info('Program loaded, ID:', this.programId);
|
|
} else {
|
|
this.isNewProgram = true;
|
|
if (this.merchant) {
|
|
this.settings.card_name = this.merchant.name + ' Loyalty';
|
|
}
|
|
loyaltyProgramEditLog.info('No program found, create mode');
|
|
}
|
|
} catch (error) {
|
|
this.isNewProgram = true;
|
|
if (this.merchant) {
|
|
this.settings.card_name = this.merchant.name + ' Loyalty';
|
|
}
|
|
loyaltyProgramEditLog.info('No program, switching to create mode');
|
|
}
|
|
},
|
|
|
|
async saveSettings() {
|
|
this.saving = true;
|
|
|
|
try {
|
|
const payload = this.buildPayload();
|
|
if (!payload) { this.saving = false; return; }
|
|
|
|
if (this.isNewProgram) {
|
|
const response = await apiClient.post(
|
|
`/admin/loyalty/merchants/${this.merchantId}/program`,
|
|
payload
|
|
);
|
|
this.programId = response.id;
|
|
this.isNewProgram = false;
|
|
Utils.showToast('Program created successfully', 'success');
|
|
} else {
|
|
await apiClient.patch(
|
|
`/admin/loyalty/programs/${this.programId}`,
|
|
payload
|
|
);
|
|
Utils.showToast('Program updated successfully', 'success');
|
|
}
|
|
|
|
loyaltyProgramEditLog.info('Program saved');
|
|
window.location.href = this.backUrl;
|
|
} catch (error) {
|
|
Utils.showToast(`Failed to save: ${error.message}`, 'error');
|
|
loyaltyProgramEditLog.error('Save failed:', error);
|
|
} finally {
|
|
this.saving = false;
|
|
}
|
|
},
|
|
|
|
async deleteProgram() {
|
|
if (!this.programId) return;
|
|
this.deleting = true;
|
|
|
|
try {
|
|
await apiClient.delete(`/admin/loyalty/programs/${this.programId}`);
|
|
Utils.showToast('Program deleted', 'success');
|
|
loyaltyProgramEditLog.info('Program deleted');
|
|
window.location.href = this.backUrl;
|
|
} catch (error) {
|
|
Utils.showToast(`Failed to delete: ${error.message}`, 'error');
|
|
loyaltyProgramEditLog.error('Delete failed:', error);
|
|
} finally {
|
|
this.deleting = false;
|
|
this.showDeleteModal = false;
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
if (!window.LogConfig.loggers.loyaltyProgramEdit) {
|
|
window.LogConfig.loggers.loyaltyProgramEdit = window.LogConfig.createLogger('loyaltyProgramEdit');
|
|
}
|
|
loyaltyProgramEditLog.info('Admin loyalty program edit module loaded');
|