From 54865553e6d3f96e255efd57ed8ff0be0e1f9abd Mon Sep 17 00:00:00 2001 From: MarharytaLepushynska Date: Tue, 17 Jun 2025 21:38:39 +0300 Subject: [PATCH 1/5] add homeewok --- index.html | 146 +++++++++++++++++++++++++++- src/main.js | 19 ++++ style/style.css | 249 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 413 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 09c6dc0..cc86208 100644 --- a/index.html +++ b/index.html @@ -3,11 +3,155 @@ - Simple HTML Page + Poll +
+ + +
+
+ + +
+ + + +
+ +
+
+

What is your favorite programming language?

+
+ JavaScript +
+
+
+ 45% +
+ +
+ Python +
+
+
+ 45% +
+ +
+ Java +
+
+
+ 45% +
+ +
+ C++ +
+
+
+ 3% +
+ + 150 votes +
+ +
+

Which social media platform do you use the most?

+
+ Facebook +
+
+
+ 35% +
+ +
+ Twitter +
+
+
+ 25% +
+ +
+ Instagram +
+
+
+ 30% +
+ +
+ LinkedIn +
+
+
+ 10% +
+ + 180 votes +
+
+
+ +
+

Create Poll

+ + Question + + + + Category + + + + Options + +
+ + + + +
+ Add option + +
+ +
+

Poll Question

+ + What is your favorite color? + + + + + + + + + + +
\ No newline at end of file diff --git a/src/main.js b/src/main.js index e69de29..5992d0f 100644 --- a/src/main.js +++ b/src/main.js @@ -0,0 +1,19 @@ +document.addEventListener('DOMContentLoaded', () => { + const createButton = document.querySelector('.create'); + const createForm = document.querySelector('.create-poll'); + const pollsContainer = document.querySelector('.polls'); + const questionForm = document.querySelector('.poll-question'); + + createButton.addEventListener('click', () => { + questionForm.style.display = 'none'; + createForm.style.display = 'grid'; + }); + + pollsContainer.addEventListener('click', (event) => { + const chosenPoll = event.target.closest('.poll'); + if (chosenPoll) { + createForm.style.display = 'none'; + questionForm.style.display = 'grid'; + } + }); +}); \ No newline at end of file diff --git a/style/style.css b/style/style.css index e69de29..e34c4af 100644 --- a/style/style.css +++ b/style/style.css @@ -0,0 +1,249 @@ +body{ + background-color: white; + font-family: Arial, Helvetica, sans-serif; + display: flex; + flex-direction: column; + align-items: center; + margin: 20px; +} + +.create{ + width: 100%; + max-width: 700px; + height: 40px; + border-radius: 5px; + border: none; + background-color: #2d92e5; + display: flex; + justify-content: center; + align-items: center; + padding: 10px; + font-size: 20px; + font-weight: bold; + color: white; + box-shadow: 0 0 2px #2d92e5; + cursor: pointer; + margin-bottom: 20px; +} + +.filter{ + display: flex; + justify-self: center; + flex-wrap: wrap; + max-width: 700px; + width: 100%; + height: 40px; + justify-self: center; + gap: 20px; + padding: 10px; + justify-content: center; + align-items: center; +} + +.searching { + display: flex; + gap: 5px; + width: auto; + flex-grow: 1; + justify-content: center; + flex-wrap: wrap; +} + +.search-input{ + width: 100%; + max-width: 400px; + min-width: 200px; + height: 30px; + border-radius: 5px; + border: 2px solid #d9d9d9; + font-size: 17px; + flex-grow: 1; +} + +.search{ + width: 100px; + min-width: 50px; + height: 34px; + border-radius: 5px; + border: none; + background-color: #2d92e5; + color: white; + font-weight: bold; + font-size: 17px; + cursor: pointer; +} + +select{ + width: 165px; + min-width: 120px; + height: 35px; + border-radius: 5px; + border: 2px solid #d9d9d9; + font-size: 17px; +} + +.polls{ + gap: 20px; + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +.poll{ + display: grid; + width:300px; + max-width: 300px; + height: 210px; + border-radius: 5px; + border: 2px solid #d9d9d9; + padding: 20px; +} + +h4{ + margin: 0px; +} + +.poll-row{ + display: flex; + margin: 0px; + align-items: center; + justify-content: space-between; + flex-wrap: nowrap; + padding: 5px; +} + +.name{ + width: 50px; +} + +.whole-line { + background-color: #e0e0e0; + width: 100px; + height: 7px; + border-radius: 4px; + overflow: hidden; +} + +.filled { + background-color: #2d92e5; + height: 100%; + border-radius: 4px; +} + +.votes{ + display: flex; + justify-content: flex-end; + margin-top: 15px; + color:dimgrey; +} + +.create-poll{ + display: none; + margin-top: 20px; + width:250px; + max-width: 300px; + height: 400px; + border-radius: 5px; + border: 2px solid #d9d9d9; + padding: 10px; + justify-content: center; +} + +.span-c, a{ + margin-top: 10px; + margin-bottom: 7px; +} + +.input-c{ + width: 230px; + height: 25px; + margin-bottom: 5px; + border-radius: 5px; + border: 1px solid #d9d9d9; + flex-grow: 1; + justify-self: start; +} + +a{ + font-weight: bold; + color:#2d92e5; +} + +.create-f{ + width: 230px; + height: 30px; + background-color: #2d92e5; + border-radius: 5px; + border: none; + font-size: 15px; + font-weight: bold; + color: white; + cursor: pointer; +} + +h3{ + margin: 0px; + justify-self: center; +} + +.poll-question{ + display: none; + margin-top: 20px; + width:250px; + max-width: 300px; + height: 250px; + border-radius: 5px; + border: 2px solid #d9d9d9; + padding: 10px; + justify-content: center; +} + +label{ + display: flex; + align-items: center; + gap: 10px; + font-size: 16px; + cursor: pointer; + justify-self: start; +} + +.vote{ + width: 230px; + height: 30px; + background-color: #2d92e5; + border-radius: 5px; + border: none; + font-size: 15px; + font-weight: bold; + color: white; + cursor: pointer; +} + +@media (max-width: 740px) { + .filter { + flex-direction: column; + align-items: center; + height: auto; + } + + .searching { + flex-direction: column; + align-items: center; + width: 100%; + } + + input, .search, select, .create { + width: 90%; + max-width: none; + justify-self: center; + } + + .search { + margin-top: 10px; + } + + select { + margin-top: 10px; + } +} + From 47f0a0e9e2fc3be32f9f0da5adb1541bf9397e9e Mon Sep 17 00:00:00 2001 From: MarharytaLepushynska Date: Mon, 23 Jun 2025 08:44:31 +0300 Subject: [PATCH 2/5] add js --- index.html | 16 ++-- src/main.js | 230 ++++++++++++++++++++++++++++++++++++++++++++++-- src/polls.json | 73 +++++++++++++++ style/style.css | 19 ++-- 4 files changed, 318 insertions(+), 20 deletions(-) create mode 100644 src/polls.json diff --git a/index.html b/index.html index cc86208..ce8284b 100644 --- a/index.html +++ b/index.html @@ -27,7 +27,7 @@
-
+
-
+

Create Poll

Question @@ -124,9 +124,9 @@

Create Poll

Add option - +
-
+

Poll Question

What is your favorite color? @@ -152,6 +152,6 @@

Poll Question

- +
\ No newline at end of file diff --git a/src/main.js b/src/main.js index 5992d0f..a49d4d9 100644 --- a/src/main.js +++ b/src/main.js @@ -1,19 +1,237 @@ document.addEventListener('DOMContentLoaded', () => { const createButton = document.querySelector('.create'); - const createForm = document.querySelector('.create-poll'); + const createPollDialog = document.querySelector('.create-poll'); const pollsContainer = document.querySelector('.polls'); - const questionForm = document.querySelector('.poll-question'); + const pollQuestionDialog = document.querySelector('.poll-question'); + const createPollFormButton = createPollDialog.querySelector('.create-f'); + const optionsContainer = createPollDialog.querySelector('.options'); + const voteButton = pollQuestionDialog.querySelector('.vote'); + const searchInput = document.querySelector('.search-input'); + const searchButton = document.querySelector('.search'); + const categorySelect = document.querySelector('select[name="category"]'); + const addOptionLink = document.querySelector('a'); + + let pollsInfo = []; + + async function loadPolls() { + const res = await fetch('./src/polls.json'); + if (!res.ok) { + throw new Error(`HTTP error! status: ${res.status}`); + } + const info = await res.json(); + pollsInfo = info; + showPolls(pollsInfo); + addCategories(pollsInfo); + } + + function showPolls(polls) { + pollsContainer.innerHTML = ''; + + polls.forEach(poll => { + const onePoll = document.createElement('div'); + onePoll.classList.add('poll'); + onePoll.dataset.question = poll.question; + + let optionsHtml = ''; + Object.entries(poll.options).forEach(([optText, votesCount]) => { + const percentage = poll.votes > 0 ? ((votesCount / poll.votes) * 100).toFixed(0) : 0; + optionsHtml += ` +
+ ${optText} +
+
+
+ ${percentage}% +
+ `; + }); + + onePoll.innerHTML = ` +

${poll.question}

+ ${optionsHtml} + ${poll.votes} votes + `; + pollsContainer.appendChild(onePoll); + }); + } + + function addCategories(pollsData) { + const categories = new Set(); + pollsData.forEach(poll => categories.add(poll.category)); + + categorySelect.innerHTML = ''; + categories.forEach(category => { + const option = document.createElement('option'); + option.value = category; + option.textContent = category; + categorySelect.appendChild(option); + }); + } createButton.addEventListener('click', () => { - questionForm.style.display = 'none'; - createForm.style.display = 'grid'; + pollQuestionDialog.style.display = 'none'; + createPollDialog.style.display = 'grid'; + + createPollDialog.querySelector('input[placeholder="Enter your question"]').value = ''; + createPollDialog.querySelector('input[placeholder="Category"]').value = ''; + optionsContainer.innerHTML = ` + + + `; + }); + + addOptionLink.addEventListener('click', (e) => { + e.preventDefault(); + const optionCount = optionsContainer.children.length + 1; + const newInput = document.createElement('input'); + newInput.classList.add('input-c'); + newInput.type = 'text'; + newInput.placeholder = `Option ${optionCount}`; + optionsContainer.appendChild(newInput); + }); + + createPollFormButton.addEventListener('click', () => { + const questionInput = createPollDialog.querySelector('input[placeholder="Enter your question"]'); + const categoryInput = createPollDialog.querySelector('input[placeholder="Category"]'); + const optionInputs = optionsContainer.querySelectorAll('input'); + + const question = questionInput.value.trim(); + const category = categoryInput.value.trim(); + const options = {}; + let optionsCount = 0; + + optionInputs.forEach(input => { + const optValue = input.value.trim(); + if (optValue !== '') { + options[optValue] = 0; + optionsCount++; + } + }); + + if (!question || !category || optionsCount < 2) { + alert('Please provide a question, category, and at least two valid options.'); + return; + } + + const newPoll = { + question: question, + category: category, + options: options, + votes: 0 + }; + + pollsInfo.push(newPoll); + showPolls(pollsInfo); + addCategories(pollsInfo); + createPollDialog.style.display = 'none'; }); + + let wantedPoll = null; pollsContainer.addEventListener('click', (event) => { const chosenPoll = event.target.closest('.poll'); if (chosenPoll) { - createForm.style.display = 'none'; - questionForm.style.display = 'grid'; + createPollDialog.style.display = 'none'; + pollQuestionDialog.style.display = 'grid'; + + wantedPoll = chosenPoll.dataset.question; + const poll = pollsInfo.find(p => p.question === wantedPoll); + + if (poll) { + pollQuestionDialog.querySelector('h3').textContent = 'Poll Question'; + pollQuestionDialog.querySelector('span').textContent = poll.question; + + const existingLabels = pollQuestionDialog.querySelectorAll('label'); + existingLabels.forEach(label => label.remove()); + + let optionsHtml = ''; + Object.entries(poll.options).forEach(([optText, optVotes], index) => { + optionsHtml += ` + + `; + }); + voteButton.insertAdjacentHTML('beforebegin', optionsHtml); + } } }); + + voteButton.addEventListener('click', () => { + if (!wantedPoll) return; + + const selectedOptionInput = pollQuestionDialog.querySelector('input[name="pollOption"]:checked'); + if (!selectedOptionInput) { + alert('Please select an option to vote.'); + return; + } + + const selectedOptionText = selectedOptionInput.value; + const pollIndex = pollsInfo.findIndex(p => p.question === wantedPoll); + + if (pollIndex !== -1) { + const poll = pollsInfo[pollIndex]; + poll.options[selectedOptionText]++; + poll.votes++; + + updateOnePoll(poll); + pollQuestionDialog.style.display = 'none'; + } + }); + + searchButton.addEventListener('click', () => { + filterPolls(); + }); + + function filterPolls() { + const text = searchInput.value.toLowerCase().trim(); + const selectedCategory = categorySelect.value; + + let filteredPolls = pollsInfo; + + if (selectedCategory !== 'all') { + filteredPolls = filteredPolls.filter(poll => poll.category === selectedCategory); + } + + if (text) { + filteredPolls = filteredPolls.filter(poll => + poll.question.toLowerCase().includes(text) || + poll.category.toLowerCase().includes(text) + ); + } + showPolls(filteredPolls); + } + + categorySelect.addEventListener('change', () => { + filterPolls(); + }); + + + function updateOnePoll(poll) { + const pollDiv = pollsContainer.querySelector(`[data-question="${poll.question}"]`); + if (!pollDiv) return; + + let optionsHtml = ''; + Object.entries(poll.options).forEach(([optText, votesCount]) => { + const percentage = poll.votes > 0 ? ((votesCount / poll.votes) * 100).toFixed(0) : 0; + optionsHtml += ` +
+ ${optText} +
+
+
+ ${percentage}% +
+ `; + }); + + pollDiv.innerHTML = ` +

${poll.question}

+ ${optionsHtml} + ${poll.votes} votes + `; +} + + loadPolls(); }); \ No newline at end of file diff --git a/src/polls.json b/src/polls.json new file mode 100644 index 0000000..f54a210 --- /dev/null +++ b/src/polls.json @@ -0,0 +1,73 @@ +[ + { + "question": "What is your favorite programming language?", + "category": "Programming", + "options": { + "JavaScript": 45, + "Python": 45, + "Java": 45, + "C++": 3 + }, + "votes": 150 + }, + { + "question": "Which social media platform do you use the most?", + "category": "Social media", + "options": { + "Facebook": 35, + "Twitter": 25, + "Instagram": 30, + "LinkedIn": 10 + }, + "votes": 180 + }, + { + "question": "What is your favorite mobile OS?", + "category": "Programming", + "options": { + "Android": 40, + "iOS": 60 + }, + "votes": 100 + }, + { + "question": "Where do you spend the most time?", + "category": "Social media", + "options": { + "Reels": 40, + "Tik tok": 40, + "YouTube Shorts": 20 + }, + "votes": 142 + }, + { + "question": "What is your favorite browser?", + "category": "Programming", + "options": { + "Chrome": 30, + "Safari": 30, + "Microsoft Edge": 20, + "Firefox": 20 + }, + "votes": 203 + }, + { + "question": "What is your favorite AI?", + "category": "Programming", + "options": { + "GPT": 40, + "Gemini": 30, + "Copilot": 30 + }, + "votes": 341 + }, + { + "question": "Do you like to watch movies?", + "category": "Social media", + "options": { + "Yes": 90, + "No": 10 + }, + "votes": 154 + } +] diff --git a/style/style.css b/style/style.css index e34c4af..daa894b 100644 --- a/style/style.css +++ b/style/style.css @@ -28,12 +28,9 @@ body{ .filter{ display: flex; - justify-self: center; flex-wrap: wrap; max-width: 700px; width: 100%; - height: 40px; - justify-self: center; gap: 20px; padding: 10px; justify-content: center; @@ -43,7 +40,7 @@ body{ .searching { display: flex; gap: 5px; - width: auto; + width: 550px; flex-grow: 1; justify-content: center; flex-wrap: wrap; @@ -83,10 +80,14 @@ select{ } .polls{ + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; - display: flex; + justify-items: center; + max-width: 700px; flex-wrap: wrap; - justify-content: center; + width: 100%; + margin-top: 20px; } .poll{ @@ -222,6 +223,8 @@ label{ @media (max-width: 740px) { .filter { flex-direction: column; + justify-content: center; + justify-self: center; align-items: center; height: auto; } @@ -245,5 +248,9 @@ label{ select { margin-top: 10px; } + + .polls { + grid-template-columns: 1fr; + } } From f8d8e1cab80402909f1edc2e63edd5d66bf3da39 Mon Sep 17 00:00:00 2001 From: MarharytaLepushynska Date: Mon, 23 Jun 2025 08:49:03 +0300 Subject: [PATCH 3/5] add all --- index.html | 73 ------------------------------------------------------ 1 file changed, 73 deletions(-) diff --git a/index.html b/index.html index ce8284b..fc8be5e 100644 --- a/index.html +++ b/index.html @@ -27,79 +27,6 @@
-
From 9cba7bc593b5ca6f3d245fd9209389db52f99bd5 Mon Sep 17 00:00:00 2001 From: MarharytaLepushynska Date: Tue, 24 Jun 2025 16:36:06 +0300 Subject: [PATCH 4/5] add report --- index.html | 2 ++ report.html | 18 ++++++++++++++++++ src/main.js | 6 ++++++ src/report.js | 31 +++++++++++++++++++++++++++++++ style/report.css | 7 +++++++ style/style.css | 8 ++++++-- 6 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 report.html create mode 100644 src/report.js create mode 100644 style/report.css diff --git a/index.html b/index.html index fc8be5e..4f19925 100644 --- a/index.html +++ b/index.html @@ -30,6 +30,8 @@ + +

Create Poll

diff --git a/report.html b/report.html new file mode 100644 index 0000000..eaf2e73 --- /dev/null +++ b/report.html @@ -0,0 +1,18 @@ + + + + + + + Звіт + + + + + + + +

Звіт

+
+ + diff --git a/src/main.js b/src/main.js index a49d4d9..4155cdf 100644 --- a/src/main.js +++ b/src/main.js @@ -233,5 +233,11 @@ document.addEventListener('DOMContentLoaded', () => { `; } +document.querySelector('.tableB').addEventListener('click', () => { + localStorage.setItem('pollData', JSON.stringify(pollsInfo)); + location.href = 'report.html'; +}); + + loadPolls(); }); \ No newline at end of file diff --git a/src/report.js b/src/report.js new file mode 100644 index 0000000..266b401 --- /dev/null +++ b/src/report.js @@ -0,0 +1,31 @@ +const pollsData = localStorage.getItem('pollData'); +const parsedData = pollsData ? JSON.parse(pollsData) : []; + +const data = parsedData.flatMap(poll => + Object.entries(poll.options).map(([option, votes]) => ({ + Question: poll.question, + Category: poll.category, + Option: option, + Votes: votes + })) +); + +new WebDataRocks({ +container: "#pivotContainer", +toolbar: true, +height: 400, + report: { + dataSource: { + data: data + }, + showGrandTotalsRows: false, + slice: { + rows: [{ uniqueName: "Question" }], + columns: [{ uniqueName: "Category" }], + measures: [{ uniqueName: "Votes", aggregation: "sum" }] + } + + + } + +}); \ No newline at end of file diff --git a/style/report.css b/style/report.css new file mode 100644 index 0000000..831e8d2 --- /dev/null +++ b/style/report.css @@ -0,0 +1,7 @@ +body { + font-family: Arial, sans-serif; +} + +h2 { + text-align: center; +} \ No newline at end of file diff --git a/style/style.css b/style/style.css index daa894b..5a92b79 100644 --- a/style/style.css +++ b/style/style.css @@ -7,7 +7,7 @@ body{ margin: 20px; } -.create{ +.create, .tableB{ width: 100%; max-width: 700px; height: 40px; @@ -26,6 +26,10 @@ body{ margin-bottom: 20px; } +.tableB{ + margin-top: 20px; +} + .filter{ display: flex; flex-wrap: wrap; @@ -235,7 +239,7 @@ label{ width: 100%; } - input, .search, select, .create { + input, .search, select, .create, .tableB { width: 90%; max-width: none; justify-self: center; From d841130e3912ebb93690bb007c8fe9aaa2710e67 Mon Sep 17 00:00:00 2001 From: MarharytaLepushynska Date: Wed, 25 Jun 2025 08:52:24 +0300 Subject: [PATCH 5/5] css report --- src/report.js | 1 + style/report.css | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/report.js b/src/report.js index 266b401..24d28fd 100644 --- a/src/report.js +++ b/src/report.js @@ -14,6 +14,7 @@ new WebDataRocks({ container: "#pivotContainer", toolbar: true, height: 400, +width: 1000, report: { dataSource: { data: data diff --git a/style/report.css b/style/report.css index 831e8d2..980190d 100644 --- a/style/report.css +++ b/style/report.css @@ -1,7 +1,14 @@ body { font-family: Arial, sans-serif; + display: grid; } h2 { text-align: center; + color: #2d92e5; +} + +#pivotContainer{ + justify-self: center; + margin-top: 20px; } \ No newline at end of file