Spaces:
Running
Running
Download index.html from MrHouse111/programeri: direct link, hf CLI and curl.
- Browser
- Download file 41.6 kB
-
https://huggingface.co/spaces/MrHouse111/programeri/resolve/main/index.html
- Command line
-
hf download hf://spaces/MrHouse111/programeri/index.html
-
curl -L -o index.html https://huggingface.co/spaces/MrHouse111/programeri/resolve/main/index.html
41.6 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Šta Klopati</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .hide-scrollbar { | |
| -ms-overflow-style: none; | |
| scrollbar-width: none; | |
| } | |
| .hide-scrollbar::-webkit-scrollbar { | |
| display: none; | |
| } | |
| body { | |
| background-color: #121212; | |
| color: white; | |
| font-family: sans-serif; | |
| } | |
| .radio-player { | |
| transition: all 0.3s ease; | |
| } | |
| .radio-player.open { | |
| transform: translateY(0); | |
| } | |
| .radio-player.closed { | |
| transform: translateY(100%); | |
| } | |
| .fade-in { | |
| animation: fadeIn 0.3s ease-in; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; } | |
| to { opacity: 1; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="app" class="min-h-screen"> | |
| <!-- Cities Screen --> | |
| <div id="cities-screen" class="flex flex-col items-center justify-center min-h-screen pt-16"> | |
| <div class="fixed top-0 right-0 p-4 flex gap-4 z-50"> | |
| <button onclick="showRadio()" class="text-gray-400 hover:text-[#00bfa5] transition-colors" aria-label="Otvori radio"> | |
| <i class="fas fa-radio text-2xl"></i> | |
| </button> | |
| <button onclick="showChatScreen()" class="text-gray-400 hover:text-[#00bfa5] transition-colors"> | |
| <i class="fas fa-comments text-2xl"></i> | |
| </button> | |
| <button onclick="showFavorites()" class="text-gray-400 hover:text-[#00bfa5] transition-colors"> | |
| <i class="fas fa-heart text-2xl"></i> | |
| </button> | |
| <button onclick="showScreen('loyalty')" class="text-gray-400 hover:text-[#00bfa5] transition-colors"> | |
| <i class="fas fa-gift text-2xl"></i> | |
| </button> | |
| <button onclick="showScreen('profile')" class="text-gray-400 hover:text-[#00bfa5] transition-colors"> | |
| <i class="fas fa-user text-2xl"></i> | |
| </button> | |
| </div> | |
| <h1 class="text-4xl md:text-6xl font-serif mb-8">Šta Klopati</h1> | |
| <img src="https://ucarecdn.com/84e97dda-5149-45c9-910a-8ee1fcb5bf35/-/format/auto/" alt="Šta Klopati Logo" class="w-[120px] h-[120px] rounded-full mb-12"> | |
| <div class="flex flex-col gap-6 w-full max-w-xs"> | |
| <button onclick="selectCity('Nova Pazova')" class="group relative bg-gradient-to-r from-[#00bfa5] to-[#00a693] py-4 px-8 rounded-lg text-xl shadow-lg transform transition-all duration-300 hover:scale-105 hover:shadow-xl active:scale-95"> | |
| <div class="absolute inset-0 bg-white opacity-0 group-hover:opacity-10 rounded-lg transition-opacity"></div> | |
| <div class="flex items-center justify-center gap-3"> | |
| <i class="fas fa-map-marker-alt"></i> | |
| <span>Nova Pazova</span> | |
| </div> | |
| </button> | |
| <button onclick="selectCity('Stara Pazova')" class="group relative bg-gradient-to-r from-[#00bfa5] to-[#00a693] py-4 px-8 rounded-lg text-xl shadow-lg transform transition-all duration-300 hover:scale-105 hover:shadow-xl active:scale-95"> | |
| <div class="absolute inset-0 bg-white opacity-0 group-hover:opacity-10 rounded-lg transition-opacity"></div> | |
| <div class="flex items-center justify-center gap-3"> | |
| <i class="fas fa-map-marker-alt"></i> | |
| <span>Stara Pazova</span> | |
| </div> | |
| </button> | |
| <button onclick="selectCity('Banovci')" class="group relative bg-gradient-to-r from-[#00bfa5] to-[#00a693] py-4 px-8 rounded-lg text-xl shadow-lg transform transition-all duration-300 hover:scale-105 hover:shadow-xl active:scale-95"> | |
| <div class="absolute inset-0 bg-white opacity-0 group-hover:opacity-10 rounded-lg transition-opacity"></div> | |
| <div class="flex items-center justify-center gap-3"> | |
| <i class="fas fa-map-marker-alt"></i> | |
| <span>Banovci</span> | |
| </div> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Restaurants Screen --> | |
| <div id="restaurants-screen" class="hidden p-4"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <button onclick="showScreen('cities')" class="text-[#00bfa5] flex items-center"> | |
| <i class="fas fa-city mr-2"></i> | |
| Promeni grad | |
| </button> | |
| <h2 id="current-city" class="text-2xl"></h2> | |
| </div> | |
| <div id="restaurants-loading" class="flex justify-center items-center p-8 hidden"> | |
| <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-[#00bfa5]"></div> | |
| </div> | |
| <div id="restaurants-error" class="text-red-500 p-4 text-center bg-[#2a2a2a] rounded-lg hidden"> | |
| <i class="fas fa-exclamation-circle text-2xl mb-2"></i> | |
| <p id="error-message"></p> | |
| <button onclick="loadRestaurants()" class="mt-4 px-4 py-2 bg-[#00bfa5] rounded-lg text-white hover:bg-[#00a693]"> | |
| Pokušaj ponovo | |
| </button> | |
| </div> | |
| <div id="restaurants-container" class="grid gap-4 hidden"></div> | |
| <div id="no-restaurants" class="text-center text-gray-400 p-8 bg-[#2a2a2a] rounded-lg hidden"> | |
| <i class="fas fa-store-alt-slash text-4xl mb-4"></i> | |
| <p id="no-restaurants-message"></p> | |
| </div> | |
| </div> | |
| <!-- Menu Screen --> | |
| <div id="menu-screen" class="hidden pb-20 relative min-h-screen"> | |
| <div class="sticky top-0 bg-[#121212] z-10 p-4 border-b border-gray-800"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <button onclick="showScreen('restaurants')" class="text-[#00bfa5] flex items-center"> | |
| <i class="fas fa-arrow-left mr-2"></i> Nazad | |
| </button> | |
| <h2 id="restaurant-name" class="text-xl font-semibold"></h2> | |
| <div class="w-8"></div> | |
| </div> | |
| <div class="flex items-center text-sm text-gray-400"> | |
| <div class="flex items-center"> | |
| <i class="far fa-clock mr-2"></i> | |
| <span id="restaurant-hours"></span> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="menu-loading" class="flex justify-center items-center p-8 hidden"> | |
| <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-[#00bfa5]"></div> | |
| </div> | |
| <div id="menu-error" class="text-red-500 p-4 text-center bg-[#2a2a2a] rounded-lg m-4 hidden"> | |
| <i class="fas fa-exclamation-circle text-2xl mb-2"></i> | |
| <p id="menu-error-message"></p> | |
| <button onclick="loadRestaurantMenu()" class="mt-4 px-4 py-2 bg-[#00bfa5] rounded-lg text-white hover:bg-[#00a693]"> | |
| Pokušaj ponovo | |
| </button> | |
| </div> | |
| <div id="menu-content" class="hidden"> | |
| <div class="sticky top-[72px] bg-[#121212] z-10 border-b border-gray-800"> | |
| <div class="overflow-x-auto hide-scrollbar"> | |
| <div id="categories-container" class="flex p-2 space-x-2 min-w-max"></div> | |
| </div> | |
| </div> | |
| <div id="menu-items-container" class="p-4"></div> | |
| </div> | |
| <div id="no-menu" class="text-center text-gray-400 p-8 hidden"> | |
| <p>Meni nije dostupan</p> | |
| </div> | |
| <a id="call-restaurant" href="#" class="fixed bottom-6 right-6 bg-[#00bfa5] w-14 h-14 rounded-full flex items-center justify-center shadow-lg hover:bg-[#00a693] transition-colors z-40"> | |
| <i class="fas fa-phone text-white text-2xl"></i> | |
| </a> | |
| </div> | |
| <!-- Loyalty Screen --> | |
| <div id="loyalty-screen" class="hidden min-h-screen bg-[#121212] p-4"> | |
| <div class="sticky top-0 bg-[#121212] z-10 pb-4"> | |
| <button onclick="showScreen('cities')" class="text-[#00bfa5] flex items-center mb-4"> | |
| <i class="fas fa-arrow-left mr-2"></i> Nazad | |
| </button> | |
| <h2 class="text-2xl font-semibold mb-2">Loyalty Program</h2> | |
| <div class="bg-[#2a2a2a] p-4 rounded-lg mb-4"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <p class="text-gray-400">Vaši poeni</p> | |
| <p class="text-3xl font-bold text-[#00bfa5]">0</p> | |
| </div> | |
| <i class="fas fa-star text-[#00bfa5] text-4xl"></i> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="rewards-container" class="grid gap-4"></div> | |
| </div> | |
| <!-- Profile Screen --> | |
| <div id="profile-screen" class="hidden min-h-screen bg-[#121212] p-4"> | |
| <div class="sticky top-0 bg-[#121212] z-10 pb-4"> | |
| <button onclick="showScreen('cities')" class="text-[#00bfa5] flex items-center mb-4"> | |
| <i class="fas fa-arrow-left mr-2"></i> Nazad | |
| </button> | |
| <h2 class="text-2xl font-semibold mb-4">Vaš Profil</h2> | |
| </div> | |
| <div class="space-y-4"> | |
| <div class="bg-[#2a2a2a] p-4 rounded-lg"> | |
| <div class="flex items-center space-x-4"> | |
| <div class="w-20 h-20 bg-[#3a3a3a] rounded-full flex items-center justify-center"> | |
| <i class="fas fa-user text-3xl text-[#00bfa5]"></i> | |
| </div> | |
| <div> | |
| <h3 class="text-xl font-medium">Korisnik</h3> | |
| <p class="text-gray-400">ID: anonymous</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-[#2a2a2a] p-4 rounded-lg"> | |
| <h3 class="text-lg font-medium mb-3">Vaša Dostignuća</h3> | |
| <div class="grid grid-cols-3 gap-3"> | |
| <div class="p-3 rounded-lg text-center bg-[#3a3a3a]"> | |
| <i class="fas fa-circle text-gray-400 text-2xl mb-2"></i> | |
| <p class="text-sm">Prvi Pregled</p> | |
| </div> | |
| <div class="p-3 rounded-lg text-center bg-[#3a3a3a]"> | |
| <i class="fas fa-circle text-gray-400 text-2xl mb-2"></i> | |
| <p class="text-sm">Redovan Korisnik</p> | |
| </div> | |
| <div class="p-3 rounded-lg text-center bg-[#3a3a3a]"> | |
| <i class="fas fa-circle text-gray-400 text-2xl mb-2"></i> | |
| <p class="text-sm">Gurman</p> | |
| </div> | |
| <div class="p-3 rounded-lg text-center bg-[#3a3a3a]"> | |
| <i class="fas fa-circle text-gray-400 text-2xl mb-2"></i> | |
| <p class="text-sm">Društvenjak</p> | |
| </div> | |
| <div class="p-3 rounded-lg text-center bg-[#3a3a3a]"> | |
| <i class="fas fa-circle text-gray-400 text-2xl mb-2"></i> | |
| <p class="text-sm">Ekspert</p> | |
| </div> | |
| <div class="p-3 rounded-lg text-center bg-[#00bfa5] bg-opacity-20"> | |
| <i class="fas fa-check-circle text-[#00bfa5] text-2xl mb-2"></i> | |
| <p class="text-sm">Foodie</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-[#2a2a2a] p-4 rounded-lg"> | |
| <h3 class="text-lg font-medium mb-3">Omiljene Kategorije</h3> | |
| <div class="flex flex-wrap gap-2"> | |
| <span class="bg-[#3a3a3a] px-3 py-1 rounded-full text-sm">Roštilj</span> | |
| <span class="bg-[#3a3a3a] px-3 py-1 rounded-full text-sm">Pica</span> | |
| <span class="bg-[#3a3a3a] px-3 py-1 rounded-full text-sm">Salate</span> | |
| </div> | |
| </div> | |
| <div class="bg-[#2a2a2a] p-4 rounded-lg"> | |
| <h3 class="text-lg font-medium mb-3">Posećeni Restorani</h3> | |
| <div class="space-y-2"> | |
| <div class="flex items-center justify-between"> | |
| <span>Caribic</span> | |
| <i class="fas fa-check text-[#00bfa5]"></i> | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <span>Dukat</span> | |
| <i class="fas fa-check text-[#00bfa5]"></i> | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <span>Kod Žike</span> | |
| <i class="fas fa-check text-[#00bfa5]"></i> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Chat Screen --> | |
| <div id="chat-screen" class="hidden fixed inset-0 bg-[#121212] z-50 flex flex-col"> | |
| <div class="bg-[#2a2a2a] px-4 py-3 flex items-center justify-between border-b border-gray-700"> | |
| <div class="flex items-center"> | |
| <button onclick="hideChatScreen()" class="mr-3 text-gray-400 hover:text-white"> | |
| <i class="fas fa-arrow-left text-lg"></i> | |
| </button> | |
| <div> | |
| <h2 class="text-lg font-semibold">Grupni Chat</h2> | |
| <p id="chat-stats" class="text-sm text-gray-400">0 poruka • 0 učesnika</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="chat-messages" class="flex-1 overflow-y-auto p-4 space-y-4"></div> | |
| <div class="bg-[#2a2a2a] p-3 border-t border-gray-700"> | |
| <div id="emoji-picker" class="hidden absolute bottom-20 right-4 bg-[#3a3a3a] rounded-lg shadow-xl p-2"> | |
| <div class="grid grid-cols-8 gap-2"> | |
| <button onclick="addEmoji('😊')" class="text-2xl hover:bg-[#4a4a4a] p-2 rounded-lg transition-colors">😊</button> | |
| <button onclick="addEmoji('😂')" class="text-2xl hover:bg-[#4a4a4a] p-2 rounded-lg transition-colors">😂</button> | |
| <button onclick="addEmoji('❤️')" class="text-2xl hover:bg-[#4a4a4a] p-2 rounded-lg transition-colors">❤️</button> | |
| <button onclick="addEmoji('👍')" class="text-2xl hover:bg-[#4a4a4a] p-2 rounded-lg transition-colors">👍</button> | |
| <button onclick="addEmoji('😍')" class="text-2xl hover:bg-[#4a4a4a] p-2 rounded-lg transition-colors">😍</button> | |
| <button onclick="addEmoji('🎉')" class="text-2xl hover:bg-[#4a4a4a] p-2 rounded-lg transition-colors">🎉</button> | |
| <button onclick="addEmoji('👋')" class="text-2xl hover:bg-[#4a4a2a] p-2 rounded-lg transition-colors">👋</button> | |
| <button onclick="addEmoji('🤔')" class="text-2xl hover:bg-[#4a4a4a] p-2 rounded-lg transition-colors">🤔</button> | |
| </div> | |
| </div> | |
| <form onsubmit="sendMessage(event)" class="flex items-center gap-2"> | |
| <div class="flex-1 relative"> | |
| <input id="message-input" type="text" placeholder="Napišite poruku..." class="w-full bg-[#3a3a3a] rounded-full px-4 py-2 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-[#00bfa5]"> | |
| <button type="button" onclick="toggleEmojiPicker()" class="absolute right-2 top-1/2 -translate-y-1/2 p-2 text-[#00bfa5] hover:text-[#00a693]"> | |
| <i class="fas fa-smile text-xl"></i> | |
| </button> | |
| </div> | |
| <button type="submit" class="p-2 bg-[#00bfa5] text-white rounded-full hover:bg-[#00a693] transition-colors"> | |
| <i class="fas fa-paper-plane text-xl"></i> | |
| </button> | |
| </form> | |
| </div> | |
| </div> | |
| <!-- Favorites Modal --> | |
| <div id="favorites-modal" class="hidden fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 p-4"> | |
| <div class="bg-[#2a2a2a] rounded-lg max-w-md w-full max-h-[80vh] overflow-hidden"> | |
| <div class="p-4 border-b border-gray-700 flex justify-between items-center sticky top-0 bg-[#2a2a2a]"> | |
| <h2 class="text-xl font-semibold flex items-center"> | |
| <i class="fas fa-heart text-red-500 mr-2"></i> | |
| Omiljena jela | |
| </h2> | |
| <button onclick="hideFavorites()" class="text-gray-400 hover:text-white transition-colors"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="p-4 overflow-y-auto" style="max-height: calc(80vh - 70px)"> | |
| <div id="no-favorites" class="text-center py-8 text-gray-400"> | |
| <i class="far fa-heart text-4xl mb-3"></i> | |
| <p>Nemate označenih omiljenih jela</p> | |
| <p class="text-sm mt-2"> | |
| Označite srce pored jela da ga dodate u omiljene | |
| </p> | |
| </div> | |
| <div id="favorites-container" class="space-y-3 hidden"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Radio Player --> | |
| <div id="radio-player" class="fixed bottom-0 left-0 right-0 bg-[#2a2a2a] p-4 shadow-lg radio-player closed"> | |
| <div class="flex items-center justify-between"> | |
| <div class="flex items-center space-x-4"> | |
| <button id="play-pause-btn" onclick="toggleRadio()" class="bg-[#00bfa5] text-white w-12 h-12 rounded-full flex items-center justify-center"> | |
| <i id="play-pause-icon" class="fas fa-play"></i> | |
| </button> | |
| <div> | |
| <h3 class="font-medium">Radio Šta Klopati</h3> | |
| <p class="text-sm text-gray-400">Uživo</p> | |
| </div> | |
| </div> | |
| <button onclick="hideRadio()" class="text-gray-400 hover:text-white"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <audio id="radio-stream" src="https://stream.example.com/radio"></audio> | |
| </div> | |
| </div> | |
| <script> | |
| // App state | |
| const state = { | |
| user: { id: "anonymous" }, | |
| selectedCity: "", | |
| selectedRestaurant: null, | |
| activeCategory: "", | |
| favoriteItems: {}, | |
| points: 0, | |
| messages: [], | |
| restaurants: { | |
| "Nova Pazova": [ | |
| { id: 1, name: "Restoran 1", hours: "08:00 - 23:00", phone: "011 1234567", status: true }, | |
| { id: 2, name: "Restoran 2", hours: "09:00 - 22:00", phone: "011 7654321", status: false } | |
| ], | |
| "Stara Pazova": [ | |
| { id: 3, name: "Restoran 3", hours: "07:00 - 24:00", phone: "011 1111111", status: true } | |
| ], | |
| "Banovci": [ | |
| { id: 4, name: "Restoran 4", hours: "10:00 - 20:00", phone: "011 2222222", status: true } | |
| ] | |
| }, | |
| menuData: { | |
| "1": { | |
| menu: { | |
| "Roštilj": [ | |
| { name: "Ćevapi", description: "10 komada sa lukom", portion: "300g", price: "800" }, | |
| { name: "Pljeskavica", description: "Domaća pljeskavica", portion: "400g", price: "900" } | |
| ], | |
| "Pica": [ | |
| { name: "Margarita", description: "Paradajz sos, kačkavalj", portion: "30cm", price: "1000" }, | |
| { name: "Capricciosa", description: "Paradajz sos, kačkavalj, šunka, pečurke", portion: "30cm", price: "1200" } | |
| ], | |
| "Salate": [ | |
| { name: "Šopska salata", description: "Paradajz, krastavac, luk, sir", portion: "300g", price: "500" } | |
| ] | |
| } | |
| }, | |
| "2": { | |
| menu: { | |
| "Roštilj": [ | |
| { name: "Vešalica", description: "Domaća vešalica", portion: "300g", price: "850" } | |
| ], | |
| "Pice": [ | |
| { name: "Quattro Formaggi", description: "4 vrste sira", portion: "30cm", price: "1100" } | |
| ] | |
| } | |
| } | |
| }, | |
| rewards: [ | |
| { id: 1, description: "10% popusta na sledeću porudžbinu", points: 100 }, | |
| { id: 2, description: "Besplatno piće uz obrok", points: 150 }, | |
| { id: 3, description: "Besplatna dostava", points: 200 }, | |
| { id: 4, description: "Besplatan obrok", points: 500 } | |
| ], | |
| isRadioPlaying: false | |
| }; | |
| // Initialize the app | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Load rewards | |
| renderRewards(); | |
| // Check for last selected city | |
| const lastCity = localStorage.getItem('lastSelectedCity'); | |
| if (lastCity) { | |
| state.selectedCity = lastCity; | |
| showScreen('restaurants'); | |
| document.getElementById('current-city').textContent = lastCity; | |
| } | |
| }); | |
| // Screen navigation | |
| function showScreen(screen) { | |
| document.querySelectorAll('[id$="-screen"]').forEach(el => { | |
| el.classList.add('hidden'); | |
| }); | |
| document.getElementById(`${screen}-screen`).classList.remove('hidden'); | |
| } | |
| function showChatScreen() { | |
| document.getElementById('chat-screen').classList.remove('hidden'); | |
| renderMessages(); | |
| } | |
| function hideChatScreen() { | |
| document.getElementById('chat-screen').classList.add('hidden'); | |
| showScreen('cities'); | |
| } | |
| // City selection | |
| function selectCity(city) { | |
| state.selectedCity = city; | |
| localStorage.setItem('lastSelectedCity', city); | |
| document.getElementById('current-city').textContent = city; | |
| showScreen('restaurants'); | |
| loadRestaurants(); | |
| } | |
| // Restaurants | |
| function loadRestaurants() { | |
| const loadingEl = document.getElementById('restaurants-loading'); | |
| const errorEl = document.getElementById('restaurants-error'); | |
| const containerEl = document.getElementById('restaurants-container'); | |
| const noRestaurantsEl = document.getElementById('no-restaurants'); | |
| loadingEl.classList.remove('hidden'); | |
| errorEl.classList.add('hidden'); | |
| containerEl.classList.add('hidden'); | |
| noRestaurantsEl.classList.add('hidden'); | |
| // Simulate API call | |
| setTimeout(() => { | |
| loadingEl.classList.add('hidden'); | |
| if (!state.restaurants[state.selectedCity] || state.restaurants[state.selectedCity].length === 0) { | |
| document.getElementById('no-restaurants-message').textContent = | |
| `Trenutno nema dostupnih restorana u ${state.selectedCity}`; | |
| noRestaurantsEl.classList.remove('hidden'); | |
| return; | |
| } | |
| renderRestaurants(); | |
| containerEl.classList.remove('hidden'); | |
| }, 1000); | |
| } | |
| function renderRestaurants() { | |
| const container = document.getElementById('restaurants-container'); | |
| container.innerHTML = ''; | |
| state.restaurants[state.selectedCity].forEach(restaurant => { | |
| const restaurantEl = document.createElement('div'); | |
| restaurantEl.className = 'bg-[#2a2a2a] p-4 rounded-lg cursor-pointer hover:bg-[#3a3a3a] transition-all duration-200'; | |
| restaurantEl.innerHTML = ` | |
| <div class="flex justify-between items-start"> | |
| <div class="flex-1"> | |
| <h3 class="text-xl mb-2">${restaurant.name}</h3> | |
| <div class="space-y-1 text-sm"> | |
| <p class="text-gray-400">${restaurant.hours}</p> | |
| <p class="text-gray-400">${restaurant.phone}</p> | |
| </div> | |
| </div> | |
| <div class="ml-4"> | |
| <div class="px-3 py-1 rounded-full text-sm font-medium ${ | |
| restaurant.status ? "bg-green-500/10 text-green-500" : "bg-red-500/10 text-red-500" | |
| }"> | |
| ${restaurant.status ? "Otvoreno" : "Zatvoreno"} | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| restaurantEl.addEventListener('click', () => selectRestaurant(restaurant)); | |
| container.appendChild(restaurantEl); | |
| }); | |
| } | |
| function selectRestaurant(restaurant) { | |
| state.selectedRestaurant = restaurant; | |
| document.getElementById('restaurant-name').textContent = restaurant.name; | |
| document.getElementById('restaurant-hours').textContent = restaurant.hours; | |
| document.getElementById('call-restaurant').href = `tel:${restaurant.phone}`; | |
| showScreen('menu'); | |
| loadRestaurantMenu(); | |
| } | |
| // Menu | |
| function loadRestaurantMenu() { | |
| const loadingEl = document.getElementById('menu-loading'); | |
| const errorEl = document.getElementById('menu-error'); | |
| const menuContentEl = document.getElementById('menu-content'); | |
| const noMenuEl = document.getElementById('no-menu'); | |
| loadingEl.classList.remove('hidden'); | |
| errorEl.classList.add('hidden'); | |
| menuContentEl.classList.add('hidden'); | |
| noMenuEl.classList.add('hidden'); | |
| // Simulate API call | |
| setTimeout(() => { | |
| loadingEl.classList.add('hidden'); | |
| if (!state.menuData[state.selectedRestaurant.id]) { | |
| noMenuEl.classList.remove('hidden'); | |
| return; | |
| } | |
| renderMenu(); | |
| menuContentEl.classList.remove('hidden'); | |
| }, 1000); | |
| } | |
| function renderMenu() { | |
| const menu = state.menuData[state.selectedRestaurant.id].menu; | |
| const categoriesContainer = document.getElementById('categories-container'); | |
| const itemsContainer = document.getElementById('menu-items-container'); | |
| // Render categories | |
| categoriesContainer.innerHTML = ''; | |
| Object.keys(menu).forEach(category => { | |
| const button = document.createElement('button'); | |
| button.className = `px-4 py-2 rounded-full whitespace-nowrap transition-all duration-200 ${ | |
| state.activeCategory === category || (!state.activeCategory && category === Object.keys(menu)[0]) | |
| ? "bg-[#00bfa5] text-white" | |
| : "bg-[#2a2a2a] text-gray-300 hover:bg-[#3a3a3a]" | |
| }`; | |
| // Add icons based on category | |
| let icon = ''; | |
| if (category === "Roštilj") icon = '<i class="fas fa-fire mr-2"></i>'; | |
| if (category === "Prilozi") icon = '<i class="fas fa-utensils mr-2"></i>'; | |
| if (category === "Salate") icon = '<i class="fas fa-leaf mr-2"></i>'; | |
| if (category === "Pića") icon = '<i class="fas fa-glass-martini mr-2"></i>'; | |
| button.innerHTML = `${icon}${category}`; | |
| button.addEventListener('click', () => { | |
| state.activeCategory = category; | |
| renderMenuItems(category); | |
| // Update active button | |
| document.querySelectorAll('#categories-container button').forEach(btn => { | |
| btn.className = btn.className.replace('bg-[#00bfa5] text-white', 'bg-[#2a2a2a] text-gray-300 hover:bg-[#3a3a3a]'); | |
| }); | |
| button.className = button.className.replace('bg-[#2a2a2a] text-gray-300 hover:bg-[#3a3a3a]', 'bg-[#00bfa5] text-white'); | |
| }); | |
| categoriesContainer.appendChild(button); | |
| }); | |
| // Render items for first category if none selected | |
| const categoryToShow = state.activeCategory || Object.keys(menu)[0]; | |
| renderMenuItems(categoryToShow); | |
| } | |
| function renderMenuItems(category) { | |
| const itemsContainer = document.getElementById('menu-items-container'); | |
| const menu = state.menuData[state.selectedRestaurant.id].menu; | |
| itemsContainer.innerHTML = ''; | |
| menu[category].forEach((item, index) => { | |
| const key = `${state.selectedRestaurant.name}-${item.name}`; | |
| const isFavorite = state.favoriteItems[key] || false; | |
| const itemEl = document.createElement('div'); | |
| itemEl.className = 'bg-[#2a2a2a] rounded-lg p-4 hover:bg-[#3a3a3a] transition-colors duration-200 mb-3'; | |
| itemEl.innerHTML = ` | |
| <div class="flex justify-between items-start"> | |
| <div class="flex-1"> | |
| <h4 class="text-lg font-medium mb-1">${item.name}</h4> | |
| <div class="space-y-1"> | |
| ${item.description ? `<p class="text-sm text-gray-400">${item.description}</p>` : ''} | |
| ${item.portion ? `<p class="text-sm text-gray-400 flex items-center"><i class="fas fa-weight mr-2"></i>${item.portion}</p>` : ''} | |
| </div> | |
| </div> | |
| <div class="flex flex-col items-end ml-4"> | |
| <span class="text-[#00bfa5] font-semibold mb-2">${item.price} RSD</span> | |
| <button class="text-2xl transition-colors duration-200 hover:scale-110"> | |
| <i class="fas fa-heart ${isFavorite ? 'text-red-500' : 'text-gray-400'}"></i> | |
| </button> | |
| </div> | |
| </div> | |
| `; | |
| // Add favorite toggle | |
| const favButton = itemEl.querySelector('button'); | |
| favButton.addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| toggleFavorite(key); | |
| favButton.innerHTML = `<i class="fas fa-heart ${state.favoriteItems[key] ? 'text-red-500' : 'text-gray-400'}"></i>`; | |
| }); | |
| itemsContainer.appendChild(itemEl); | |
| }); | |
| } | |
| // Favorites | |
| function toggleFavorite(key) { | |
| state.favoriteItems[key] = !state.favoriteItems[key]; | |
| localStorage.setItem('favoriteItems', JSON.stringify(state.favoriteItems)); | |
| } | |
| function showFavorites() { | |
| document.getElementById('favorites-modal').classList.remove('hidden'); | |
| renderFavorites(); | |
| } | |
| function hideFavorites() { | |
| document.getElementById('favorites-modal').classList.add('hidden'); | |
| } | |
| function renderFavorites() { | |
| const container = document.getElementById('favorites-container'); | |
| const noFavoritesEl = document.getElementById('no-favorites'); | |
| const favorites = Object.entries(state.favoriteItems).filter(([, isFavorite]) => isFavorite); | |
| if (favorites.length === 0) { | |
| container.classList.add('hidden'); | |
| noFavoritesEl.classList.remove('hidden'); | |
| return; | |
| } | |
| container.innerHTML = ''; | |
| noFavoritesEl.classList.add('hidden'); | |
| container.classList.remove('hidden'); | |
| favorites.forEach(([key]) => { | |
| const [restaurant, item] = key.split('-'); | |
| const favoriteEl = document.createElement('div'); | |
| favoriteEl.className = 'bg-[#3a3a3a] rounded-lg p-3 flex justify-between items-center group hover:bg-[#4a4a4a] transition-colors'; | |
| favoriteEl.innerHTML = ` | |
| <div> | |
| <p class="font-medium">${item}</p> | |
| <p class="text-sm text-gray-400">${restaurant}</p> | |
| </div> | |
| <button class="text-red-500 opacity-75 group-hover:opacity-100 transition-opacity"> | |
| <i class="fas fa-heart"></i> | |
| </button> | |
| `; | |
| // Add remove favorite | |
| const removeBtn = favoriteEl.querySelector('button'); | |
| removeBtn.addEventListener('click', () => { | |
| toggleFavorite(key); | |
| renderFavorites(); | |
| }); | |
| container.appendChild(favoriteEl); | |
| }); | |
| } | |
| // Loyalty | |
| function renderRewards() { | |
| const container = document.getElementById('rewards-container'); | |
| container.innerHTML = ''; | |
| state.rewards.forEach(reward => { | |
| const rewardEl = document.createElement('div'); | |
| rewardEl.className = 'bg-[#2a2a2a] p-4 rounded-lg'; | |
| rewardEl.innerHTML = ` | |
| <div class="flex justify-between items-center"> | |
| <div> | |
| <h3 class="text-lg font-medium mb-1">${reward.description}</h3> | |
| <p class="text-sm text-gray-400">Potrebno poena: ${reward.points}</p> | |
| </div> | |
| <button class="px-4 py-2 rounded-lg ${ | |
| state.points >= reward.points | |
| ? "bg-[#00bfa5] text-white" | |
| : "bg-gray-600 text-gray-400" | |
| }"> | |
| Aktiviraj | |
| </button> | |
| </div> | |
| `; | |
| const button = rewardEl.querySelector('button'); | |
| if (state.points < reward.points) { | |
| button.disabled = true; | |
| } else { | |
| button.addEventListener('click', () => { | |
| alert("Nagrada je uspešno aktivirana!"); | |
| }); | |
| } | |
| container.appendChild(rewardEl); | |
| }); | |
| } | |
| // Chat | |
| function renderMessages() { | |
| const container = document.getElementById('chat-messages'); | |
| container.innerHTML = ''; | |
| state.messages.forEach((msg, index) => { | |
| const isFirstInGroup = index === 0 || state.messages[index - 1].user_id !== msg.user_id; | |
| const isLastInGroup = index === state.messages.length - 1 || state.messages[index + 1].user_id !== msg.user_id; | |
| const messageEl = document.createElement('div'); | |
| messageEl.className = `flex ${ | |
| msg.user_id === state.user.id ? "justify-end" : "justify-start" | |
| }`; | |
| messageEl.innerHTML = ` | |
| <div class="max-w-[80%] ${!isLastInGroup ? 'mb-1' : 'mb-3'}"> | |
| ${isFirstInGroup ? ` | |
| <div class="text-sm mb-1 ${ | |
| msg.user_id === state.user.id | |
| ? "text-right text-gray-300" | |
| : "text-gray-300" | |
| }"> | |
| ${msg.user_id === state.user.id ? "Vi" : `Korisnik ${msg.user_id.slice(0, 4)}`} | |
| </div> | |
| ` : ''} | |
| <div class="rounded-2xl px-4 py-2 ${ | |
| msg.user_id === state.user.id | |
| ? "bg-[#00bfa5] text-white rounded-tr-none" | |
| : "bg-[#3a3a3a] text-gray-200 rounded-tl-none" | |
| }"> | |
| <p class="text-[15px] leading-tight">${msg.message}</p> | |
| <div class="text-[11px] opacity-70 mt-1"> | |
| ${new Date(msg.created_at).toLocaleTimeString([], { | |
| hour: "2-digit", | |
| minute: "2-digit" | |
| })} | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| container.appendChild(messageEl); | |
| }); | |
| // Scroll to bottom | |
| container.scrollTop = container.scrollHeight; | |
| // Update stats | |
| document.getElementById('chat-stats').textContent = | |
| `${state.messages.length} poruka • ${ | |
| new Set(state.messages.map(m => m.user_id)).size | |
| } učesnika`; | |
| } | |
| function sendMessage(e) { | |
| e.preventDefault(); | |
| const input = document.getElementById('message-input'); | |
| const message = input.value.trim(); | |
| if (!message) return; | |
| const newMessage = { | |
| message, | |
| user_id: state.user.id, | |
| created_at: new Date().toISOString() | |
| }; | |
| state.messages.push(newMessage); | |
| input.value = ''; | |
| renderMessages(); | |
| } | |
| function toggleEmojiPicker() { | |
| const picker = document.getElementById('emoji-picker'); | |
| picker.classList.toggle('hidden'); | |
| } | |
| function addEmoji(emoji) { | |
| const input = document.getElementById('message-input'); | |
| input.value += emoji; | |
| document.getElementById('emoji-picker').classList.add('hidden'); | |
| } | |
| // Radio | |
| function showRadio() { | |
| document.getElementById('radio-player').classList.remove('closed'); | |
| document.getElementById('radio-player').classList.add('open'); | |
| } | |
| function hideRadio() { | |
| document.getElementById('radio-player').classList.remove('open'); | |
| document.getElementById('radio-player').classList.add('closed'); | |
| } | |
| function toggleRadio() { | |
| const audio = document.getElementById('radio-stream'); | |
| const icon = document.getElementById('play-pause-icon'); | |
| if (state.isRadioPlaying) { | |
| audio.pause(); | |
| icon.className = 'fas fa-play'; | |
| } else { | |
| audio.play(); | |
| icon.className = 'fas fa-pause'; | |
| } | |
| state.isRadioPlaying = !state.isRadioPlaying; | |
| } | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=MrHouse111/programeri" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |