196 lines
7.7 KiB
JavaScript
196 lines
7.7 KiB
JavaScript
|
document.addEventListener('DOMContentLoaded', function() {
|
||
|
const paletteSelector = document.getElementById('palette-selector');
|
||
|
const newPaletteButton = document.getElementById('new-palette');
|
||
|
const newPaletteForm = document.getElementById('new-palette-form');
|
||
|
const createPaletteForm = document.getElementById('create-palette-form');
|
||
|
const addColorForm = document.getElementById('add-color-form');
|
||
|
const createColorForm = document.getElementById('create-color-form');
|
||
|
const paletteColorsDiv = document.getElementById('palette-colors');
|
||
|
const colorEditorsDiv = document.getElementById('color-editors');
|
||
|
const addColorButton = document.getElementById('add-color');
|
||
|
const savePaletteButton = document.getElementById('save-palette');
|
||
|
|
||
|
newPaletteButton.addEventListener('click', function() {
|
||
|
newPaletteForm.style.display = 'block';
|
||
|
});
|
||
|
|
||
|
createPaletteForm.addEventListener('submit', function(event) {
|
||
|
event.preventDefault();
|
||
|
const formData = new FormData(createPaletteForm);
|
||
|
fetch('/palette-editor', {
|
||
|
method: 'POST',
|
||
|
body: formData
|
||
|
})
|
||
|
.then(response => response.json())
|
||
|
.then(data => {
|
||
|
alert('Palette created: ' + data.name);
|
||
|
paletteSelector.innerHTML += `<option value="${data.id}">${data.name}</option>`;
|
||
|
newPaletteForm.style.display = 'none';
|
||
|
createPaletteForm.reset();
|
||
|
})
|
||
|
.catch(error => {
|
||
|
console.error('Error:', error);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
paletteSelector.addEventListener('change', function() {
|
||
|
const paletteId = paletteSelector.value;
|
||
|
if (paletteId) {
|
||
|
loadPaletteColors(paletteId);
|
||
|
} else {
|
||
|
paletteColorsDiv.innerHTML = '';
|
||
|
addColorForm.style.display = 'none';
|
||
|
colorEditorsDiv.innerHTML = '';
|
||
|
}
|
||
|
});
|
||
|
|
||
|
addColorButton.addEventListener('click', function() {
|
||
|
addColorEditor();
|
||
|
});
|
||
|
|
||
|
savePaletteButton.addEventListener('click', function() {
|
||
|
const paletteId = createColorForm.getAttribute('data-palette-id');
|
||
|
const colorEditors = document.querySelectorAll('.color-editor');
|
||
|
colorEditors.forEach(editor => {
|
||
|
const colorId = editor.getAttribute('data-color-id');
|
||
|
const colorName = editor.querySelector('.color-name').value;
|
||
|
const colorHex = editor.querySelector('.color-hex-input').value;
|
||
|
if (colorId) {
|
||
|
// Update existing color
|
||
|
fetch(`/palette-editor/${paletteId}/colors/${colorId}`, {
|
||
|
method: 'PUT',
|
||
|
headers: {
|
||
|
'Content-Type': 'application/json',
|
||
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
|
||
|
},
|
||
|
body: JSON.stringify({ name: colorName, hex_value: colorHex })
|
||
|
})
|
||
|
.then(response => response.json())
|
||
|
.then(data => {
|
||
|
alert('Color updated: ' + data.name);
|
||
|
})
|
||
|
.catch(error => {
|
||
|
console.error('Error:', error);
|
||
|
});
|
||
|
} else {
|
||
|
// Add new color
|
||
|
fetch(`/palette-editor/${paletteId}/colors`, {
|
||
|
method: 'POST',
|
||
|
headers: {
|
||
|
'Content-Type': 'application/json',
|
||
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
|
||
|
},
|
||
|
body: JSON.stringify({ name: colorName, hex_value: colorHex })
|
||
|
})
|
||
|
.then(response => response.json())
|
||
|
.then(data => {
|
||
|
alert('Color added: ' + data.name);
|
||
|
editor.setAttribute('data-color-id', data.id);
|
||
|
})
|
||
|
.catch(error => {
|
||
|
console.error('Error:', error);
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
function loadPaletteColors(paletteId) {
|
||
|
fetch(`/palette-editor/${paletteId}/colors`)
|
||
|
.then(response => response.json())
|
||
|
.then(data => {
|
||
|
paletteColorsDiv.innerHTML = '<h2>Colors in Palette</h2>';
|
||
|
colorEditorsDiv.innerHTML = '';
|
||
|
data.forEach(color => {
|
||
|
addColorEditor(color.id, color.name, color.hex_value);
|
||
|
});
|
||
|
addColorForm.style.display = 'block';
|
||
|
createColorForm.setAttribute('data-palette-id', paletteId);
|
||
|
})
|
||
|
.catch(error => {
|
||
|
console.error('Error:', error);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function addColorEditor(colorId = '', colorName = '', colorHex = '#ffffff') {
|
||
|
const editor = document.createElement('div');
|
||
|
editor.className = 'color-editor col-md-2 mb-3';
|
||
|
editor.setAttribute('data-color-id', colorId);
|
||
|
editor.innerHTML = `
|
||
|
<div class="form-row align-items-end">
|
||
|
<div class="col-12">
|
||
|
<label>Color Name:</label>
|
||
|
<input type="text" class="form-control color-name" value="${colorName}" required>
|
||
|
</div>
|
||
|
<div class="col-12">
|
||
|
<label>Color Hex:</label>
|
||
|
<div class="color-picker"></div>
|
||
|
<input type="hidden" class="color-hex-input" value="${colorHex}" required>
|
||
|
</div>
|
||
|
<div class="col-12 text-right mt-2">
|
||
|
<button type="button" class="btn btn-danger btn-sm delete-color"><i class="fas fa-trash-alt"></i></button>
|
||
|
</div>
|
||
|
</div>
|
||
|
`;
|
||
|
colorEditorsDiv.appendChild(editor);
|
||
|
|
||
|
const deleteButton = editor.querySelector('.delete-color');
|
||
|
deleteButton.addEventListener('click', function() {
|
||
|
if (colorId) {
|
||
|
const paletteId = createColorForm.getAttribute('data-palette-id');
|
||
|
fetch(`/palette-editor/${paletteId}/colors/${colorId}`, {
|
||
|
method: 'DELETE',
|
||
|
headers: {
|
||
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
|
||
|
}
|
||
|
})
|
||
|
.then(response => response.json())
|
||
|
.then(data => {
|
||
|
alert('Color deleted: ' + data.message);
|
||
|
colorEditorsDiv.removeChild(editor);
|
||
|
})
|
||
|
.catch(error => {
|
||
|
console.error('Error:', error);
|
||
|
});
|
||
|
} else {
|
||
|
colorEditorsDiv.removeChild(editor);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
const pickr = Pickr.create({
|
||
|
el: editor.querySelector('.color-picker'),
|
||
|
theme: 'classic', // or 'monolith', or 'nano'
|
||
|
default: colorHex,
|
||
|
components: {
|
||
|
preview: true,
|
||
|
opacity: false,
|
||
|
hue: true,
|
||
|
|
||
|
interaction: {
|
||
|
hex: true,
|
||
|
input: true,
|
||
|
clear: true,
|
||
|
save: true
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
pickr.on('save', (color, instance) => {
|
||
|
editor.querySelector('.color-hex-input').value = color.toHEXA().toString();
|
||
|
pickr.hide();
|
||
|
});
|
||
|
|
||
|
pickr.on('clear', instance => {
|
||
|
editor.querySelector('.color-hex-input').value = '';
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Load default colors on page load
|
||
|
window.onload = function() {
|
||
|
const defaultPaletteOption = Array.from(paletteSelector.options).find(option => option.text === 'default-colors');
|
||
|
if (defaultPaletteOption) {
|
||
|
defaultPaletteOption.selected = true;
|
||
|
loadPaletteColors(defaultPaletteOption.value);
|
||
|
}
|
||
|
};
|
||
|
});
|