Files
licores-son-amores/src/main.js
2026-02-01 22:23:24 +01:00

257 lines
8.0 KiB
JavaScript

import "./styles.css";
import data from "./data.json";
let spiritsData = [];
let recipesData = [];
async function loadData() {
try {
spiritsData = data.spirits.sort((a, b) => a.name > b.name);
recipesData = data.recipes.sort((a, b) => a.name > b.name);
renderSpirits();
enableButtonsLogic();
} catch (error) {
console.error("Error cargando datos:", error);
document.getElementById("spiritsGrid").innerHTML =
'<p class="no-recipes">Error al cargar los datos. Asegúrate de que data.json está disponible.</p>';
}
}
function renderSpirits() {
const grid = document.getElementById("spiritsGrid");
grid.innerHTML = spiritsData
.map(
(spirit, index) => `
<div class="spirit-card" id="spirit-${index}">
<input type="checkbox" id="check-${index}">
<div class="spirit-name">${spirit.name}</div>
<div class="spirit-brand">${spirit.brand}</div>
<div class="spirit-type">${spirit.type}</div>
</div>
`,
)
.join("");
}
function toggleSpirit(index, forcedCheckValue) {
const card = document.getElementById(`spirit-${index}`);
const checkbox = document.getElementById(`check-${index}`);
checkbox.checked =
forcedCheckValue !== undefined ? forcedCheckValue : !checkbox.checked;
card.classList.toggle("selected");
// Update buttons status only on natural toggle
if (forcedCheckValue === undefined) {
updateMixButtonStatus();
updateMassSelectButtonsStatus();
}
}
function enableButtonsLogic() {
const grid = document.getElementById("spiritsGrid");
// Add toggle logic to cards
spiritsData.map((spirit, index) => {
grid.querySelector(`#spirit-${index}`).addEventListener("click", (e) => {
toggleSpirit(index);
});
});
// Add recipes crossing to mix button
const section = document.getElementsByClassName("section");
if (section && section.length > 0) {
section[0].querySelector(".mix-button").addEventListener("click", (e) => {
findRecipes();
});
section[0].querySelector(".mix-button").disabled = true;
}
// Add logic to select all / none buttons
if (section && section.length > 0) {
section[0]
.querySelector("#select-all-button")
.addEventListener("click", (e) => {
selectAll();
});
section[0]
.querySelector("#select-none-button")
.addEventListener("click", (e) => {
selectNone();
});
updateMassSelectButtonsStatus();
}
}
function updateMixButtonStatus(forcedDisabledValue) {
const section = document.getElementsByClassName("section");
const selected = getSelectedSpiritsTypes();
if (section && section.length > 0) {
section[0].querySelector(".mix-button").disabled =
forcedDisabledValue ?? selected.length === 0;
}
}
function updateMassSelectButtonsStatus() {
const section = document.getElementsByClassName("selection-options");
const selected = getSelectedSpiritsNames();
if (section && section.length > 0) {
section[0].querySelector("#select-all-button").disabled =
selected.length === spiritsData.length;
section[0].querySelector("#select-none-button").disabled =
selected.length === 0;
}
}
function getSelectedSpiritsTypes() {
const selectedSpirits = [];
spiritsData.forEach((spirit, index) => {
const checkbox = document.getElementById(`check-${index}`);
if (checkbox.checked) {
selectedSpirits.push(spirit.type);
}
});
return selectedSpirits;
}
function getSelectedSpiritsNames() {
const selectedSpirits = [];
spiritsData.forEach((spirit, index) => {
const checkbox = document.getElementById(`check-${index}`);
if (checkbox.checked) {
selectedSpirits.push(spirit.name);
}
});
return selectedSpirits;
}
function selectAll() {
const selectAllButton = document.getElementById("select-all-button");
if (selectAllButton) {
const selectedNames = getSelectedSpiritsNames();
spiritsData.forEach((spirit, index) => {
if (!selectedNames.includes(spirit.name)) {
toggleSpirit(index, true);
}
});
}
updateMixButtonStatus(false);
updateMassSelectButtonsStatus();
return;
}
function selectNone() {
const selectNoneButton = document.getElementById("select-none-button");
if (selectNoneButton) {
const selectedNames = getSelectedSpiritsNames();
spiritsData.forEach((spirit, index) => {
if (selectedNames.includes(spirit.name)) {
toggleSpirit(index, false);
}
});
}
updateMixButtonStatus(true);
updateMassSelectButtonsStatus();
return;
}
function findRecipes() {
const selectedSpirits = getSelectedSpiritsTypes();
if (selectedSpirits.length === 0) {
document.getElementById("recipesContainer").innerHTML =
'<p class="no-recipes">Por favor, selecciona al menos un licor para encontrar recetas.</p>';
return;
}
const availableRecipes = recipesData.filter((recipe) => {
const alcoholIngredients = recipe.ingredients.filter(
(ing) => ing.isAlcohol,
);
return alcoholIngredients.every((ingredient) =>
selectedSpirits.includes(ingredient.type),
);
});
renderRecipes(availableRecipes);
document.getElementById("recipesContainer").scrollIntoView({
behavior: "smooth",
block: "start",
});
}
function renderRecipes(recipes) {
const container = document.getElementById("recipesContainer");
if (recipes.length === 0) {
container.innerHTML =
'<p class="no-recipes">No se encontraron recetas con los licores seleccionados. ¡Intenta agregar más licores!</p>';
return;
}
container.innerHTML = recipes
.map((recipe) => {
const alcoholIngredients = recipe.ingredients.filter(
(ing) => ing.isAlcohol,
);
const nonAlcoholIngredients = recipe.ingredients.filter(
(ing) => !ing.isAlcohol,
);
return `
<div class="recipe-card">
<div class="recipe-content">
<div class="recipe-name">${recipe.name}</div>
<div class="non-alcohol-title">Licores:</div>
<div class="recipe-ingredients">
${alcoholIngredients
.map(
(ing) => `
<div class="ingredient alcohol-ingredient">
<span class="ingredient-amount">${ing.amount}</span>
<span>${ing.name}</span>
</div>
`,
)
.join("")}
${
nonAlcoholIngredients.length > 0
? `
<div class="non-alcohol-section">
<div class="non-alcohol-title">Otros ingredientes:</div>
${nonAlcoholIngredients
.map(
(ing) => `
<div class="ingredient non-alcohol-ingredient">
${ing.amount ? `<span class="ingredient-amount">${ing.amount}</span>` : ""}
<span>${ing.name}</span>
</div>
`,
)
.join("")}
</div>
`
: ""
}
</div>
${
recipe.instructions
? `
<div class="recipe-instructions">
<strong>Preparación:</strong> ${recipe.instructions}
</div>
`
: ""
}
</div>
<div class="recipe-img">
<img
src="/public/spirits/${recipe.name?.toLowerCase()}.jpg"
alt=""
onerror="this.onerror=null; this.src='/public/spirits/default.png';"
/>
</div>
</div>
`;
})
.join("");
}
// Inicializar al cargar la página
document.addEventListener("DOMContentLoaded", loadData);