diff --git a/css/styles.css b/css/styles.css index ba97049f7..c997ff0a8 100644 --- a/css/styles.css +++ b/css/styles.css @@ -1243,3 +1243,174 @@ html[data-view='flexible-day'] .footer .punch-button { html[data-view='flexible-day'] .punch-button img { display: none; } + + + + + +.switch { + position: relative; + width: 3.75rem; /* Half of the original width */ + height: 2rem; /* Half of the original height */ +} + +.switch input { + position: absolute; + top: 0; + left: 0; + z-index: 2; + opacity: 0; +} + +.switch label { + cursor: pointer; +} + +.background { + z-index: 1; + position: absolute; + width: 3.75rem; + height: 2rem; + border-radius: 1.25rem; /* Half of the original border-radius */ + border: 0.125rem solid #202020; /* Half of the original border thickness */ + background: linear-gradient(to right, #484848 0%, #202020 100%); + transition: all 0.3s; +} + +.switch input:checked ~ .fill { + background: #E9F8FD; +} + +.stars1, +.stars2 { + position: absolute; + height: 0.2rem; /* Half of the original height */ + width: 0.2rem; /* Half of the original width */ + background: #FFFFFF; + border-radius: 50%; + transition: 0.3s all ease; +} + +.stars1 { + top: 3px; + right: 11.5px; +} + +.stars2 { + top: 20px; + right: 24px; +} + +.stars1:after, +.stars1:before, +.stars2:after, +.stars2:before { + position: absolute; + content: ""; + display: block; + height: 0.125rem; /* Half of the original size */ + width: 0.125rem; /* Half of the original size */ + background: #FFFFFF; + border-radius: 50%; + transition: 0.2s all ease; +} + +.stars1:after { + top: 4px; + right: 10px; +} + +.stars1:before { + top: 9px; + right: -6px; +} + +.stars2:after { + top: -4px; + right: -8px; +} + +.stars2:before { + top: 3px; + right: -13px; +} + +.sun-moon { + z-index: 2; + position: absolute; + left: 0; + display: inline-block; + height: 1.5rem; /* Half of the original height */ + width: 1.5rem; /* Half of the original width */ + margin: 0.25rem; /* Half of the original margin */ + background: #FFFDF2; + border-radius: 50%; + transition: all 0.5s ease; + border: 0.125rem solid #DEE2C6; /* Half of the original border thickness */ +} + +.sun-moon .dots { + position: absolute; + top: 1.5px; + left: 11.5px; + height: 0.5rem; /* Half of the original height */ + width: 0.5rem; /* Half of the original width */ + background: #EFEEDB; + border: 0.125rem solid #DEE2C6; /* Half of the original border thickness */ + border-radius: 50%; + transition: 0.4s all ease; +} + +.sun-moon .dots:after, +.sun-moon .dots:before { + position: absolute; + content: ""; + display: block; + height: 0.5rem; /* Half of the original size */ + width: 0.5rem; /* Half of the original size */ + background: #EFEEDB; + border: 0.125rem solid #DEE2C6; /* Half of the original border thickness */ + border-radius: 50%; + transition: 0.4s all ease; +} + + + +.sun-moon .dots:before { + top: 2.5px; + left: -4px; +} + +/* Transition to Sun */ +.switch input:checked ~ .sun-moon { + left: calc(100% - 2rem); /* Adjusted left value */ + background: #F5EC59; + border-color: #E7C65C; + transform: rotate(-25deg); +} + +.switch input:checked ~ .sun-moon .dots, +.switch input:checked ~ .sun-moon .dots:after, +.switch input:checked ~ .sun-moon .dots:before { + background: #FFFFFF; + border-color: #FFFFFF; +} + +.switch input:checked ~ .sun-moon .dots { + height: 0.75rem; /* Adjusted height */ + width: 0.75rem; /* Adjusted width */ + top: 0px; + left: -10px; /* Adjusted left value */ + transform: rotate(25deg); +} + +.switch input:checked ~ .background .stars1, +.switch input:checked ~ .background .stars2 { + opacity: 0; + transform: translateY(1rem); /* Adjusted translateY value */ +} + +.switch input:checked ~ .background { + border: 0.125rem solid #78C1D5; /* Half of the original border thickness */ + background: linear-gradient(to right, #78C1D5 0%, #BBE7F5 100%); +} diff --git a/renderer/classes/FlexibleDayCalendar.js b/renderer/classes/FlexibleDayCalendar.js index 6baa64e2c..ea4550762 100644 --- a/renderer/classes/FlexibleDayCalendar.js +++ b/renderer/classes/FlexibleDayCalendar.js @@ -17,29 +17,52 @@ class FlexibleDayCalendar extends BaseCalendar * @param {Object.} preferences * @param {Object.} languageData */ - constructor(preferences, languageData) - { + constructor(preferences, languageData) { super(preferences, languageData); + this._currentTheme = localStorage.getItem('theme') || 'light'; // Load theme from localStorage or default to 'light' } /** * Initializes the calendar by generating the html code, binding JS events and then drawing according to DB. */ - _initCalendar() - { + _initCalendar() { this._generateTemplate(); + this._bindEvents(); + this._applyInitialTheme(); // Apply the stored or default theme on initialization + } + + _bindEvents() { $('#next-day').on('click', () => { this._nextDay(); }); $('#prev-day').on('click', () => { this._prevDay(); }); $('#switch-view').on('click', () => { this._switchView(); }); $('#current-day').on('click', () => { this._goToCurrentDate(); }); - $('#input-calendar-date').on('change', (event) => - { + $('#input-calendar-date').on('change', (event) => { const [year, month, day] = $(event.target).val().split('-'); - this._goToDate(new Date(year, month-1, day)); + this._goToDate(new Date(year, month - 1, day)); + }); + this._setupThemeToggle(); + } + + _setupThemeToggle() { + const themeToggle = document.getElementById('toggle'); + themeToggle.addEventListener('change', () => { + if (themeToggle.checked) { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } else { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } }); } + _applyInitialTheme() { + document.documentElement.setAttribute('data-theme', this._currentTheme); + const themeToggle = document.getElementById('toggle'); + themeToggle.checked = this._currentTheme === 'dark'; + } + /** * Generates the calendar HTML view. */ @@ -48,32 +71,48 @@ class FlexibleDayCalendar extends BaseCalendar const body = this._getBody(); $('#calendar').html(body); $('html').attr('data-view', 'flexible-day'); + $('#calendar').html(this._getBody()); + $('html').attr('data-view', 'flexible-day'); } /** * Returns the header of the page, with the image, name and a message. * @return {string} */ - _getPageHeader() - { + _getPageHeader() { const switchView = ``; const todayBut = ``; const leftBut = ``; const rightBut = ``; const title = 'Time to Leave'; - return '
'+ - '
' + + const themeToggleButton = ` +
+
+ +
+
`; + + // Theme toggle button moved to the left of the logo + return '
' + + `
` + `
${title}
` + '
' + '
' + - '' + + '
' + + `${themeToggleButton}` + '' + '' + '' + '' + '' + - '
' + switchView + '' + leftBut + '
' + rightBut + '' + todayBut + '
'; + ''; } + /** * Returns the template code of the body of the page. @@ -720,6 +759,8 @@ class FlexibleDayCalendar extends BaseCalendar } return targetDate; } + + } export { diff --git a/renderer/classes/FlexibleMonthCalendar.js b/renderer/classes/FlexibleMonthCalendar.js index 4bb413de1..be3af3a6c 100644 --- a/renderer/classes/FlexibleMonthCalendar.js +++ b/renderer/classes/FlexibleMonthCalendar.js @@ -22,21 +22,43 @@ class FlexibleMonthCalendar extends BaseCalendar * @param {Object.} preferences * @param {Object.} languageData */ - constructor(preferences, languageData) - { + constructor(preferences, languageData) { super(preferences, languageData); + this._currentTheme = localStorage.getItem('theme') || 'light'; // Load theme from localStorage or default to 'light' } - /** - * Initializes the calendar by generating the html code, binding JS events and then drawing according to DB. - */ - _initCalendar() - { + _initCalendar() { this._generateTemplate(); + this._bindEvents(); + this._applyInitialTheme(); // Apply the stored or default theme on initialization + } + + + _bindEvents() { $('#next-month').on('click', () => { this._nextMonth(); }); $('#prev-month').on('click', () => { this._prevMonth(); }); $('#current-month').on('click', () => { this._goToCurrentDate(); }); $('#switch-view').on('click', () => { this._switchView(); }); + this._setupThemeToggle(); + } + + _setupThemeToggle() { + const themeToggle = document.getElementById('toggle'); + themeToggle.addEventListener('change', () => { + if (themeToggle.checked) { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } else { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } + }); + } + + _applyInitialTheme() { + document.documentElement.setAttribute('data-theme', this._currentTheme); + const themeToggle = document.getElementById('toggle'); + themeToggle.checked = this._currentTheme === 'dark'; } /** @@ -87,23 +109,37 @@ class FlexibleMonthCalendar extends BaseCalendar /* * Returns the header of the page, with the image, name and a message. */ - _getPageHeader() - { + _getPageHeader() { const switchView = ``; const todayBut = ``; const leftBut = ``; const rightBut = ``; const title = 'Time to Leave'; + + const themeToggleButton = ` +
+
+ +
+
`; + return '
'+ - '
' + - `
${title}
` + - '
' + + '
' + + `
${title}
` + + '
' + '
' + + '' + + `${themeToggleButton}` + '' + '' + '' + - '' + + '' + '' + '
' + switchView + '' + leftBut + '
' + rightBut + '' + rightBut + '' + todayBut + '
'; } diff --git a/src/calendar.js b/src/calendar.js index 04a91de24..14ef0fe02 100644 --- a/src/calendar.js +++ b/src/calendar.js @@ -76,3 +76,8 @@ $(async() => const preferences = await window.mainApi.getUserPreferencesPromise(); setupCalendar(preferences); }); + + + + +