236 lines
6.7 KiB
JavaScript
236 lines
6.7 KiB
JavaScript
// Data models
|
|
class Dish {
|
|
constructor(name) {
|
|
this.id = this.generateUUID();
|
|
this.name = name;
|
|
this.createdAt = new Date().toISOString();
|
|
}
|
|
|
|
generateUUID() {
|
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
const r = Math.random() * 16 | 0;
|
|
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
return v.toString(16);
|
|
});
|
|
}
|
|
}
|
|
|
|
class History {
|
|
constructor(dishId) {
|
|
this.id = this.generateUUID();
|
|
this.dishId = dishId;
|
|
this.selectedAt = new Date().toISOString();
|
|
}
|
|
|
|
generateUUID() {
|
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
const r = Math.random() * 16 | 0;
|
|
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
return v.toString(16);
|
|
});
|
|
}
|
|
}
|
|
|
|
// App state
|
|
let dishes = [];
|
|
let history = [];
|
|
|
|
// DOM Elements
|
|
const welcomeScreen = document.getElementById('welcome-screen');
|
|
const dishesScreen = document.getElementById('dishes-screen');
|
|
const homeScreen = document.getElementById('home-screen');
|
|
const resultScreen = document.getElementById('result-screen');
|
|
|
|
const addFirstDishBtn = document.getElementById('add-first-dish-btn');
|
|
const dishInput = document.getElementById('dish-input');
|
|
const addDishBtn = document.getElementById('add-dish-btn');
|
|
const dishesList = document.getElementById('dishes-list');
|
|
const randomBtn = document.getElementById('random-btn');
|
|
const selectedDish = document.getElementById('selected-dish');
|
|
const cookBtn = document.getElementById('cook-btn');
|
|
const anotherBtn = document.getElementById('another-btn');
|
|
const manageDishesBtn = document.getElementById('manage-dishes-btn');
|
|
const backToHomeBtn = document.getElementById('back-to-home-btn');
|
|
const backToHomeResultBtn = document.getElementById('back-to-home-result-btn');
|
|
|
|
// Initialize app
|
|
function init() {
|
|
loadData();
|
|
setupEventListeners();
|
|
|
|
if (dishes.length === 0) {
|
|
showScreen('welcome');
|
|
} else {
|
|
showScreen('home');
|
|
}
|
|
}
|
|
|
|
// Event listeners
|
|
function setupEventListeners() {
|
|
addFirstDishBtn.addEventListener('click', () => {
|
|
showScreen('dishes');
|
|
dishInput.focus();
|
|
});
|
|
|
|
addDishBtn.addEventListener('click', addDish);
|
|
dishInput.addEventListener('keypress', (e) => {
|
|
if (e.key === 'Enter') addDish();
|
|
});
|
|
|
|
randomBtn.addEventListener('click', getRandomDish);
|
|
cookBtn.addEventListener('click', () => showScreen('home'));
|
|
anotherBtn.addEventListener('click', getRandomDish);
|
|
|
|
manageDishesBtn.addEventListener('click', () => {
|
|
showScreen('dishes');
|
|
renderDishesList();
|
|
});
|
|
|
|
backToHomeBtn.addEventListener('click', () => {
|
|
if (dishes.length === 0) {
|
|
showScreen('welcome');
|
|
} else {
|
|
showScreen('home');
|
|
}
|
|
});
|
|
|
|
backToHomeResultBtn.addEventListener('click', () => showScreen('home'));
|
|
}
|
|
|
|
// Screen management
|
|
function showScreen(screen) {
|
|
welcomeScreen.classList.add('hidden');
|
|
dishesScreen.classList.add('hidden');
|
|
homeScreen.classList.add('hidden');
|
|
resultScreen.classList.add('hidden');
|
|
|
|
switch(screen) {
|
|
case 'welcome':
|
|
welcomeScreen.classList.remove('hidden');
|
|
break;
|
|
case 'dishes':
|
|
dishesScreen.classList.remove('hidden');
|
|
renderDishesList();
|
|
break;
|
|
case 'home':
|
|
homeScreen.classList.remove('hidden');
|
|
break;
|
|
case 'result':
|
|
resultScreen.classList.remove('hidden');
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Dish management
|
|
function addDish() {
|
|
const name = dishInput.value.trim();
|
|
if (!name) return;
|
|
|
|
const dish = new Dish(name);
|
|
dishes.push(dish);
|
|
saveData();
|
|
|
|
dishInput.value = '';
|
|
renderDishesList();
|
|
|
|
if (dishes.length === 1) {
|
|
showScreen('home');
|
|
}
|
|
}
|
|
|
|
function editDish(id) {
|
|
const dish = dishes.find(d => d.id === id);
|
|
if (!dish) return;
|
|
|
|
const newName = prompt('Введите новое название:', dish.name);
|
|
if (newName && newName.trim()) {
|
|
dish.name = newName.trim();
|
|
saveData();
|
|
renderDishesList();
|
|
}
|
|
}
|
|
|
|
function deleteDish(id) {
|
|
if (!confirm('Вы уверены, что хотите удалить это блюдо?')) return;
|
|
|
|
dishes = dishes.filter(d => d.id !== id);
|
|
history = history.filter(h => h.dishId !== id);
|
|
saveData();
|
|
renderDishesList();
|
|
|
|
if (dishes.length === 0) {
|
|
showScreen('welcome');
|
|
}
|
|
}
|
|
|
|
// Random selection with 3-day repeat protection
|
|
function getRandomDish() {
|
|
if (dishes.length === 0) {
|
|
showScreen('welcome');
|
|
return;
|
|
}
|
|
|
|
const threeDaysAgo = new Date();
|
|
threeDaysAgo.setDate(threeDaysAgo.getDate() - 3);
|
|
|
|
const recentDishIds = history
|
|
.filter(h => new Date(h.selectedAt) > threeDaysAgo)
|
|
.map(h => h.dishId);
|
|
|
|
let availableDishes = dishes.filter(d => !recentDishIds.includes(d.id));
|
|
|
|
if (availableDishes.length === 0) {
|
|
availableDishes = dishes;
|
|
}
|
|
|
|
const randomIndex = Math.floor(Math.random() * availableDishes.length);
|
|
const selected = availableDishes[randomIndex];
|
|
|
|
const historyEntry = new History(selected.id);
|
|
history.push(historyEntry);
|
|
saveData();
|
|
|
|
selectedDish.textContent = selected.name;
|
|
showScreen('result');
|
|
}
|
|
|
|
// Render functions
|
|
function renderDishesList() {
|
|
dishesList.innerHTML = '';
|
|
|
|
if (dishes.length === 0) {
|
|
dishesList.innerHTML = '<p style="text-align: center; color: #666;">Пока нет блюд. Добавьте первое!</p>';
|
|
return;
|
|
}
|
|
|
|
dishes.forEach(dish => {
|
|
const dishElement = document.createElement('div');
|
|
dishElement.className = 'dish-item';
|
|
dishElement.innerHTML = `
|
|
<span class="dish-name">${dish.name}</span>
|
|
<div class="dish-actions">
|
|
<button onclick="editDish('${dish.id}')">Изменить</button>
|
|
<button class="delete-btn" onclick="deleteDish('${dish.id}')">Удалить</button>
|
|
</div>
|
|
`;
|
|
dishesList.appendChild(dishElement);
|
|
});
|
|
}
|
|
|
|
// Local storage
|
|
function saveData() {
|
|
localStorage.setItem('whatToCookDishes', JSON.stringify(dishes));
|
|
localStorage.setItem('whatToCookHistory', JSON.stringify(history));
|
|
}
|
|
|
|
function loadData() {
|
|
const savedDishes = localStorage.getItem('whatToCookDishes');
|
|
const savedHistory = localStorage.getItem('whatToCookHistory');
|
|
|
|
if (savedDishes) dishes = JSON.parse(savedDishes);
|
|
if (savedHistory) history = JSON.parse(savedHistory);
|
|
}
|
|
|
|
// Initialize app when DOM is loaded
|
|
document.addEventListener('DOMContentLoaded', init);
|