Files
michaelschiemer/resources/js/modules/admin/variant-creation.js
2025-11-24 21:28:25 +01:00

187 lines
5.9 KiB
JavaScript

/**
* Variant Creation Module
*
* Handles variant creation UI and API calls
*/
export class VariantCreation {
constructor() {
this.modal = null;
this.assetId = null;
this.init();
}
init() {
this.setupCreateButtons();
this.setupModal();
this.setupPresets();
this.setupSubmit();
}
setupCreateButtons() {
document.addEventListener('click', (e) => {
const button = e.target.closest('[data-create-variant]');
if (!button) return;
e.preventDefault();
this.assetId = button.closest('[data-asset-id]')?.dataset.assetId ||
window.location.pathname.split('/').pop();
this.showModal();
});
}
setupModal() {
// Create or get modal
this.modal = document.getElementById('variant-create-modal');
if (!this.modal) {
console.warn('Variant creation modal not found');
return;
}
// Setup close handlers
this.modal.querySelectorAll('[data-close-variant-modal]').forEach(el => {
el.addEventListener('click', () => this.closeModal());
});
// Setup quality slider
const qualitySlider = this.modal.querySelector('#variant-quality');
const qualityValue = this.modal.querySelector('#quality-value');
if (qualitySlider && qualityValue) {
qualitySlider.addEventListener('input', (e) => {
qualityValue.textContent = e.target.value;
});
}
}
setupPresets() {
const presets = {
'1200w': { variant: '1200w', width: 1200, quality: 85 },
'800w': { variant: '800w', width: 800, quality: 85 },
'thumb@1x': { variant: 'thumb@1x', width: 200, quality: 80 },
'thumb@2x': { variant: 'thumb@2x', width: 400, quality: 80 },
};
this.modal?.querySelectorAll('[data-preset]').forEach(button => {
button.addEventListener('click', () => {
const preset = presets[button.dataset.preset];
if (preset) {
this.modal.querySelector('#variant-name').value = preset.variant;
this.modal.querySelector('#variant-width').value = preset.width;
this.modal.querySelector('#variant-quality').value = preset.quality;
this.modal.querySelector('#quality-value').textContent = preset.quality;
}
});
});
}
setupSubmit() {
const submitButton = this.modal?.querySelector('#variant-create-submit');
if (!submitButton) return;
submitButton.addEventListener('click', async () => {
await this.createVariant();
});
}
showModal() {
if (!this.modal) return;
// Reset form
const form = this.modal.querySelector('#variant-create-form');
if (form) {
form.reset();
this.modal.querySelector('#variant-quality').value = 85;
this.modal.querySelector('#quality-value').textContent = '85';
}
this.modal.style.display = 'block';
}
closeModal() {
if (this.modal) {
this.modal.style.display = 'none';
}
}
async createVariant() {
if (!this.assetId) {
console.error('Asset ID not set');
return;
}
const form = this.modal.querySelector('#variant-create-form');
if (!form) return;
const formData = new FormData(form);
const data = {
variant: formData.get('variant'),
width: formData.get('width') ? parseInt(formData.get('width')) : null,
height: formData.get('height') ? parseInt(formData.get('height')) : null,
quality: formData.get('quality') ? parseInt(formData.get('quality')) : null,
};
// Validate
if (!data.variant) {
if (window.Toast) {
window.Toast.error('Variant name is required');
} else {
alert('Variant name is required');
}
return;
}
const submitButton = this.modal.querySelector('#variant-create-submit');
const originalText = submitButton.textContent;
submitButton.disabled = true;
submitButton.textContent = 'Creating...';
try {
const response = await fetch(`/api/v1/assets/${this.assetId}/variants`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
},
body: JSON.stringify(data),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));
throw new Error(errorData.error || `HTTP ${response.status}`);
}
const result = await response.json();
if (window.Toast) {
window.Toast.success('Variant creation queued. It will be processed shortly.');
} else {
alert('Variant creation queued successfully');
}
this.closeModal();
// Reload page after a short delay to show new variant
setTimeout(() => {
window.location.reload();
}, 1500);
} catch (error) {
console.error('Failed to create variant:', error);
if (window.Toast) {
window.Toast.error(`Failed to create variant: ${error.message}`);
} else {
alert(`Failed to create variant: ${error.message}`);
}
} finally {
submitButton.disabled = false;
submitButton.textContent = originalText;
}
}
}
// Auto-initialize
document.addEventListener('DOMContentLoaded', () => {
new VariantCreation();
});