שיתוף | מנהל התזכורות לדפדפן | שיתוף חמוד שאולי יהיה לכם שימושי
-
לאחרונה נתקלתי בצורך (של עצמי..) לכתוב תזכורות לכל מיני מטלות קטנות שאסור לי לשכוח
'פתקים נדבקים' כמובן הם האופציה הכי מתאימה, אבל משום מה לי זה לא התאים, אז יצרתי {לא יפה לומר ככה. GEMINI יצר עבורי...} קוד לדף אינטרנט יפה ומעוצב שנותן לשמור תזכורות [ע"י עוגיות בדפדפן] ולמחוק, וגם להגדיר סיסמה
צילו"מ לדוגמה בספויילראז הנה אני משתף את זה איתכם, תהנו...
קישור לקוד בגיטהאב
הקוד המלא בספויילר,ניתן כמובן לשמור באופן מקומי על המחשב שלכם בקובץ בסיומת HTML ולפתוח בדפדפן. תהנו...
עריכה: א"א להשתמש בקוד הנוכחי באופן מקומי, מצורף כאן קובץ עם קוד אחר שלא משתמש בעוגיות אלא ב-localStorage ומיועד להרצה על מחשב מקומי תזכורות.txt (קליק ימני, שמירת קישור בשם. להחליף את הסיומת ל-html כמובן)<!DOCTYPE html> <html lang="he" dir="rtl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>מנהל התזכורות</title> <style> @keyframes subtleGradientShift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } body { color: #00ffcc; font-family: 'Courier New', Courier, monospace; margin: 0; padding: 20px; display: flex; flex-direction: column; align-items: center; min-height: 100vh; background: linear-gradient(270deg, #0a0f1f, #10152f, #0a0f1f); background-size: 600% 600%; animation: subtleGradientShift 30s ease infinite; } .container { background-color: rgba(26, 31, 54, 0.85); backdrop-filter: blur(5px); padding: 30px; border-radius: 15px; box-shadow: 0 0 35px rgba(0, 255, 204, 0.4), 0 0 15px rgba(0, 255, 204, 0.2) inset; border: 1px solid #00ffcc; width: 90%; max-width: 700px; text-align: center; margin-top: 20px; } h1 { color: #ffffff; text-shadow: 0 0 10px #00ffcc; margin-bottom: 30px; } .input-area, .password-area { margin-bottom: 25px; display: flex; gap: 10px; flex-wrap: wrap; } input[type="text"], input[type="password"] { flex-grow: 1; padding: 12px 15px; background-color: #0a0f1f; color: #e0e0e0; border: 1px solid #007766; border-radius: 8px; font-size: 16px; outline: none; min-width: 200px; } input[type="text"]::placeholder, input[type="password"]::placeholder { color: #555f78; } input[type="text"]:focus, input[type="password"]:focus { border-color: #00ffcc; box-shadow: 0 0 10px rgba(0, 255, 204, 0.4); } button { padding: 12px 20px; background-color: #007766; color: #ffffff; border: none; border-radius: 8px; cursor: pointer; font-size: 16px; transition: background-color 0.3s ease, box-shadow 0.3s ease; text-shadow: 0 0 5px rgba(0,0,0,0.5); flex-shrink: 0; } button:hover { background-color: #00ffcc; color: #0a0f1f; box-shadow: 0 0 15px rgba(0, 255, 204, 0.6); } button.delete-btn { background-color: #990033; padding: 5px 10px; font-size: 12px; } button.delete-btn:hover { background-color: #ff3366; } button.cancel-btn { background-color: #4a4f66; } button.cancel-btn:hover { background-color: #6a6f86; } #deleteAllRemindersBtn { background-color: #cc0000; margin-top: 10px; width: 100%; font-size: 1em; padding: 12px 20px; } #deleteAllRemindersBtn:hover { background-color: #ff4d4d; } #remindersListArea { margin-top: 20px; background-color: rgba(10, 15, 31, 0.7); padding: 20px; border-radius: 10px; border: 1px dashed #007766; min-height: 100px; text-align: right; } #remindersListArea h2 { color: #ffffff; text-align: center; margin-top: 0; margin-bottom: 15px; border-bottom: 1px solid #007766; padding-bottom: 10px; } .reminder-item { background-color: #1a1f36; border: 1px solid #00ffcc; padding: 10px; margin-bottom: 8px; border-radius: 5px; color: #e0e0e0; font-size: 15px; word-wrap: break-word; display: flex; justify-content: space-between; align-items: center; } .reminder-item-text { flex-grow: 1; text-align: right; } .hidden { display: none !important; } #toast-container { position: fixed; bottom: 20px; left: 20px; z-index: 10000; display: flex; flex-direction: column-reverse; gap: 10px; } .toast-message { background-color: #00ffcc; color: #0a0f1f; padding: 12px 18px; border-radius: 8px; box-shadow: 0 3px 12px rgba(0,0,0,0.25); opacity: 0; transform: translateX(-100%); transition: opacity 0.4s ease-out, transform 0.4s ease-out; min-width: 250px; text-align: left; } .toast-message.show { opacity: 0.95; transform: translateX(0); } .toast-message.error { background-color: #ff3366; color: #ffffff; } .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.7); display: flex; justify-content: center; align-items: center; z-index: 9000; opacity: 0; transition: opacity 0.3s ease-in-out; } .modal-overlay.show { opacity: 1; } .modal-content { background-color: #1a1f36; padding: 30px 40px; border-radius: 12px; border: 1px solid #00ffcc; text-align: center; box-shadow: 0 0 30px rgba(0, 255, 204, 0.5); transform: scale(0.7); transition: transform 0.3s ease-in-out; } .modal-overlay.show .modal-content { transform: scale(1); } .modal-content p { margin-bottom: 25px; font-size: 1.1em; color: #e0e0e0; } .modal-buttons button { margin: 0 12px; } #confirm-no-btn { background-color: #4a4f66; } #confirm-no-btn:hover { background-color: #6a6f86; } #passwordManagementArea { margin-top: 20px; } #passwordMgmtBtn { background-color: #3a3f56; } #passwordMgmtBtn:hover { background-color: #555f78; } </style> </head> <body> <div class="container"> <h1>מנהל התזכורות</h1> <div id="password-section" class="hidden"> <div id="password-setup-area" class="password-area hidden"> <p>הגדר סיסמה לגישה לתזכורות:</p> <input type="password" id="newPassword" placeholder="הזן סיסמה חדשה (לפחות 4 תווים)"> <button id="setPasswordBtn">הגדר סיסמה</button> <button id="cancelPasswordSetupBtn" class="cancel-btn">ביטול</button> </div> <div id="password-entry-area" class="password-area hidden"> <p>אנא הזן את הסיסמה שלך כדי לגשת לתזכורות:</p> <input type="password" id="enteredPassword" placeholder="הזן סיסמה"> <button id="loginBtn">הכנס</button> <button id="cancelLoginAttemptBtn" class="cancel-btn hidden">ביטול</button> </div> </div> <div id="app-content-area"> <div class="input-area"> <input type="text" id="reminderText" placeholder="הזן תזכורת חדשה ולחץ Enter או על הכפתור..."> <button id="saveReminderBtn">שמור תזכורת</button> </div> <button id="toggleRemindersBtn">הצג את כל התזכורות</button> <button id="deleteAllRemindersBtn">מחק את כל התזכורות</button> <div id="remindersListArea" class="hidden"> <h2>רשימת תזכורות:</h2> <div id="remindersList"> <p>עדיין לא נשמרו תזכורות, או שלא נלחץ על כפתור ההצגה.</p> </div> </div> <div id="passwordManagementArea"> <button id="passwordMgmtBtn">הפעל הגנת סיסמה</button> </div> </div> </div> <div id="toast-container"></div> <div id="confirmation-modal-overlay" class="modal-overlay hidden"> <div class="modal-content"> <p id="confirmation-message">האם אתה בטוח?</p> <div class="modal-buttons"> <button id="confirm-yes-btn" class="confirm-action-btn">כן</button> <button id="confirm-no-btn" class="confirm-action-btn">לא</button> </div> </div> </div> <script> const APP_PASSWORD_COOKIE = 'app_access_password_v1'; const REMINDER_PREFIX = "reminder_item_"; const passwordSection = document.getElementById('password-section'); const passwordSetupArea = document.getElementById('password-setup-area'); const newPasswordInput = document.getElementById('newPassword'); const setPasswordBtn = document.getElementById('setPasswordBtn'); const cancelPasswordSetupBtn = document.getElementById('cancelPasswordSetupBtn'); const passwordEntryArea = document.getElementById('password-entry-area'); const enteredPasswordInput = document.getElementById('enteredPassword'); const loginBtn = document.getElementById('loginBtn'); const cancelLoginAttemptBtn = document.getElementById('cancelLoginAttemptBtn'); const appContentArea = document.getElementById('app-content-area'); const reminderTextElement = document.getElementById('reminderText'); const saveReminderBtn = document.getElementById('saveReminderBtn'); const toggleRemindersBtn = document.getElementById('toggleRemindersBtn'); const deleteAllRemindersBtn = document.getElementById('deleteAllRemindersBtn'); const remindersListArea = document.getElementById('remindersListArea'); const remindersListDiv = document.getElementById('remindersList'); const passwordMgmtBtn = document.getElementById('passwordMgmtBtn'); const toastContainer = document.getElementById('toast-container'); const confirmationModalOverlay = document.getElementById('confirmation-modal-overlay'); const confirmationMessageElement = document.getElementById('confirmation-message'); const confirmYesBtn = document.getElementById('confirm-yes-btn'); const confirmNoBtn = document.getElementById('confirm-no-btn'); let currentOnConfirmCallback = null; function setCookie(name, value, days) { let expires = ""; if (days) { const date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toUTCString(); } document.cookie = name + "=" + (encodeURIComponent(value) || "") + expires + "; path=/; SameSite=Lax"; } function getCookie(name) { const nameEQ = name + "="; const ca = document.cookie.split(';'); for(let i = 0; i < ca.length; i++) { let c = ca[i]; while (c.charAt(0) === ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) === 0) return decodeURIComponent(c.substring(nameEQ.length, c.length)); } return null; } function eraseCookie(name) { document.cookie = name+'=; Max-Age=-99999999; path=/; SameSite=Lax'; } function getAllReminderCookies() { const cookies = {}; if (document.cookie && document.cookie !== '') { document.cookie.split(';').forEach(function(cookie) { const parts = cookie.match(/^\s*([^=]+)=(.*)$/); if(parts && parts.length === 3 && parts[1].startsWith(REMINDER_PREFIX)) { cookies[parts[1]] = decodeURIComponent(parts[2]); } }); } return cookies; } function showToast(message, type = 'success', duration = 2500) { const toast = document.createElement('div'); toast.classList.add('toast-message'); if (type === 'error') toast.classList.add('error'); toast.textContent = message; toastContainer.appendChild(toast); setTimeout(() => toast.classList.add('show'), 10); setTimeout(() => { toast.classList.remove('show'); toast.addEventListener('transitionend', () => toast.remove(), { once: true }); }, duration); } function showConfirmation(message, onConfirm) { confirmationMessageElement.textContent = message; currentOnConfirmCallback = onConfirm; confirmationModalOverlay.classList.remove('hidden'); setTimeout(() => confirmationModalOverlay.classList.add('show'), 10); } function hideConfirmation() { confirmationModalOverlay.classList.remove('show'); confirmationModalOverlay.addEventListener('transitionend', () => { confirmationModalOverlay.classList.add('hidden'); currentOnConfirmCallback = null; }, { once: true }); } confirmYesBtn.addEventListener('click', () => { if (currentOnConfirmCallback) currentOnConfirmCallback(); hideConfirmation(); }); confirmNoBtn.addEventListener('click', hideConfirmation); function updatePasswordMgmtButton() { if (getCookie(APP_PASSWORD_COOKIE)) { passwordMgmtBtn.textContent = "הסר הגנת סיסמה"; } else { passwordMgmtBtn.textContent = "הפעל הגנת סיסמה"; } } passwordMgmtBtn.addEventListener('click', () => { if (getCookie(APP_PASSWORD_COOKIE)) { showConfirmation("האם אתה בטוח שברצונך להסיר את הגנת הסיסמה? התזכורות יהיו נגישות ללא סיסמה.", () => { eraseCookie(APP_PASSWORD_COOKIE); showToast("הגנת הסיסמה הוסרה."); updatePasswordMgmtButton(); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); }); } else { passwordSection.classList.remove('hidden'); passwordSetupArea.classList.remove('hidden'); passwordEntryArea.classList.add('hidden'); appContentArea.classList.add('hidden'); } }); setPasswordBtn.addEventListener('click', () => { const newPassword = newPasswordInput.value; if (newPassword.length < 4) { showToast("הסיסמה חייבת להכיל לפחות 4 תווים.", 'error'); return; } setCookie(APP_PASSWORD_COOKIE, btoa(newPassword), 365); showToast("הסיסמה הוגדרה בהצלחה!"); newPasswordInput.value = ''; passwordSetupArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); updatePasswordMgmtButton(); }); cancelPasswordSetupBtn.addEventListener('click', () => { passwordSetupArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); newPasswordInput.value = ''; }); cancelLoginAttemptBtn.addEventListener('click', () => { enteredPasswordInput.value = ''; showToast("הגישה מוגנת. עליך להזין סיסמה כדי להמשיך.", "error", 3000); appContentArea.classList.add('hidden'); passwordSection.classList.remove('hidden'); passwordEntryArea.classList.remove('hidden'); }); loginBtn.addEventListener('click', () => { const enteredPassword = enteredPasswordInput.value; const storedEncodedPassword = getCookie(APP_PASSWORD_COOKIE); if (!storedEncodedPassword) { showToast("שגיאה: לא נמצאה סיסמה שמורה.", 'error'); passwordEntryArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); updatePasswordMgmtButton(); return; } try { if (btoa(enteredPassword) === storedEncodedPassword) { showToast("התחברת בהצלחה!"); passwordEntryArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); enteredPasswordInput.value = ''; cancelLoginAttemptBtn.classList.add('hidden'); updatePasswordMgmtButton(); } else { showToast("סיסמה שגויה. נסה שוב.", 'error'); enteredPasswordInput.value = ''; } } catch (e) { showToast("שגיאה בעיבוד הסיסמה.", 'error'); } }); function saveReminder() { const reminderText = reminderTextElement.value.trim(); if (reminderText === "") { showToast("אנא הזן תוכן לתזכורת.", 'error'); return; } const cookieName = REMINDER_PREFIX + Date.now(); setCookie(cookieName, reminderText, 365); showToast("התזכורת נשמרה!"); reminderTextElement.value = ""; if (!remindersListArea.classList.contains('hidden')) { displayReminders(); } } function displayReminders() { remindersListDiv.innerHTML = ""; const allCookies = getAllReminderCookies(); let remindersFound = false; const sortedCookieNames = Object.keys(allCookies).sort((a, b) => { return parseInt(b.substring(REMINDER_PREFIX.length)) - parseInt(a.substring(REMINDER_PREFIX.length)); }); for (const cookieName of sortedCookieNames) { remindersFound = true; const reminderValue = allCookies[cookieName]; const reminderElement = document.createElement('div'); reminderElement.classList.add('reminder-item'); const textSpan = document.createElement('span'); textSpan.classList.add('reminder-item-text'); textSpan.textContent = reminderValue; const deleteButton = document.createElement('button'); deleteButton.classList.add('delete-btn'); deleteButton.textContent = "מחק"; deleteButton.onclick = function() { showConfirmation(`האם אתה בטוח שברצונך למחוק את התזכורת: "${reminderValue.substring(0,20)}..."?`, () => { eraseCookie(cookieName); showToast("התזכורת נמחקה."); displayReminders(); }); }; reminderElement.appendChild(deleteButton); reminderElement.appendChild(textSpan); remindersListDiv.appendChild(reminderElement); } if (!remindersFound) { remindersListDiv.innerHTML = "<p>לא נמצאו תזכורות שמורות.</p>"; } } function toggleRemindersDisplay() { remindersListArea.classList.toggle('hidden'); if (remindersListArea.classList.contains('hidden')) { toggleRemindersBtn.textContent = "הצג את כל התזכורות"; } else { toggleRemindersBtn.textContent = "הסתר תזכורות"; displayReminders(); } } function deleteAllReminders() { showConfirmation("האם אתה בטוח שברצונך למחוק את *כל* התזכורות? לא ניתן יהיה לשחזר פעולה זו.", () => { const allReminderCookies = getAllReminderCookies(); let remindersWereDeleted = false; for (const cookieName in allReminderCookies) { eraseCookie(cookieName); remindersWereDeleted = true; } if (remindersWereDeleted) { showToast("כל התזכורות נמחקו בהצלחה!"); } else { showToast("לא נמצאו תזכורות למחיקה.", "error"); } displayReminders(); }); } window.onload = function() { const storedPassword = getCookie(APP_PASSWORD_COOKIE); if (storedPassword) { appContentArea.classList.add('hidden'); passwordSection.classList.remove('hidden'); passwordEntryArea.classList.remove('hidden'); passwordSetupArea.classList.add('hidden'); cancelLoginAttemptBtn.classList.remove('hidden'); } else { appContentArea.classList.remove('hidden'); passwordSection.classList.add('hidden'); cancelLoginAttemptBtn.classList.add('hidden'); } updatePasswordMgmtButton(); newPasswordInput.addEventListener('keypress', function(event) { if (event.key === 'Enter' || event.keyCode === 13) { setPasswordBtn.click(); } }); enteredPasswordInput.addEventListener('keypress', function(event) { if (event.key === 'Enter' || event.keyCode === 13) { loginBtn.click(); } }); saveReminderBtn.addEventListener('click', saveReminder); reminderTextElement.addEventListener('keypress', function(event) { if (event.key === 'Enter' || event.keyCode === 13) { event.preventDefault(); saveReminder(); } }); toggleRemindersBtn.addEventListener('click', toggleRemindersDisplay); deleteAllRemindersBtn.addEventListener('click', deleteAllReminders); }; </script> </body> </html>
-
לאחרונה נתקלתי בצורך (של עצמי..) לכתוב תזכורות לכל מיני מטלות קטנות שאסור לי לשכוח
'פתקים נדבקים' כמובן הם האופציה הכי מתאימה, אבל משום מה לי זה לא התאים, אז יצרתי {לא יפה לומר ככה. GEMINI יצר עבורי...} קוד לדף אינטרנט יפה ומעוצב שנותן לשמור תזכורות [ע"י עוגיות בדפדפן] ולמחוק, וגם להגדיר סיסמה
צילו"מ לדוגמה בספויילראז הנה אני משתף את זה איתכם, תהנו...
קישור לקוד בגיטהאב
הקוד המלא בספויילר,ניתן כמובן לשמור באופן מקומי על המחשב שלכם בקובץ בסיומת HTML ולפתוח בדפדפן. תהנו...
עריכה: א"א להשתמש בקוד הנוכחי באופן מקומי, מצורף כאן קובץ עם קוד אחר שלא משתמש בעוגיות אלא ב-localStorage ומיועד להרצה על מחשב מקומי תזכורות.txt (קליק ימני, שמירת קישור בשם. להחליף את הסיומת ל-html כמובן)<!DOCTYPE html> <html lang="he" dir="rtl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>מנהל התזכורות</title> <style> @keyframes subtleGradientShift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } body { color: #00ffcc; font-family: 'Courier New', Courier, monospace; margin: 0; padding: 20px; display: flex; flex-direction: column; align-items: center; min-height: 100vh; background: linear-gradient(270deg, #0a0f1f, #10152f, #0a0f1f); background-size: 600% 600%; animation: subtleGradientShift 30s ease infinite; } .container { background-color: rgba(26, 31, 54, 0.85); backdrop-filter: blur(5px); padding: 30px; border-radius: 15px; box-shadow: 0 0 35px rgba(0, 255, 204, 0.4), 0 0 15px rgba(0, 255, 204, 0.2) inset; border: 1px solid #00ffcc; width: 90%; max-width: 700px; text-align: center; margin-top: 20px; } h1 { color: #ffffff; text-shadow: 0 0 10px #00ffcc; margin-bottom: 30px; } .input-area, .password-area { margin-bottom: 25px; display: flex; gap: 10px; flex-wrap: wrap; } input[type="text"], input[type="password"] { flex-grow: 1; padding: 12px 15px; background-color: #0a0f1f; color: #e0e0e0; border: 1px solid #007766; border-radius: 8px; font-size: 16px; outline: none; min-width: 200px; } input[type="text"]::placeholder, input[type="password"]::placeholder { color: #555f78; } input[type="text"]:focus, input[type="password"]:focus { border-color: #00ffcc; box-shadow: 0 0 10px rgba(0, 255, 204, 0.4); } button { padding: 12px 20px; background-color: #007766; color: #ffffff; border: none; border-radius: 8px; cursor: pointer; font-size: 16px; transition: background-color 0.3s ease, box-shadow 0.3s ease; text-shadow: 0 0 5px rgba(0,0,0,0.5); flex-shrink: 0; } button:hover { background-color: #00ffcc; color: #0a0f1f; box-shadow: 0 0 15px rgba(0, 255, 204, 0.6); } button.delete-btn { background-color: #990033; padding: 5px 10px; font-size: 12px; } button.delete-btn:hover { background-color: #ff3366; } button.cancel-btn { background-color: #4a4f66; } button.cancel-btn:hover { background-color: #6a6f86; } #deleteAllRemindersBtn { background-color: #cc0000; margin-top: 10px; width: 100%; font-size: 1em; padding: 12px 20px; } #deleteAllRemindersBtn:hover { background-color: #ff4d4d; } #remindersListArea { margin-top: 20px; background-color: rgba(10, 15, 31, 0.7); padding: 20px; border-radius: 10px; border: 1px dashed #007766; min-height: 100px; text-align: right; } #remindersListArea h2 { color: #ffffff; text-align: center; margin-top: 0; margin-bottom: 15px; border-bottom: 1px solid #007766; padding-bottom: 10px; } .reminder-item { background-color: #1a1f36; border: 1px solid #00ffcc; padding: 10px; margin-bottom: 8px; border-radius: 5px; color: #e0e0e0; font-size: 15px; word-wrap: break-word; display: flex; justify-content: space-between; align-items: center; } .reminder-item-text { flex-grow: 1; text-align: right; } .hidden { display: none !important; } #toast-container { position: fixed; bottom: 20px; left: 20px; z-index: 10000; display: flex; flex-direction: column-reverse; gap: 10px; } .toast-message { background-color: #00ffcc; color: #0a0f1f; padding: 12px 18px; border-radius: 8px; box-shadow: 0 3px 12px rgba(0,0,0,0.25); opacity: 0; transform: translateX(-100%); transition: opacity 0.4s ease-out, transform 0.4s ease-out; min-width: 250px; text-align: left; } .toast-message.show { opacity: 0.95; transform: translateX(0); } .toast-message.error { background-color: #ff3366; color: #ffffff; } .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.7); display: flex; justify-content: center; align-items: center; z-index: 9000; opacity: 0; transition: opacity 0.3s ease-in-out; } .modal-overlay.show { opacity: 1; } .modal-content { background-color: #1a1f36; padding: 30px 40px; border-radius: 12px; border: 1px solid #00ffcc; text-align: center; box-shadow: 0 0 30px rgba(0, 255, 204, 0.5); transform: scale(0.7); transition: transform 0.3s ease-in-out; } .modal-overlay.show .modal-content { transform: scale(1); } .modal-content p { margin-bottom: 25px; font-size: 1.1em; color: #e0e0e0; } .modal-buttons button { margin: 0 12px; } #confirm-no-btn { background-color: #4a4f66; } #confirm-no-btn:hover { background-color: #6a6f86; } #passwordManagementArea { margin-top: 20px; } #passwordMgmtBtn { background-color: #3a3f56; } #passwordMgmtBtn:hover { background-color: #555f78; } </style> </head> <body> <div class="container"> <h1>מנהל התזכורות</h1> <div id="password-section" class="hidden"> <div id="password-setup-area" class="password-area hidden"> <p>הגדר סיסמה לגישה לתזכורות:</p> <input type="password" id="newPassword" placeholder="הזן סיסמה חדשה (לפחות 4 תווים)"> <button id="setPasswordBtn">הגדר סיסמה</button> <button id="cancelPasswordSetupBtn" class="cancel-btn">ביטול</button> </div> <div id="password-entry-area" class="password-area hidden"> <p>אנא הזן את הסיסמה שלך כדי לגשת לתזכורות:</p> <input type="password" id="enteredPassword" placeholder="הזן סיסמה"> <button id="loginBtn">הכנס</button> <button id="cancelLoginAttemptBtn" class="cancel-btn hidden">ביטול</button> </div> </div> <div id="app-content-area"> <div class="input-area"> <input type="text" id="reminderText" placeholder="הזן תזכורת חדשה ולחץ Enter או על הכפתור..."> <button id="saveReminderBtn">שמור תזכורת</button> </div> <button id="toggleRemindersBtn">הצג את כל התזכורות</button> <button id="deleteAllRemindersBtn">מחק את כל התזכורות</button> <div id="remindersListArea" class="hidden"> <h2>רשימת תזכורות:</h2> <div id="remindersList"> <p>עדיין לא נשמרו תזכורות, או שלא נלחץ על כפתור ההצגה.</p> </div> </div> <div id="passwordManagementArea"> <button id="passwordMgmtBtn">הפעל הגנת סיסמה</button> </div> </div> </div> <div id="toast-container"></div> <div id="confirmation-modal-overlay" class="modal-overlay hidden"> <div class="modal-content"> <p id="confirmation-message">האם אתה בטוח?</p> <div class="modal-buttons"> <button id="confirm-yes-btn" class="confirm-action-btn">כן</button> <button id="confirm-no-btn" class="confirm-action-btn">לא</button> </div> </div> </div> <script> const APP_PASSWORD_COOKIE = 'app_access_password_v1'; const REMINDER_PREFIX = "reminder_item_"; const passwordSection = document.getElementById('password-section'); const passwordSetupArea = document.getElementById('password-setup-area'); const newPasswordInput = document.getElementById('newPassword'); const setPasswordBtn = document.getElementById('setPasswordBtn'); const cancelPasswordSetupBtn = document.getElementById('cancelPasswordSetupBtn'); const passwordEntryArea = document.getElementById('password-entry-area'); const enteredPasswordInput = document.getElementById('enteredPassword'); const loginBtn = document.getElementById('loginBtn'); const cancelLoginAttemptBtn = document.getElementById('cancelLoginAttemptBtn'); const appContentArea = document.getElementById('app-content-area'); const reminderTextElement = document.getElementById('reminderText'); const saveReminderBtn = document.getElementById('saveReminderBtn'); const toggleRemindersBtn = document.getElementById('toggleRemindersBtn'); const deleteAllRemindersBtn = document.getElementById('deleteAllRemindersBtn'); const remindersListArea = document.getElementById('remindersListArea'); const remindersListDiv = document.getElementById('remindersList'); const passwordMgmtBtn = document.getElementById('passwordMgmtBtn'); const toastContainer = document.getElementById('toast-container'); const confirmationModalOverlay = document.getElementById('confirmation-modal-overlay'); const confirmationMessageElement = document.getElementById('confirmation-message'); const confirmYesBtn = document.getElementById('confirm-yes-btn'); const confirmNoBtn = document.getElementById('confirm-no-btn'); let currentOnConfirmCallback = null; function setCookie(name, value, days) { let expires = ""; if (days) { const date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toUTCString(); } document.cookie = name + "=" + (encodeURIComponent(value) || "") + expires + "; path=/; SameSite=Lax"; } function getCookie(name) { const nameEQ = name + "="; const ca = document.cookie.split(';'); for(let i = 0; i < ca.length; i++) { let c = ca[i]; while (c.charAt(0) === ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) === 0) return decodeURIComponent(c.substring(nameEQ.length, c.length)); } return null; } function eraseCookie(name) { document.cookie = name+'=; Max-Age=-99999999; path=/; SameSite=Lax'; } function getAllReminderCookies() { const cookies = {}; if (document.cookie && document.cookie !== '') { document.cookie.split(';').forEach(function(cookie) { const parts = cookie.match(/^\s*([^=]+)=(.*)$/); if(parts && parts.length === 3 && parts[1].startsWith(REMINDER_PREFIX)) { cookies[parts[1]] = decodeURIComponent(parts[2]); } }); } return cookies; } function showToast(message, type = 'success', duration = 2500) { const toast = document.createElement('div'); toast.classList.add('toast-message'); if (type === 'error') toast.classList.add('error'); toast.textContent = message; toastContainer.appendChild(toast); setTimeout(() => toast.classList.add('show'), 10); setTimeout(() => { toast.classList.remove('show'); toast.addEventListener('transitionend', () => toast.remove(), { once: true }); }, duration); } function showConfirmation(message, onConfirm) { confirmationMessageElement.textContent = message; currentOnConfirmCallback = onConfirm; confirmationModalOverlay.classList.remove('hidden'); setTimeout(() => confirmationModalOverlay.classList.add('show'), 10); } function hideConfirmation() { confirmationModalOverlay.classList.remove('show'); confirmationModalOverlay.addEventListener('transitionend', () => { confirmationModalOverlay.classList.add('hidden'); currentOnConfirmCallback = null; }, { once: true }); } confirmYesBtn.addEventListener('click', () => { if (currentOnConfirmCallback) currentOnConfirmCallback(); hideConfirmation(); }); confirmNoBtn.addEventListener('click', hideConfirmation); function updatePasswordMgmtButton() { if (getCookie(APP_PASSWORD_COOKIE)) { passwordMgmtBtn.textContent = "הסר הגנת סיסמה"; } else { passwordMgmtBtn.textContent = "הפעל הגנת סיסמה"; } } passwordMgmtBtn.addEventListener('click', () => { if (getCookie(APP_PASSWORD_COOKIE)) { showConfirmation("האם אתה בטוח שברצונך להסיר את הגנת הסיסמה? התזכורות יהיו נגישות ללא סיסמה.", () => { eraseCookie(APP_PASSWORD_COOKIE); showToast("הגנת הסיסמה הוסרה."); updatePasswordMgmtButton(); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); }); } else { passwordSection.classList.remove('hidden'); passwordSetupArea.classList.remove('hidden'); passwordEntryArea.classList.add('hidden'); appContentArea.classList.add('hidden'); } }); setPasswordBtn.addEventListener('click', () => { const newPassword = newPasswordInput.value; if (newPassword.length < 4) { showToast("הסיסמה חייבת להכיל לפחות 4 תווים.", 'error'); return; } setCookie(APP_PASSWORD_COOKIE, btoa(newPassword), 365); showToast("הסיסמה הוגדרה בהצלחה!"); newPasswordInput.value = ''; passwordSetupArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); updatePasswordMgmtButton(); }); cancelPasswordSetupBtn.addEventListener('click', () => { passwordSetupArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); newPasswordInput.value = ''; }); cancelLoginAttemptBtn.addEventListener('click', () => { enteredPasswordInput.value = ''; showToast("הגישה מוגנת. עליך להזין סיסמה כדי להמשיך.", "error", 3000); appContentArea.classList.add('hidden'); passwordSection.classList.remove('hidden'); passwordEntryArea.classList.remove('hidden'); }); loginBtn.addEventListener('click', () => { const enteredPassword = enteredPasswordInput.value; const storedEncodedPassword = getCookie(APP_PASSWORD_COOKIE); if (!storedEncodedPassword) { showToast("שגיאה: לא נמצאה סיסמה שמורה.", 'error'); passwordEntryArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); updatePasswordMgmtButton(); return; } try { if (btoa(enteredPassword) === storedEncodedPassword) { showToast("התחברת בהצלחה!"); passwordEntryArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); enteredPasswordInput.value = ''; cancelLoginAttemptBtn.classList.add('hidden'); updatePasswordMgmtButton(); } else { showToast("סיסמה שגויה. נסה שוב.", 'error'); enteredPasswordInput.value = ''; } } catch (e) { showToast("שגיאה בעיבוד הסיסמה.", 'error'); } }); function saveReminder() { const reminderText = reminderTextElement.value.trim(); if (reminderText === "") { showToast("אנא הזן תוכן לתזכורת.", 'error'); return; } const cookieName = REMINDER_PREFIX + Date.now(); setCookie(cookieName, reminderText, 365); showToast("התזכורת נשמרה!"); reminderTextElement.value = ""; if (!remindersListArea.classList.contains('hidden')) { displayReminders(); } } function displayReminders() { remindersListDiv.innerHTML = ""; const allCookies = getAllReminderCookies(); let remindersFound = false; const sortedCookieNames = Object.keys(allCookies).sort((a, b) => { return parseInt(b.substring(REMINDER_PREFIX.length)) - parseInt(a.substring(REMINDER_PREFIX.length)); }); for (const cookieName of sortedCookieNames) { remindersFound = true; const reminderValue = allCookies[cookieName]; const reminderElement = document.createElement('div'); reminderElement.classList.add('reminder-item'); const textSpan = document.createElement('span'); textSpan.classList.add('reminder-item-text'); textSpan.textContent = reminderValue; const deleteButton = document.createElement('button'); deleteButton.classList.add('delete-btn'); deleteButton.textContent = "מחק"; deleteButton.onclick = function() { showConfirmation(`האם אתה בטוח שברצונך למחוק את התזכורת: "${reminderValue.substring(0,20)}..."?`, () => { eraseCookie(cookieName); showToast("התזכורת נמחקה."); displayReminders(); }); }; reminderElement.appendChild(deleteButton); reminderElement.appendChild(textSpan); remindersListDiv.appendChild(reminderElement); } if (!remindersFound) { remindersListDiv.innerHTML = "<p>לא נמצאו תזכורות שמורות.</p>"; } } function toggleRemindersDisplay() { remindersListArea.classList.toggle('hidden'); if (remindersListArea.classList.contains('hidden')) { toggleRemindersBtn.textContent = "הצג את כל התזכורות"; } else { toggleRemindersBtn.textContent = "הסתר תזכורות"; displayReminders(); } } function deleteAllReminders() { showConfirmation("האם אתה בטוח שברצונך למחוק את *כל* התזכורות? לא ניתן יהיה לשחזר פעולה זו.", () => { const allReminderCookies = getAllReminderCookies(); let remindersWereDeleted = false; for (const cookieName in allReminderCookies) { eraseCookie(cookieName); remindersWereDeleted = true; } if (remindersWereDeleted) { showToast("כל התזכורות נמחקו בהצלחה!"); } else { showToast("לא נמצאו תזכורות למחיקה.", "error"); } displayReminders(); }); } window.onload = function() { const storedPassword = getCookie(APP_PASSWORD_COOKIE); if (storedPassword) { appContentArea.classList.add('hidden'); passwordSection.classList.remove('hidden'); passwordEntryArea.classList.remove('hidden'); passwordSetupArea.classList.add('hidden'); cancelLoginAttemptBtn.classList.remove('hidden'); } else { appContentArea.classList.remove('hidden'); passwordSection.classList.add('hidden'); cancelLoginAttemptBtn.classList.add('hidden'); } updatePasswordMgmtButton(); newPasswordInput.addEventListener('keypress', function(event) { if (event.key === 'Enter' || event.keyCode === 13) { setPasswordBtn.click(); } }); enteredPasswordInput.addEventListener('keypress', function(event) { if (event.key === 'Enter' || event.keyCode === 13) { loginBtn.click(); } }); saveReminderBtn.addEventListener('click', saveReminder); reminderTextElement.addEventListener('keypress', function(event) { if (event.key === 'Enter' || event.keyCode === 13) { event.preventDefault(); saveReminder(); } }); toggleRemindersBtn.addEventListener('click', toggleRemindersDisplay); deleteAllRemindersBtn.addEventListener('click', deleteAllReminders); }; </script> </body> </html>
נחמד ושימושי!
@אופיר123 כתב בשיתוף | מנהל התזכורות לדפדפן | שיתוף חמוד שאולי יהיה לכם שימושי:
ניתן כמובן לשמור באופן מקומי על המחשב שלכם בקובץ בסיומת HTML ולפתוח בדפדפן
זה מה שעשיתי, אבל הוא לא שומר תזכורות
הדף נפתח והכל מוצג אותו דבר כמו בגיטהב, אבל לא שומר כלום
אני לוחץ על שמור - כותב נשמר, אבל בפועל אין תזכורות להצגה
מה פספסתי? -
נחמד ושימושי!
@אופיר123 כתב בשיתוף | מנהל התזכורות לדפדפן | שיתוף חמוד שאולי יהיה לכם שימושי:
ניתן כמובן לשמור באופן מקומי על המחשב שלכם בקובץ בסיומת HTML ולפתוח בדפדפן
זה מה שעשיתי, אבל הוא לא שומר תזכורות
הדף נפתח והכל מוצג אותו דבר כמו בגיטהב, אבל לא שומר כלום
אני לוחץ על שמור - כותב נשמר, אבל בפועל אין תזכורות להצגה
מה פספסתי? -
לאחרונה נתקלתי בצורך (של עצמי..) לכתוב תזכורות לכל מיני מטלות קטנות שאסור לי לשכוח
'פתקים נדבקים' כמובן הם האופציה הכי מתאימה, אבל משום מה לי זה לא התאים, אז יצרתי {לא יפה לומר ככה. GEMINI יצר עבורי...} קוד לדף אינטרנט יפה ומעוצב שנותן לשמור תזכורות [ע"י עוגיות בדפדפן] ולמחוק, וגם להגדיר סיסמה
צילו"מ לדוגמה בספויילראז הנה אני משתף את זה איתכם, תהנו...
קישור לקוד בגיטהאב
הקוד המלא בספויילר,ניתן כמובן לשמור באופן מקומי על המחשב שלכם בקובץ בסיומת HTML ולפתוח בדפדפן. תהנו...
עריכה: א"א להשתמש בקוד הנוכחי באופן מקומי, מצורף כאן קובץ עם קוד אחר שלא משתמש בעוגיות אלא ב-localStorage ומיועד להרצה על מחשב מקומי תזכורות.txt (קליק ימני, שמירת קישור בשם. להחליף את הסיומת ל-html כמובן)<!DOCTYPE html> <html lang="he" dir="rtl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>מנהל התזכורות</title> <style> @keyframes subtleGradientShift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } body { color: #00ffcc; font-family: 'Courier New', Courier, monospace; margin: 0; padding: 20px; display: flex; flex-direction: column; align-items: center; min-height: 100vh; background: linear-gradient(270deg, #0a0f1f, #10152f, #0a0f1f); background-size: 600% 600%; animation: subtleGradientShift 30s ease infinite; } .container { background-color: rgba(26, 31, 54, 0.85); backdrop-filter: blur(5px); padding: 30px; border-radius: 15px; box-shadow: 0 0 35px rgba(0, 255, 204, 0.4), 0 0 15px rgba(0, 255, 204, 0.2) inset; border: 1px solid #00ffcc; width: 90%; max-width: 700px; text-align: center; margin-top: 20px; } h1 { color: #ffffff; text-shadow: 0 0 10px #00ffcc; margin-bottom: 30px; } .input-area, .password-area { margin-bottom: 25px; display: flex; gap: 10px; flex-wrap: wrap; } input[type="text"], input[type="password"] { flex-grow: 1; padding: 12px 15px; background-color: #0a0f1f; color: #e0e0e0; border: 1px solid #007766; border-radius: 8px; font-size: 16px; outline: none; min-width: 200px; } input[type="text"]::placeholder, input[type="password"]::placeholder { color: #555f78; } input[type="text"]:focus, input[type="password"]:focus { border-color: #00ffcc; box-shadow: 0 0 10px rgba(0, 255, 204, 0.4); } button { padding: 12px 20px; background-color: #007766; color: #ffffff; border: none; border-radius: 8px; cursor: pointer; font-size: 16px; transition: background-color 0.3s ease, box-shadow 0.3s ease; text-shadow: 0 0 5px rgba(0,0,0,0.5); flex-shrink: 0; } button:hover { background-color: #00ffcc; color: #0a0f1f; box-shadow: 0 0 15px rgba(0, 255, 204, 0.6); } button.delete-btn { background-color: #990033; padding: 5px 10px; font-size: 12px; } button.delete-btn:hover { background-color: #ff3366; } button.cancel-btn { background-color: #4a4f66; } button.cancel-btn:hover { background-color: #6a6f86; } #deleteAllRemindersBtn { background-color: #cc0000; margin-top: 10px; width: 100%; font-size: 1em; padding: 12px 20px; } #deleteAllRemindersBtn:hover { background-color: #ff4d4d; } #remindersListArea { margin-top: 20px; background-color: rgba(10, 15, 31, 0.7); padding: 20px; border-radius: 10px; border: 1px dashed #007766; min-height: 100px; text-align: right; } #remindersListArea h2 { color: #ffffff; text-align: center; margin-top: 0; margin-bottom: 15px; border-bottom: 1px solid #007766; padding-bottom: 10px; } .reminder-item { background-color: #1a1f36; border: 1px solid #00ffcc; padding: 10px; margin-bottom: 8px; border-radius: 5px; color: #e0e0e0; font-size: 15px; word-wrap: break-word; display: flex; justify-content: space-between; align-items: center; } .reminder-item-text { flex-grow: 1; text-align: right; } .hidden { display: none !important; } #toast-container { position: fixed; bottom: 20px; left: 20px; z-index: 10000; display: flex; flex-direction: column-reverse; gap: 10px; } .toast-message { background-color: #00ffcc; color: #0a0f1f; padding: 12px 18px; border-radius: 8px; box-shadow: 0 3px 12px rgba(0,0,0,0.25); opacity: 0; transform: translateX(-100%); transition: opacity 0.4s ease-out, transform 0.4s ease-out; min-width: 250px; text-align: left; } .toast-message.show { opacity: 0.95; transform: translateX(0); } .toast-message.error { background-color: #ff3366; color: #ffffff; } .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.7); display: flex; justify-content: center; align-items: center; z-index: 9000; opacity: 0; transition: opacity 0.3s ease-in-out; } .modal-overlay.show { opacity: 1; } .modal-content { background-color: #1a1f36; padding: 30px 40px; border-radius: 12px; border: 1px solid #00ffcc; text-align: center; box-shadow: 0 0 30px rgba(0, 255, 204, 0.5); transform: scale(0.7); transition: transform 0.3s ease-in-out; } .modal-overlay.show .modal-content { transform: scale(1); } .modal-content p { margin-bottom: 25px; font-size: 1.1em; color: #e0e0e0; } .modal-buttons button { margin: 0 12px; } #confirm-no-btn { background-color: #4a4f66; } #confirm-no-btn:hover { background-color: #6a6f86; } #passwordManagementArea { margin-top: 20px; } #passwordMgmtBtn { background-color: #3a3f56; } #passwordMgmtBtn:hover { background-color: #555f78; } </style> </head> <body> <div class="container"> <h1>מנהל התזכורות</h1> <div id="password-section" class="hidden"> <div id="password-setup-area" class="password-area hidden"> <p>הגדר סיסמה לגישה לתזכורות:</p> <input type="password" id="newPassword" placeholder="הזן סיסמה חדשה (לפחות 4 תווים)"> <button id="setPasswordBtn">הגדר סיסמה</button> <button id="cancelPasswordSetupBtn" class="cancel-btn">ביטול</button> </div> <div id="password-entry-area" class="password-area hidden"> <p>אנא הזן את הסיסמה שלך כדי לגשת לתזכורות:</p> <input type="password" id="enteredPassword" placeholder="הזן סיסמה"> <button id="loginBtn">הכנס</button> <button id="cancelLoginAttemptBtn" class="cancel-btn hidden">ביטול</button> </div> </div> <div id="app-content-area"> <div class="input-area"> <input type="text" id="reminderText" placeholder="הזן תזכורת חדשה ולחץ Enter או על הכפתור..."> <button id="saveReminderBtn">שמור תזכורת</button> </div> <button id="toggleRemindersBtn">הצג את כל התזכורות</button> <button id="deleteAllRemindersBtn">מחק את כל התזכורות</button> <div id="remindersListArea" class="hidden"> <h2>רשימת תזכורות:</h2> <div id="remindersList"> <p>עדיין לא נשמרו תזכורות, או שלא נלחץ על כפתור ההצגה.</p> </div> </div> <div id="passwordManagementArea"> <button id="passwordMgmtBtn">הפעל הגנת סיסמה</button> </div> </div> </div> <div id="toast-container"></div> <div id="confirmation-modal-overlay" class="modal-overlay hidden"> <div class="modal-content"> <p id="confirmation-message">האם אתה בטוח?</p> <div class="modal-buttons"> <button id="confirm-yes-btn" class="confirm-action-btn">כן</button> <button id="confirm-no-btn" class="confirm-action-btn">לא</button> </div> </div> </div> <script> const APP_PASSWORD_COOKIE = 'app_access_password_v1'; const REMINDER_PREFIX = "reminder_item_"; const passwordSection = document.getElementById('password-section'); const passwordSetupArea = document.getElementById('password-setup-area'); const newPasswordInput = document.getElementById('newPassword'); const setPasswordBtn = document.getElementById('setPasswordBtn'); const cancelPasswordSetupBtn = document.getElementById('cancelPasswordSetupBtn'); const passwordEntryArea = document.getElementById('password-entry-area'); const enteredPasswordInput = document.getElementById('enteredPassword'); const loginBtn = document.getElementById('loginBtn'); const cancelLoginAttemptBtn = document.getElementById('cancelLoginAttemptBtn'); const appContentArea = document.getElementById('app-content-area'); const reminderTextElement = document.getElementById('reminderText'); const saveReminderBtn = document.getElementById('saveReminderBtn'); const toggleRemindersBtn = document.getElementById('toggleRemindersBtn'); const deleteAllRemindersBtn = document.getElementById('deleteAllRemindersBtn'); const remindersListArea = document.getElementById('remindersListArea'); const remindersListDiv = document.getElementById('remindersList'); const passwordMgmtBtn = document.getElementById('passwordMgmtBtn'); const toastContainer = document.getElementById('toast-container'); const confirmationModalOverlay = document.getElementById('confirmation-modal-overlay'); const confirmationMessageElement = document.getElementById('confirmation-message'); const confirmYesBtn = document.getElementById('confirm-yes-btn'); const confirmNoBtn = document.getElementById('confirm-no-btn'); let currentOnConfirmCallback = null; function setCookie(name, value, days) { let expires = ""; if (days) { const date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toUTCString(); } document.cookie = name + "=" + (encodeURIComponent(value) || "") + expires + "; path=/; SameSite=Lax"; } function getCookie(name) { const nameEQ = name + "="; const ca = document.cookie.split(';'); for(let i = 0; i < ca.length; i++) { let c = ca[i]; while (c.charAt(0) === ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) === 0) return decodeURIComponent(c.substring(nameEQ.length, c.length)); } return null; } function eraseCookie(name) { document.cookie = name+'=; Max-Age=-99999999; path=/; SameSite=Lax'; } function getAllReminderCookies() { const cookies = {}; if (document.cookie && document.cookie !== '') { document.cookie.split(';').forEach(function(cookie) { const parts = cookie.match(/^\s*([^=]+)=(.*)$/); if(parts && parts.length === 3 && parts[1].startsWith(REMINDER_PREFIX)) { cookies[parts[1]] = decodeURIComponent(parts[2]); } }); } return cookies; } function showToast(message, type = 'success', duration = 2500) { const toast = document.createElement('div'); toast.classList.add('toast-message'); if (type === 'error') toast.classList.add('error'); toast.textContent = message; toastContainer.appendChild(toast); setTimeout(() => toast.classList.add('show'), 10); setTimeout(() => { toast.classList.remove('show'); toast.addEventListener('transitionend', () => toast.remove(), { once: true }); }, duration); } function showConfirmation(message, onConfirm) { confirmationMessageElement.textContent = message; currentOnConfirmCallback = onConfirm; confirmationModalOverlay.classList.remove('hidden'); setTimeout(() => confirmationModalOverlay.classList.add('show'), 10); } function hideConfirmation() { confirmationModalOverlay.classList.remove('show'); confirmationModalOverlay.addEventListener('transitionend', () => { confirmationModalOverlay.classList.add('hidden'); currentOnConfirmCallback = null; }, { once: true }); } confirmYesBtn.addEventListener('click', () => { if (currentOnConfirmCallback) currentOnConfirmCallback(); hideConfirmation(); }); confirmNoBtn.addEventListener('click', hideConfirmation); function updatePasswordMgmtButton() { if (getCookie(APP_PASSWORD_COOKIE)) { passwordMgmtBtn.textContent = "הסר הגנת סיסמה"; } else { passwordMgmtBtn.textContent = "הפעל הגנת סיסמה"; } } passwordMgmtBtn.addEventListener('click', () => { if (getCookie(APP_PASSWORD_COOKIE)) { showConfirmation("האם אתה בטוח שברצונך להסיר את הגנת הסיסמה? התזכורות יהיו נגישות ללא סיסמה.", () => { eraseCookie(APP_PASSWORD_COOKIE); showToast("הגנת הסיסמה הוסרה."); updatePasswordMgmtButton(); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); }); } else { passwordSection.classList.remove('hidden'); passwordSetupArea.classList.remove('hidden'); passwordEntryArea.classList.add('hidden'); appContentArea.classList.add('hidden'); } }); setPasswordBtn.addEventListener('click', () => { const newPassword = newPasswordInput.value; if (newPassword.length < 4) { showToast("הסיסמה חייבת להכיל לפחות 4 תווים.", 'error'); return; } setCookie(APP_PASSWORD_COOKIE, btoa(newPassword), 365); showToast("הסיסמה הוגדרה בהצלחה!"); newPasswordInput.value = ''; passwordSetupArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); updatePasswordMgmtButton(); }); cancelPasswordSetupBtn.addEventListener('click', () => { passwordSetupArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); newPasswordInput.value = ''; }); cancelLoginAttemptBtn.addEventListener('click', () => { enteredPasswordInput.value = ''; showToast("הגישה מוגנת. עליך להזין סיסמה כדי להמשיך.", "error", 3000); appContentArea.classList.add('hidden'); passwordSection.classList.remove('hidden'); passwordEntryArea.classList.remove('hidden'); }); loginBtn.addEventListener('click', () => { const enteredPassword = enteredPasswordInput.value; const storedEncodedPassword = getCookie(APP_PASSWORD_COOKIE); if (!storedEncodedPassword) { showToast("שגיאה: לא נמצאה סיסמה שמורה.", 'error'); passwordEntryArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); updatePasswordMgmtButton(); return; } try { if (btoa(enteredPassword) === storedEncodedPassword) { showToast("התחברת בהצלחה!"); passwordEntryArea.classList.add('hidden'); passwordSection.classList.add('hidden'); appContentArea.classList.remove('hidden'); enteredPasswordInput.value = ''; cancelLoginAttemptBtn.classList.add('hidden'); updatePasswordMgmtButton(); } else { showToast("סיסמה שגויה. נסה שוב.", 'error'); enteredPasswordInput.value = ''; } } catch (e) { showToast("שגיאה בעיבוד הסיסמה.", 'error'); } }); function saveReminder() { const reminderText = reminderTextElement.value.trim(); if (reminderText === "") { showToast("אנא הזן תוכן לתזכורת.", 'error'); return; } const cookieName = REMINDER_PREFIX + Date.now(); setCookie(cookieName, reminderText, 365); showToast("התזכורת נשמרה!"); reminderTextElement.value = ""; if (!remindersListArea.classList.contains('hidden')) { displayReminders(); } } function displayReminders() { remindersListDiv.innerHTML = ""; const allCookies = getAllReminderCookies(); let remindersFound = false; const sortedCookieNames = Object.keys(allCookies).sort((a, b) => { return parseInt(b.substring(REMINDER_PREFIX.length)) - parseInt(a.substring(REMINDER_PREFIX.length)); }); for (const cookieName of sortedCookieNames) { remindersFound = true; const reminderValue = allCookies[cookieName]; const reminderElement = document.createElement('div'); reminderElement.classList.add('reminder-item'); const textSpan = document.createElement('span'); textSpan.classList.add('reminder-item-text'); textSpan.textContent = reminderValue; const deleteButton = document.createElement('button'); deleteButton.classList.add('delete-btn'); deleteButton.textContent = "מחק"; deleteButton.onclick = function() { showConfirmation(`האם אתה בטוח שברצונך למחוק את התזכורת: "${reminderValue.substring(0,20)}..."?`, () => { eraseCookie(cookieName); showToast("התזכורת נמחקה."); displayReminders(); }); }; reminderElement.appendChild(deleteButton); reminderElement.appendChild(textSpan); remindersListDiv.appendChild(reminderElement); } if (!remindersFound) { remindersListDiv.innerHTML = "<p>לא נמצאו תזכורות שמורות.</p>"; } } function toggleRemindersDisplay() { remindersListArea.classList.toggle('hidden'); if (remindersListArea.classList.contains('hidden')) { toggleRemindersBtn.textContent = "הצג את כל התזכורות"; } else { toggleRemindersBtn.textContent = "הסתר תזכורות"; displayReminders(); } } function deleteAllReminders() { showConfirmation("האם אתה בטוח שברצונך למחוק את *כל* התזכורות? לא ניתן יהיה לשחזר פעולה זו.", () => { const allReminderCookies = getAllReminderCookies(); let remindersWereDeleted = false; for (const cookieName in allReminderCookies) { eraseCookie(cookieName); remindersWereDeleted = true; } if (remindersWereDeleted) { showToast("כל התזכורות נמחקו בהצלחה!"); } else { showToast("לא נמצאו תזכורות למחיקה.", "error"); } displayReminders(); }); } window.onload = function() { const storedPassword = getCookie(APP_PASSWORD_COOKIE); if (storedPassword) { appContentArea.classList.add('hidden'); passwordSection.classList.remove('hidden'); passwordEntryArea.classList.remove('hidden'); passwordSetupArea.classList.add('hidden'); cancelLoginAttemptBtn.classList.remove('hidden'); } else { appContentArea.classList.remove('hidden'); passwordSection.classList.add('hidden'); cancelLoginAttemptBtn.classList.add('hidden'); } updatePasswordMgmtButton(); newPasswordInput.addEventListener('keypress', function(event) { if (event.key === 'Enter' || event.keyCode === 13) { setPasswordBtn.click(); } }); enteredPasswordInput.addEventListener('keypress', function(event) { if (event.key === 'Enter' || event.keyCode === 13) { loginBtn.click(); } }); saveReminderBtn.addEventListener('click', saveReminder); reminderTextElement.addEventListener('keypress', function(event) { if (event.key === 'Enter' || event.keyCode === 13) { event.preventDefault(); saveReminder(); } }); toggleRemindersBtn.addEventListener('click', toggleRemindersDisplay); deleteAllRemindersBtn.addEventListener('click', deleteAllReminders); }; </script> </body> </html>
@אופיר123 כתב בשיתוף | מנהל התזכורות לדפדפן | שיתוף חמוד שאולי יהיה לכם שימושי:
עריכה: א"א להשתמש בקוד הנוכחי באופן מקומי, מצורף כאן קובץ עם קוד אחר שלא משתמש בעוגיות אלא ב-localStorage ומיועד להרצה על מחשב מקומי תזכורות.html
Spoiler
בדקת את זה או שסמכת על גמיני?...
לי עדיין לא עובד... -
@אופיר123 כתב בשיתוף | מנהל התזכורות לדפדפן | שיתוף חמוד שאולי יהיה לכם שימושי:
עריכה: א"א להשתמש בקוד הנוכחי באופן מקומי, מצורף כאן קובץ עם קוד אחר שלא משתמש בעוגיות אלא ב-localStorage ומיועד להרצה על מחשב מקומי תזכורות.html
Spoiler
בדקת את זה או שסמכת על גמיני?...
לי עדיין לא עובד... -
@אופיר123 כתב בשיתוף | מנהל התזכורות לדפדפן | שיתוף חמוד שאולי יהיה לכם שימושי:
עריכה: א"א להשתמש בקוד הנוכחי באופן מקומי, מצורף כאן קובץ עם קוד אחר שלא משתמש בעוגיות אלא ב-localStorage ומיועד להרצה על מחשב מקומי תזכורות.html
Spoiler
בדקת את זה או שסמכת על גמיני?...
לי עדיין לא עובד...@MAKRO כתב בשיתוף | מנהל התזכורות לדפדפן | שיתוף חמוד שאולי יהיה לכם שימושי:
לי עדיין לא עובד...
הורדת את הקובץ המצורף למעלה? כי את הקוד בספויילר לא שיניתי
משום מה אני מנסה עכשיו להוריד את הקובץ ומקבל שגיאה 403, נראה לי שפשוט יש מגבלה על קבצי HTML בפורום, אני יחליף לZIP -
@MAKRO כתב בשיתוף | מנהל התזכורות לדפדפן | שיתוף חמוד שאולי יהיה לכם שימושי:
לי עדיין לא עובד...
הורדת את הקובץ המצורף למעלה? כי את הקוד בספויילר לא שיניתי
משום מה אני מנסה עכשיו להוריד את הקובץ ומקבל שגיאה 403, נראה לי שפשוט יש מגבלה על קבצי HTML בפורום, אני יחליף לZIP -
@אופיר123
גם לי הייתה שגיאה
השתמשתי בספוילר....
עכשיו אני מבין
אגב, דיברתי בנתיים עם גמיני שיסדר את זה, הוא סידר את העניינים אבל הרס את הCSS
אז אני ממתין לשלך...עריכה: עובד מצוין! תודה!!
@MAKRO כתב בשיתוף | מנהל התזכורות לדפדפן | שיתוף חמוד שאולי יהיה לכם שימושי:
הוא סידר את העניינים אבל הרס את הCSS
כמו תמיד... אחרי הכל הוא רק AI שאולי חכם מאוד, אבל טיפש הרבה יותר...
אין על מה שהקב"ה ברא, הראש המקורי עובד הכי טוב.. כמובן אפשר להשתמש בו בשביל ליצור דברים חדשים אבל אסור לשכוח אותו בצד...