diff --git a/images/discount.svg b/images/discount.svg new file mode 100644 index 0000000..278502a --- /dev/null +++ b/images/discount.svg @@ -0,0 +1,10 @@ + + + + Rectangle 76 + Created with Sketch. + + + + + \ No newline at end of file diff --git a/images/home-icon.png b/images/home-icon.png new file mode 100644 index 0000000..f488ecd Binary files /dev/null and b/images/home-icon.png differ diff --git a/images/map-icon.png b/images/map-icon.png new file mode 100644 index 0000000..09dcf19 Binary files /dev/null and b/images/map-icon.png differ diff --git a/images/pizza_1.jpg b/images/pizza_1.jpg new file mode 100644 index 0000000..fb24ac0 Binary files /dev/null and b/images/pizza_1.jpg differ diff --git a/images/pizza_2.jpg b/images/pizza_2.jpg new file mode 100644 index 0000000..7076fd7 Binary files /dev/null and b/images/pizza_2.jpg differ diff --git a/images/pizza_3.jpg b/images/pizza_3.jpg new file mode 100644 index 0000000..dc49acf Binary files /dev/null and b/images/pizza_3.jpg differ diff --git a/images/pizza_4.jpg b/images/pizza_4.jpg new file mode 100644 index 0000000..d98bd17 Binary files /dev/null and b/images/pizza_4.jpg differ diff --git a/images/pizza_5.jpg b/images/pizza_5.jpg new file mode 100644 index 0000000..041affb Binary files /dev/null and b/images/pizza_5.jpg differ diff --git a/images/pizza_6.jpg b/images/pizza_6.jpg new file mode 100644 index 0000000..e02abff Binary files /dev/null and b/images/pizza_6.jpg differ diff --git a/images/pizza_7.jpg b/images/pizza_7.jpg new file mode 100644 index 0000000..d512907 Binary files /dev/null and b/images/pizza_7.jpg differ diff --git a/images/pizza_8.jpg b/images/pizza_8.jpg new file mode 100644 index 0000000..e8b593d Binary files /dev/null and b/images/pizza_8.jpg differ diff --git a/images/pizza_9.jpg b/images/pizza_9.jpg new file mode 100644 index 0000000..1bae3d4 Binary files /dev/null and b/images/pizza_9.jpg differ diff --git a/images/size-icon.svg b/images/size-icon.svg new file mode 100644 index 0000000..7d9c3ee --- /dev/null +++ b/images/size-icon.svg @@ -0,0 +1,23 @@ + + + + size icon + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/weight.svg b/images/weight.svg new file mode 100644 index 0000000..2e9c77b --- /dev/null +++ b/images/weight.svg @@ -0,0 +1,20 @@ + + + + weight 2 + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html index 09c6dc0..0396c94 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,71 @@ - + - - - Simple HTML Page - - + + + + +Піца KMA, дз 4 + + +
+ +
+

Усі піци 0

+
+ + + +
+
+
+ + +
+
+ +
+ ЦЬОГО ТИЖНЯ ЗНИЖКА НА ВСЕ -20% +
+ + \ No newline at end of file diff --git a/pizzas.json b/pizzas.json new file mode 100644 index 0000000..065c83b --- /dev/null +++ b/pizzas.json @@ -0,0 +1,132 @@ +[ + { + "id": 1, + "name": "Імпреза", + "categories": ["М'ясні"], + "ingredients": "Балик, салямі, куриця, сир моцарелла, сир рокфорд, ананаси, томатна паста, петрушка", + "image": "images/pizza_7.jpg", + "isNew": true, + "isPopular": false, + "prices": [ + { "size": 30, "weight": 370, "price": 100 }, + { "size": 40, "weight": 660, "price": 170 } + ] + }, + { + "id": 2, + "name": "BBQ", + "categories": ["М'ясні", "З грибами"], + "ingredients": "Мисливські ковбаски, папероні, шинка, сир домашній, шампіньйони, петрушка, оливки", + "image": "images/pizza_2.jpg", + "isNew": false, + "isPopular": false, + "prices": [ + { "size": 30, "weight": 460, "price": 140 }, + { "size": 40, "weight": 840, "price": 200 } + ] + }, + { + "id": 3, + "name": "Міксовий поло", + "categories": ["М'ясні"], + "ingredients": "Вітчина, куриця копчена, сир моцарелла, ананаси, кукурудза, петрушка, соус томатний", + "image": "images/pizza_1.jpg", + "isNew": false, + "isPopular": true, + "prices": [ + { "size": 30, "weight": 430, "price": 120 }, + { "size": 40, "weight": 780, "price": 180 } + ] + }, + { + "id": 4, + "name": "Rosso Густо", + "categories": ["Вега"], + "ingredients": "Помідори, сир моцарелла, томатний соус, базилік", + "image": "images/pizza_4.jpg", + "isNew": false, + "isPopular": false, + "prices": [ + { "size": 30, "weight": 400, "price": 110 }, + { "size": 40, "weight": 700, "price": 190 } + ] + }, + { + "id": 5, + "name": "Капрічоза", + "categories": ["М'ясні", "З грибами"], + "ingredients": "Сир моцарела, салямі, шинка, печериці, болгарський перець, базилік, томатний соус", + "image": "images/pizza_5.jpg", + "isNew": false, + "isPopular": false, + "prices": [ + { "size": 30, "weight": 390, "price": 105 }, + { "size": 40, "weight": 680, "price": 175 } + ] + }, + { + "id": 6, + "name": "Маргарита", + "categories": ["Вега"], + "ingredients": "Сир моцарелла, томати, базилік, орегано", + "image": "images/pizza_3.jpg", + "isNew": false, + "isPopular": false, + "prices": [ + { "size": 30, "weight": 350, "price": 95 }, + { "size": 40, "weight": 600, "price": 160 } + ] + }, + { + "id": 7, + "name": "Домашня", + "categories": ["М'ясні", "З грибами"], + "ingredients": "Соус, сир, мисливські ковбаски, куряче філе, мариновані огірки, печериці, червона цибуля, петрушка", + "image": "images/pizza_6.jpg", + "isNew": false, + "isPopular": false, + "prices": [ + { "size": 30, "weight": 420, "price": 130 }, + { "size": 40, "weight": 750, "price": 210 } + ] + }, + { + "id": 8, + "name": "Фрутті ді Маре", + "categories": ["З морепродуктами"], + "ingredients": "Томатний соус, моцарела, креветки, мідії, кальмари, восьминоги, червона ікра, зелень", + "image": "images/pizza_8.jpg", + "isNew": false, + "isPopular": false, + "prices": [ + { "size": 30, "weight": 380, "price": 115 }, + { "size": 40, "weight": 670, "price": 185 } + ] + }, + { + "id": 9, + "name": "М’ясна класика", + "categories": ["М'ясні"], + "ingredients": "Томатний соус, моцарела, салямі, бекон, курка, зелень", + "image": "images/pizza_9.jpg", + "isNew": false, + "isPopular": false, + "prices": [ + { "size": 30, "weight": 410, "price": 125 }, + { "size": 40, "weight": 720, "price": 195 } + ] + }, + { + "id": 10, + "name": "Супер м’ясна", + "categories": ["М'ясні", "З грибами"], + "ingredients": "Томатний соус, моцарела, салямі, ковбаски, печериці, зелені оливки, петрушка", + "image": "images/pizza_2.jpg", + "isNew": false, + "isPopular": false, + "prices": [ + { "size": 30, "weight": 450, "price": 160 }, + { "size": 40, "weight": 800, "price": 250 } + ] + } +] \ No newline at end of file diff --git a/report.html b/report.html new file mode 100644 index 0000000..99837a4 --- /dev/null +++ b/report.html @@ -0,0 +1,46 @@ + + + + + + + + Звіт Піца KMA + + + + + + + +
+
+

Звіт по піцам

+ ← На головну +
+ +
+
+
+
+ +
+ ЦЬОГО ТИЖНЯ ЗНИЖКА НА ВСЕ -20% +
+ + + + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js index e69de29..0bde1d0 100644 --- a/src/main.js +++ b/src/main.js @@ -0,0 +1,248 @@ +document.addEventListener('DOMContentLoaded', () => { + //посилання на ключові елементи DOM з якими будемо взаємодіяти + const pizzaList = document.getElementById('pizza-list'); //елемент куди будемо вставляти картки піц + const cartItemsList = document.getElementById('cart-items'); //елемент куди будемо вставляти елементи кошика + const pizzaCountSpan = document.querySelector('.pizza-header .pizza-count'); //елемент для відображення кількості піц + const cartCountSpan = document.querySelector('.cart-header .cart-count'); //елемент для відображення кількості товарів у кошику + const totalPriceSpan = document.querySelector('.total-price'); //елемент для відображення загальної суми замовлення + const filterButtons = document.querySelectorAll('.filter-btn'); //всі фільтри + const clearCartButton = document.querySelector('.clear-cart'); //кнопка очищення кошика + + let allPizzas = []; //змінна для зберігання всіх піц з JSON + //завантажує дані кошика з local storage (порожній масив якщо сторедж пустий) + let cart = JSON.parse(localStorage.getItem('pizzaCart')) || []; + //функція для асинхронного завантаження списку піц з JSON + async function loadPizzas() { + try { + //HTTP-запит до json + const response = await fetch('pizzas.json'); + if (!response.ok) { + throw new Error(`помилка HTTP: ${response.status}`); + } + //парсимо відповідь у форматі JSON та зберігаємо її в allPizzas + allPizzas = await response.json(); + //відображаємо всі піци за замовчуванням + displayPizzas('all'); + } catch (error) { + console.error('Не вдалося завантажити піци:', error); + pizzaList.innerHTML = '

Не вдалося завантажити список піц. Будь ласка, спробуйте пізніше.

'; + } + } + + //для відображення піц на сторінці відповідно до обраного фільтра + function displayPizzas(filter) { + pizzaList.innerHTML = ''; //очищаємо поточний вміст списку піц перед оновленням + let filteredPizzas = []; //змінна для зберігання відфільтрованих піц + if (filter === 'all') { + filteredPizzas = allPizzas; //якщо фільтр "all" то показуємо всі піци + } else { + //залишає ті піци у яких масив 'categories' містить значення поточного фільтра. + filteredPizzas = allPizzas.filter(pizza => pizza.categories.includes(filter)); + } + pizzaCountSpan.textContent = filteredPizzas.length; //оновлюємо лічильник кількості піц на сторінці + //якщо після фільтрації немає піц виводимо повідомлення + if (filteredPizzas.length === 0) { + pizzaList.innerHTML = '

Піци за даним фільтром відсутні.

'; + return; + } + + //для кожної відфільтрованої піци створюємо та додаємо картку на сторінку + filteredPizzas.forEach(pizza => { + const pizzaCard = document.createElement('article'); //створюємо новий HTML-елемент
+ pizzaCard.classList.add('pizza-card'); //додаємо клас 'pizza-card' для стилізації + let badgeHtml = ''; //змінна для зберігання HTML-коду для бейджа (Нова/Популярна) + if (pizza.isNew) { + badgeHtml = 'Нова'; //якщо піца нова додаємо бейдж "Нова" + } else if (pizza.isPopular) { + badgeHtml = 'Популярна'; //якщо піца популярна додаємо бейдж "Популярна" + } + let purchaseOptionsHtml = ''; //змінна для зберігання HTML-коду опцій покупки (розміри, ціни, кнопки) + //генеруємо HTML для кожної опції розміру/ціни піци + pizza.prices.forEach(option => { + purchaseOptionsHtml += ` +
+
+
Діаметр ${option.size}
+
Вага ${option.weight}г
+
+ ${option.price} грн. + +
+ `; + }); + + //вставляємо згенерований HTML в картку піци + pizzaCard.innerHTML = ` +
+ Піца ${pizza.name} + ${badgeHtml} +
+
+

${pizza.name}

+

${pizza.categories.join(', ')}

${pizza.ingredients}

+
+ ${purchaseOptionsHtml} +
+
+ `; + pizzaList.appendChild(pizzaCard); //додаємо створену картку до списку піц на сторінці + }); + + //лісенери для кнопок "Купити" + document.querySelectorAll('.buy-button').forEach(button => { + button.addEventListener('click', addToCart); //при кліку викликаємо функцію addToCart + }); + } + + //для додавання піци до кошика + function addToCart(event) { + const button = event.target; //отримуємо кнопку на яку був клік + //отримує дані про піцу з data-атрибутів кнопки + const pizzaId = parseInt(button.dataset.pizzaId); + const pizzaSize = parseInt(button.dataset.pizzaSize); + const pizzaPrice = parseInt(button.dataset.pizzaPrice); + const pizzaWeight = parseInt(button.dataset.pizzaWeight); + //знаходимо повні дані піци з масиву allPizzas за її ID + const pizza = allPizzas.find(p => p.id === pizzaId); + if (!pizza) return; // якщо піцу не знайдено (хоча такого не має бути) то виходимо + //перевірка чи не має такої самої піци у кошику (той самий ID, розмір) + const existingItemIndex = cart.findIndex(item => item.id === pizzaId && item.size === pizzaSize); + if (existingItemIndex > -1) { + cart[existingItemIndex].quantity++; //якщо є то збільшуємо кількість + } else { + //інакше додаємо її як новий об'єкт + cart.push({ + id: pizzaId, + name: pizza.name, + image: pizza.image, + size: pizzaSize, + weight: pizzaWeight, + price: pizzaPrice, + quantity: 1 + }); + } + updateCart(); //оновлює відображення кошика + } + + //для оновлення відображення кошика та збереження його в local storage + function updateCart() { + cartItemsList.innerHTML = ''; //очищаємо поточний вміст списку товарів у кошику + let totalCartCount = 0; //початкова кількість товарів в кошику + let totalCartPrice = 0; //початкова загальна сума замовлення + if (cart.length === 0) { + //повідомлення якщо кошик порожній + cartItemsList.innerHTML = '

Кошик порожній.

'; + } else { + //для кожного товару в кошику створюємо та додаємо елемент списку + cart.forEach(item => { + const cartItemElement = document.createElement('li'); //створюємо новий HTML-елемент
  • + cartItemElement.classList.add('cart-item'); //додаємо клас 'cart-item' для стилізації + cartItemElement.innerHTML = ` + ${item.name} +
    +

    ${item.name} (${item.size === 30 ? 'Мала' : 'Велика'})

    +
    +
    + Діаметр + ${item.size} +
    +
    + Вага + ${item.weight}г +
    +
    +
    +
    + + ${item.quantity} + +
    +
    ${item.price * item.quantity} грн
    +
    +
    + + `; + cartItemsList.appendChild(cartItemElement); //додаємо створений елемент до списку кошика + totalCartCount += item.quantity; //оновлюємо загальну кількість товарів + totalCartPrice += item.price * item.quantity; //оновлюємо загальну суму + }); + } + + cartCountSpan.textContent = totalCartCount; //оновлюємо відображення загальної кількості товарів у кошику + totalPriceSpan.textContent = `${totalCartPrice} грн`; //оновлюємо відображення загальної суми + //зберігає стан кошика в JSON і записує в local storage + localStorage.setItem('pizzaCart', JSON.stringify(cart)); + //додає лісенери після оновлення кошика + document.querySelectorAll('.quantity-btn-minus').forEach(button => { + button.addEventListener('click', decreaseQuantity); // для кнопки зменшення кількості + }); + document.querySelectorAll('.quantity-btn-plus').forEach(button => { + button.addEventListener('click', increaseQuantity); // для кнопки збільшення кількості + }); + document.querySelectorAll('.remove-item').forEach(button => { + button.addEventListener('click', removeItemFromCart); // для кнопки видалення товару + }); + } + + //для збільшення кількості конкретної піци в кошику + function increaseQuantity(event) { + const button = event.target; // кнопка на яку був клік + //ID та розмір піци получаєм з data-атрибутів кнопки + const pizzaId = parseInt(button.dataset.pizzaId); + const pizzaSize = parseInt(button.dataset.pizzaSize); + //працює по індексу елемента в масиві cart + const itemIndex = cart.findIndex(item => item.id === pizzaId && item.size === pizzaSize); + if (itemIndex > -1) { + cart[itemIndex].quantity++; // збільшуємо кількість + updateCart(); //оновлює відображення кошика + } + } + + //для зменшення кількості конкретної піци в кошику + function decreaseQuantity(event) { + const button = event.target; // кнопка на яку був клік + //ID та розмір піци получаєм з data-атрибутів кнопки + const pizzaId = parseInt(button.dataset.pizzaId); + const pizzaSize = parseInt(button.dataset.pizzaSize); + //працює по індексу елемента в масиві cart + const itemIndex = cart.findIndex(item => item.id === pizzaId && item.size === pizzaSize); + if (itemIndex > -1) { + cart[itemIndex].quantity--; // зменшуємо кількість + //якщо кількість 0 або менше видаляємо товар з кошика + if (cart[itemIndex].quantity <= 0) { + cart.splice(itemIndex, 1); // видаляємо 1 елемент починаючи з itemIndex + } + updateCart(); //оновлює відображення кошика + } + } + + //видалення конкретної піци з кошика + function removeItemFromCart(event) { + const button = event.target; //кнопка на яку був клік + //отримує ID та розмір піци з data-атрибутів кнопки + const pizzaId = parseInt(button.dataset.pizzaId); + const pizzaSize = parseInt(button.dataset.pizzaSize); + //фільтрує масив cart, залишаючи лише ті елементи, які НЕ відповідають ID та розміру видаленої піци + cart = cart.filter(item => !(item.id === pizzaId && item.size === pizzaSize)); + updateCart(); //оновлює відображення кошика + } + + //лісенери для всіх фільтрів + filterButtons.forEach(button => { + button.addEventListener('click', (event) => { + event.preventDefault(); //щоб не перезавантажувалось + const filter = event.target.dataset.filter; //отримує значення фільтра з data-атрибуту + filterButtons.forEach(btn => btn.classList.remove('active')); //робе всі кнопки не 'active' + event.target.classList.add('active'); //додає 'active' до натиснутої кнопки + displayPizzas(filter); //викликає функцію відображення піц з обраним фільтром + }); + }); + //лісенер для кнопки "Очистити замовлення" + clearCartButton.addEventListener('click', (event) => { + event.preventDefault(); //треба щоб сторінка не перезавантажувалась кожного разу коли кошик очищаєм + cart = []; //очищення + updateCart(); //оновлює відображення кошика + }); + loadPizzas(); //завантажує список піц + updateCart(); //оновлює кошик (треба щоб відновлювався з local storage при перезавантаженні сторінки) +}); \ No newline at end of file diff --git a/src/report.js b/src/report.js new file mode 100644 index 0000000..3acd844 --- /dev/null +++ b/src/report.js @@ -0,0 +1,75 @@ +document.addEventListener('DOMContentLoaded', () => { + //асинхронне завантаження даних про піцу з файлу pizzas.json + async function loadPizzaData() { + try { + //HTTP-запит + const response = await fetch('pizzas.json'); + if (!response.ok) { + throw new Error(`HTTP error: ${response.status}`); + } + //парсимо відповідь у форматі JSON та повертаємо її + return await response.json(); + } catch (error) { + //якщо сталася помилка під час завантаження або парсингу, виводимо її в консоль + console.error('не вдалось завантажити дані:', error); + //повертаємо порожній масив, щоб уникнути подальших помилок у логіці + return []; + } + } + + //WebDataRocks + loadPizzaData().then(pizzaData => { + // перетворюємо завантажені дані у "пласку" структуру, більш зручну для WebDataRocks + const transformedData = []; + //перебираємо кожну піцу в оригінальному масиві даних + pizzaData.forEach(pizza => { + //для кожної піци перебираємо її варіанти цін (розмірів) + pizza.prices.forEach(priceOption => { + //додаємо новий об'єкт в масив з вирівняними полями + transformedData.push({ + "Назва Піци": pizza.name, + "Категорії": pizza.categories.join(', '), + "Інгредієнти": pizza.ingredients, + "Розмір (см)": priceOption.size, + "Вага (г)": priceOption.weight, + "Ціна (грн)": priceOption.price, + "Нова": pizza.isNew ? "Так" : "Ні", + "Популярна": pizza.isPopular ? "Так" : "Ні" + }); + }); + }); + + //конфіг WebDataRocks + const pivot = new WebDataRocks({ + container: "#wdr-component", //елемент у якому відображено зведену таблицю + toolbar: true, //панель інструментів WebDataRocks для інтерактивності + report: { //об'єкт, що визначає структуру та налаштування звіту + dataSource: { + data: transformedData // дані, які будуть використовуватися для побудови звіту + }, + slice: { // визначає, як поля даних розподіляються по рядках, стовпцях та фільтрах + rows: [ + { uniqueName: "Назва Піци" } + ], + columns: [ + { uniqueName: "Розмір (см)" }, + { uniqueName: "Інгредієнти" }, + { uniqueName: "Категорії" }, + { uniqueName: "Нова"}, + { uniqueName: "Популярна"}, + { uniqueName: "[Measures]" } // спеціальне поле для відображення агрегованих значень (метрик) + ], + measures: [ // поля, для яких будуть обчислюватися агреговані значення + { uniqueName: "Ціна (грн)", aggregation: "average", caption: "Середня Ціна" }, // середня ціна + { uniqueName: "Вага (г)", aggregation: "average", caption: "Середня Вага" } // середня вага + ] + }, + options: { + grid: { + type: "flat" // відображати дані у форматі "плоскої" таблиці (без ієрархії згортання/розгортання) + } + } + } + }); + }); +}); diff --git a/style/style.css b/style/style.css index e69de29..6d2a737 100644 --- a/style/style.css +++ b/style/style.css @@ -0,0 +1,490 @@ +/*загальні стилі*/ +body { + font-family: 'Roboto', sans-serif; + margin: 0; + background-color: #f9f9f9; + color: #333; +} + +.site-container { + max-width: 1280px; + margin: 0 auto; + padding: 0 15px; +} + +/*header*/ +.site-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 15px; + background-color: #fff; + border-bottom: 1px solid #eee; + position: sticky; + top: 0; + z-index: 1000; + width: 100%; + box-sizing: border-box; + max-width: 1280px; + margin: 0 auto; +} + +.header-logo { + display: flex; + align-items: center; +} +.header-logo img { + height: 40px; + margin-right: 10px; +} +.header-logo span { + font-weight: bold; + font-size: 24px; +} + +.header-info .work-hours, +.header-info .delivery-info { + display: none; +} + +.phone-number { + font-weight: 500; +} + +.login-button { + background-color: #fff; + border: 1px solid #ccc; + padding: 8px 16px; + border-radius: 5px; + cursor: pointer; + font-weight: 500; +} + +/* Style for the new "Звіт по піцам" button in the header */ +.report-button { + background-color: #ff8c00; + color: white; + border: none; + padding: 8px 16px; + border-radius: 5px; + cursor: pointer; + font-weight: 500; + text-decoration: none; + transition: background-color 0.2s; + margin-left: auto; /* Pushes the button to the right */ + margin-right: 10px; /* Adds some space before the login button */ +} + +.report-button:hover { + background-color: #ff6f00; +} + + +/*nav bar (усі м'ясні з грибами т д)*/ +.main-nav { + padding: 0 15px; +} +.main-nav ul { + list-style: none; + padding: 0; + margin: 15px 0; + display: flex; + gap: 20px; +} +.main-nav a { + text-decoration: none; + color: #555; + font-weight: 500; + padding-bottom: 5px; +} +.main-nav a.active { + color: #ff6f00; + border-bottom: 2px solid #ff6f00; +} + +/*основна сторінка*/ +.main-content { + display: flex; + flex-direction: column; + gap: 30px; + padding: 0 15px; +} + +/*меню піци*/ +.pizza-header { + display: flex; + justify-content: center; + align-items: center; + padding-top: 10px; + padding-bottom: 10px; + margin-bottom: 15px; + text-align: center; +} +.pizza-header h3 { + margin: 0; + font-size: 20px; +} +.pizza-count { + background-color: #ff6f00; + color: white; + font-size: 14px; + padding: 2px 7px; + border-radius: 50%; +} +.pizza-menu { + display: grid; + grid-template-columns: 1fr; + gap: 20px; +} + +.pizza-card { + background-color: #fff; + border: 1px solid #e0e0e0; + border-radius: 8px; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.pizza-image-container { + position: relative; +} +.pizza-card img { + width: 100%; + height: auto; + display: block; +} + +.badge { + position: absolute; + top: 10px; + right: 10px; + left: auto; + color: white; + padding: 4px 10px; + border-radius: 4px; + font-size: 14px; + font-weight: 500; + background-color: #d9534f; +} +.popular-badge { + background-color: #007bff; +} + +.pizza-details { + padding: 20px; + display: flex; + flex-direction: column; + flex-grow: 1; +} + +.pizza-name { + margin: 0 0 5px 0; + font-size: 24px; + font-weight: bold; + color: #ff8c00; +} + +.pizza-type { + margin: 0 0 10px 0; + font-size: 14px; + color: #777; +} + +.pizza-ingredients { + margin: 0 0 20px 0; + font-size: 15px; + color: #555; + flex-grow: 1; + min-height: 55px; + border-bottom: 1px solid #f0f0f0; + padding-bottom: 20px; +} + + +/*кнопки купити*/ +.pizza-purchase-options { + display: flex; + justify-content: space-between; + gap: 15px; +} + +.purchase-option { + display: flex; + flex-direction: column; + align-items: center; + width: 50%; +} + +.purchase-option .specs { + display: flex; + justify-content: space-around; + width: 100%; + margin-bottom: 10px; + color: #555; + font-size: 14px; +} + +.purchase-option .spec-item { + display: flex; + align-items: center; + gap: 5px; +} + +.icon { + width: 16px; + height: 16px; +} + +.purchase-option .price { + font-size: 24px; + font-weight: bold; + margin-bottom: 10px; +} + +.buy-button { + background-color: #ff8c00; + border: none; + color: white; + padding: 10px 0; + width: 100%; + border-radius: 5px; + cursor: pointer; + font-weight: 500; + font-size: 16px; + transition: background-color 0.2s; +} + +.buy-button:hover { + background-color: #ff6f00; +} + +/*сайд бар з кошиком замовлень*/ +.shopping-cart { + background-color: #fff; + border: 1px solid #e0e0e0; + border-radius: 8px; + padding: 20px; +} + +.cart-header { + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #eee; + padding-bottom: 10px; + margin-bottom: 15px; +} +.cart-header h3 { margin: 0; font-size: 20px; } +.cart-count { background-color: #ff6f00; color: white; font-size: 14px; padding: 2px 7px; border-radius: 50%;} +.clear-cart { font-size: 13px; color: #777; text-decoration: none; } + +.cart-items { list-style: none; padding: 0; margin: 0; } + +.cart-item { + display: flex; + align-items: flex-start; + margin-bottom: 15px; + gap: 10px; + position: relative; + padding-bottom: 10px; + border-bottom: 1px solid #eee; /*розділювачі для кожного елементу*/ +} +.cart-item:last-child { + border-bottom: none; + margin-bottom: 0; +} + +.cart-item img { width: 50px; height: 50px; border-radius: 5px; flex-shrink: 0; } + +.item-info { flex-grow: 1; display: flex; flex-direction: column; } +.item-name { margin: 0 0 4px 0; font-weight: 500; } +.item-specs { font-size: 12px; color: #888; display: flex; gap: 15px; margin-bottom: 8px;} + +/*розміри іконок діаметру і ваги в кошику*/ +.item-specs .spec-item .icon { + width: 14px; + height: 14px; +} + +.cart-item .spec-item { + display: flex; + align-items: center; + gap: 4px; +} + +.item-controls-bottom { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + margin-top: auto; +} + +.item-price { + font-weight: 500; + text-align: right; + font-size: 16px; + min-width: 70px; +} + +.quantity-control { + display: flex; + align-items: center; + gap: 5px; +} + +.quantity-btn { + color: white; + border: none; + width: 28px; + height: 28px; + border-radius: 50%; + cursor: pointer; + font-size: 18px; + line-height: 1; + display: flex; + justify-content: center; + align-items: center; + transition: background-color 0.2s; +} + +.quantity-btn-minus { + background-color: #dc3545; +} +.quantity-btn-minus:hover { + background-color: #c82333; +} + +.quantity-btn-plus { + background-color: #28a745; +} +.quantity-btn-plus:hover { + background-color: #218838; +} + +.quantity { + margin: 0; + font-weight: 500; + min-width: 20px; + text-align: center; +} + +.remove-item { + background: none; + border: none; + border-radius: 50%; + width: 24px; + height: 24px; + color: #999; + cursor: pointer; + font-size: 20px; + position: absolute; + top: 5px; + right: 0; + transition: color 0.2s; +} +.remove-item:hover { + color: #dc3545; +} + +.cart-footer { border-top: 1px solid #eee; padding-top: 15px; margin-top: 5px; } +.total-sum { display: flex; justify-content: space-between; font-size: 18px; font-weight: 500; margin-bottom: 15px; } +.total-price { font-weight: bold; } +.order-button { background-color: #ff8c00; color: white; border: none; width: 100%; padding: 15px; border-radius: 5px; font-size: 18px; font-weight: 500; cursor: pointer; transition: background-color 0.2s; } +.order-button:hover { background-color: #ff6f00; } + +.discount-badge { + position: fixed; + bottom: 20px; + left: 20px; + background-color: #ff8c00; + color: white; + padding: 15px 25px; + border-radius: 8px; + font-size: 18px; + font-weight: bold; + text-align: center; + z-index: 1000; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + animation: pulse 1s infinite alternate; +} + +@keyframes pulse { + from { + transform: scale(1); + } + to { + transform: scale(1.05); + } +} + +/* Styles specific to the report page */ +.report-page-header { + display: flex; + justify-content: space-between; + align-items: center; + padding-top: 10px; + padding-bottom: 10px; + margin-bottom: 15px; + text-align: center; +} + +.report-page-header h3 { + margin: 0; + font-size: 20px; + color: #ff8c00; +} + +.back-to-home { + background-color: #f0f0f0; + border: 1px solid #ccc; + padding: 8px 16px; + border-radius: 5px; + cursor: pointer; + font-weight: 500; + text-decoration: none; + color: #333; + transition: background-color 0.2s; +} + +.back-to-home:hover { + background-color: #e0e0e0; +} + +.report-content { + display: block; /* Override main-content flex for report */ + padding: 20px 0; +} + +#wdr-component { + width: 100%; + height: 600px; /* Adjust height as needed */ + box-shadow: 0 2px 5px rgba(0,0,0,0.1); + border-radius: 8px; + overflow: hidden; +} + + +/* Media queries */ +@media (min-width: 690px) { + .site-header{ padding: 10px 0; } + .header-info .work-hours, .header-info .delivery-info { display: inline; margin-left: 15px; font-size: 14px; color: #777; } + .main-content { flex-direction: row; align-items: flex-start; } + .pizza-menu { grid-template-columns: repeat(1, 1fr); flex-grow: 1; } + .shopping-cart { width: 320px; flex-shrink: 0; } + /* Report page header padding for larger screens */ + .report-page-header { + padding: 10px 0; + } +} + +@media (min-width: 900px) { + .pizza-menu { grid-template-columns: repeat(2, 1fr); } +} + +@media (min-width: 1110px) { + .pizza-menu { grid-template-columns: repeat(3, 1fr); } + .header-info { display: flex; align-items: center; gap: 20px; } + .report-button { margin-left: 20px; margin-right: 0; } /* Adjust for larger screens */ +} \ No newline at end of file