diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/JS_Template.iml b/.idea/JS_Template.iml new file mode 100644 index 0000000..ead1d18 --- /dev/null +++ b/.idea/JS_Template.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 0000000..3565144 --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..6f29fee --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..8811d7b --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/index.html b/index.html index 09c6dc0..42de59c 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,72 @@ +
+
+ Create Poll + +
+ + + +
+
+
+ +
+ + + \ No newline at end of file diff --git a/report.html b/report.html new file mode 100644 index 0000000..1882e1d --- /dev/null +++ b/report.html @@ -0,0 +1,29 @@ + + + + + + Polls Report + + + + + +
+
+

Polls Report

+ +
+ +
+
+ + + + + + + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js index e69de29..54a8bd5 100644 --- a/src/main.js +++ b/src/main.js @@ -0,0 +1,395 @@ +const defaultPollsData = { + "polls": [ + { + "id": 1, + "question": "What is your favorite programming language?", + "category": "Technology", + "options": [ + {"name": "JavaScript", "votes": 68, "percentage": 45}, + {"name": "Python", "votes": 68, "percentage": 45}, + {"name": "Java", "votes": 53, "percentage": 35}, + {"name": "C++", "votes": 5, "percentage": 3} + ], + "totalVotes": 150 + }, + { + "id": 2, + "question": "Which social media platform do you use the most?", + "category": "Social Media", + "options": [ + {"name": "Facebook", "votes": 63, "percentage": 35}, + {"name": "Twitter", "votes": 45, "percentage": 25}, + {"name": "Instagram", "votes": 54, "percentage": 30}, + {"name": "LinkedIn", "votes": 18, "percentage": 10} + ], + "totalVotes": 180 + }, + { + "id": 3, + "question": "What's your preferred way to learn new skills?", + "category": "Education", + "options": [ + {"name": "Online courses", "votes": 85, "percentage": 42}, + {"name": "Books", "votes": 65, "percentage": 32}, + {"name": "YouTube videos", "votes": 40, "percentage": 20}, + {"name": "Workshops", "votes": 12, "percentage": 6} + ], + "totalVotes": 202 + }, + { + "id": 4, + "question": "Which streaming service do you use most?", + "category": "Entertainment", + "options": [ + {"name": "Netflix", "votes": 120, "percentage": 48}, + {"name": "Disney+", "votes": 65, "percentage": 26}, + {"name": "Amazon Prime", "votes": 40, "percentage": 16}, + {"name": "HBO Max", "votes": 25, "percentage": 10} + ], + "totalVotes": 250 + }, + { + "id": 5, + "question": "What's your favorite type of exercise?", + "category": "Sports", + "options": [ + {"name": "Running", "votes": 45, "percentage": 30}, + {"name": "Weight training", "votes": 60, "percentage": 40}, + {"name": "Yoga", "votes": 30, "percentage": 20}, + {"name": "Swimming", "votes": 15, "percentage": 10} + ], + "totalVotes": 150 + }, + { + "id": 6, + "question": "Which work style do you prefer?", + "category": "Business", + "options": [ + {"name": "Remote work", "votes": 140, "percentage": 56}, + {"name": "Office work", "votes": 60, "percentage": 24}, + {"name": "Hybrid", "votes": 50, "percentage": 20} + ], + "totalVotes": 250 + }, + { + "id": 7, + "question": "What's your favorite type of food?", + "category": "Lifestyle", + "options": [ + {"name": "Italian", "votes": 80, "percentage": 32}, + {"name": "Asian", "votes": 90, "percentage": 36}, + {"name": "Mexican", "votes": 50, "percentage": 20}, + {"name": "American", "votes": 30, "percentage": 12} + ], + "totalVotes": 250 + }, + { + "id": 8, + "question": "Which mobile operating system do you prefer?", + "category": "Technology", + "options": [ + {"name": "iOS", "votes": 95, "percentage": 48}, + {"name": "Android", "votes": 100, "percentage": 50}, + {"name": "Other", "votes": 5, "percentage": 2} + ], + "totalVotes": 200 + } + ] +}; + +const LocalStorageManager = { + STORAGE_KEY: 'pollsAppData', + + loadData() { + try { + const savedData = localStorage.getItem(this.STORAGE_KEY); + if (savedData) { + return JSON.parse(savedData); + } + } catch (error) { + console.error('Error loading data from localStorage:', error); + } + return null; + }, + + saveData(data) { + try { + localStorage.setItem(this.STORAGE_KEY, JSON.stringify(data)); + console.log('Data saved to localStorage successfully'); + return true; + } catch (error) { + console.error('Error saving data to localStorage:', error); + return false; + } + }, +}; + +function initializePollsData() { + const savedData = LocalStorageManager.loadData(); + if (savedData && savedData.polls && Array.isArray(savedData.polls)) { + console.log('Loaded data from localStorage:', savedData.polls.length, 'polls'); + return savedData; + } else { + console.log('No saved data found, using default data'); + LocalStorageManager.saveData(defaultPollsData); + return defaultPollsData; + } +} +let pollsData = initializePollsData(); + +function updatePollPercentages(poll) { + if (poll.totalVotes === 0) { + poll.options.forEach(option => { + option.percentage = 0; + }); + return; + } + poll.options.forEach(option => { + option.percentage = Math.round((option.votes / poll.totalVotes) * 100); + }); + + let currentTotalPercentage = poll.options.reduce((sum, option) => sum + option.percentage, 0); + if (currentTotalPercentage !== 100) { + const diff = 100 - currentTotalPercentage; + if (poll.options.length > 0) { + poll.options[0].percentage += diff; + } + } +} + +function savePollsData() { + const success = LocalStorageManager.saveData(pollsData); + if (success) { + if (typeof window.updateReportData === 'function') { + window.updateReportData(); + } + + window.dispatchEvent(new CustomEvent('pollsDataUpdated', { detail: pollsData })); + } + return success; +} + +window.addEventListener('storage', function(e) { + if (e.key === LocalStorageManager.STORAGE_KEY && e.newValue) { + try { + const updatedData = JSON.parse(e.newValue); + pollsData = updatedData; + console.log('Data updated from another tab'); + renderPolls(); + } catch (error) { + console.error('Error parsing updated data from storage:', error); + } + } +}); + +function renderPolls(polls = pollsData.polls) { + const pollsGrid = document.getElementById('pollsGrid'); + const dynamicPopups = document.getElementById('dynamicPopups'); + + if (!pollsGrid || !dynamicPopups) return; + + pollsGrid.innerHTML = ''; + dynamicPopups.innerHTML = ''; + + polls.forEach(poll => { + const pollCard = document.createElement('a'); + pollCard.href = `#votePopup${poll.id}`; + pollCard.className = 'poll-card'; + + let optionsHTML = ''; + poll.options.forEach(option => { + optionsHTML += ` +
+ ${option.name} +
+
+
+ ${option.percentage}% +
+ `; + }); + + pollCard.innerHTML = ` +
${poll.question}
+ ${optionsHTML} +
+
${poll.category}
+
${poll.totalVotes} голосів
+
+ `; + + pollsGrid.appendChild(pollCard); + + const popup = document.createElement('div'); + popup.id = `votePopup${poll.id}`; + popup.className = 'popup-overlay'; + + let radioOptionsHTML = ''; + poll.options.forEach((option, index) => { + const optionId = `option${poll.id}_${index}`; + radioOptionsHTML += ` +
+ + +
+ `; + }); + + popup.innerHTML = ` + + `; + + dynamicPopups.appendChild(popup); + + const form = popup.querySelector('form'); + form.addEventListener('submit', function(e) { + e.preventDefault(); + const formData = new FormData(form); + const selectedOptionName = formData.get(`poll${poll.id}`); + + if (selectedOptionName) { + const currentPoll = pollsData.polls.find(p => p.id === poll.id); + + if (currentPoll) { + currentPoll.totalVotes++; + + const selectedOption = currentPoll.options.find(opt => opt.name === selectedOptionName); + if (selectedOption) { + selectedOption.votes++; + } + + updatePollPercentages(currentPoll); + savePollsData(); + renderPolls(); + + alert(`Дякуємо за ваш голос за: ${selectedOptionName}!`); + window.location.hash = '#'; + } + } else { + alert('Будь ласка, оберіть варіант, щоб проголосувати.'); + } + }); + }); +} +const createPollForm = document.querySelector('#createPopup form'); +const optionsContainer = document.querySelector('.options-container'); +const addOptionBtn = document.querySelector('.add-option'); + +function addOptionInput() { + if (optionsContainer) { + const newOptionInput = document.createElement('input'); + newOptionInput.type = 'text'; + newOptionInput.className = 'option-input'; + newOptionInput.name = `option${optionsContainer.children.length + 1}`; + newOptionInput.placeholder = `Варіант ${optionsContainer.children.length + 1}`; + optionsContainer.appendChild(newOptionInput); + } +} +if (addOptionBtn) { + addOptionBtn.addEventListener('click', function(e) { + e.preventDefault(); + addOptionInput(); + }); +} +if (createPollForm) { + createPollForm.addEventListener('submit', function(e) { + e.preventDefault(); + + const question = document.getElementById('question').value; + const category = document.getElementById('category').value; + const optionInputs = document.querySelectorAll('.option-input'); + + const options = []; + optionInputs.forEach(input => { + const optionName = input.value.trim(); + if (optionName) { + options.push({ + name: optionName, + votes: 0, + percentage: 0 + }); + } + }); + + if (options.length < 2) { + alert('Будь ласка, додайте щонайменше дві опції.'); + return; + } + + const newId = pollsData.polls.length > 0 ? Math.max(...pollsData.polls.map(p => p.id)) + 1 : 1; + + const newPoll = { + id: newId, + question: question, + category: category, + options: options, + totalVotes: 0 + }; + + pollsData.polls.push(newPoll); + savePollsData(); + renderPolls(); + + createPollForm.reset(); + while (optionsContainer.children.length > 2) { + optionsContainer.removeChild(optionsContainer.lastChild); + } + window.location.hash = '#'; + + alert('Опитування успішно створено та збережено!'); + }); +} + +function setupSearch() { + const searchInput = document.querySelector('.search-input'); + const categoryDropdown = document.querySelector('.category-dropdown'); + + if (!searchInput || !categoryDropdown) return; + + function filterPolls() { + const searchTerm = searchInput.value.toLowerCase(); + const selectedCategory = categoryDropdown.value.toLowerCase(); + + const filteredPolls = pollsData.polls.filter(poll => { + const matchesSearch = poll.question.toLowerCase().includes(searchTerm) || + poll.options.some(option => option.name.toLowerCase().includes(searchTerm)); + const matchesCategory = !selectedCategory || poll.category.toLowerCase() === selectedCategory; + + return matchesSearch && matchesCategory; + }); + + renderPolls(filteredPolls); + } + + searchInput.addEventListener('input', filterPolls); + categoryDropdown.addEventListener('change', filterPolls); +} + +window.resetToDefault = function() { + if (confirm('Ви впевнені, що хочете скинути всі дані до початкових значень?')) { + pollsData = JSON.parse(JSON.stringify(defaultPollsData)); + savePollsData(); + renderPolls(); + alert('Дані скинуті до початкових значень'); + } +}; + +document.addEventListener('DOMContentLoaded', function() { + console.log('Initializing polls app with localStorage support'); + renderPolls(); + setupSearch(); + window.PollsManager.showStats(); +}); \ No newline at end of file diff --git a/src/report.js b/src/report.js new file mode 100644 index 0000000..e72b050 --- /dev/null +++ b/src/report.js @@ -0,0 +1,256 @@ +function transformPollsDataForWebDataRocks(pollsData) { + const transformedData = []; + + pollsData.polls.forEach(poll => { + poll.options.forEach(option => { + transformedData.push({ + "Poll ID": poll.id, + "Question": poll.question, + "Category": poll.category, + "Option": option.name, + "Votes": option.votes, + "Percentage": option.percentage, + "Total Poll Votes": poll.totalVotes + }); + }); + }); + + return transformedData; +} + +const fallbackPollsData = { + "polls": [ + { + "id": 1, + "question": "What is your favorite programming language?", + "category": "Technology", + "options": [ + {"name": "JavaScript", "votes": 68, "percentage": 45}, + {"name": "Python", "votes": 68, "percentage": 45}, + {"name": "Java", "votes": 53, "percentage": 35}, + {"name": "C++", "votes": 5, "percentage": 3} + ], + "totalVotes": 150 + }, + { + "id": 2, + "question": "Which social media platform do you use the most?", + "category": "Social Media", + "options": [ + {"name": "Facebook", "votes": 63, "percentage": 35}, + {"name": "Twitter", "votes": 45, "percentage": 25}, + {"name": "Instagram", "votes": 54, "percentage": 30}, + {"name": "LinkedIn", "votes": 18, "percentage": 10} + ], + "totalVotes": 180 + }, + { + "id": 3, + "question": "What's your preferred way to learn new skills?", + "category": "Education", + "options": [ + {"name": "Online courses", "votes": 85, "percentage": 42}, + {"name": "Books", "votes": 65, "percentage": 32}, + {"name": "YouTube videos", "votes": 40, "percentage": 20}, + {"name": "Workshops", "votes": 12, "percentage": 6} + ], + "totalVotes": 202 + }, + { + "id": 4, + "question": "Which streaming service do you use most?", + "category": "Entertainment", + "options": [ + {"name": "Netflix", "votes": 120, "percentage": 48}, + {"name": "Disney+", "votes": 65, "percentage": 26}, + {"name": "Amazon Prime", "votes": 40, "percentage": 16}, + {"name": "HBO Max", "votes": 25, "percentage": 10} + ], + "totalVotes": 250 + }, + { + "id": 5, + "question": "What's your favorite type of exercise?", + "category": "Sports", + "options": [ + {"name": "Running", "votes": 45, "percentage": 30}, + {"name": "Weight training", "votes": 60, "percentage": 40}, + {"name": "Yoga", "votes": 30, "percentage": 20}, + {"name": "Swimming", "votes": 15, "percentage": 10} + ], + "totalVotes": 150 + }, + { + "id": 6, + "question": "Which work style do you prefer?", + "category": "Business", + "options": [ + {"name": "Remote work", "votes": 140, "percentage": 56}, + {"name": "Office work", "votes": 60, "percentage": 24}, + {"name": "Hybrid", "votes": 50, "percentage": 20} + ], + "totalVotes": 250 + }, + { + "id": 7, + "question": "What's your favorite type of food?", + "category": "Lifestyle", + "options": [ + {"name": "Italian", "votes": 80, "percentage": 32}, + {"name": "Asian", "votes": 90, "percentage": 36}, + {"name": "Mexican", "votes": 50, "percentage": 20}, + {"name": "American", "votes": 30, "percentage": 12} + ], + "totalVotes": 250 + }, + { + "id": 8, + "question": "Which mobile operating system do you prefer?", + "category": "Technology", + "options": [ + {"name": "iOS", "votes": 95, "percentage": 48}, + {"name": "Android", "votes": 100, "percentage": 50}, + {"name": "Other", "votes": 5, "percentage": 2} + ], + "totalVotes": 200 + } + ] +}; + +function loadPollsDataFromStorage() { + try { + const savedData = localStorage.getItem('pollsAppData'); + if (savedData) { + const parsedData = JSON.parse(savedData); + console.log('Loaded polls data from localStorage for report'); + return parsedData; + } + } catch (error) { + console.error('Error loading data from localStorage:', error); + } + + console.log('Using fallback data for report'); + return typeof pollsData !== 'undefined' ? pollsData : fallbackPollsData; +} + +let pivot; + +document.addEventListener('DOMContentLoaded', function() { + const dataToUse = loadPollsDataFromStorage(); + const transformedData = transformPollsDataForWebDataRocks(dataToUse); + + console.log('Transformed data for WebDataRocks:', transformedData); + + pivot = new WebDataRocks({ + container: "#wdr-component", + toolbar: true, + height: 600, + report: { + dataSource: { + data: transformedData + }, + slice: { + rows: [ + { + uniqueName: "Category", + caption: "Category" + }, + { + uniqueName: "Question", + caption: "Question" + } + ], + columns: [ + { + uniqueName: "Option", + caption: "Option" + } + ], + measures: [ + { + uniqueName: "Votes", + aggregation: "sum", + caption: "Votes" + }, + { + uniqueName: "Percentage", + aggregation: "average", + caption: "Percentage" + } + ] + }, + options: { + grid: { + showGrandTotals: "on", + showTotals: "on" + } + } + }, + customizeCell: function(cell, data) { + if (data.isClassicTotalRow || data.isClassicTotalColumn || data.isGrandTotalRow || data.isGrandTotalColumn) { + cell.style.backgroundColor = "#f5f5f5"; + cell.style.fontWeight = "bold"; + } + if (data.measure && data.measure.uniqueName === "Votes" && data.value > 80) { + cell.style.backgroundColor = "#e8f5e8"; + cell.style.color = "#2e7d32"; + } + }, + reportcomplete: function() { + console.log('WebDataRocks report completed successfully'); + addRefreshButton(); + } + }); + + function addRefreshButton() { + const toolbar = document.querySelector('.wdr-toolbar-wrapper'); + if (toolbar) { + const refreshBtn = document.createElement('button'); + refreshBtn.innerHTML = '🔄 Оновити дані'; + refreshBtn.className = 'wdr-toolbar-button'; + refreshBtn.style.marginLeft = '10px'; + refreshBtn.style.padding = '5px 10px'; + refreshBtn.style.backgroundColor = '#4CAF50'; + refreshBtn.style.color = 'white'; + refreshBtn.style.border = 'none'; + refreshBtn.style.borderRadius = '4px'; + refreshBtn.style.cursor = 'pointer'; + + refreshBtn.addEventListener('click', function() { + console.log('Manual refresh triggered'); + window.updateReportData(); + }); + + toolbar.appendChild(refreshBtn); + } + } + + window.updateReportData = function() { + console.log('Updating report data from localStorage'); + const currentData = loadPollsDataFromStorage(); + const newTransformedData = transformPollsDataForWebDataRocks(currentData); + + if (pivot) { + pivot.updateData({ + data: newTransformedData + }); + console.log('Report data updated successfully'); + } + }; + + window.addEventListener('storage', function(e) { + if (e.key === 'pollsAppData' && e.newValue) { + console.log('Detected localStorage update, refreshing report data'); + window.updateReportData(); + } + }); + + window.addEventListener('pollsDataUpdated', function(e) { + console.log('Detected polls data update event, refreshing report'); + window.updateReportData(); + }); +}); + +if (typeof module !== 'undefined' && module.exports) { + module.exports = { transformPollsDataForWebDataRocks }; +} \ No newline at end of file diff --git a/style/style.css b/style/style.css index e69de29..87d3843 100644 --- a/style/style.css +++ b/style/style.css @@ -0,0 +1,493 @@ +:root { + --blue--: #4378d8; + --blue--hover: #275cbe; + --border_color_white--: #e0e0e0; +} + +* { + 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 { + margin: 0 auto; +} + +.create-poll-header, header { + background: var(--blue--); + color: white; + padding: 20px; + border-radius: 12px; + margin-bottom: 20px; + display: flex; + justify-content: space-between; + align-items: center; + box-shadow: 0 4px 12px rgba(0,0,0,0.25); +} + +.create-poll-btn, .back-to-home-btn, .to-report-btn { + background: var(--blue--); + border: var(--blue--); + color: white; + padding: 12px 24px; + border-radius: 8px; + cursor: pointer; + font-size: 30px; + font-weight: 500; + transition: all 0.3s ease; + text-decoration: none; +} + +.create-poll-btn:hover,.back-to-home-btn:hover , .to-report-btn:hover { + background: var(--blue--hover); + border: var(--blue--hover); + transform: translateY(-2px); +} + +.search-bar { + background: white; + border-radius: 12px; + border: 2px solid var(--border_color_white--); + padding: 4px; + margin-bottom: 20px; + box-shadow: 0 2px 8px rgba(0,0,0,0.1); + display: flex; + gap: 15px; +} + +.search-input { + flex: 1; + padding: 12px 20px; + border: none; + border-radius: 8px 0 0 8px; + font-size: 25px; + outline: none; + width: 70%; + background: transparent; +} + +.search-bar:focus-within { + border-color: var(--blue--); +} + +.category-dropdown { + padding: 12px; + border: none; + border-radius: 0 8px 8px 0; + font-size: 25px; + background: white; + cursor: pointer; + min-width: 150px; + width: 15%; + outline: none; +} + +.polls-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); + gap: 20px; + margin-top: 20px; +} + +@media (max-width: 768px) { + .polls-grid { + grid-template-columns: 1fr; + gap: 15px; + } + + .container { + max-width: 100%; + padding: 0 10px; + } +} + +@media (min-width: 1400px) { + .polls-grid { + grid-template-columns: repeat(3, 1fr); + } +} + +.poll-card { + background: white; + border-radius: 12px; + border: 2px solid var(--border_color_white--); + padding: 24px; + margin-bottom: 20px; + box-shadow: 0 2px 8px rgba(0,0,0,0.1); + transition: transform 0.3s ease, box-shadow 0.3s ease; + text-decoration: none; + cursor: pointer; + display: flex; + flex-direction: column; +} + +.poll-card:hover { + transform: translateY(-2px); + box-shadow: 0 4px 16px rgba(0,0,0,0.15); +} + +.poll-title { + font-size: 25px; + font-weight: 600; + color: #333; + margin-bottom: 20px; +} + +.poll-option { + display: flex; + align-items: center; + margin-bottom: 12px; + cursor: pointer; + padding: 8px; + border-radius: 8px; + transition: background-color 0.3s ease; +} + +.option-label { + font-size: 20px; + font-weight: 500; + color: #333; + width: 120px; + flex-shrink: 0; + text-align: left; +} + +.progress-container { + flex: 1; + margin: 0 20px; + background-color: white; + border-radius: 20px; + height: 8px; + position: relative; + overflow: hidden; +} + +.progress-bar { + height: 100%; + background: linear-gradient(90deg, #4285f4, #5b9bd5); + border-radius: 20px; + transition: width 0.6s ease; + position: relative; +} + +.percentage { + font-size: 20px; + font-weight: 600; + color: black; + min-width: 50px; + text-align: right; +} + +.info { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: auto; + padding-top: 15px; +} + +.category { + color: gray; + font-size: 20px; + margin-top: 15px; + font-weight: 500; +} + +.vote-count { + color: gray; + font-size: 20px; + margin-top: 15px; + font-weight: 500; +} + +/* Popup styles using CSS :target */ +.popup-overlay { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 1000; + justify-content: center; + align-items: center; +} + +.popup-overlay:target { + display: flex; + animation: fadeIn 0.3s ease; +} + +.popup-content { + background: white; + border-radius: 16px; + padding: 40px; + max-width: 500px; + width: 90%; + max-height: 90vh; + overflow-y: auto; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); + animation: slideIn 0.3s ease; + position: relative; +} + +.popup-close { + position: absolute; + top: 15px; + right: 20px; + background: none; + border: none; + font-size: 24px; + cursor: pointer; + color: #666; + padding: 5px; + text-decoration: none; + line-height: 1; +} + +.popup-close:hover { + color: #333; +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(-50px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Vote popup styles */ +.vote-popup h1 { + text-align: center; + margin-bottom: 40px; + font-size: 2.5rem; +} + +.vote-popup .question { + font-size: 1.5rem; + text-align: center; + margin-bottom: 40px; +} + +.vote-popup .options { + display: flex; + flex-direction: column; + gap: 20px; + margin-bottom: 40px; +} + +.vote-popup .option { + position: relative; +} + +.vote-popup .option input[type="radio"] { + position: absolute; + opacity: 0; + cursor: pointer; +} + +.vote-popup .option label { + display: flex; + align-items: center; + font-size: 1.25rem; + cursor: pointer; + padding: 15px 20px; + border-radius: 12px; + transition: all 0.3s ease; + border: 2px solid transparent; +} + +.vote-popup .option label:hover { + background-color: #f8f9fa; + border-color: #e9ecef; +} + +.vote-popup .option input[type="radio"]:checked + label { + background-color: #e3f2fd; + border-color: var(--blue--hover); + color: var(--blue--); +} + +.vote-popup .radio-button { + width: 24px; + height: 24px; + border: 2px solid #ccc; + border-radius: 50%; + margin-right: 15px; + position: relative; + transition: all 0.3s ease; +} + +.vote-popup .option input[type="radio"]:checked + label .radio-button { + border-color: var(--blue--hover); + background-color: var(--blue--hover); +} + +.vote-popup .option input[type="radio"]:checked + label .radio-button::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 8px; + height: 8px; + background-color: white; + border-radius: 50%; +} + +.vote-popup .vote-button { + width: 100%; + background-color: var(--blue--); + color: white; + border: none; + border-radius: 12px; + padding: 18px; + font-size: 20px; + font-weight: 500; + cursor: pointer; + transition: all 0.3s ease; +} + +.vote-popup .vote-button:hover { + background-color: var(--blue--hover); + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(33, 150, 243, 0.3); +} + +/* Create poll popup styles */ +.create-popup h1 { + text-align: center; + margin-bottom: 40px; + font-size: 2.5rem; +} + +.create-popup .form-group { + margin-bottom: 30px; +} + +.create-popup label { + display: block; + font-size: 25px; + color: #333; + margin-bottom: 12px; + font-weight: 500; +} + +.create-popup input[type="text"] { + width: 100%; + padding: 16px; + border: 2px solid var(--border_color_white--); + border-radius: 8px; + font-size: 20px; + transition: all 0.3s ease; +} + +.create-popup input[type="text"]:focus { + outline: none; + border-color: #4285f4; + background-color: white; +} + +.create-popup .options-container { + display: flex; + flex-direction: column; + gap: 12px; +} + +.create-popup .option-input { + width: 100%; + padding: 16px; + border: 2px solid #e0e0e0; + border-radius: 8px; + font-size: 20px; + background-color: #fafafa; + transition: all 0.3s ease; +} + +.create-popup .add-option { + color: var(--blue--); + font-size: 20px; + text-decoration: none; + margin-top: 8px; + display: inline-block; + font-weight: 500; +} + +.create-popup .add-option:hover { + text-decoration: underline; +} + +.create-popup .create-btn { + width: 100%; + padding: 16px; + background-color: var(--blue--); + color: white; + border: none; + border-radius: 8px; + font-size: 25px; + font-weight: 500; + cursor: pointer; + margin-top: 10px; + transition: background-color 0.3s ease; +} + +.create-popup .create-btn:hover { + background-color: var(--blue--hover); +} + +.create-popup .category-select { + width: 100%; + padding: 16px; + border: 2px solid var(--border_color_white--); + border-radius: 8px; + font-size: 20px; + background-color: white; + transition: all 0.3s ease; + background-position: right 16px center; + background-size: 16px; +} + +.create-popup .category-select:focus { + outline: none; + border-color: var(--blue--); + background-color: white; + box-shadow: 0 0 0 3px rgba(67, 120, 216, 0.1); +} + +.create-popup .category-select:hover { + border-color: var(--blue--hover); +} + +.create-popup .category-select option { + padding: 12px 16px; + font-size: 18px; + color: #333; + background-color: white; +} + +.create-popup .category-select option:hover { + background-color: #f8f9fa; +} + +.create-popup .category-select option:checked { + background-color: var(--blue--); + color: white; +}