diff --git a/package.json b/package.json index d0b70b9..5d3cd51 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,11 @@ "check": "biome check .", "fix": "biome lint --write" }, - "keywords": ["scrum", "google groups", "fossasia"], + "keywords": [ + "scrum", + "google groups", + "fossasia" + ], "author": "hkedia321", "license": "ISC", "bugs": { @@ -19,6 +23,12 @@ }, "homepage": "https://github.com/fossasia/scrum_helper", "devDependencies": { - "@biomejs/biome": "1.9.4" + "@biomejs/biome": "1.9.4", + "autoprefixer": "^10.4.21", + "postcss": "^8.5.3", + "tailwindcss": "^4.1.4" + }, + "dependencies": { + "@tailwindcss/cli": "^4.1.3" } } diff --git a/src/icons/light-mode.png b/src/icons/light-mode.png new file mode 100644 index 0000000..1505866 Binary files /dev/null and b/src/icons/light-mode.png differ diff --git a/src/icons/night-mode.png b/src/icons/night-mode.png new file mode 100644 index 0000000..b12103d Binary files /dev/null and b/src/icons/night-mode.png differ diff --git a/src/index.css b/src/index.css index 77bed34..ca33a72 100644 --- a/src/index.css +++ b/src/index.css @@ -1,9 +1,12 @@ +@import "tailwindcss"; +@tailwind base; +@tailwind components; +@tailwind utilities; body { margin: 0; padding: 0; background-color: rgba(251, 251, 251, 0.6); } - * { box-sizing: border-box; } @@ -50,39 +53,68 @@ li { list-style-type: disc !important; margin-left: 1rem; } -.selectedLabel { - font-weight: 400; - color: #333333; + +body,input,div,h3,h4,p,label,hr, #scrumReport{ + transition: all 0.3s ease-in-out; } -.unselectedLabel { - font-weight: 300; - color: #666666; +.dark-mode { + background: #1a1a1a !important; + color: #ffffff !important; + transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out; +} +.dark-mode .bg-white{ + background-color: #2d2d2d !important; + border-color: #404040 !important; + transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out; } -.selectedLabel, .unselectedLabel { - transition: color 0.3s ease-in-out, font-weight 0.3s ease-in-out; +.dark-mode input[type="text"], +.dark-mode input[type="date"], +.dark-mode #scrumReport { + background-color: #404040 !important; + border-color: #505050 !important; + color: #ffffff !important; + transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out; +} +.dark-mode h3, +.dark-mode h4, +.dark-mode p, +.dark-mode label { + color: #ffffff !important; + transition: color 0.3s ease-in-out; } +.dark-mode hr { + border-color: #505050 !important; + transition: border-color 0.3s ease-in-out; +} #scrumReport { - border: 1px solid #ccc; - padding: 10px; - min-height: 200px; - max-height: 400px; - overflow-y: auto; - background-color: white; + font-size: 13px !important; + line-height: 1.5 !important; } -#scrumReport:focus { - outline: none; - border-color: #26a69a; +#scrumReport b { + font-size: 13px !important; } -#scrumReport a { - color: #26a69a; - text-decoration: none; +#scrumReport li { + font-size: 13px !important; + margin-bottom: 4px !important; } -#scrumReport a:hover { - text-decoration: underline; +.dark-mode #scrumReport { + font-size: 13px !important; } + +.dark-mode #scrumReport b { + font-size: 13px !important; +} + +.dark-mode #scrumReport li { + font-size: 13px !important; +} + +.dark-mode a { + color: #00b7ff !important; +} \ No newline at end of file diff --git a/src/manifest.json b/src/manifest.json index d4f8d2c..8a427ad 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -31,6 +31,13 @@ "content_security_policy": { "extension_pages": "script-src 'self'; object-src 'self';" }, + "web_accessible_resources": [{ + "resources": [ + "/icons/night-mode.png", + "icons/night-mode.png" + ], + "matches": [""] + }], "permissions": [ "tabs", "storage", diff --git a/src/popup.html b/src/popup.html index 7a924f2..5df594b 100644 --- a/src/popup.html +++ b/src/popup.html @@ -4,116 +4,149 @@ - + -
-

SCRUM Helper

-
- SCRUM helper prefills the Scrums in google groups, with your FOSSASIA's contributions. -
-
-
-
- -
-
-
-
- -
-
-
-
- - -
-
- - -
-
Fetch your contributions between: - - -
- -
-
Starting Date:
- - -
-
-
Ending Date
- -
-
-
- - -
-
- - -
-
-
Scrum Report
-
-
-
-
- - +
+
+
+

Scrum Helper

+ Night Mode +
+
+

Report your development progress by auto-fetching your Git activity for a selected period

+
+
+
-
+
+ +
+
+
+

Your Project Name

+ +
+
+

Your Github Username

+ +
-
Note:
-
-
    -
  • The PRs fetched are according to the date last reviewed by anyone. So if you reviewed a PR 10 days back, and someone reviewed it 2 days back, it will appear in your last week's activity. See this issue. -
  • -
  • By using the extension you understand that there might be discrepancies in the SCRUM generated. You are advised to edit the SCRUM afterwards to remove any discrepancies. -
  • -
-
+
+

Fetch your contributions between:

+
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+
+ +
+
+ + +
+
+

What is blocking you from making progress?

+ +
+
+
+
+
Scrum Report
+
+
+
+
+ + +
+ + +
+
+

Note:

+
    +
  • The PRs fetched are based on the most recent review by any contributor. If you reviewed a PR 10 days ago and someone else reviewed it 2 days ago, it will still appear in your activity for the past week. (See this issue.) +
  • +
  • Please note that some discrepancies may occur in the generated SCRUM. We recommend manually reviewing and editing the report to ensure accuracy before sharing +
  • +
+
+
-
- +
+ +
+

+ Made with ❤️ by FOSSASIA • + v2.0 +

+
+
+
- + diff --git a/src/scripts/main.js b/src/scripts/main.js index 590d579..94fef36 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1,15 +1,13 @@ -/* global $,Materialize*/ var enableToggleElement = document.getElementById('enable'); var githubUsernameElement = document.getElementById('githubUsername'); var projectNameElement = document.getElementById('projectName'); var lastWeekContributionElement = document.getElementById('lastWeekContribution'); +let yesterdayContributionElement = document.getElementById('yesterdayContribution'); var startingDateElement = document.getElementById('startingDate'); var endingDateElement = document.getElementById('endingDate'); var showOpenLabelElement = document.getElementById('showOpenLabel'); var userReasonElement = document.getElementById('userReason'); -var gsoc = 0; //0 means gsoc. 1 means gsoc function handleBodyOnLoad() { - // prefill name chrome.storage.local.get( [ 'githubUsername', @@ -21,8 +19,7 @@ function handleBodyOnLoad() { 'showClosedLabel', 'userReason', 'lastWeekContribution', - 'gsoc', - 'selectedTab', + 'yesterdayContribution', ], (items) => { if (items.githubUsername) { @@ -57,24 +54,19 @@ function handleBodyOnLoad() { if (items.lastWeekContribution) { lastWeekContributionElement.checked = items.lastWeekContribution; handleLastWeekContributionChange(); - } else if (items.lastWeekContribution !== false) { + } + else if (items.lastWeekContribution !== false) { lastWeekContributionElement.checked = true; handleLastWeekContributionChange(); } - if (items.gsoc == 1) { - handleGsocClick(); - } else { - handleCodeheatClick(); + if (items.yesterdayContribution) { + yesterdayContributionElement.checked = items.yesterdayContribution; + handleYesterdayContributionChange(); } - if (items.selectedTab === 'gsoc') { - handleGsocClick(); - } - else { - handleCodeheatClick(); + else if (items.yesterdayContribution !== false) { + yesterdayContributionElement.checked = true; + handleYesterdayContributionChange(); } - - // initialize materialize tabs - $('.tabs').tabs('select_tab', items.selectedTab === 'gsoc' ? 'gsocBox' : 'codeheatBox' ); }, ); } @@ -113,10 +105,31 @@ function handleLastWeekContributionChange() { chrome.storage.local.set({ lastWeekContribution: value }); } +function handleYesterdayContributionChange() { + let value = yesterdayContributionElement.checked; + let labelElement = document.querySelector("label[for='yesterdayContribution']"); + + if (value) { + startingDateElement.disabled = true; + endingDateElement.disabled = true; + endingDateElement.value = getToday(); + startingDateElement.value = getYesterday(); + handleEndingDateChange(); + handleStartingDateChange(); + labelElement.classList.add("selectedLabel"); + labelElement.classList.remove("unselectedLabel"); + } else { + startingDateElement.disabled = false; + endingDateElement.disabled = false; + labelElement.classList.add("unselectedLabel"); + labelElement.classList.remove("selectedLabel"); + } + chrome.storage.local.set({ yesterdayContribution: value }); +} + function getLastWeek() { var today = new Date(); - var noDays_to_goback = gsoc == 0 ? 7 : 1; - var lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - noDays_to_goback); + var lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); var lastWeekMonth = lastWeek.getMonth() + 1; var lastWeekDay = lastWeek.getDate(); var lastWeekYear = lastWeek.getFullYear(); @@ -128,6 +141,20 @@ function getLastWeek() { ('00' + lastWeekDay.toString()).slice(-2); return lastWeekDisplayPadded; } +function getYesterday() { + let today = new Date(); + let yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); + let yesterdayMonth = yesterday.getMonth() + 1; + let yesterdayWeekDay = yesterday.getDate(); + let yesterdayYear = yesterday.getFullYear(); + let yesterdayPadded = + ('0000' + yesterdayYear.toString()).slice(-4) + + '-' + + ('00' + yesterdayMonth.toString()).slice(-2) + + '-' + + ('00' + yesterdayWeekDay.toString()).slice(-2); + return yesterdayPadded; +} function getToday() { var today = new Date(); var Week = new Date(today.getFullYear(), today.getMonth(), today.getDate()); @@ -170,30 +197,13 @@ function handleUserReasonChange() { var value = userReasonElement.value; chrome.storage.local.set({ userReason: value }); } -function handleCodeheatClick() { - gsoc = 0; - $('#codeheatTab').addClass('active'); - $('.tabs').tabs(); - $('#noDays').text('7 days'); - chrome.storage.local.set({ gsoc: 0, selectedTab: 'codeheat' }); - handleLastWeekContributionChange(); -} -function handleGsocClick() { - gsoc = 1; - $('#gsocTab').addClass('active'); - $('.tabs').tabs(); - $('#noDays').text('1 day'); - chrome.storage.local.set({ gsoc: 1, selectedTab: 'gsoc' }); - handleLastWeekContributionChange(); -} enableToggleElement.addEventListener('change', handleEnableChange); githubUsernameElement.addEventListener('keyup', handleGithubUsernameChange); projectNameElement.addEventListener('keyup', handleProjectNameChange); startingDateElement.addEventListener('change', handleStartingDateChange); endingDateElement.addEventListener('change', handleEndingDateChange); lastWeekContributionElement.addEventListener('change', handleLastWeekContributionChange); +yesterdayContributionElement.addEventListener('change', handleYesterdayContributionChange); showOpenLabelElement.addEventListener('change', handleOpenLabelChange); userReasonElement.addEventListener('keyup', handleUserReasonChange); -document.addEventListener('DOMContentLoaded', handleBodyOnLoad); -document.getElementById('codeheatTab').addEventListener('click', handleCodeheatClick); -document.getElementById('gsocTab').addEventListener('click', handleGsocClick); +document.addEventListener('DOMContentLoaded', handleBodyOnLoad); \ No newline at end of file diff --git a/src/scripts/popup.js b/src/scripts/popup.js index a9c2b4e..254a1d6 100644 --- a/src/scripts/popup.js +++ b/src/scripts/popup.js @@ -1,25 +1,84 @@ +function getLastWeek() { + var today = new Date(); + var lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7); + var lastWeekMonth = lastWeek.getMonth() + 1; + var lastWeekDay = lastWeek.getDate(); + var lastWeekYear = lastWeek.getFullYear(); + var lastWeekDisplayPadded = + ('0000' + lastWeekYear.toString()).slice(-4) + + '-' + + ('00' + lastWeekMonth.toString()).slice(-2) + + '-' + + ('00' + lastWeekDay.toString()).slice(-2); + return lastWeekDisplayPadded; +} + +function getToday() { + var today = new Date(); + var WeekMonth = today.getMonth() + 1; + var WeekDay = today.getDate(); + var WeekYear = today.getFullYear(); + var WeekDisplayPadded = + ('0000' + WeekYear.toString()).slice(-4) + + '-' + + ('00' + WeekMonth.toString()).slice(-2) + + '-' + + ('00' + WeekDay.toString()).slice(-2); + return WeekDisplayPadded; +} + +function getYesterday() { + let today = new Date(); + let yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); + let yesterdayMonth = yesterday.getMonth() + 1; + let yesterdayDay = yesterday.getDate(); + let yesterdayYear = yesterday.getFullYear(); + let yesterdayPadded = + ('0000' + yesterdayYear.toString()).slice(-4) + + '-' + + ('00' + yesterdayMonth.toString()).slice(-2) + + '-' + + ('00' + yesterdayDay.toString()).slice(-2); + return yesterdayPadded; +} + document.addEventListener('DOMContentLoaded', function() { + // Dark mode setup + const darkModeToggle = document.querySelector('img[alt="Night Mode"]'); + const body = document.body; + + chrome.storage.local.get(['darkMode'], function(result) { + if(result.darkMode) { + body.classList.add('dark-mode'); + darkModeToggle.src = 'icons/light-mode.png'; + } + }); + + darkModeToggle.addEventListener('click', function() { + body.classList.toggle('dark-mode'); + const isDarkMode = body.classList.contains('dark-mode'); + chrome.storage.local.set({ darkMode: isDarkMode }); + this.src = isDarkMode ? 'icons/light-mode.png' : 'icons/night-mode.png'; + }); + + // Button setup const generateBtn = document.getElementById('generateReport'); const copyBtn = document.getElementById('copyReport'); generateBtn.addEventListener('click', function() { this.innerHTML = ' Generating...'; this.disabled = true; - window.generateScrumReport(); }); copyBtn.addEventListener('click', function() { const scrumReport = document.getElementById('scrumReport'); - - // Create container for HTML content const tempDiv = document.createElement('div'); tempDiv.innerHTML = scrumReport.innerHTML; document.body.appendChild(tempDiv); tempDiv.style.position = 'absolute'; tempDiv.style.left = '-9999px'; - // Select the content const range = document.createRange(); range.selectNode(tempDiv); const selection = window.getSelection(); @@ -27,19 +86,136 @@ document.addEventListener('DOMContentLoaded', function() { selection.addRange(range); try { - // Copy HTML content - const success = document.execCommand('copy'); - if (!success) { - throw new Error('Copy command failed'); - } - Materialize.toast('Report copied with formatting!', 3000, 'green'); + document.execCommand('copy'); + this.innerHTML = ' Copied!'; + setTimeout(() => { + this.innerHTML = ' Copy Report'; + }, 2000); } catch (err) { - console.error('Failed to copy:', err); - Materialize.toast('Failed to copy report', 3000, 'red'); + console.error('Failed to copy: ', err); } finally { - // Cleanup selection.removeAllRanges(); document.body.removeChild(tempDiv); } }); -}); \ No newline at end of file + + // Custom date container click handler + document.getElementById('customDateContainer').addEventListener('click', () => { + document.querySelectorAll('input[name="timeframe"]').forEach(radio => { + radio.checked = false + radio.dataset.wasChecked = 'false' + }); + + const startDateInput = document.getElementById('startingDate'); + const endDateInput = document.getElementById('endingDate'); + startDateInput.disabled = false; + endDateInput.disabled = false; + + chrome.storage.local.set({ + lastWeekContribution: false, + yesterdayContribution: false, + selectedTimeframe: null + }); + }); + + chrome.storage.local.get([ + 'selectedTimeframe', + 'lastWeekContribution', + 'yesterdayContribution' + ], (items) => { + console.log('Restoring state:', items); + + if (!items.selectedTimeframe) { + items.selectedTimeframe = 'yesterdayContribution'; + items.lastWeekContribution = false; + items.yesterdayContribution = true; + } + + const radio = document.getElementById(items.selectedTimeframe); + if (radio) { + radio.checked = true; + radio.dataset.wasChecked = 'true'; + + const startDateInput = document.getElementById('startingDate'); + const endDateInput = document.getElementById('endingDate'); + + if (items.selectedTimeframe === 'lastWeekContribution') { + startDateInput.value = getLastWeek(); + endDateInput.value = getToday(); + } else { + startDateInput.value = getYesterday(); + endDateInput.value = getToday(); + } + + startDateInput.disabled = endDateInput.disabled = true; + + chrome.storage.local.set({ + startingDate: startDateInput.value, + endingDate: endDateInput.value, + lastWeekContribution: items.selectedTimeframe === 'lastWeekContribution', + yesterdayContribution: items.selectedTimeframe === 'yesterdayContribution', + selectedTimeframe: items.selectedTimeframe + }); + } + }); + + // Radio button click handlers with toggle functionality + document.querySelectorAll('input[name="timeframe"]').forEach(radio => { + radio.addEventListener('click', function() { + if (this.dataset.wasChecked === 'true') { + this.checked = false; + this.dataset.wasChecked = 'false'; + + const startDateInput = document.getElementById('startingDate'); + const endDateInput = document.getElementById('endingDate'); + startDateInput.disabled = false; + endDateInput.disabled = false; + + chrome.storage.local.set({ + lastWeekContribution: false, + yesterdayContribution: false, + selectedTimeframe: null + }); + } else { + document.querySelectorAll('input[name="timeframe"]').forEach(r => { + r.dataset.wasChecked = 'false'; + }); + this.dataset.wasChecked = 'true'; + toggleRadio(this); + } + }); + }); +}); + +function toggleRadio(radio) { + const startDateInput = document.getElementById('startingDate'); + const endDateInput = document.getElementById('endingDate'); + + console.log('Toggling radio:', radio.id); + + if (radio.id === 'lastWeekContribution') { + startDateInput.value = getLastWeek(); + endDateInput.value = getToday(); + } else if (radio.id === 'yesterdayContribution') { + startDateInput.value = getYesterday(); + endDateInput.value = getToday(); + } + + startDateInput.disabled = endDateInput.disabled = true; + + chrome.storage.local.set({ + startingDate: startDateInput.value, + endingDate: endDateInput.value, + lastWeekContribution: radio.id === 'lastWeekContribution', + yesterdayContribution: radio.id === 'yesterdayContribution', + selectedTimeframe: radio.id, + githubCache: null // Clear cache to force new fetch + }, () => { + console.log('State saved, dates:', { + start: startDateInput.value, + end: endDateInput.value, + isLastWeek: radio.id === 'lastWeekContribution' + }); + // window.generateScrumReport(); + }); +} \ No newline at end of file diff --git a/src/scripts/scrumHelper.js b/src/scripts/scrumHelper.js index 9b83502..b9f1e13 100644 --- a/src/scripts/scrumHelper.js +++ b/src/scripts/scrumHelper.js @@ -15,13 +15,13 @@ function allIncluded(outputTarget = 'email') { var reviewedPrsArray = []; var githubIssuesData = null; var lastWeekContribution = false; + let yesterdayContribution = false; var githubPrsReviewData = null; var githubUserData = null; var githubPrsReviewDataProcessed = {}; var showOpenLabel = true; var showClosedLabel = true; var userReason = ''; - var gsoc = 0; //0 means codeheat. 1 means gsoc var pr_merged_button = '
closed
'; @@ -46,21 +46,20 @@ function allIncluded(outputTarget = 'email') { 'showOpenLabel', 'showClosedLabel', 'lastWeekContribution', + 'yesterdayContribution', 'userReason', - 'gsoc', ], (items) => { console.log("Storage items received:", items); - if (items.gsoc) { - //gsoc - gsoc = 1; - } else { - gsoc = 0; //codeheat - } + if (items.lastWeekContribution) { lastWeekContribution = true; handleLastWeekContributionChange(); } + if (items.yesterdayContribution) { + yesterdayContribution = true; + handleYesterdayContributionChange(); + } if (!items.enableToggle) { enableToggle = items.enableToggle; } @@ -70,6 +69,12 @@ function allIncluded(outputTarget = 'email') { if (items.startingDate && !lastWeekContribution) { startingDate = items.startingDate; } + if (items.endingDate && !yesterdayContribution){ + endingDate = items.endingDate; + } + if (items.startingDate && !yesterdayContribution){ + startingDate = items.startingDate; + } if (items.githubUsername) { githubUsername = items.githubUsername; console.log("About to fetch GitHub data for:", githubUsername); @@ -118,10 +123,13 @@ function allIncluded(outputTarget = 'email') { endingDate = getToday(); startingDate = getLastWeek(); } + function handleYesterdayContributionChange() { + endingDate = getToday(); + startingDate = getYesterday(); + } function getLastWeek() { var today = new Date(); - var noDays_to_goback = gsoc == 0 ? 7 : 1; - var lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - noDays_to_goback); + var lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7); var lastWeekMonth = lastWeek.getMonth() + 1; var lastWeekDay = lastWeek.getDate(); var lastWeekYear = lastWeek.getFullYear(); @@ -133,6 +141,20 @@ function allIncluded(outputTarget = 'email') { ('00' + lastWeekDay.toString()).slice(-2); return lastWeekDisplayPadded; } + function getYesterday() { + let today = new Date(); + let yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); + let yesterdayMonth = yesterday.getMonth() + 1; + let yesterdayWeekDay = yesterday.getDate(); + let yesterdayYear = yesterday.getFullYear(); + let yesterdayPadded = + ('0000' + yesterdayYear.toString()).slice(-4) + + '-' + + ('00' + yesterdayMonth.toString()).slice(-2) + + '-' + + ('00' + yesterdayWeekDay.toString()).slice(-2); + return yesterdayPadded; + } function getToday() { var today = new Date(); var Week = new Date(today.getFullYear(), today.getMonth(), today.getDate()); @@ -247,24 +269,24 @@ function allIncluded(outputTarget = 'email') { for (i = 0; i < nextWeekArray.length; i++) nextWeekUl += nextWeekArray[i]; nextWeekUl += ''; - var weekOrDay = gsoc == 1 ? 'yesterday' : 'last week'; - var weekOrDay2 = gsoc == 1 ? 'today' : 'this week'; + var weekOrDay = lastWeekContribution ? 'last week' : (yesterdayContribution ? 'yesterday' : 'the period'); + var weekOrDay2 = lastWeekContribution ? 'this week' : 'today'; // Create the complete content let content; - if (lastWeekContribution == true) { + if (lastWeekContribution == true || yesterdayContribution == true ) { content = `1. What did I do ${weekOrDay}?
${lastWeekUl}
-2. What I plan to do ${weekOrDay2}?
+2. What do I plan to do ${weekOrDay2}?
${nextWeekUl}
-3. What is stopping me from doing my work?
+3. What is blocking me from making progress?
${userReason}`; } else { content = `1. What did I do from ${formatDate(startingDate)} to ${formatDate(endingDate)}?
${lastWeekUl}
-2. What I plan to do ${weekOrDay2}?
+2. What do I plan to do ${weekOrDay2}?
${nextWeekUl}
-3. What is stopping me from doing my work?
+3. What is blocking me from making progress?
${userReason}`; } @@ -378,7 +400,6 @@ ${userReason}`; } else { repoLi += 'PR - '; } - if (githubPrsReviewDataProcessed[repo].length <= 1) { for (var pr in githubPrsReviewDataProcessed[repo]) { var pr_arr = githubPrsReviewDataProcessed[repo][pr]; diff --git a/src/tailwindcss.css b/src/tailwindcss.css new file mode 100644 index 0000000..3bebcb8 --- /dev/null +++ b/src/tailwindcss.css @@ -0,0 +1,863 @@ +/*! tailwindcss v4.1.3 | MIT License | https://tailwindcss.com */ +@layer properties; +@layer theme, base, components, utilities; +@layer theme { + :root, :host { + --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", + "Courier New", monospace; + --color-green-400: oklch(79.2% 0.209 151.711); + --color-green-600: oklch(62.7% 0.194 149.214); + --color-blue-300: oklch(80.9% 0.105 251.813); + --color-blue-600: oklch(54.6% 0.245 262.881); + --color-blue-700: oklch(48.8% 0.243 264.376); + --color-blue-800: oklch(42.4% 0.199 265.638); + --color-gray-100: oklch(96.7% 0.003 264.542); + --color-gray-200: oklch(92.8% 0.006 264.531); + --color-gray-300: oklch(87.2% 0.01 258.338); + --color-gray-600: oklch(44.6% 0.03 256.802); + --color-gray-700: oklch(37.3% 0.034 259.733); + --color-gray-800: oklch(27.8% 0.033 256.848); + --color-black: #000; + --color-white: #fff; + --spacing: 0.25rem; + --text-xs: 0.75rem; + --text-xs--line-height: calc(1 / 0.75); + --text-sm: 0.875rem; + --text-sm--line-height: calc(1.25 / 0.875); + --text-base: 1rem; + --text-base--line-height: calc(1.5 / 1); + --text-xl: 1.25rem; + --text-xl--line-height: calc(1.75 / 1.25); + --text-3xl: 1.875rem; + --text-3xl--line-height: calc(2.25 / 1.875); + --font-weight-medium: 500; + --font-weight-semibold: 600; + --radius-xl: 0.75rem; + --radius-2xl: 1rem; + --radius-3xl: 1.5rem; + --ease-in: cubic-bezier(0.4, 0, 1, 1); + --ease-out: cubic-bezier(0, 0, 0.2, 1); + --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); + --default-transition-duration: 150ms; + --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + --default-font-family: var(--font-sans); + --default-mono-font-family: var(--font-mono); + } +} +@layer base { + *, ::after, ::before, ::backdrop, ::file-selector-button { + box-sizing: border-box; + margin: 0; + padding: 0; + border: 0 solid; + } + html, :host { + line-height: 1.5; + -webkit-text-size-adjust: 100%; + tab-size: 4; + font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); + font-feature-settings: var(--default-font-feature-settings, normal); + font-variation-settings: var(--default-font-variation-settings, normal); + -webkit-tap-highlight-color: transparent; + } + hr { + height: 0; + color: inherit; + border-top-width: 1px; + } + abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + } + h1, h2, h3, h4, h5, h6 { + font-size: inherit; + font-weight: inherit; + } + a { + color: inherit; + -webkit-text-decoration: inherit; + text-decoration: inherit; + } + b, strong { + font-weight: bolder; + } + code, kbd, samp, pre { + font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace); + font-feature-settings: var(--default-mono-font-feature-settings, normal); + font-variation-settings: var(--default-mono-font-variation-settings, normal); + font-size: 1em; + } + small { + font-size: 80%; + } + sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; + } + sub { + bottom: -0.25em; + } + sup { + top: -0.5em; + } + table { + text-indent: 0; + border-color: inherit; + border-collapse: collapse; + } + :-moz-focusring { + outline: auto; + } + progress { + vertical-align: baseline; + } + summary { + display: list-item; + } + ol, ul, menu { + list-style: none; + } + img, svg, video, canvas, audio, iframe, embed, object { + display: block; + vertical-align: middle; + } + img, video { + max-width: 100%; + height: auto; + } + button, input, select, optgroup, textarea, ::file-selector-button { + font: inherit; + font-feature-settings: inherit; + font-variation-settings: inherit; + letter-spacing: inherit; + color: inherit; + border-radius: 0; + background-color: transparent; + opacity: 1; + } + :where(select:is([multiple], [size])) optgroup { + font-weight: bolder; + } + :where(select:is([multiple], [size])) optgroup option { + padding-inline-start: 20px; + } + ::file-selector-button { + margin-inline-end: 4px; + } + ::placeholder { + opacity: 1; + } + @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) { + ::placeholder { + color: currentcolor; + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, currentcolor 50%, transparent); + } + } + } + textarea { + resize: vertical; + } + ::-webkit-search-decoration { + -webkit-appearance: none; + } + ::-webkit-date-and-time-value { + min-height: 1lh; + text-align: inherit; + } + ::-webkit-datetime-edit { + display: inline-flex; + } + ::-webkit-datetime-edit-fields-wrapper { + padding: 0; + } + ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field { + padding-block: 0; + } + :-moz-ui-invalid { + box-shadow: none; + } + button, input:where([type="button"], [type="reset"], [type="submit"]), ::file-selector-button { + appearance: button; + } + ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { + height: auto; + } + [hidden]:where(:not([hidden="until-found"])) { + display: none !important; + } +} +@layer utilities { + .collapse { + visibility: collapse; + } + .visible { + visibility: visible; + } + .sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + .absolute { + position: absolute; + } + .fixed { + position: fixed; + } + .relative { + position: relative; + } + .static { + position: static; + } + .container { + width: 100%; + @media (width >= 40rem) { + max-width: 40rem; + } + @media (width >= 48rem) { + max-width: 48rem; + } + @media (width >= 64rem) { + max-width: 64rem; + } + @media (width >= 80rem) { + max-width: 80rem; + } + @media (width >= 96rem) { + max-width: 96rem; + } + } + .mx-2 { + margin-inline: calc(var(--spacing) * 2); + } + .mx-3 { + margin-inline: calc(var(--spacing) * 3); + } + .mx-4 { + margin-inline: calc(var(--spacing) * 4); + } + .my-2 { + margin-block: calc(var(--spacing) * 2); + } + .my-4 { + margin-block: calc(var(--spacing) * 4); + } + .mt-1 { + margin-top: calc(var(--spacing) * 1); + } + .mt-2 { + margin-top: calc(var(--spacing) * 2); + } + .mt-3 { + margin-top: calc(var(--spacing) * 3); + } + .mb-0 { + margin-bottom: calc(var(--spacing) * 0); + } + .mb-2 { + margin-bottom: calc(var(--spacing) * 2); + } + .block { + display: block; + } + .contents { + display: contents; + } + .flex { + display: flex; + } + .grid { + display: grid; + } + .hidden { + display: none; + } + .inline { + display: inline; + } + .inline-block { + display: inline-block; + } + .list-item { + display: list-item; + } + .table { + display: table; + } + .table-row { + display: table-row; + } + .table-row-group { + display: table-row-group; + } + .h-4 { + height: calc(var(--spacing) * 4); + } + .h-6 { + height: calc(var(--spacing) * 6); + } + .h-7 { + height: calc(var(--spacing) * 7); + } + .min-h-\[200px\] { + min-height: 200px; + } + .w-4 { + width: calc(var(--spacing) * 4); + } + .w-7 { + width: calc(var(--spacing) * 7); + } + .w-11 { + width: calc(var(--spacing) * 11); + } + .w-full { + width: 100%; + } + .border-collapse { + border-collapse: collapse; + } + .transform { + transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y); + } + .cursor-pointer { + cursor: pointer; + } + .resize { + resize: both; + } + .list-inside { + list-style-position: inside; + } + .list-disc { + list-style-type: disc; + } + .items-center { + align-items: center; + } + .justify-between { + justify-content: space-between; + } + .justify-center { + justify-content: center; + } + .gap-2 { + gap: calc(var(--spacing) * 2); + } + .overflow-y-auto { + overflow-y: auto; + } + .rounded { + border-radius: 0.25rem; + } + .rounded-2xl { + border-radius: var(--radius-2xl); + } + .rounded-3xl { + border-radius: var(--radius-3xl); + } + .rounded-full { + border-radius: calc(infinity * 1px); + } + .rounded-xl { + border-radius: var(--radius-xl); + } + .border { + border-style: var(--tw-border-style); + border-width: 1px; + } + .border-2 { + border-style: var(--tw-border-style); + border-width: 2px; + } + .border-t-2 { + border-top-style: var(--tw-border-style); + border-top-width: 2px; + } + .border-black { + border-color: var(--color-black); + } + .border-gray-100 { + border-color: var(--color-gray-100); + } + .border-gray-200 { + border-color: var(--color-gray-200); + } + .border-gray-700 { + border-color: var(--color-gray-700); + } + .bg-blue-600 { + background-color: var(--color-blue-600); + } + .bg-gray-100 { + background-color: var(--color-gray-100); + } + .bg-gray-200 { + background-color: var(--color-gray-200); + } + .bg-green-400 { + background-color: var(--color-green-400); + } + .bg-green-600 { + background-color: var(--color-green-600); + } + .bg-white { + background-color: var(--color-white); + } + .p-1 { + padding: calc(var(--spacing) * 1); + } + .p-2 { + padding: calc(var(--spacing) * 2); + } + .px-4 { + padding-inline: calc(var(--spacing) * 4); + } + .py-1 { + padding-block: calc(var(--spacing) * 1); + } + .py-2 { + padding-block: calc(var(--spacing) * 2); + } + .py-4 { + padding-block: calc(var(--spacing) * 4); + } + .pl-1 { + padding-left: calc(var(--spacing) * 1); + } + .text-3xl { + font-size: var(--text-3xl); + line-height: var(--tw-leading, var(--text-3xl--line-height)); + } + .text-base { + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + } + .text-sm { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } + .text-xl { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + } + .text-xs { + font-size: var(--text-xs); + line-height: var(--tw-leading, var(--text-xs--line-height)); + } + .font-medium { + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + } + .font-semibold { + --tw-font-weight: var(--font-weight-semibold); + font-weight: var(--font-weight-semibold); + } + .whitespace-pre-wrap { + white-space: pre-wrap; + } + .text-blue-600 { + color: var(--color-blue-600); + } + .text-gray-700 { + color: var(--color-gray-700); + } + .text-gray-800 { + color: var(--color-gray-800); + } + .text-white { + color: var(--color-white); + } + .underline { + text-decoration-line: underline; + } + .outline { + outline-style: var(--tw-outline-style); + outline-width: 1px; + } + .blur { + --tw-blur: blur(8px); + filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); + } + .filter { + filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); + } + .ease-in { + --tw-ease: var(--ease-in); + transition-timing-function: var(--ease-in); + } + .ease-in-out { + --tw-ease: var(--ease-in-out); + transition-timing-function: var(--ease-in-out); + } + .ease-out { + --tw-ease: var(--ease-out); + transition-timing-function: var(--ease-out); + } + .peer-checked\:bg-blue-600 { + &:is(:where(.peer):checked ~ *) { + background-color: var(--color-blue-600); + } + } + .peer-focus\:ring-blue-300 { + &:is(:where(.peer):focus ~ *) { + --tw-ring-color: var(--color-blue-300); + } + } + .after\:absolute { + &::after { + content: var(--tw-content); + position: absolute; + } + } + .after\:start-\[2px\] { + &::after { + content: var(--tw-content); + inset-inline-start: 2px; + } + } + .after\:top-0\.5 { + &::after { + content: var(--tw-content); + top: calc(var(--spacing) * 0.5); + } + } + .after\:h-5 { + &::after { + content: var(--tw-content); + height: calc(var(--spacing) * 5); + } + } + .after\:w-5 { + &::after { + content: var(--tw-content); + width: calc(var(--spacing) * 5); + } + } + .after\:rounded-full { + &::after { + content: var(--tw-content); + border-radius: calc(infinity * 1px); + } + } + .after\:border { + &::after { + content: var(--tw-content); + border-style: var(--tw-border-style); + border-width: 1px; + } + } + .after\:border-gray-300 { + &::after { + content: var(--tw-content); + border-color: var(--color-gray-300); + } + } + .after\:bg-white { + &::after { + content: var(--tw-content); + background-color: var(--color-white); + } + } + .after\:transition-all { + &::after { + content: var(--tw-content); + transition-property: all; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + } + .after\:content-\[\'\'\] { + &::after { + content: var(--tw-content); + --tw-content: ''; + content: var(--tw-content); + } + } + .peer-checked\:after\:translate-x-full { + &:is(:where(.peer):checked ~ *) { + &::after { + content: var(--tw-content); + --tw-translate-x: 100%; + translate: var(--tw-translate-x) var(--tw-translate-y); + } + } + } + .peer-checked\:after\:border-white { + &:is(:where(.peer):checked ~ *) { + &::after { + content: var(--tw-content); + border-color: var(--color-white); + } + } + } + .hover\:bg-blue-700 { + &:hover { + @media (hover: hover) { + background-color: var(--color-blue-700); + } + } + } + .rtl\:peer-checked\:after\:-translate-x-full { + &:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) { + &:is(:where(.peer):checked ~ *) { + &::after { + content: var(--tw-content); + --tw-translate-x: -100%; + translate: var(--tw-translate-x) var(--tw-translate-y); + } + } + } + } + .dark\:border-gray-600 { + @media (prefers-color-scheme: dark) { + border-color: var(--color-gray-600); + } + } + .dark\:bg-gray-700 { + @media (prefers-color-scheme: dark) { + background-color: var(--color-gray-700); + } + } + .dark\:peer-checked\:bg-blue-600 { + @media (prefers-color-scheme: dark) { + &:is(:where(.peer):checked ~ *) { + background-color: var(--color-blue-600); + } + } + } + .dark\:peer-focus\:ring-blue-800 { + @media (prefers-color-scheme: dark) { + &:is(:where(.peer):focus ~ *) { + --tw-ring-color: var(--color-blue-800); + } + } + } +} +body { + margin: 0; + padding: 0; + background-color: rgba(251, 251, 251, 0.6); +} +* { + box-sizing: border-box; +} +.datepicker { + margin-bottom: 5px !important; +} +.tabs .tab a:hover, .tabs .tab a.active { + background-color: transparent; + color: #3f51b5; +} +.tabs { + background-color: transparent; +} +.tabs .tab a { + color: #3f51b5; +} +.tabs .indicator { + background-color: #3f51b5; +} +.switch label input[type="checkbox"]:checked + .lever { + background-color: #3f51b5; +} +.switch label input[type="checkbox"]:checked + .lever:after { + background-color: #fcfcfc; + left: 24px; +} +[type="checkbox"].filled-in:checked + label:after { + border: 2px solid #3f51b5; + background-color: #3f51b5; +} +.btn:hover, .btn-large:hover { + background-color: #3f51b5; +} +a { + color: #3f51b5; +} +.btn, .btn-large { + background-color: #3f51b5; +} +li { + list-style-type: disc !important; + margin-left: 1rem; +} +.dark-mode { + background: #1a1a1a !important; + color: #ffffff !important; +} +.dark-mode .bg-white { + background-color: #2d2d2d !important; + border-color: #404040 !important; +} +.dark-mode input[type="text"], .dark-mode input[type="date"], .dark-mode #scrumReport { + background-color: #404040 !important; + border-color: #505050 !important; + color: #ffffff !important; +} +.dark-mode h3, .dark-mode h4, .dark-mode p, .dark-mode label { + color: #ffffff !important; +} +.dark-mode hr { + border-color: #505050 !important; +} +@property --tw-rotate-x { + syntax: "*"; + inherits: false; + initial-value: rotateX(0); +} +@property --tw-rotate-y { + syntax: "*"; + inherits: false; + initial-value: rotateY(0); +} +@property --tw-rotate-z { + syntax: "*"; + inherits: false; + initial-value: rotateZ(0); +} +@property --tw-skew-x { + syntax: "*"; + inherits: false; + initial-value: skewX(0); +} +@property --tw-skew-y { + syntax: "*"; + inherits: false; + initial-value: skewY(0); +} +@property --tw-border-style { + syntax: "*"; + inherits: false; + initial-value: solid; +} +@property --tw-font-weight { + syntax: "*"; + inherits: false; +} +@property --tw-outline-style { + syntax: "*"; + inherits: false; + initial-value: solid; +} +@property --tw-blur { + syntax: "*"; + inherits: false; +} +@property --tw-brightness { + syntax: "*"; + inherits: false; +} +@property --tw-contrast { + syntax: "*"; + inherits: false; +} +@property --tw-grayscale { + syntax: "*"; + inherits: false; +} +@property --tw-hue-rotate { + syntax: "*"; + inherits: false; +} +@property --tw-invert { + syntax: "*"; + inherits: false; +} +@property --tw-opacity { + syntax: "*"; + inherits: false; +} +@property --tw-saturate { + syntax: "*"; + inherits: false; +} +@property --tw-sepia { + syntax: "*"; + inherits: false; +} +@property --tw-drop-shadow { + syntax: "*"; + inherits: false; +} +@property --tw-drop-shadow-color { + syntax: "*"; + inherits: false; +} +@property --tw-drop-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} +@property --tw-drop-shadow-size { + syntax: "*"; + inherits: false; +} +@property --tw-ease { + syntax: "*"; + inherits: false; +} +@property --tw-content { + syntax: "*"; + initial-value: ""; + inherits: false; +} +@property --tw-translate-x { + syntax: "*"; + inherits: false; + initial-value: 0; +} +@property --tw-translate-y { + syntax: "*"; + inherits: false; + initial-value: 0; +} +@property --tw-translate-z { + syntax: "*"; + inherits: false; + initial-value: 0; +} +@layer properties { + @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) { + *, ::before, ::after, ::backdrop { + --tw-rotate-x: rotateX(0); + --tw-rotate-y: rotateY(0); + --tw-rotate-z: rotateZ(0); + --tw-skew-x: skewX(0); + --tw-skew-y: skewY(0); + --tw-border-style: solid; + --tw-font-weight: initial; + --tw-outline-style: solid; + --tw-blur: initial; + --tw-brightness: initial; + --tw-contrast: initial; + --tw-grayscale: initial; + --tw-hue-rotate: initial; + --tw-invert: initial; + --tw-opacity: initial; + --tw-saturate: initial; + --tw-sepia: initial; + --tw-drop-shadow: initial; + --tw-drop-shadow-color: initial; + --tw-drop-shadow-alpha: 100%; + --tw-drop-shadow-size: initial; + --tw-ease: initial; + --tw-content: ""; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-translate-z: 0; + } + } +} diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..e6aec75 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,9 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./src/**/*.{html,js}"], // adjust if needed + theme: { + extend: {}, + }, + plugins: [], + }; + \ No newline at end of file