diff --git a/index.html b/index.html index 09c6dc0..d2c5f52 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,81 @@ - + - Simple HTML Page - - + Голосування + +
+
+ + +
+
+
+ + + +
+
+
+
+ + + + +
+ \ No newline at end of file diff --git a/polls.json b/polls.json new file mode 100644 index 0000000..61d3b82 --- /dev/null +++ b/polls.json @@ -0,0 +1,98 @@ +[ + { + "id": 1, + "question": "Яка ваша улюблена мова програмування?", + "category": "Технології", + "options": [ + { "text": "JavaScript", "votes": 525 }, + { "text": "Python", "votes": 600 }, + { "text": "Java", "votes": 300 }, + { "text": "C++", "votes": 75 } + ], + "totalVotes": 1500 + }, + { + "id": 2, + "question": "Якою соціальною мережею ви користуєтесь найбільше?", + "category": "Соціальні мережі", + "options": [ + { "text": "Instagram", "votes": 540 }, + { "text": "TikTok", "votes": 450 }, + { "text": "Facebook", "votes": 315 }, + { "text": "Twitter", "votes": 195 } + ], + "totalVotes": 1500 + }, + { + "id": 3, + "question": "Який ваш улюблений жанр фільмів?", + "category": "Розваги", + "options": [ + { "text": "Драма", "votes": 280 }, + { "text": "Комедія", "votes": 350 }, + { "text": "Бойовик", "votes": 300 }, + { "text": "Жахи", "votes": 170 } + ], + "totalVotes": 1100 + }, + { + "id": 4, + "question": "Яке ваше улюблене заняття у вільний час?", + "category": "Розваги", + "options": [ + { "text": "Читання", "votes": 250 }, + { "text": "Спорт", "votes": 400 }, + { "text": "Відеоігри", "votes": 350 }, + { "text": "Подорожі", "votes": 300 } + ], + "totalVotes": 1300 + }, + { + "id": 5, + "question": "Який найкращий спосіб навчання?", + "category": "Освіта", + "options": [ + { "text": "Онлайн курси", "votes": 450 }, + { "text": "Книги", "votes": 300 }, + { "text": "Відео", "votes": 600 }, + { "text": "Практика", "votes": 650 } + ], + "totalVotes": 2000 + }, + { + "id": 6, + "question": "Який ваш улюблений вид спорту?", + "category": "Спорт", + "options": [ + { "text": "Футбол", "votes": 500 }, + { "text": "Баскетбол", "votes": 300 }, + { "text": "Теніс", "votes": 200 }, + { "text": "Плавання", "votes": 250 } + ], + "totalVotes": 1250 + }, + { + "id": 7, + "question": "Яка ваша улюблена кухня?", + "category": "Їжа", + "options": [ + { "text": "Італійська", "votes": 400 }, + { "text": "Японська", "votes": 350 }, + { "text": "Українська", "votes": 300 }, + { "text": "Французька", "votes": 150 } + ], + "totalVotes": 1200 + }, + { + "id": 8, + "question": "Куди б ви хотіли поїхати у відпустку?", + "category": "Подорожі", + "options": [ + { "text": "Європа", "votes": 450 }, + { "text": "Азія", "votes": 350 }, + { "text": "Америка", "votes": 250 }, + { "text": "Океанія", "votes": 100 } + ], + "totalVotes": 1150 + } +] \ No newline at end of file diff --git a/reports.html b/reports.html new file mode 100644 index 0000000..249b9f4 --- /dev/null +++ b/reports.html @@ -0,0 +1,23 @@ + + + + + + Звіти по опитуванням + + + + + + + + +
+ +

Аналітика опитувань

+
+
+ + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js index e69de29..b2a992d 100644 --- a/src/main.js +++ b/src/main.js @@ -0,0 +1,422 @@ +const CONFIG = { + POLLS_URL: 'polls.json', + DEBOUNCE_DELAY: 300, + NOTIFICATION_TIMEOUT: 3000, + AUTO_SAVE_DELAY: 2000 +}; + +const state = { + polls: [], + filteredPolls: [], + currentPollId: null, + searchCache: new Map(), + hasUnsavedChanges: false, + autoSaveTimeout: null +}; + +const elements = { + pollsGrid: document.getElementById('pollsGrid'), + searchInput: document.getElementById('searchInput'), + categorySelect: document.getElementById('categorySelect'), + voteModal: document.getElementById('voteModal'), + voteQuestion: document.getElementById('voteQuestion'), + voteOptions: document.getElementById('voteOptions'), + createModal: document.getElementById('createModal'), + questionInput: document.getElementById('questionInput'), + categorySelectCreate: document.getElementById('categorySelectCreate'), + notification: document.getElementById('notification'), + optionsGroup: document.getElementById('optionsGroup') +}; + +document.addEventListener('DOMContentLoaded', async () => { + try { + restoreFromBackup(); + + if (state.polls.length === 0) { + await initApp(); + } else { + state.filteredPolls = [...state.polls]; + renderPolls(state.filteredPolls); + populateCategorySelect(); + markAsSaved(); + } + + setupEventListeners(); + } catch (error) { + showNotification(`Помилка ініціалізації: ${error.message}`, 'error'); + } +}); + +async function initApp() { + try { + const response = await fetch(CONFIG.POLLS_URL); + if (!response.ok) throw new Error('Не вдалося завантажити опитування'); + + state.polls = await response.json(); + state.filteredPolls = [...state.polls]; + + renderPolls(state.filteredPolls); + populateCategorySelect(); + } catch (error) { + elements.pollsGrid.innerHTML = '
Помилка завантаження опитувань
'; + throw error; + } +} + +function setupEventListeners() { + elements.searchInput.addEventListener('input', debounce(performSearch, CONFIG.DEBOUNCE_DELAY)); + elements.categorySelect.addEventListener('change', performSearch); + + elements.searchInput.addEventListener('keypress', e => { + if (e.key === 'Enter') performSearch(); + }); + + window.addEventListener('click', e => { + if (e.target.classList.contains('modal')) { + closeModal(e.target.id); + } + }); + + elements.pollsGrid.addEventListener('click', e => { + const pollCard = e.target.closest('.poll-card'); + if (pollCard) { + const pollId = parseInt(pollCard.dataset.id); + openVoteModal(pollId); + } + }); + + window.addEventListener('beforeunload', e => { + if (state.hasUnsavedChanges) { + e.preventDefault(); + e.returnValue = 'У вас є незбережені зміни. Ви впевнені, що хочете залишити сторінку?'; + } + }); +} + +function populateCategorySelect() { + const categories = [...new Set(state.polls.map(poll => poll.category))]; + + const firstOption = elements.categorySelect.firstElementChild; + elements.categorySelect.innerHTML = ''; + elements.categorySelect.appendChild(firstOption); + + categories.forEach(category => { + const option = document.createElement('option'); + option.value = category; + option.textContent = category; + elements.categorySelect.appendChild(option); + }); +} + +function renderPolls(polls) { + if (!polls.length) { + elements.pollsGrid.innerHTML = '
Опитування не знайдено
'; + return; + } + + const fragment = document.createDocumentFragment(); + + polls.forEach(poll => { + const pollElement = createPollElement(poll); + fragment.appendChild(pollElement); + }); + + elements.pollsGrid.innerHTML = ''; + elements.pollsGrid.appendChild(fragment); +} + +function createPollElement(poll) { + const pollCard = document.createElement('div'); + pollCard.className = 'poll-card'; + pollCard.dataset.id = poll.id; + + const optionsHTML = poll.options.map(option => { + const percentage = poll.totalVotes > 0 ? + Math.round((option.votes / poll.totalVotes) * 100) : 0; + + return ` +
+ ${option.text} +
+
+
+ ${percentage}% +
+ `; + }).join(''); + + pollCard.innerHTML = ` +
${poll.category}
+

${poll.question}

+
${optionsHTML}
+
${poll.totalVotes} голосів
+ `; + + return pollCard; +} + +function openCreateModal() { + resetCreateForm(); + elements.createModal.style.display = 'flex'; + elements.questionInput.focus(); +} + +function resetCreateForm() { + elements.questionInput.value = ''; + elements.categorySelectCreate.selectedIndex = 0; + + const optionInputs = elements.optionsGroup.querySelectorAll('.option-input'); + + if (optionInputs.length > 4) { + for (let i = 4; i < optionInputs.length; i++) { + optionInputs[i].remove(); + } + } + + const remainingInputs = elements.optionsGroup.querySelectorAll('.option-input'); + remainingInputs.forEach((input, index) => { + input.value = ''; + input.placeholder = `Варіант ${index + 1}`; + }); +} + +function openVoteModal(pollId) { + const poll = state.polls.find(p => p.id === pollId); + if (!poll) return; + + state.currentPollId = pollId; + elements.voteQuestion.textContent = poll.question; + elements.voteOptions.innerHTML = ''; + + poll.options.forEach((option, index) => { + const optionElement = document.createElement('label'); + optionElement.className = 'vote-option'; + optionElement.innerHTML = ` + + ${option.text} + `; + elements.voteOptions.appendChild(optionElement); + }); + + elements.voteModal.style.display = 'flex'; +} + +function closeModal(modalId) { + document.getElementById(modalId).style.display = 'none'; + if (modalId === 'voteModal') { + state.currentPollId = null; + } +} + +function submitVote() { + const selected = document.querySelector('input[name="vote"]:checked'); + if (!selected || !state.currentPollId) { + showNotification('Будь ласка, оберіть варіант відповіді', 'error'); + return; + } + + const poll = state.polls.find(p => p.id === state.currentPollId); + if (poll) { + const option = poll.options.find(opt => opt.text === selected.value); + if (option) { + option.votes++; + poll.totalVotes++; + markAsChanged(); + updatePollCard(poll); + closeModal('voteModal'); + showNotification(`Ваш голос за "${selected.value}" подано!`, 'success'); + } + } +} + +function updatePollCard(poll) { + const pollCard = elements.pollsGrid.querySelector(`.poll-card[data-id="${poll.id}"]`); + if (!pollCard) return; + + const optionsContainer = pollCard.querySelector('.poll-options'); + optionsContainer.innerHTML = ''; + + poll.options.forEach(option => { + const percentage = poll.totalVotes > 0 ? + Math.round((option.votes / poll.totalVotes) * 100) : 0; + + const optionElement = document.createElement('div'); + optionElement.className = 'poll-option'; + optionElement.innerHTML = ` + ${option.text} +
+
+
+ ${percentage}% + `; + + optionsContainer.appendChild(optionElement); + }); + + pollCard.querySelector('.vote-count').textContent = `${poll.totalVotes} голосів`; +} + +function createPoll() { + const question = elements.questionInput.value.trim(); + const category = elements.categorySelectCreate.value; + const optionInputs = document.querySelectorAll('.option-input'); + const options = Array.from(optionInputs) + .map(input => input.value.trim()) + .filter(value => value !== ''); + + if (!question) { + showNotification('Будь ласка, введіть питання', 'error'); + return; + } + + if (!category) { + showNotification('Будь ласка, оберіть категорію', 'error'); + return; + } + + if (options.length < 2) { + showNotification('Будь ласка, додайте принаймні 2 варіанти відповідей', 'error'); + return; + } + + const newPoll = { + id: state.polls.length > 0 ? Math.max(...state.polls.map(p => p.id)) + 1 : 1, + question, + category, + options: options.map(option => ({ text: option, votes: 0 })), + totalVotes: 0 + }; + + state.polls.push(newPoll); + state.filteredPolls.push(newPoll); + markAsChanged(); + + populateCategorySelect(); + + performSearch(); + closeModal('createModal'); + showNotification('Опитування створено успішно!', 'success'); +} + +function addOption() { + const optionCount = elements.optionsGroup.querySelectorAll('.option-input').length; + + const newInput = document.createElement('input'); + newInput.type = 'text'; + newInput.className = 'form-input option-input'; + newInput.placeholder = `Варіант ${optionCount + 1}`; + + elements.optionsGroup.insertBefore(newInput, elements.optionsGroup.querySelector('.add-option-btn')); +} + +function performSearch() { + const searchTerm = elements.searchInput.value.toLowerCase().trim(); + const selectedCategory = elements.categorySelect.value; + + const cacheKey = `${searchTerm}-${selectedCategory}`; + if (state.searchCache.has(cacheKey)) { + state.filteredPolls = state.searchCache.get(cacheKey); + renderPolls(state.filteredPolls); + return; + } + + state.filteredPolls = state.polls.filter(poll => { + const matchesSearch = !searchTerm || + poll.question.toLowerCase().includes(searchTerm) || + poll.options.some(option => option.text.toLowerCase().includes(searchTerm)); + + const matchesCategory = !selectedCategory || poll.category === selectedCategory; + + return matchesSearch && matchesCategory; + }); + + state.searchCache.set(cacheKey, [...state.filteredPolls]); + renderPolls(state.filteredPolls); +} + +function markAsChanged() { + state.hasUnsavedChanges = true; + scheduleAutoSave(); +} + +function markAsSaved() { + state.hasUnsavedChanges = false; + clearAutoSave(); +} + +function scheduleAutoSave() { + clearAutoSave(); + state.autoSaveTimeout = setTimeout(() => { + autoSave(); + }, CONFIG.AUTO_SAVE_DELAY); +} + +function clearAutoSave() { + if (state.autoSaveTimeout) { + clearTimeout(state.autoSaveTimeout); + state.autoSaveTimeout = null; + } +} + +function autoSave() { + if (state.hasUnsavedChanges) { + try { + localStorage.setItem('pollsBackup', JSON.stringify({ + polls: state.polls, + timestamp: new Date().toISOString() + })); + + markAsSaved(); + showNotification('Зміни автоматично збережено', 'success'); + + } catch (error) { + showNotification('Помилка автозбереження: ' + error.message, 'error'); + } + } +} + +function restoreFromBackup() { + try { + const backup = localStorage.getItem('pollsBackup'); + if (backup) { + const data = JSON.parse(backup); + state.polls = data.polls; + + const backupDate = new Date(data.timestamp); + const weekAgo = new Date(); + weekAgo.setDate(weekAgo.getDate() - 7); + + if (backupDate < weekAgo) { + localStorage.removeItem('pollsBackup'); + state.polls = []; + showNotification('Резервна копія застаріла та видалена', 'error'); + } else { + showNotification(`Відновлено дані з резервної копії (${backupDate.toLocaleString()})`, 'success'); + } + } + } catch (error) { + showNotification('Помилка відновлення: ' + error.message, 'error'); + } +} + +function showNotification(message, type) { + if (!elements.notification) return; + + elements.notification.textContent = message; + elements.notification.className = `notification ${type} show`; + + setTimeout(() => { + if (elements.notification) { + elements.notification.classList.remove('show'); + } + }, CONFIG.NOTIFICATION_TIMEOUT); +} + +function debounce(func, delay) { + let timeoutId; + return function(...args) { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => func.apply(this, args), delay); + }; +} \ No newline at end of file diff --git a/src/reports.js b/src/reports.js new file mode 100644 index 0000000..0e238af --- /dev/null +++ b/src/reports.js @@ -0,0 +1,71 @@ + document.addEventListener('DOMContentLoaded', function() { + const backup = localStorage.getItem('pollsBackup'); + let polls = []; + + if (backup) { + try { + const data = JSON.parse(backup); + polls = data.polls || []; + } catch (e) { + console.error('Помилка парсингу резервної копії:', e); + } + } + + const reportData = []; + + polls.forEach(poll => { + poll.options.forEach(option => { + reportData.push({ + "Питання": poll.question, + "Категорія": poll.category, + "Варіант": option.text, + "Кількість голосів": option.votes, + "Загальна кількість голосів": poll.totalVotes, + "Відсоток": poll.totalVotes > 0 + ? (option.votes / poll.totalVotes * 100).toFixed(1) + : 0 + }); + }); + }); + + const pivot = new WebDataRocks({ + container: "#pivot-container", + toolbar: true, + report: { + dataSource: { + data: reportData + }, + "slice": { + "rows": [{ + "uniqueName": "Категорія" + }, { + "uniqueName": "Питання" + }, { + "uniqueName": "Варіант" + }], + "measures": [{ + "uniqueName": "Кількість голосів", + "aggregation": "sum", + "format": "number" + }, { + "uniqueName": "Відсоток", + "aggregation": "average", + "format": "percent" + }] + }, + "options": { + "grid": { + "type": "flat", + "showTotals": "off", + "showGrandTotals": "off" + } + }, + "formats": [{ + "name": "percent", + "decimalPlaces": 1, + "maxSymbols": 20, + "textAlign": "right" + }] + } + }); + }); \ No newline at end of file diff --git a/style/reports.css b/style/reports.css new file mode 100644 index 0000000..652eca8 --- /dev/null +++ b/style/reports.css @@ -0,0 +1,31 @@ +.reports-container { + max-width: 1200px; + margin: 30px auto; + padding: 20px; + } + + .back-btn { + display: block; + margin-bottom: 20px; + background-color: #4285f4; + color: white; + border: none; + padding: 10px 20px; + border-radius: 8px; + font-size: 14px; + cursor: pointer; + text-align: center; + max-width: 200px; + } + + .back-btn:hover { + background-color: #3367d6; + } + + #pivot-container { + height: 600px; + background: white; + border-radius: 12px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + overflow: hidden; + } \ No newline at end of file diff --git a/style/style.css b/style/style.css index e69de29..ea2865d 100644 --- a/style/style.css +++ b/style/style.css @@ -0,0 +1,509 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background-color: #f5f5f5; + padding: 20px; + line-height: 1.6; +} + +.container { + max-width: 900px; + margin: 0 auto; +} + +.header { + display: flex; + gap: 20px; + margin-bottom: 30px; + justify-content: center; +} + +.create-poll-btn { + background-color: #4285f4; + color: white; + border: none; + padding: 12px 30px; + border-radius: 8px; + font-size: 16px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s; + width: 100%; +} + +.create-poll-btn:hover { + background-color: #3367d6; +} + +/* Search Section */ +.search-section { + margin-bottom: 30px; +} + +.search-container { + display: flex; + background: white; + border: 1px solid #dadce0; + border-radius: 12px; + overflow: hidden; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + transition: all 0.2s; +} + +.search-container:focus-within { + border-color: #4285f4; + box-shadow: 0 2px 8px rgba(66, 133, 244, 0.2); +} + +.search-input { + flex: 1; + padding: 14px 18px; + border: none; + font-size: 16px; + outline: none; + background: transparent; + min-width: 0; +} + +.search-input::placeholder { + color: #9aa0a6; +} + +.category-select { + padding: 14px 18px; + border: none; + border-left: 1px solid #e8eaed; + font-size: 16px; + background: transparent; + cursor: pointer; + outline: none; + min-width: 140px; + color: #3c4043; +} + +.category-select:focus { + background-color: #f8f9fa; +} + +.search-btn { + padding: 14px 20px; + background-color: #4285f4; + color: white; + border: none; + cursor: pointer; + font-size: 16px; + font-weight: 500; + transition: background-color 0.2s; + min-width: 100px; +} + +.search-btn:hover { + background-color: #3367d6; +} + +.search-btn:active { + background-color: #2b57c7; +} + +.polls-grid { + display: grid; + gap: 20px; + grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); +} + +.poll-card { + background: white; + border-radius: 12px; + padding: 24px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + border: 1px solid #e8eaed; + cursor: pointer; + transition: box-shadow 0.2s; + position: relative; +} + +.poll-card:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); +} + +.poll-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 12px; +} + +.poll-category { + display: inline-block; + background-color: #e8f0fe; + color: #1967d2; + font-size: 12px; + padding: 4px 8px; + border-radius: 4px; + font-weight: 500; +} + +.delete-poll-btn { + background: none; + border: none; + color: #ea4335; + font-size: 20px; + cursor: pointer; + padding: 0 5px; + transition: color 0.2s; + position: absolute; + top: 10px; + right: 10px; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; +} + +.delete-poll-btn:hover { + background-color: #fce8e6; + color: #b3261e; +} + +.poll-question { + font-size: 18px; + font-weight: 600; + color: #202124; + margin-bottom: 20px; + line-height: 1.4; + padding-right: 15px; +} + +.poll-options { + margin-bottom: 16px; +} + +.poll-option { + display: flex; + align-items: center; + margin-bottom: 12px; + gap: 12px; +} + +.option-text { + min-width: 80px; + font-size: 14px; + color: #3c4043; + font-weight: 500; +} + +.progress-bar { + flex: 1; + height: 8px; + background-color: #f1f3f4; + border-radius: 4px; + overflow: hidden; +} + +.progress-fill { + height: 100%; + background-color: #4285f4; + border-radius: 4px; + transition: width 0.3s ease; +} + +.percentage { + font-size: 14px; + color: #3c4043; + font-weight: 500; + min-width: 35px; + text-align: right; +} + +.vote-count { + text-align: right; + font-size: 12px; + color: #5f6368; + margin-top: 8px; +} + +.modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modal-content { + background: white; + border-radius: 12px; + padding: 32px; + max-width: 500px; + width: 90%; + max-height: 80vh; + overflow-y: auto; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); + position: relative; +} + +.close-btn { + position: absolute; + top: 15px; + right: 20px; + background: none; + border: none; + font-size: 24px; + cursor: pointer; + color: #5f6368; + padding: 5px; +} + +.close-btn:hover { + color: #202124; +} + +.modal-title { + font-size: 24px; + font-weight: 600; + color: #202124; + margin-bottom: 8px; + text-align: center; +} + +.modal-question { + font-size: 18px; + color: #3c4043; + margin-bottom: 24px; + text-align: center; + font-weight: 400; +} + +/* Vote Modal */ +.vote-options { + margin-bottom: 24px; +} + +.vote-option { + display: flex; + align-items: center; + padding: 12px 0; + cursor: pointer; + transition: background-color 0.2s; + border-radius: 8px; + padding-left: 8px; +} + +.vote-option:hover { + background-color: #f8f9fa; +} + +.vote-radio { + width: 20px; + height: 20px; + margin-right: 12px; + cursor: pointer; +} + +.vote-text { + font-size: 16px; + color: #3c4043; + cursor: pointer; +} + +.vote-btn { + width: 100%; + background-color: #4285f4; + color: white; + border: none; + padding: 14px; + border-radius: 8px; + font-size: 16px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s; +} + +.vote-btn:hover { + background-color: #3367d6; +} + +.form-group { + margin-bottom: 24px; +} + +.form-label { + display: block; + font-size: 16px; + font-weight: 500; + color: #3c4043; + margin-bottom: 8px; +} + +.form-input { + width: 100%; + padding: 12px 16px; + border: 1px solid #dadce0; + border-radius: 8px; + font-size: 16px; + outline: none; + transition: border-color 0.2s; +} + +.form-input:focus { + border-color: #4285f4; +} + +.option-input { + margin-bottom: 12px; +} + +.add-option-btn { + color: #4285f4; + background: none; + border: none; + font-size: 14px; + cursor: pointer; + font-weight: 500; + padding: 8px 0; +} + +.add-option-btn:hover { + text-decoration: underline; +} + +.create-btn { + width: 100%; + background-color: #4285f4; + color: white; + border: none; + padding: 14px; + border-radius: 8px; + font-size: 16px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s; +} + +.create-btn:hover { + background-color: #3367d6; +} + +.no-polls { + text-align: center; + color: #5f6368; + font-size: 18px; + margin-top: 50px; +} + +.notification { + position: fixed; + top: 20px; + right: 20px; + padding: 15px 25px; + border-radius: 8px; + color: white; + font-weight: 500; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + z-index: 2000; + transform: translateX(150%); + transition: transform 0.3s ease-out; +} + +.notification.show { + transform: translateX(0); +} + +.notification.success { + background-color: #34a853; +} + +.notification.error { + background-color: #ea4335; +} + +.reports-btn { + background-color: #0f9d58; + color: white; + border: none; + padding: 12px 30px; + border-radius: 8px; + font-size: 16px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s; + width: 100%; +} + +.reports-btn:hover { + background-color: #0b8045; +} + +@media (max-width: 768px) { + .container { + padding: 0 10px; + } + + .header { + flex-direction: column; + align-items: center; + } + + .search-container { + flex-direction: column; + } + + .category-select { + border-left: none; + border-top: 1px solid #e8eaed; + min-width: auto; + } + + .search-btn { + min-width: auto; + } + + .polls-grid { + grid-template-columns: 1fr; + } + + .poll-card { + padding: 20px; + } + + .modal-content { + padding: 24px; + margin: 20px; + } + + .poll-option { + flex-direction: column; + align-items: flex-start; + gap: 8px; + width: 100%; + } + + .progress-bar { + width: 100%; + flex: none; + } + + .percentage { + align-self: flex-end; + width: 100%; + text-align: right; + } + + .create-poll-btn, + .reports-btn { + width: 100%; + margin-bottom: 10px; + } +} \ No newline at end of file