166 lines
5.9 KiB
JavaScript
166 lines
5.9 KiB
JavaScript
import $ from 'jquery';
|
|
import axios from 'axios';
|
|
|
|
function showToast(message, type = 'error') {
|
|
let container = document.querySelector('[data-role="toast-container"]');
|
|
if (!container) {
|
|
container = document.createElement('div');
|
|
container.dataset.role = 'toast-container';
|
|
container.style.position = 'fixed';
|
|
container.style.top = '1rem';
|
|
container.style.right = '1rem';
|
|
container.style.zIndex = '9999';
|
|
container.style.display = 'flex';
|
|
container.style.flexDirection = 'column';
|
|
container.style.gap = '0.5rem';
|
|
document.body.appendChild(container);
|
|
}
|
|
|
|
const toast = document.createElement('div');
|
|
toast.textContent = message;
|
|
toast.style.padding = '0.6rem 0.9rem';
|
|
toast.style.borderRadius = '6px';
|
|
toast.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)';
|
|
toast.style.color = '#0f172a';
|
|
toast.style.fontSize = '0.9rem';
|
|
toast.style.backgroundColor = type === 'success' ? '#bbf7d0' : '#fee2e2';
|
|
|
|
container.appendChild(toast);
|
|
|
|
setTimeout(() => {
|
|
toast.remove();
|
|
if (!container.children.length) {
|
|
container.remove();
|
|
}
|
|
}, 3000);
|
|
}
|
|
|
|
function parseJson(id, fallback) {
|
|
const node = document.getElementById(id);
|
|
if (!node) {
|
|
return fallback;
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(node.textContent ?? 'null') ?? fallback;
|
|
} catch (error) {
|
|
console.error(`Unable to parse JSON from ${id}`, error);
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
|
|
function parseRows(formData) {
|
|
return formData.getAll('rows[]').map((value) => parseInt(value, 10)).filter((value) => !Number.isNaN(value));
|
|
}
|
|
|
|
function buildPayload(form) {
|
|
const formData = new FormData(form);
|
|
console.log(Object.fromEntries(formData.entries()));
|
|
const payload = {
|
|
rows: parseRows(formData),
|
|
variety_variation_id: formData.get('variety_variation_id') || null,
|
|
};
|
|
|
|
// If no variation selected, build creation object
|
|
if (!payload.variety_variation_id) {
|
|
payload.create_variation = {
|
|
grape_variety_id: formData.get('grape_variety_id') || null,
|
|
grape_variety_name: formData.get('grape_variety_name') || null,
|
|
color: formData.get('color'),
|
|
description: formData.get('description') || null,
|
|
typical_sugar_content: formData.get('typical_sugar_content') || null,
|
|
typical_alcohol: formData.get('typical_alcohol') || null,
|
|
ripening_period: formData.get('ripening_period') || null,
|
|
};
|
|
}
|
|
|
|
return payload;
|
|
}
|
|
|
|
export default function initAddPlants() {
|
|
const $root = $('[data-page="vineyard-add-plants"]');
|
|
if (!$root.length) {
|
|
return;
|
|
}
|
|
|
|
const apiRoutes = parseJson('add-plants-api', {});
|
|
const rows = parseJson('add-plants-rows', []);
|
|
|
|
const $form = $root.find('#assign-plants-form');
|
|
const $variationSelect = $form.find('[name="variety_variation_id"]');
|
|
const $createSection = $root.find('[data-role="create-variation"]');
|
|
|
|
$root.find('[data-control="toggle-create"]').on('click', (event) => {
|
|
event.preventDefault();
|
|
$createSection.toggleClass('hidden');
|
|
});
|
|
|
|
$createSection.find('[data-control="submit-variation"]').on('click', async () => {
|
|
const payload = {
|
|
grape_variety_id: $createSection.find('[name="grape_variety_id"]').val() || null,
|
|
grape_variety_name: $createSection.find('[name="grape_variety_name"]').val() || null,
|
|
color: $createSection.find('[name="color"]').val(),
|
|
description: $createSection.find('[name="description"]').val() || null,
|
|
typical_sugar_content: $createSection.find('[name="typical_sugar_content"]').val() || null,
|
|
typical_alcohol: $createSection.find('[name="typical_alcohol"]').val() || null,
|
|
ripening_period: $createSection.find('[name="ripening_period"]').val() || null,
|
|
};
|
|
|
|
if (!payload.color) {
|
|
showToast('Choose a color for the new variation.', 'error');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await axios.post(apiRoutes.createVariation, payload);
|
|
const variation = response.data?.variation;
|
|
if (!variation) {
|
|
return;
|
|
}
|
|
|
|
const option = $('<option />', {
|
|
value: variation.id,
|
|
text: variation.label,
|
|
});
|
|
$variationSelect.append(option);
|
|
$variationSelect.val(String(variation.id));
|
|
$createSection.addClass('hidden');
|
|
$createSection.find('input, textarea, select').val('');
|
|
} catch (error) {
|
|
console.error('Failed to create variation', error);
|
|
showToast('Unable to create variation. Please verify details.', 'error');
|
|
}
|
|
});
|
|
|
|
$form.on('submit', async (event) => {
|
|
event.preventDefault();
|
|
|
|
const payload = buildPayload($form[0]);
|
|
console.log(payload);
|
|
|
|
if (!payload.rows.length) {
|
|
showToast('Select at least one row to assign plants.', 'error');
|
|
return;
|
|
}
|
|
|
|
if (!payload.variety_variation_id && (!payload.create_variation || !payload.create_variation.color)) {
|
|
showToast('Select an existing variation or provide details for a new one.', 'error');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await axios.post($form.attr('action'), payload);
|
|
if (response.data?.success) {
|
|
showToast('Plants assigned successfully.', 'success');
|
|
const url = new URL(window.location.href);
|
|
url.pathname = '/vineyard/map';
|
|
url.search = '';
|
|
window.location.assign(url.toString());
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to assign plants', error);
|
|
showToast('Unable to assign plants. Please check input values.', 'error');
|
|
}
|
|
});
|
|
}
|