Daniel Bohry пре 1 месец
родитељ
комит
34ebd96440

BIN
src/main/resources/static/favicon.ico


+ 1 - 0
src/main/resources/static/index.html

@@ -11,6 +11,7 @@
         <div class="title">KNotes</div>
         <div class="header-right">
             <span class="note-id" id="noteIdDisplay" style="display: none;"></span>
+            <div class="theme-switch" id="themeSwitch" onclick="toggleTheme()" title="Toggle dark/light theme"></div>
             <button class="new-btn" onclick="showIdInput()">Open</button>
             <button class="new-btn" onclick="newNote()">New</button>
         </div>

+ 50 - 0
src/main/resources/static/script.js

@@ -3,7 +3,57 @@ let currentNoteId = null;
 let autoSaveTimeout = null;
 let lastSavedContent = '';
 
+// Theme management
+function initializeTheme() {
+    // Get saved theme preference or default to light
+    const savedTheme = localStorage.getItem('theme') || 'light';
+    const body = document.body;
+    const themeSwitch = document.getElementById('themeSwitch');
+
+    if (!themeSwitch) {
+        console.error('Theme switch element not found');
+        return;
+    }
+
+    // Apply the theme
+    if (savedTheme === 'dark') {
+        body.setAttribute('data-theme', 'dark');
+        themeSwitch.classList.add('dark');
+    } else {
+        body.removeAttribute('data-theme');
+        themeSwitch.classList.remove('dark');
+    }
+}
+
+function toggleTheme() {
+    const body = document.body;
+    const themeSwitch = document.getElementById('themeSwitch');
+
+    if (!themeSwitch) {
+        console.error('Theme switch element not found');
+        return;
+    }
+
+    // Toggle between light and dark themes
+    const currentTheme = body.getAttribute('data-theme');
+
+    if (currentTheme === 'dark') {
+        // Switch to light theme
+        body.removeAttribute('data-theme');
+        themeSwitch.classList.remove('dark');
+        localStorage.setItem('theme', 'light');
+    } else {
+        // Switch to dark theme
+        body.setAttribute('data-theme', 'dark');
+        themeSwitch.classList.add('dark');
+        localStorage.setItem('theme', 'dark');
+    }
+}
+
 function init() {
+    // Initialize theme first
+    initializeTheme();
+
     // Extract note ID from URL path (e.g., /01KDECFWYDMS857DZMCR680MCY)
     const pathname = window.location.pathname;
     const pathParts = pathname.split('/');

+ 111 - 17
src/main/resources/static/style.css

@@ -1,5 +1,39 @@
 @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
 
+/* CSS Variables for Theme Support */
+:root {
+    --bg-primary: #fafafa;
+    --bg-secondary: white;
+    --bg-tertiary: #f5f5f5;
+    --text-primary: #333;
+    --text-secondary: #666;
+    --text-tertiary: #999;
+    --border-primary: #e0e0e0;
+    --border-secondary: #ddd;
+    --accent-primary: #007bff;
+    --accent-primary-hover: #0056b3;
+    --accent-secondary: #6c757d;
+    --overlay-bg: rgba(0,0,0,0.5);
+    --shadow: rgba(0,0,0,0.3);
+}
+
+/* Dark Theme Variables */
+[data-theme="dark"] {
+    --bg-primary: #1a1a1a;
+    --bg-secondary: #2d2d2d;
+    --bg-tertiary: #404040;
+    --text-primary: #e0e0e0;
+    --text-secondary: #b0b0b0;
+    --text-tertiary: #808080;
+    --border-primary: #404040;
+    --border-secondary: #555;
+    --accent-primary: #4dabf7;
+    --accent-primary-hover: #339af0;
+    --accent-secondary: #868e96;
+    --overlay-bg: rgba(0,0,0,0.7);
+    --shadow: rgba(0,0,0,0.5);
+}
+
 * {
     margin: 0;
     padding: 0;
@@ -8,49 +42,59 @@
 
 body {
     font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
-    background-color: #fafafa;
+    background-color: var(--bg-primary);
+    color: var(--text-primary);
     height: 100vh;
     display: flex;
     flex-direction: column;
+    transition: background-color 0.3s ease, color 0.3s ease;
 }
 
 .header {
-    background: white;
-    border-bottom: 1px solid #e0e0e0;
+    background: var(--bg-secondary);
+    border-bottom: 1px solid var(--border-primary);
     padding: 15px 20px;
     display: flex;
     justify-content: space-between;
     align-items: center;
     min-height: 60px;
+    transition: background-color 0.3s ease, border-color 0.3s ease;
 }
 
 .title {
     font-size: 18px;
-    color: #333;
+    color: var(--text-primary);
     font-weight: 500;
 }
 
 .note-id {
     font-family: monospace;
     font-size: 12px;
-    color: #666;
-    background: #f5f5f5;
+    color: var(--text-secondary);
+    background: var(--bg-tertiary);
     padding: 4px 8px;
     border-radius: 3px;
 }
 
+.header-right {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+}
+
 .new-btn {
-    background: #007bff;
+    background: var(--accent-primary);
     color: white;
     border: none;
     padding: 8px 16px;
     border-radius: 4px;
     cursor: pointer;
     font-size: 14px;
+    transition: background-color 0.2s ease;
 }
 
 .new-btn:hover {
-    background: #0056b3;
+    background: var(--accent-primary-hover);
 }
 
 .content {
@@ -67,11 +111,13 @@ body {
     font-size: 16px;
     line-height: 1.6;
     resize: none;
-    background: white;
+    background: var(--bg-secondary);
+    color: var(--text-primary);
+    transition: background-color 0.3s ease, color 0.3s ease;
 }
 
 .note-area::placeholder {
-    color: #999;
+    color: var(--text-tertiary);
 }
 
 .id-input-overlay {
@@ -80,7 +126,7 @@ body {
     left: 0;
     right: 0;
     bottom: 0;
-    background: rgba(0,0,0,0.5);
+    background: var(--overlay-bg);
     display: flex;
     justify-content: center;
     align-items: center;
@@ -88,26 +134,30 @@ body {
 }
 
 .id-input-dialog {
-    background: white;
+    background: var(--bg-secondary);
     padding: 30px;
     border-radius: 8px;
-    box-shadow: 0 4px 20px rgba(0,0,0,0.3);
+    box-shadow: 0 4px 20px var(--shadow);
     max-width: 400px;
     width: 90%;
+    transition: background-color 0.3s ease;
 }
 
 .id-input-dialog h3 {
     margin-bottom: 15px;
-    color: #333;
+    color: var(--text-primary);
 }
 
 .id-input {
     width: 100%;
     padding: 12px;
-    border: 1px solid #ddd;
+    border: 1px solid var(--border-secondary);
     border-radius: 4px;
     font-size: 14px;
     margin-bottom: 15px;
+    background: var(--bg-secondary);
+    color: var(--text-primary);
+    transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
 }
 
 .dialog-buttons {
@@ -122,18 +172,62 @@ body {
     border-radius: 4px;
     cursor: pointer;
     font-size: 14px;
+    transition: background-color 0.2s ease;
 }
 
 .dialog-btn.primary {
-    background: #007bff;
+    background: var(--accent-primary);
     color: white;
 }
 
+.dialog-btn.primary:hover {
+    background: var(--accent-primary-hover);
+}
+
 .dialog-btn.secondary {
-    background: #6c757d;
+    background: var(--accent-secondary);
     color: white;
 }
 
+.dialog-btn.secondary:hover {
+    opacity: 0.9;
+}
+
+/* Theme Switch Styles */
+.theme-switch {
+    background: var(--bg-tertiary);
+    border: 1px solid var(--border-primary);
+    border-radius: 20px;
+    padding: 4px;
+    cursor: pointer;
+    width: 44px;
+    height: 24px;
+    position: relative;
+    transition: all 0.3s ease;
+    display: flex;
+    align-items: center;
+}
+
+.theme-switch:hover {
+    background: var(--border-primary);
+}
+
+.theme-switch::before {
+    content: '';
+    width: 16px;
+    height: 16px;
+    border-radius: 50%;
+    background: var(--accent-primary);
+    position: absolute;
+    left: 4px;
+    transition: all 0.3s ease;
+    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
+}
+
+.theme-switch.dark::before {
+    transform: translateX(20px);
+}
+
 .hidden {
     display: none;
 }