changed frontend structure
authorPhiTux <redacted>
Fri, 18 Jul 2025 16:56:06 +0000 (18:56 +0200)
committerPhiTux <redacted>
Fri, 18 Jul 2025 16:56:06 +0000 (18:56 +0200)
frontend/src/lib/DatepickerLogic.svelte
frontend/src/lib/helpers.js
frontend/src/routes/(authed)/+layout.svelte [new file with mode: 0644]
frontend/src/routes/(authed)/read/+page.js [moved from frontend/src/routes/read/+page.js with 100% similarity]
frontend/src/routes/(authed)/read/+page.svelte [moved from frontend/src/routes/read/+page.svelte with 98% similarity]
frontend/src/routes/(authed)/write/+page.js [moved from frontend/src/routes/write/+page.js with 100% similarity]
frontend/src/routes/(authed)/write/+page.svelte [moved from frontend/src/routes/write/+page.svelte with 99% similarity]
frontend/src/routes/+layout.svelte

index 650aa20a17f5d2048453ba292f9cd1b86cc0c337..9e2212fa27f171920967310a26e7ae3e2f1d17a7 100644 (file)
@@ -2,6 +2,7 @@
        import { API_URL } from '$lib/APIurl.js';
        import { cal } from '$lib/calendarStore.js';
        import axios from 'axios';
+       import { currentUser } from '$lib/helpers.js';
 
        $effect(() => {
                if ($cal.currentMonth || $cal.currentYear) {
                        return;
                }
 
+               if (!$currentUser) {
+                       console.log('User not logged in, skipping loadMarkedDays');
+                       return;
+               }
+
                if (isLoadingMarkedDays) {
                        return;
                }
index bb8590bcc932a06bac2fe48ac390e1a7b405d7a0..086fa6d68b318fbb3768fcbcc40a6890cf193683 100644 (file)
@@ -26,5 +26,3 @@ export let alwaysShowSidenav = writable(true);
 
 // check if offcanvas/sidenav is open
 export let offcanvasIsOpen = writable(false);
-
-export let currentUser = writable("")
\ No newline at end of file
diff --git a/frontend/src/routes/(authed)/+layout.svelte b/frontend/src/routes/(authed)/+layout.svelte
new file mode 100644 (file)
index 0000000..4644868
--- /dev/null
@@ -0,0 +1,1318 @@
+<script>
+       import * as bootstrap from 'bootstrap';
+       import Fa from 'svelte-fa';
+       import { goto } from '$app/navigation';
+       import { onMount } from 'svelte';
+       import {
+               readingMode,
+               settings,
+               tempSettings,
+               autoLoadImagesThisDevice,
+               useTrianglify,
+               trianglifyOpacity
+       } from '$lib/settingsStore.js';
+       import { API_URL } from '$lib/APIurl.js';
+       import { tags } from '$lib/tagStore.js';
+       import TagModal from '$lib/TagModal.svelte';
+       import { alwaysShowSidenav } from '$lib/helpers.js';
+       import { templates } from '$lib/templateStore';
+       import {
+               faRightFromBracket,
+               faGlasses,
+               faPencil,
+               faSliders,
+               faTriangleExclamation,
+               faTrash
+       } from '@fortawesome/free-solid-svg-icons';
+       import Tag from '$lib/Tag.svelte';
+       import SelectTimezone from '$lib/SelectTimezone.svelte';
+       import axios from 'axios';
+       import { page } from '$app/state';
+       import { blur, slide, fade } from 'svelte/transition';
+
+       let { children } = $props();
+       let inDuration = 150;
+       let outDuration = 150;
+
+       $effect(() => {
+               if ($readingMode === true && page.url.pathname !== '/read') {
+                       goto('/read');
+               } else if ($readingMode === false) {
+                       goto('/write');
+               }
+       });
+
+       onMount(() => {
+               getUserSettings();
+               getTemplates();
+
+               if (page.url.pathname === '/read') {
+                       $readingMode = true;
+               } else if (page.url.pathname === '/write') {
+                       $readingMode = false;
+               }
+
+               const scrollSpy = new bootstrap.ScrollSpy(document.body, {
+                       target: '#settings-nav'
+               });
+
+               document.getElementById('settingsModal').addEventListener('shown.bs.modal', function () {
+                       console.log("triggered 'shown.bs.modal' event");
+                       const height = document.getElementById('modal-body').clientHeight;
+                       document.getElementById('settings-content').style.height = 'calc(' + height + 'px - 2rem)';
+                       document.getElementById('settings-nav').style.height = 'calc(' + height + 'px - 2rem)';
+                       document.getElementById('settings-content').style.overflowY = 'auto';
+
+                       setTimeout(() => {
+                               const dataSpyList = document.querySelectorAll('[data-bs-spy="scroll"]');
+                               dataSpyList.forEach((dataSpyEl) => {
+                                       //bootstrap.ScrollSpy.getInstance(dataSpyEl).refresh();
+                                       scrollSpy.refresh();
+                               });
+                       }, 400);
+               });
+       });
+
+       function logout() {
+               axios
+                       .get(API_URL + '/users/logout')
+                       .then((response) => {
+                               localStorage.removeItem('user');
+                               goto('/login');
+                       })
+                       .catch((error) => {
+                               console.error(error);
+
+                               // show toast
+                               const toast = new bootstrap.Toast(document.getElementById('toastErrorLogout'));
+                               toast.show();
+                       });
+       }
+
+       let settingsModal;
+       function openSettingsModal() {
+               $tempSettings = JSON.parse(JSON.stringify($settings));
+               onThisDayYears = $settings.onThisDayYears.toString();
+
+               settingsModal = new bootstrap.Modal(document.getElementById('settingsModal'));
+               settingsModal.show();
+       }
+
+       /* Important for development: convenient modal-handling with HMR */
+       if (import.meta.hot) {
+               import.meta.hot.dispose(() => {
+                       document.querySelectorAll('.modal-backdrop').forEach((el) => el.remove());
+               });
+       }
+
+       let onThisDayYears = $state('');
+       let isGettingUserSettings = $state(false);
+       function getUserSettings() {
+               if (isGettingUserSettings) return;
+               isGettingUserSettings = true;
+
+               axios
+                       .get(API_URL + '/users/getUserSettings')
+                       .then((response) => {
+                               $settings = response.data;
+                               onThisDayYears = $settings.onThisDayYears.toString();
+                       })
+                       .catch((error) => {
+                               console.error(error);
+                       })
+                       .finally(() => {
+                               if ($autoLoadImagesThisDevice === null || $autoLoadImagesThisDevice === undefined) {
+                                       $autoLoadImagesThisDevice = $settings.autoloadImagesByDefault;
+                               }
+                               isGettingUserSettings = false;
+                       });
+       }
+
+       let onThisDayYearsInvalid = $state(false);
+       // check if onThisDayYears is valid
+       $effect(() => {
+               onThisDayYearsInvalid = false;
+               if ($tempSettings.useOnThisDay === false) {
+                       return;
+               }
+
+               //regex: years may only contain numbers and commas
+               if (onThisDayYears.match(/[^0-9,]/)) {
+                       onThisDayYearsInvalid = true;
+                       return;
+               }
+
+               onThisDayYears
+                       .trim()
+                       .split(',')
+                       .forEach((year) => {
+                               if (!Number.isInteger(parseInt(year.trim()))) {
+                                       onThisDayYearsInvalid = true;
+                               }
+                               return year;
+                       });
+       });
+
+       let settingsHaveChanged = $derived(
+               JSON.stringify($settings) !== JSON.stringify($tempSettings) ||
+                       JSON.stringify($settings.onThisDayYears) !==
+                               JSON.stringify(
+                                       onThisDayYears
+                                               .trim()
+                                               .split(',')
+                                               .map((year) => parseInt(year.trim()))
+                               )
+       );
+
+       let isSaving = $state(false);
+       function saveUserSettings() {
+               if (isSaving) return;
+               isSaving = true;
+
+               $tempSettings.onThisDayYears = onThisDayYears
+                       .trim()
+                       .split(',')
+                       .map((year) => parseInt(year.trim()));
+
+               axios
+                       .post(API_URL + '/users/saveUserSettings', $tempSettings)
+                       .then((response) => {
+                               if (response.data.success) {
+                                       $settings = $tempSettings;
+
+                                       // show toast
+                                       const toast = new bootstrap.Toast(document.getElementById('toastSuccessSaveSettings'));
+                                       toast.show();
+
+                                       settingsModal.hide();
+                               } else {
+                                       console.error('Error saving settings');
+                               }
+                       })
+                       .catch((error) => {
+                               console.error(error);
+
+                               // show toast
+                               const toast = new bootstrap.Toast(document.getElementById('toastErrorSaveSettings'));
+                               toast.show();
+                       })
+                       .finally(() => {
+                               isSaving = false;
+                       });
+       }
+
+       let editTagModal;
+       let editTag = $state({});
+       let isSavingEditedTag = $state(false);
+
+       function openTagModal(tagId) {
+               $tags.forEach((tag) => {
+                       if (tag.id === tagId) {
+                               editTag.name = tag.name;
+                               editTag.color = tag.color;
+                               editTag.icon = tag.icon;
+                               editTag.id = tag.id;
+                               return;
+                       }
+               });
+
+               settingsModal.hide();
+               editTagModal.open();
+       }
+
+       let selectedTemplate = $state(null);
+       let templateName = $state('');
+       let templateText = $state('');
+       let oldTemplateName = $state('');
+       let oldTemplateText = $state('');
+       let confirmDeleteTemplate = $state(false);
+
+       function getTemplates() {
+               axios
+                       .get(API_URL + '/logs/getTemplates')
+                       .then((response) => {
+                               $templates = response.data;
+
+                               selectedTemplate = null;
+                               updateSelectedTemplate();
+                       })
+                       .catch((error) => {
+                               console.error(error);
+                       });
+       }
+
+       let isSavingTemplate = $state(false);
+       function saveTemplate() {
+               // check if name or text is empty
+               if (templateName === '' || templateText === '') {
+                       // show toast
+                       const toast = new bootstrap.Toast(document.getElementById('toastErrorInvalidTemplateEmpty'));
+                       toast.show();
+                       return;
+               }
+
+               // check if template name already exists
+               for (let i = 0; i < $templates.length; i++) {
+                       if ($templates[i].name === templateName && selectedTemplate !== i) {
+                               // show toast
+                               const toast = new bootstrap.Toast(
+                                       document.getElementById('toastErrorInvalidTemplateDouble')
+                               );
+                               toast.show();
+                               return;
+                       }
+               }
+
+               if (isSavingTemplate) return;
+               isSavingTemplate = true;
+
+               if (selectedTemplate === '-1') {
+                       // add new template
+                       $templates.push({ name: templateName, text: templateText });
+               } else {
+                       // update existing template
+                       $templates[selectedTemplate].name = templateName;
+                       $templates[selectedTemplate].text = templateText;
+               }
+
+               axios
+                       .post(API_URL + '/logs/saveTemplates', {
+                               templates: $templates
+                       })
+                       .then((response) => {
+                               if (response.data.success) {
+                                       getTemplates();
+
+                                       // show toast
+                                       const toast = new bootstrap.Toast(document.getElementById('toastSuccessSaveTemplate'));
+                                       toast.show();
+                               }
+                       })
+                       .catch((error) => {
+                               console.error(error);
+
+                               // show toast
+                               const toast = new bootstrap.Toast(document.getElementById('toastErrorSaveTemplates'));
+                               toast.show();
+                       })
+                       .finally(() => {
+                               isSavingTemplate = false;
+                       });
+       }
+
+       let isDeletingTemplate = $state(false);
+       function deleteTemplate() {
+               if (selectedTemplate === null || selectedTemplate === '-1') return;
+
+               if (isDeletingTemplate) return;
+               isDeletingTemplate = true;
+
+               // remove template from list
+               $templates.splice(selectedTemplate, 1);
+
+               axios
+                       .post(API_URL + '/logs/saveTemplates', {
+                               templates: $templates
+                       })
+                       .then((response) => {
+                               if (response.data.success) {
+                                       getTemplates();
+
+                                       // show toast
+                                       const toast = new bootstrap.Toast(
+                                               document.getElementById('toastSuccessDeletingTemplate')
+                                       );
+                                       toast.show();
+                               }
+                       })
+                       .catch((error) => {
+                               console.error(error);
+                               // show toast
+                               const toast = new bootstrap.Toast(document.getElementById('toastErrorDeletingTemplate'));
+                               toast.show();
+                       })
+                       .finally(() => {
+                               isDeletingTemplate = false;
+                               confirmDeleteTemplate = false;
+                       });
+       }
+
+       function updateSelectedTemplate() {
+               if (selectedTemplate === '-1' || selectedTemplate === null || $templates.length === 0) {
+                       // new template
+                       templateName = '';
+                       templateText = '';
+               } else {
+                       // existing template
+                       templateName = $templates[selectedTemplate].name;
+                       templateText = $templates[selectedTemplate].text;
+               }
+               oldTemplateName = templateName;
+               oldTemplateText = templateText;
+
+               confirmDeleteTemplate = false;
+       }
+
+       let deleteTagId = $state(null);
+       function askDeleteTag(tagId) {
+               if (deleteTagId === tagId) deleteTagId = null;
+               else deleteTagId = tagId;
+       }
+
+       let isDeletingTag = $state(false);
+       function deleteTag(tagId) {
+               if (isDeletingTag) return;
+               isDeletingTag = true;
+
+               axios
+                       .get(API_URL + '/logs/deleteTag', { params: { id: tagId } })
+                       .then((response) => {
+                               if (response.data.success) {
+                                       $tags = $tags.filter((tag) => tag.id !== tagId);
+                               }
+                       })
+                       .catch((error) => {
+                               console.error(error);
+
+                               // show toast
+                               const toast = new bootstrap.Toast(document.getElementById('toastErrorDeleteTag'));
+                               toast.show();
+                       })
+                       .finally(() => {
+                               deleteTagId = null;
+                               isDeletingTag = false;
+                       });
+       }
+
+       function saveEditedTag() {
+               if (isSavingEditedTag) return;
+               isSavingEditedTag = true;
+
+               axios
+                       .post(API_URL + '/logs/editTag', editTag)
+                       .then((response) => {
+                               if (response.data.success) {
+                                       $tags = $tags.map((tag) => {
+                                               if (tag.id === editTag.id) {
+                                                       tag.name = editTag.name;
+                                                       tag.color = editTag.color;
+                                                       tag.icon = editTag.icon;
+                                               }
+                                               return tag;
+                                       });
+
+                                       // show toast
+                                       const toast = new bootstrap.Toast(document.getElementById('toastSuccessEditTag'));
+                                       toast.show();
+                               }
+                       })
+                       .catch((error) => {
+                               console.error(error);
+
+                               // show toast
+                               const toast = new bootstrap.Toast(document.getElementById('toastErrorEditTag'));
+                               toast.show();
+                       })
+                       .finally(() => {
+                               isSavingEditedTag = false;
+                               editTagModal.close();
+                               openSettingsModal();
+                       });
+       }
+
+       $effect(() => {
+               if ($autoLoadImagesThisDevice === null || $autoLoadImagesThisDevice === undefined) {
+                       return;
+               }
+
+               localStorage.setItem('autoLoadImagesThisDevice', $autoLoadImagesThisDevice);
+       });
+
+       let currentPassword = $state('');
+       let newPassword = $state('');
+       let confirmNewPassword = $state('');
+       let changePasswordNotEqual = $state(false);
+       let isChangingPassword = $state(false);
+       let changingPasswordSuccess = $state(false);
+       let changingPasswordError = $state(false);
+       let changingPasswordIncorrect = $state(false);
+
+       function changePassword() {
+               changePasswordNotEqual = false;
+               changingPasswordSuccess = false;
+               changingPasswordError = false;
+               changingPasswordIncorrect = false;
+
+               if (newPassword !== confirmNewPassword) {
+                       changePasswordNotEqual = true;
+                       return;
+               }
+
+               if (isChangingPassword) return;
+               isChangingPassword = true;
+
+               axios
+                       .post(API_URL + '/users/changePassword', {
+                               old_password: currentPassword,
+                               new_password: newPassword
+                       })
+                       .then((response) => {
+                               if (response.data.success) {
+                                       changingPasswordSuccess = true;
+                               } else {
+                                       changingPasswordError = true;
+                                       console.error('Error changing password');
+                                       if (response.data.password_incorrect) {
+                                               changingPasswordIncorrect = true;
+                                       }
+                               }
+                       })
+                       .catch((error) => {
+                               console.error(error);
+                               console.log('Error on Changing password:', error.response.data.message);
+                               changingPasswordError = true;
+                       })
+                       .finally(() => {
+                               isChangingPassword = false;
+                       });
+       }
+</script>
+
+<div class="d-flex flex-column h-100">
+       <nav class="navbar navbar-expand-lg bg-body-tertiary">
+               <div class="row w-100">
+                       <div class="col-lg-4 col-sm-5 col d-flex flex-row justify-content-start align-items-center">
+                               {#if !$alwaysShowSidenav}
+                                       <button
+                                               class="btn d-xl-none"
+                                               type="button"
+                                               data-bs-toggle="offcanvas"
+                                               data-bs-target="#sidenav"
+                                               aria-controls="sidenav">menü</button
+                                       >
+                               {/if}
+
+                               <div class="form-check form-switch d-flex flex-row">
+                                       <label class="me-3" for="selectMode"><Fa icon={faPencil} size="1.5x" /></label>
+                                       <div class="form-check form-switch">
+                                               <input
+                                                       class="form-check-input"
+                                                       bind:checked={$readingMode}
+                                                       type="checkbox"
+                                                       role="switch"
+                                                       id="selectMode"
+                                                       style="transform: scale(1.3);"
+                                               />
+                                       </div>
+                                       <label class="ms-2" for="selectMode"><Fa icon={faGlasses} size="1.5x" /></label>
+                               </div>
+                       </div>
+
+                       <div class="col-lg-4 col-sm-2 col d-flex flex-row justify-content-center align-items-center">
+                               Center-LOGO
+                       </div>
+
+                       <div class="col-lg-4 col-sm-5 col pe-0 d-flex flex-row justify-content-end">
+                               <button class="btn btn-outline-secondary me-2" onclick={openSettingsModal}
+                                       ><Fa icon={faSliders} /></button
+                               >
+                               <button class="btn btn-outline-secondary" onclick={logout}
+                                       ><Fa icon={faRightFromBracket} /></button
+                               >
+                       </div>
+               </div>
+       </nav>
+
+       {#key page.data}
+               <div
+                       class="transition-wrapper overflow-y-auto"
+                       out:blur={{ duration: outDuration }}
+                       in:blur={{ duration: inDuration, delay: outDuration }}
+               >
+                       {@render children()}
+               </div>
+       {/key}
+</div>
+
+<TagModal
+       bind:this={editTagModal}
+       createTag={false}
+       bind:editTag
+       isSaving={isSavingEditedTag}
+       {saveEditedTag}
+/>
+
+<!-- Full screen modal -->
+<div class="modal fade" data-bs-backdrop="static" id="settingsModal">
+       <div
+               class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-xl modal-fullscreen-sm-down"
+       >
+               <!--  -->
+               <div class="modal-content shadow-lg">
+                       <div class="modal-header">
+                               <h1>Settings</h1>
+                               <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+                       </div>
+                       <div class="modal-body" id="modal-body">
+                               <div class="row">
+                                       <div class="col-4 overflow-y-auto">
+                                               <nav class="flex-column align-items-stretch" id="settings-nav">
+                                                       <nav class="nav nav-pills flex-column">
+                                                               <a class="nav-link mb-1" href="#appearance">Aussehen</a>
+                                                               <!-- <a href="#lightdark" class="ms-3 mb-1 nav-link">Light/Dark-Mode</a>
+                                                                       <a href="#background" class="ms-3 mb-1 nav-link">Hintergrund</a> -->
+                                                               <a class="nav-link mb-1" href="#functions">Funktionen</a>
+                                                               <!-- <nav class="nav nav-pills flex-column">
+                                                                               <a href="#language" class="ms-3 mb-1 nav-link">Sprache</a>
+                                                                               <a href="#timezone" class="ms-3 mb-1 nav-link">Zeitzone</a>
+                                                                               <a href="#onthisday" class="ms-3 mb-1 nav-link">An diesem Tag</a>
+                                                                               <a href="#loginonreload" class="ms-3 mb-1 nav-link">Login bei Reload</a>
+                                                                       </nav> -->
+                                                               <a class="nav-link mb-1" href="#tags">Tags</a>
+                                                               <a class="nav-link mb-1" href="#templates">Vorlagen</a>
+                                                               <a class="nav-link mb-1" href="#data">Daten</a>
+                                                               <!-- <nav class="nav nav-pills flex-column">
+                                                                               <a href="#export" class="ms-3 nav-link mb-1">Export</a>
+                                                                               <a href="#import" class="ms-3 nav-link mb-1">Import</a>
+                                                                       </nav> -->
+                                                               <a class="nav-link mb-1" href="#security">Sicherheit</a>
+                                                               <!-- <nav class="nav nav-pills flex-column">
+                                                                               <a href="#password" class="ms-3 mb-1 nav-link">Password ändern</a>
+                                                                               <a href="#backupkeys" class="ms-3 mb-1 nav-link">Backup-Keys</a>
+                                                                               <a href="#username" class="ms-3 mb-1 nav-link">Username ändern</a>
+                                                                               <a href="#deleteaccount" class="ms-3 mb-1 nav-link">Konto löschen</a>
+                                                                       </nav> -->
+                                                               <a class="nav-link mb-1" href="#about">About</a>
+                                                       </nav>
+                                               </nav>
+                                       </div>
+                                       <div class="col-8">
+                                               <div
+                                                       class="settings-content overflow-y-auto"
+                                                       data-bs-spy="scroll"
+                                                       data-bs-target="#settings-nav"
+                                                       data-bs-smooth-scroll="true"
+                                                       id="settings-content"
+                                               >
+                                                       <div id="appearance">
+                                                               <h3 class="text-primary">🎨 Aussehen</h3>
+                                                               <div id="lightdark">
+                                                                       <h5>Light/Dark-Mode</h5>
+                                                                       Bla<br />
+                                                                       blub <br />
+                                                                       bla <br />
+                                                                       blub <br />
+                                                               </div>
+                                                               <div id="background">
+                                                                       <h5>Hintergrund</h5>
+                                                                       <div class="d-flex flex-row justify-content-start">
+                                                                               <label for="trianglifyOpacity" class="form-label"
+                                                                                       >Transparenz der Dreiecke</label
+                                                                               >
+                                                                               <input
+                                                                                       bind:value={$trianglifyOpacity}
+                                                                                       type="range"
+                                                                                       class="mx-3 form-range"
+                                                                                       id="trianglifyOpacity"
+                                                                                       min="0"
+                                                                                       max="1"
+                                                                                       step="0.01"
+                                                                               />
+                                                                               <input
+                                                                                       bind:value={$trianglifyOpacity}
+                                                                                       type="number"
+                                                                                       id="trianglifyOpacityNumber"
+                                                                               />
+                                                                       </div>
+                                                               </div>
+                                                       </div>
+
+                                                       <div id="functions">
+                                                               <h3 class="text-primary">🛠️ Funktionen</h3>
+
+                                                               <div id="autoLoadImages">
+                                                                       {#if $tempSettings.setAutoloadImagesPerDevice !== $settings.setAutoloadImagesPerDevice || $tempSettings.autoloadImagesByDefault !== $settings.autoloadImagesByDefault}
+                                                                               <div class="unsaved-changes" transition:slide></div>
+                                                                       {/if}
+
+                                                                       <h5>Bilder automatisch laden</h5>
+                                                                       <ul>
+                                                                               <li>
+                                                                                       Beim Laden eines Textes können hochgeladene Bilder (sofern vorhanden)
+                                                                                       automatisch geladen werden. <em>Erhöhter Datenverbrauch!</em>
+                                                                               </li>
+                                                                               <li>Alternativ wird ein Button zum Nachladen aller Bilder angezeigt.</li>
+                                                                       </ul>
+
+                                                                       <div class="form-check form-switch">
+                                                                               <input
+                                                                                       class="form-check-input"
+                                                                                       bind:checked={$tempSettings.setAutoloadImagesPerDevice}
+                                                                                       type="checkbox"
+                                                                                       role="switch"
+                                                                                       id="setImageLoadingPerDeviceSwitch"
+                                                                               />
+                                                                               <label class="form-check-label" for="setImageLoadingPerDeviceSwitch">
+                                                                                       Für jedes Gerät einzeln festlegen, ob die Bilder automatisch geladen werden
+                                                                                       sollen</label
+                                                                               >
+                                                                       </div>
+
+                                                                       <div class="form-check form-switch ms-3">
+                                                                               <input
+                                                                                       class="form-check-input"
+                                                                                       bind:checked={$autoLoadImagesThisDevice}
+                                                                                       type="checkbox"
+                                                                                       role="switch"
+                                                                                       id="loadImagesThisDeviceSwitch"
+                                                                                       disabled={!$tempSettings.setAutoloadImagesPerDevice}
+                                                                               />
+                                                                               <label class="form-check-label" for="loadImagesThisDeviceSwitch">
+                                                                                       {#if $autoLoadImagesThisDevice}
+                                                                                               Bilder werden auf <b>diesem Gerät</b> automatisch geladen
+                                                                                       {:else}
+                                                                                               Bilder werden auf <b>diesem Gerät <u>nicht</u></b> automatisch geladen
+                                                                                       {/if}</label
+                                                                               >
+                                                                       </div>
+
+                                                                       <div class="form-check form-switch mt-3">
+                                                                               <input
+                                                                                       class="form-check-input"
+                                                                                       bind:checked={$tempSettings.autoloadImagesByDefault}
+                                                                                       type="checkbox"
+                                                                                       role="switch"
+                                                                                       id="autoLoadImagesSwitch"
+                                                                                       disabled={$tempSettings.setAutoloadImagesPerDevice}
+                                                                               />
+                                                                               <label class="form-check-label" for="autoLoadImagesSwitch">
+                                                                                       {#if $tempSettings.autoloadImagesByDefault}
+                                                                                               Bilder werden (auf jedem Gerät) automatisch geladen
+                                                                                       {:else}
+                                                                                               Bilder werden (auf jedem Gerät) <b>nicht</b> automatisch geladen
+                                                                                       {/if}</label
+                                                                               >
+                                                                       </div>
+                                                               </div>
+
+                                                               <div id="language">
+                                                                       <h5>Sprache</h5>
+                                                                       Bla<br />
+                                                                       blub <br />
+                                                                       bla <br />
+                                                                       blub <br />
+                                                               </div>
+                                                               <div id="timezone">
+                                                                       {#if $tempSettings.useBrowserTimezone !== $settings.useBrowserTimezone || ($tempSettings.timezone !== undefined && $tempSettings.timezone?.value !== $settings.timezone?.value)}
+                                                                               <div class="unsaved-changes" transition:slide></div>
+                                                                       {/if}
+                                                                       <h5>Zeitzone</h5>
+                                                                       Stelle die Zeitzone ein, die für den Timestamp ("Geschrieben am") genutzt werden soll.
+
+                                                                       <div class="form-check mt-2">
+                                                                               <input
+                                                                                       class="form-check-input"
+                                                                                       type="radio"
+                                                                                       name="timezone"
+                                                                                       id="timezone1"
+                                                                                       value={true}
+                                                                                       bind:group={$tempSettings.useBrowserTimezone}
+                                                                               />
+                                                                               <label class="form-check-label" for="timezone1">
+                                                                                       Zeitzone automatisch anhand des Browsers ermitteln.
+                                                                               </label>
+                                                                               <br />
+                                                                               Aktuell: <code>{new Intl.DateTimeFormat().resolvedOptions().timeZone}</code>
+                                                                       </div>
+                                                                       <div class="form-check">
+                                                                               <input
+                                                                                       class="form-check-input"
+                                                                                       type="radio"
+                                                                                       name="timezone"
+                                                                                       id="timezone2"
+                                                                                       value={false}
+                                                                                       bind:group={$tempSettings.useBrowserTimezone}
+                                                                               />
+                                                                               <label class="form-check-label" for="timezone2">
+                                                                                       Für diesen Account immer die folgende Zeitzone verwenden:
+                                                                               </label>
+                                                                               <br />
+                                                                               <SelectTimezone />
+                                                                               {#if !$tempSettings.useBrowserTimezone}
+                                                                                       <span transition:fade>
+                                                                                               Ausgewählt: <code>{$tempSettings.timezone}</code>
+                                                                                       </span>
+                                                                               {/if}
+                                                                       </div>
+
+                                                                       <div class="form-text mt-3">
+                                                                               Wenn man auf Reisen ist, kann es sinnvoll sein, die Zeitzone anhand des Browsers
+                                                                               zu ermitteln. Dann werden Datum und Uhrzeit am Zielort vorraussichtlich besser
+                                                                               erkannt.<br />
+                                                                               Wenn man hingegen zuhause im privaten Browser teils andere Zeitzonen (z. B. immer
+                                                                               UTC) verwendet, kann es sinnvoll sein, hier eine bestimmte Zeitzone festzulegen.
+                                                                       </div>
+                                                               </div>
+
+                                                               <div id="onthisday">
+                                                                       {#if $tempSettings.useOnThisDay !== $settings.useOnThisDay || JSON.stringify(onThisDayYears
+                                                                                               .trim()
+                                                                                               .split(',')
+                                                                                               .map( (year) => parseInt(year.trim()) )) !== JSON.stringify($settings.onThisDayYears)}
+                                                                               <div class="unsaved-changes" transition:slide></div>
+                                                                       {/if}
+
+                                                                       <h5>Ein Blick zurück</h5>
+                                                                       <ul>
+                                                                               <li>
+                                                                                       Lege fest, aus welchen vergangenen Jahren Tagebucheinträge desselben
+                                                                                       Kalendertags angezeigt werden sollen.
+                                                                               </li>
+                                                                               <li>Gilt nur für den Schreibmodus.</li>
+                                                                               <li>
+                                                                                       Beispiel: <code>1,5,10</code> sorgt dafür, dass du unter dem Textfeld noch die
+                                                                                       Einträge von vor 1 Jahr, vor 5 Jahren und vor 10 Jahren angezeigt bekommst (sofern
+                                                                                       vorhanden).
+                                                                               </li>
+                                                                       </ul>
+                                                                       <div class="form-check form-switch">
+                                                                               <input
+                                                                                       class="form-check-input"
+                                                                                       bind:checked={$tempSettings.useOnThisDay}
+                                                                                       type="checkbox"
+                                                                                       role="switch"
+                                                                                       id="useOnThisDaySwitch"
+                                                                               />
+                                                                               <label class="form-check-label" for="useOnThisDaySwitch">
+                                                                                       {#if $tempSettings.useOnThisDay}
+                                                                                               Einträge desselben Tags aus der Vergangenheit anzeigen
+                                                                                       {:else}
+                                                                                               Einträge desselben Tags aus der Vergangenheit <b>nicht</b> anzeigen
+                                                                                       {/if}</label
+                                                                               >
+                                                                       </div>
+
+                                                                       <div>
+                                                                               <!-- <label for="useOnThisDayYears" class="form-label">Jahre</label> -->
+                                                                               <input
+                                                                                       type="text"
+                                                                                       id="useOnThisDayYears"
+                                                                                       class="form-control {onThisDayYearsInvalid ? 'is-invalid' : ''}"
+                                                                                       aria-describedby="useOnThisDayHelpBlock"
+                                                                                       disabled={!$tempSettings.useOnThisDay}
+                                                                                       placeholder="Jahre, mit Komma getrennt"
+                                                                                       bind:value={onThisDayYears}
+                                                                                       invalid
+                                                                               />
+                                                                               {#if onThisDayYearsInvalid}
+                                                                                       <div class="alert alert-danger mt-2" role="alert" transition:slide>
+                                                                                               Bitte nur Zahlen eingeben, die durch Kommas getrennt sind.
+                                                                                       </div>
+                                                                               {/if}
+                                                                               <div id="useOnThisDayHelpBlock" class="form-text">
+                                                                                       Trage hier alle vergangenen Jahre ein, die angezeigt werden sollen. Beispiel: <code
+                                                                                               >1,5,10</code
+                                                                                       >. Benutze Komma zur Trennung, verzichte auf Leerzeichen.
+                                                                               </div>
+                                                                       </div>
+                                                               </div>
+                                                               <div id="loginonreload">
+                                                                       <h5>Login bei Reload</h5>
+                                                                       Bla<br />
+                                                                       blub <br />
+                                                                       bla <br />
+                                                                       blub <br />
+                                                               </div>
+                                                       </div>
+
+                                                       <div id="tags">
+                                                               <h3 class="text-primary">#️⃣ Tags</h3>
+                                                               <div>
+                                                                       Hier können Tags bearbeitet oder auch vollständig aus DailyTxT gelöscht werden.
+                                                                       <div class="d-flex flex-column tagColumn mt-1">
+                                                                               {#each $tags as tag}
+                                                                                       <Tag
+                                                                                               {tag}
+                                                                                               isEditable
+                                                                                               editTag={openTagModal}
+                                                                                               isDeletable
+                                                                                               deleteTag={askDeleteTag}
+                                                                                       />
+                                                                                       {#if deleteTagId === tag.id}
+                                                                                               <div class="alert alert-danger align-items-center" role="alert">
+                                                                                                       <div>
+                                                                                                               <Fa icon={faTriangleExclamation} fw /> <b>Tag dauerhaft löschen?</b>
+                                                                                                               Dies kann einen Moment dauern, da jeder Eintrag nach potenziellen Verlinkungen
+                                                                                                               durchsucht werden muss. Änderungen werden zudem u. U. erst nach einem Neuladen
+                                                                                                               im Browser angezeigt.
+                                                                                                       </div>
+                                                                                                       <!-- svelte-ignore a11y_consider_explicit_label -->
+                                                                                                       <div class="d-flex flex-row mt-2">
+                                                                                                               <button class="btn btn-secondary" onclick={() => (deleteTagId = null)}
+                                                                                                                       >Abbrechen
+                                                                                                               </button>
+                                                                                                               <button
+                                                                                                                       disabled={isDeletingTag}
+                                                                                                                       class="btn btn-danger ms-3"
+                                                                                                                       onclick={() => deleteTag(tag.id)}
+                                                                                                                       >Löschen
+                                                                                                                       {#if isDeletingTag}
+                                                                                                                               <span
+                                                                                                                                       class="spinner-border spinner-border-sm ms-2"
+                                                                                                                                       role="status"
+                                                                                                                                       aria-hidden="true"
+                                                                                                                               ></span>
+                                                                                                                       {/if}
+                                                                                                               </button>
+                                                                                                       </div>
+                                                                                               </div>
+                                                                                       {/if}
+                                                                               {/each}
+                                                                       </div>
+                                                               </div>
+                                                       </div>
+
+                                                       <div id="templates">
+                                                               <h3 class="text-primary">📝 Vorlagen</h3>
+                                                               <div>
+                                                                       {#if oldTemplateName !== templateName || oldTemplateText !== templateText}
+                                                                               <div class="unsaved-changes" transition:slide></div>
+                                                                       {/if}
+
+                                                                       <div class="d-flex flex-column">
+                                                                               <select
+                                                                                       bind:value={selectedTemplate}
+                                                                                       class="form-select"
+                                                                                       aria-label="Select template"
+                                                                                       onchange={updateSelectedTemplate}
+                                                                               >
+                                                                                       <option value="-1" selected={selectedTemplate === '-1'}>
+                                                                                               Neue Vorlage erstellen...
+                                                                                       </option>
+                                                                                       {#each $templates as template, index}
+                                                                                               <option value={index} selected={index === selectedTemplate}>
+                                                                                                       {template.name}
+                                                                                               </option>
+                                                                                       {/each}
+                                                                               </select>
+                                                                       </div>
+
+                                                                       <hr />
+
+                                                                       {#if confirmDeleteTemplate}
+                                                                               <div transition:slide class="d-flex flex-row align-items-center mb-2">
+                                                                                       <span
+                                                                                               >Vorlage <b>{$templates[selectedTemplate]?.name}</b> wirklich löschen?</span
+                                                                                       >
+                                                                                       <button
+                                                                                               type="button"
+                                                                                               class="btn btn-secondary ms-2"
+                                                                                               onclick={() => (confirmDeleteTemplate = false)}>Abbrechen</button
+                                                                                       >
+                                                                                       <button
+                                                                                               type="button"
+                                                                                               class="btn btn-danger ms-2"
+                                                                                               onclick={() => {
+                                                                                                       deleteTemplate();
+                                                                                               }}
+                                                                                               disabled={isDeletingTemplate}
+                                                                                               >Löschen
+                                                                                               {#if isDeletingTemplate}
+                                                                                                       <span
+                                                                                                               class="spinner-border spinner-border-sm ms-2"
+                                                                                                               role="status"
+                                                                                                               aria-hidden="true"
+                                                                                                       ></span>
+                                                                                               {/if}
+                                                                                       </button>
+                                                                               </div>
+                                                                       {/if}
+                                                                       <div class="d-flex flex-row">
+                                                                               <input
+                                                                                       disabled={selectedTemplate === null}
+                                                                                       type="text"
+                                                                                       bind:value={templateName}
+                                                                                       class="form-control"
+                                                                                       placeholder="Name der Vorlage"
+                                                                               />
+                                                                               <button
+                                                                                       disabled={selectedTemplate === '-1' || selectedTemplate === null}
+                                                                                       type="button"
+                                                                                       class="btn btn-outline-danger ms-5"
+                                                                                       onclick={() => {
+                                                                                               confirmDeleteTemplate = !confirmDeleteTemplate;
+                                                                                       }}><Fa fw icon={faTrash} /></button
+                                                                               >
+                                                                       </div>
+                                                                       <textarea
+                                                                               disabled={selectedTemplate === null}
+                                                                               bind:value={templateText}
+                                                                               class="form-control mt-2"
+                                                                               rows="10"
+                                                                               placeholder="Inhalt der Vorlage"
+                                                                       >
+                                                                       </textarea>
+                                                                       <div class="d-flex justify-content-end">
+                                                                               <button
+                                                                                       disabled={(oldTemplateName === templateName &&
+                                                                                               oldTemplateText === templateText) ||
+                                                                                               isSavingTemplate}
+                                                                                       type="button"
+                                                                                       class="btn btn-primary mt-2"
+                                                                                       onclick={saveTemplate}
+                                                                               >
+                                                                                       Vorlage speichern
+                                                                                       {#if isSavingTemplate}
+                                                                                               <span
+                                                                                                       class="spinner-border spinner-border-sm ms-2"
+                                                                                                       role="status"
+                                                                                                       aria-hidden="true"
+                                                                                               ></span>
+                                                                                       {/if}
+                                                                               </button>
+                                                                       </div>
+                                                               </div>
+                                                       </div>
+
+                                                       <div id="data">
+                                                               <h3 class="text-primary">📁 Daten</h3>
+                                                               <div id="export"><h5>Export</h5></div>
+                                                               <div id="import"><h5>Import</h5></div>
+                                                       </div>
+
+                                                       <div id="security">
+                                                               <h3 class="text-primary">🔒 Sicherheit</h3>
+                                                               <div id="password">
+                                                                       <h5>Password ändern</h5>
+                                                                       <form onsubmit={changePassword}>
+                                                                               <div class="form-floating mb-3">
+                                                                                       <input
+                                                                                               type="password"
+                                                                                               class="form-control"
+                                                                                               id="currentPassword"
+                                                                                               placeholder="Aktuelles Passwort"
+                                                                                               bind:value={currentPassword}
+                                                                                       />
+                                                                                       <label for="currentPassword">Aktuelles Passwort</label>
+                                                                               </div>
+                                                                               <div class="form-floating mb-3">
+                                                                                       <input
+                                                                                               type="password"
+                                                                                               class="form-control"
+                                                                                               id="newPassword"
+                                                                                               placeholder="Neues Passwort"
+                                                                                               bind:value={newPassword}
+                                                                                       />
+                                                                                       <label for="newPassword">Neues Passwort</label>
+                                                                               </div>
+                                                                               <div class="form-floating mb-3">
+                                                                                       <input
+                                                                                               type="password"
+                                                                                               class="form-control"
+                                                                                               id="confirmNewPassword"
+                                                                                               placeholder="Neues Passwort bestätigen"
+                                                                                               bind:value={confirmNewPassword}
+                                                                                       />
+                                                                                       <label for="confirmNewPassword">Neues Passwort bestätigen</label>
+                                                                               </div>
+                                                                               <button class="btn btn-primary" onclick={changePassword}>
+                                                                                       {#if isChangingPassword}
+                                                                                               <!-- svelte-ignore a11y_no_static_element_interactions -->
+                                                                                               <div class="spinner-border" role="status">
+                                                                                                       <span class="visually-hidden">Loading...</span>
+                                                                                               </div>
+                                                                                       {/if}
+                                                                                       Passwort ändern
+                                                                               </button>
+                                                                       </form>
+                                                                       {#if changePasswordNotEqual}
+                                                                               <div class="alert alert-danger mt-2" role="alert" transition:slide>
+                                                                                       Die neuen Passwörter stimmen nicht überein!
+                                                                               </div>
+                                                                       {/if}
+                                                                       {#if changingPasswordSuccess}
+                                                                               <div class="alert alert-success mt-2" role="alert" transition:slide>
+                                                                                       Das Passwort wurde erfolgreich geändert!<br />
+                                                                                       Backup-Keys wurden ungültig gemacht (sofern vorhanden), und müssen neu erstellt
+                                                                                       werden.
+                                                                               </div>
+                                                                       {/if}
+                                                                       {#if changingPasswordIncorrect}
+                                                                               <div class="alert alert-danger mt-2" role="alert" transition:slide>
+                                                                                       Das aktuelle Passwort ist falsch!
+                                                                               </div>
+                                                                       {:else if changingPasswordError}
+                                                                               <div class="alert alert-danger mt-2" role="alert" transition:slide>
+                                                                                       Fehler beim Ändern des Passworts!
+                                                                               </div>
+                                                                       {/if}
+                                                               </div>
+                                                               <div id="backupkeys"><h5>Backup-Keys</h5></div>
+                                                               <div id="username"><h5>Username ändern</h5></div>
+                                                               <div id="deleteaccount"><h5>Konto löschen</h5></div>
+                                                       </div>
+
+                                                       <div id="about">
+                                                               <h3 class="text-primary">💡 About</h3>
+                                                               Version:<br />
+                                                               Changelog: <br />
+                                                               Link zu github
+                                                       </div>
+                                               </div>
+                                       </div>
+                               </div>
+                       </div>
+                       <div class="modal-footer">
+                               {#if settingsHaveChanged}
+                                       <div class="footer-unsaved-changes" transition:fade={{ duration: 100 }}>
+                                               Ungespeicherte Änderungen!
+                                       </div>
+                               {/if}
+                               <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
+                               <button
+                                       type="button"
+                                       class="btn btn-primary"
+                                       onclick={saveUserSettings}
+                                       disabled={isSaving || !settingsHaveChanged}
+                                       >Speichern
+                                       {#if isSaving}
+                                               <span class="spinner-border spinner-border-sm ms-2" role="status" aria-hidden="true"
+                                               ></span>
+                                       {/if}
+                               </button>
+                       </div>
+               </div>
+       </div>
+</div>
+
+<div class="toast-container position-fixed bottom-0 end-0 p-3">
+       <div
+               id="toastSuccessEditTag"
+               class="toast align-items-center text-bg-success"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Änderungen wurden gespeichert!</div>
+               </div>
+       </div>
+
+       <div
+               id="toastErrorEditTag"
+               class="toast align-items-center text-bg-danger"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Fehler beim Speichern der Änderungen!</div>
+               </div>
+       </div>
+
+       <div
+               id="toastErrorDeleteTag"
+               class="toast align-items-center text-bg-danger"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Fehler beim Löschen des Tags!</div>
+               </div>
+       </div>
+
+       <div
+               id="toastSuccessSaveSettings"
+               class="toast align-items-center text-bg-success"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Einstellungen gespeichert!</div>
+               </div>
+       </div>
+
+       <div
+               id="toastErrorSaveSettings"
+               class="toast align-items-center text-bg-danger"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Fehler beim Speichern der Einstellungen!</div>
+               </div>
+       </div>
+
+       <div
+               id="toastErrorInvalidTemplateEmpty"
+               class="toast align-items-center text-bg-danger"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Name oder Inhalt einer Vorlage dürfen nicht leer sein!</div>
+               </div>
+       </div>
+
+       <div
+               id="toastErrorInvalidTemplateDouble"
+               class="toast align-items-center text-bg-danger"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Name der Vorlage existiert bereits</div>
+               </div>
+       </div>
+
+       <div
+               id="toastSuccessSaveTemplate"
+               class="toast align-items-center text-bg-success"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Vorlage gespeichert</div>
+               </div>
+       </div>
+
+       <div
+               id="toastErrorDeletingTemplate"
+               class="toast align-items-center text-bg-danger"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Fehler beim Löschen der Vorlage</div>
+               </div>
+       </div>
+
+       <div
+               id="toastSuccessDeletingTemplate"
+               class="toast align-items-center text-bg-success"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Vorlage gelöscht</div>
+               </div>
+       </div>
+
+       <div
+               id="toastErrorLogout"
+               class="toast align-items-center text-bg-danger"
+               role="alert"
+               aria-live="assertive"
+               aria-atomic="true"
+       >
+               <div class="d-flex">
+                       <div class="toast-body">Fehler beim Logout</div>
+               </div>
+       </div>
+</div>
+
+<style>
+       .footer-unsaved-changes {
+               background-color: orange;
+               color: black;
+               padding: 0.25rem 0.5rem;
+               border-radius: 10px;
+               margin-left: auto;
+               margin-right: 2rem;
+               font-style: italic;
+       }
+
+       div:has(> .unsaved-changes) {
+               outline: 1px solid orange;
+       }
+
+       .unsaved-changes {
+               background-color: orange;
+               margin-top: -0.5rem;
+               margin-left: -0.5rem;
+               margin-right: -0.5rem;
+               border-top-left-radius: 10px;
+               border-top-right-radius: 10px;
+               padding-left: 0.5rem;
+               margin-bottom: 0.5rem;
+       }
+
+       .unsaved-changes::before {
+               content: 'Ungespeicherte Änderungen';
+       }
+
+       :global(.tagColumn > span) {
+               width: min-content;
+       }
+
+       .tagColumn {
+               gap: 0.5rem;
+               /* width: min-content; */
+       }
+
+       #selectMode:checked {
+               border-color: #da880e;
+               background-color: #da880e;
+       }
+
+       #selectMode:not(:checked) {
+               background-color: #2196f3;
+               background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba(255, 255, 255, 1)'/></svg>");
+       }
+
+       .settings-content > div {
+               padding: 0.5rem;
+       }
+
+       #settings-content > div > div {
+               background-color: #bdbdbd5d;
+               padding: 0.5rem;
+               border-radius: 10px;
+               margin-bottom: 1rem;
+       }
+
+       h3.text-primary {
+               font-weight: 700;
+               position: sticky;
+               top: 0;
+               backdrop-filter: blur(10px) saturate(150%);
+               background-color: rgba(240, 240, 240, 0.9);
+               padding: 4px;
+               border-radius: 5px;
+       }
+
+       #trianglifyOpacity {
+               max-width: 300px;
+       }
+
+       #trianglifyOpacityNumber {
+               width: 80px;
+       }
+
+       .modal-body {
+               overflow-y: hidden;
+       }
+
+       .modal-content {
+               backdrop-filter: blur(10px) saturate(150%);
+               /* background-color: rgba(43, 56, 78, 0.75); */
+               background-color: rgba(208, 208, 208, 0.61);
+               /* color: rgb(22, 22, 22); */
+       }
+
+       .modal-header {
+               border-bottom: 1px solid rgba(255, 255, 255, 0.2);
+       }
+
+       .modal-footer {
+               border-top: 1px solid rgba(255, 255, 255, 0.2);
+       }
+</style>
similarity index 98%
rename from frontend/src/routes/read/+page.svelte
rename to frontend/src/routes/(authed)/read/+page.svelte
index ee972800711f59014318852b670c0d039cece9d6..2ae3ca5800e05e34d2a525031803e9617c440380 100644 (file)
 
        $effect(() => {
                if ($selectedDate) {
-                       $cal.currentYear = $selectedDate.getFullYear();
-                       $cal.currentMonth = $selectedDate.getMonth();
+                       $cal.currentYear = $selectedDate.year;
+                       $cal.currentMonth = $selectedDate.month - 1;
 
-                       let el = document.querySelector(`.log[data-log-day="${$selectedDate.getDate()}"]`);
+                       let el = document.querySelector(`.log[data-log-day="${$selectedDate.day}"]`);
                        if (el) {
                                el.scrollIntoView({ behavior: 'smooth', block: 'start' });
                        }
similarity index 99%
rename from frontend/src/routes/write/+page.svelte
rename to frontend/src/routes/(authed)/write/+page.svelte
index 2ac0d6f8e69ffaeed1e9f37631524fa8d8674b50..a3dcce0acc177acb86ae1d41b97b73bc0d58d89e 100644 (file)
@@ -1,5 +1,5 @@
 <script>
-       import '../../scss/styles.scss';
+       import '../../../scss/styles.scss';
        import * as bootstrap from 'bootstrap';
        import Sidenav from '$lib/Sidenav.svelte';
        import { selectedDate, cal, readingDate } from '$lib/calendarStore.js';
@@ -8,7 +8,7 @@
        import { mount, onMount } from 'svelte';
        import { searchString, searchResults } from '$lib/searchStore.js';
        import * as TinyMDE from 'tiny-markdown-editor';
-       import '../../../node_modules/tiny-markdown-editor/dist/tiny-mde.css';
+       import '../../../../node_modules/tiny-markdown-editor/dist/tiny-mde.css';
        import { API_URL } from '$lib/APIurl.js';
        import DatepickerLogic from '$lib/DatepickerLogic.svelte';
        import {
index 4df7f677ab57b93b9f6a9597d2ff0465c8dc54aa..ab5f4a4319174b3a28d7481e045b1449428d275f 100644 (file)
@@ -1,37 +1,15 @@
 <script>
-       import { blur, slide, fade } from 'svelte/transition';
+       import { blur } from 'svelte/transition';
        import axios from 'axios';
        //import { dev } from '$app/environment';
        import { goto } from '$app/navigation';
        import { onMount } from 'svelte';
        import '../scss/styles.scss';
-       import * as bootstrap from 'bootstrap';
-       import Fa from 'svelte-fa';
-       import {
-               readingMode,
-               settings,
-               tempSettings,
-               autoLoadImagesThisDevice,
-               useTrianglify,
-               trianglifyOpacity
-       } from '$lib/settingsStore.js';
+       import { useTrianglify, trianglifyOpacity } from '$lib/settingsStore.js';
        import { page } from '$app/state';
        import { API_URL } from '$lib/APIurl.js';
        import trianglify from 'trianglify';
-       import { tags } from '$lib/tagStore.js';
-       import TagModal from '$lib/TagModal.svelte';
        import { alwaysShowSidenav, currentUser } from '$lib/helpers.js';
-       import { templates } from '$lib/templateStore';
-       import {
-               faRightFromBracket,
-               faGlasses,
-               faPencil,
-               faSliders,
-               faTriangleExclamation,
-               faTrash
-       } from '@fortawesome/free-solid-svg-icons';
-       import Tag from '$lib/Tag.svelte';
-       import SelectTimezone from '$lib/SelectTimezone.svelte';
 
        let { children } = $props();
        let inDuration = 150;
@@ -57,6 +35,7 @@
                                        .get(API_URL + '/users/logout')
                                        .then((response) => {
                                                localStorage.removeItem('user');
+                                               $currentUser = null;
                                                goto(`/login?error=${error.response.status}`);
                                        })
                                        .catch((error) => {
                }
        );
 
-       $effect(() => {
-               if ($readingMode === true && page.url.pathname !== '/read') {
-                       goto('/read');
-               } else if ($readingMode === false) {
-                       goto('/write');
-               }
-       });
-
-       $effect(() => {
-               if ($currentUser !== null) {
-                       getUserSettings();
-                       getTemplates();
-               } else {
-                       $settings = {};
-                       $templates = [];
-               }
-       });
-
-       function logout() {
-               axios
-                       .get(API_URL + '/users/logout')
-                       .then((response) => {
-                               localStorage.removeItem('user');
-                               $currentUser = null;
-                               goto('/login');
-                       })
-                       .catch((error) => {
-                               console.error(error);
-                       });
-       }
-
        function createBackground() {
                if ($useTrianglify) {
                        //remove old canvas
                }
        }
 
-       let settingsModal;
-       function openSettingsModal() {
-               $tempSettings = JSON.parse(JSON.stringify($settings));
-               onThisDayYears = $settings.onThisDayYears.toString();
-
-               settingsModal = new bootstrap.Modal(document.getElementById('settingsModal'));
-               settingsModal.show();
-       }
-
        $effect(() => {
                if ($trianglifyOpacity) {
                        if (document.querySelector('canvas')) {
                }
        });
 
-       /* Important for development: convenient modal-handling with HMR */
-       if (import.meta.hot) {
-               import.meta.hot.dispose(() => {
-                       document.querySelectorAll('.modal-backdrop').forEach((el) => el.remove());
-               });
-       }
-
        function calculateResize() {
                if (window.innerWidth > 840) {
                        $alwaysShowSidenav = true;
                calculateResize();
        });
 
-       let onThisDayYears = $state('');
-       function getUserSettings() {
-               axios
-                       .get(API_URL + '/users/getUserSettings')
-                       .then((response) => {
-                               $settings = response.data;
-                               onThisDayYears = $settings.onThisDayYears.toString();
-                       })
-                       .catch((error) => {
-                               console.error(error);
-                       })
-                       .finally(() => {
-                               if ($autoLoadImagesThisDevice === null || $autoLoadImagesThisDevice === undefined) {
-                                       $autoLoadImagesThisDevice = $settings.autoloadImagesByDefault;
-                               }
-                       });
-       }
-
-       let onThisDayYearsInvalid = $state(false);
-       // check if onThisDayYears is valid
-       $effect(() => {
-               onThisDayYearsInvalid = false;
-               if ($tempSettings.useOnThisDay === false) {
-                       return;
-               }
-
-               //regex: years may only contain numbers and commas
-               if (onThisDayYears.match(/[^0-9,]/)) {
-                       onThisDayYearsInvalid = true;
-                       return;
-               }
-
-               onThisDayYears
-                       .trim()
-                       .split(',')
-                       .forEach((year) => {
-                               if (!Number.isInteger(parseInt(year.trim()))) {
-                                       onThisDayYearsInvalid = true;
-                               }
-                               return year;
-                       });
-       });
-
-       let settingsHaveChanged = $derived(
-               JSON.stringify($settings) !== JSON.stringify($tempSettings) ||
-                       JSON.stringify($settings.onThisDayYears) !==
-                               JSON.stringify(
-                                       onThisDayYears
-                                               .trim()
-                                               .split(',')
-                                               .map((year) => parseInt(year.trim()))
-                               )
-       );
-
-       let isSaving = $state(false);
-       function saveUserSettings() {
-               if (isSaving) return;
-               isSaving = true;
-
-               $tempSettings.onThisDayYears = onThisDayYears
-                       .trim()
-                       .split(',')
-                       .map((year) => parseInt(year.trim()));
-
-               axios
-                       .post(API_URL + '/users/saveUserSettings', $tempSettings)
-                       .then((response) => {
-                               if (response.data.success) {
-                                       $settings = $tempSettings;
-
-                                       // show toast
-                                       const toast = new bootstrap.Toast(document.getElementById('toastSuccessSaveSettings'));
-                                       toast.show();
-
-                                       settingsModal.hide();
-                               } else {
-                                       console.error('Error saving settings');
-                               }
-                       })
-                       .catch((error) => {
-                               console.error(error);
-
-                               // show toast
-                               const toast = new bootstrap.Toast(document.getElementById('toastErrorSaveSettings'));
-                               toast.show();
-                       })
-                       .finally(() => {
-                               isSaving = false;
-                       });
-       }
-
        onMount(() => {
                createBackground();
                calculateResize();
-               getUserSettings();
-               getTemplates();
-
-               if (page.url.pathname === '/read') {
-                       $readingMode = true;
-               } else if (page.url.pathname === '/write') {
-                       $readingMode = false;
-               }
-
-               document.getElementById('settingsModal').addEventListener('shown.bs.modal', function () {
-                       const height = document.getElementById('modal-body').clientHeight;
-                       document.getElementById('settings-content').style.height = 'calc(' + height + 'px - 2rem)';
-                       document.getElementById('settings-nav').style.height = 'calc(' + height + 'px - 2rem)';
-                       document.getElementById('settings-content').style.overflowY = 'auto';
-
-                       setTimeout(() => {
-                               const dataSpyList = document.querySelectorAll('[data-bs-spy="scroll"]');
-                               dataSpyList.forEach((dataSpyEl) => {
-                                       bootstrap.ScrollSpy.getInstance(dataSpyEl).refresh();
-                               });
-                       }, 200);
-               });
        });
 
-       let editTagModal;
-       let editTag = $state({});
-       let isSavingEditedTag = $state(false);
-
-       function openTagModal(tagId) {
-               $tags.forEach((tag) => {
-                       if (tag.id === tagId) {
-                               editTag.name = tag.name;
-                               editTag.color = tag.color;
-                               editTag.icon = tag.icon;
-                               editTag.id = tag.id;
-                               return;
-                       }
-               });
-
-               settingsModal.hide();
-               editTagModal.open();
-       }
-
-       let selectedTemplate = $state(null);
-       let templateName = $state('');
-       let templateText = $state('');
-       let oldTemplateName = $state('');
-       let oldTemplateText = $state('');
-       let confirmDeleteTemplate = $state(false);
-
-       function getTemplates() {
-               axios
-                       .get(API_URL + '/logs/getTemplates')
-                       .then((response) => {
-                               $templates = response.data;
-
-                               selectedTemplate = null;
-                               updateSelectedTemplate();
-                       })
-                       .catch((error) => {
-                               console.error(error);
-                       });
-       }
-
-       let isSavingTemplate = $state(false);
-       function saveTemplate() {
-               // check if name or text is empty
-               if (templateName === '' || templateText === '') {
-                       // show toast
-                       const toast = new bootstrap.Toast(document.getElementById('toastErrorInvalidTemplateEmpty'));
-                       toast.show();
-                       return;
-               }
-
-               // check if template name already exists
-               for (let i = 0; i < $templates.length; i++) {
-                       if ($templates[i].name === templateName && selectedTemplate !== i) {
-                               // show toast
-                               const toast = new bootstrap.Toast(
-                                       document.getElementById('toastErrorInvalidTemplateDouble')
-                               );
-                               toast.show();
-                               return;
-                       }
-               }
-
-               if (isSavingTemplate) return;
-               isSavingTemplate = true;
-
-               if (selectedTemplate === '-1') {
-                       // add new template
-                       $templates.push({ name: templateName, text: templateText });
-               } else {
-                       // update existing template
-                       $templates[selectedTemplate].name = templateName;
-                       $templates[selectedTemplate].text = templateText;
-               }
-
-               axios
-                       .post(API_URL + '/logs/saveTemplates', {
-                               templates: $templates
-                       })
-                       .then((response) => {
-                               if (response.data.success) {
-                                       getTemplates();
-
-                                       // show toast
-                                       const toast = new bootstrap.Toast(document.getElementById('toastSuccessSaveTemplate'));
-                                       toast.show();
-                               }
-                       })
-                       .catch((error) => {
-                               console.error(error);
-
-                               // show toast
-                               const toast = new bootstrap.Toast(document.getElementById('toastErrorSaveTemplates'));
-                               toast.show();
-                       })
-                       .finally(() => {
-                               isSavingTemplate = false;
-                       });
-       }
-
-       let isDeletingTemplate = $state(false);
-       function deleteTemplate() {
-               if (selectedTemplate === null || selectedTemplate === '-1') return;
-
-               if (isDeletingTemplate) return;
-               isDeletingTemplate = true;
-
-               // remove template from list
-               $templates.splice(selectedTemplate, 1);
-
-               axios
-                       .post(API_URL + '/logs/saveTemplates', {
-                               templates: $templates
-                       })
-                       .then((response) => {
-                               if (response.data.success) {
-                                       getTemplates();
-
-                                       // show toast
-                                       const toast = new bootstrap.Toast(
-                                               document.getElementById('toastSuccessDeletingTemplate')
-                                       );
-                                       toast.show();
-                               }
-                       })
-                       .catch((error) => {
-                               console.error(error);
-                               // show toast
-                               const toast = new bootstrap.Toast(document.getElementById('toastErrorDeletingTemplate'));
-                               toast.show();
-                       })
-                       .finally(() => {
-                               isDeletingTemplate = false;
-                               confirmDeleteTemplate = false;
-                       });
-       }
-
-       function updateSelectedTemplate() {
-               if (selectedTemplate === '-1' || selectedTemplate === null || $templates.length === 0) {
-                       // new template
-                       templateName = '';
-                       templateText = '';
-               } else {
-                       // existing template
-                       templateName = $templates[selectedTemplate].name;
-                       templateText = $templates[selectedTemplate].text;
-               }
-               oldTemplateName = templateName;
-               oldTemplateText = templateText;
-
-               confirmDeleteTemplate = false;
-       }
-
-       let deleteTagId = $state(null);
-       function askDeleteTag(tagId) {
-               if (deleteTagId === tagId) deleteTagId = null;
-               else deleteTagId = tagId;
-       }
-
-       let isDeletingTag = $state(false);
-       function deleteTag(tagId) {
-               if (isDeletingTag) return;
-               isDeletingTag = true;
-
-               axios
-                       .get(API_URL + '/logs/deleteTag', { params: { id: tagId } })
-                       .then((response) => {
-                               if (response.data.success) {
-                                       $tags = $tags.filter((tag) => tag.id !== tagId);
-                               }
-                       })
-                       .catch((error) => {
-                               console.error(error);
-
-                               // show toast
-                               const toast = new bootstrap.Toast(document.getElementById('toastErrorDeleteTag'));
-                               toast.show();
-                       })
-                       .finally(() => {
-                               deleteTagId = null;
-                               isDeletingTag = false;
-                       });
-       }
-
-       function saveEditedTag() {
-               if (isSavingEditedTag) return;
-               isSavingEditedTag = true;
-
-               axios
-                       .post(API_URL + '/logs/editTag', editTag)
-                       .then((response) => {
-                               if (response.data.success) {
-                                       $tags = $tags.map((tag) => {
-                                               if (tag.id === editTag.id) {
-                                                       tag.name = editTag.name;
-                                                       tag.color = editTag.color;
-                                                       tag.icon = editTag.icon;
-                                               }
-                                               return tag;
-                                       });
-
-                                       // show toast
-                                       const toast = new bootstrap.Toast(document.getElementById('toastSuccessEditTag'));
-                                       toast.show();
-                               }
-                       })
-                       .catch((error) => {
-                               console.error(error);
-
-                               // show toast
-                               const toast = new bootstrap.Toast(document.getElementById('toastErrorEditTag'));
-                               toast.show();
-                       })
-                       .finally(() => {
-                               isSavingEditedTag = false;
-                               editTagModal.close();
-                               openSettingsModal();
-                       });
-       }
-
-       $effect(() => {
-               if ($autoLoadImagesThisDevice === null || $autoLoadImagesThisDevice === undefined) {
-                       return;
-               }
-
-               localStorage.setItem('autoLoadImagesThisDevice', $autoLoadImagesThisDevice);
-       });
-
-       let currentPassword = $state('');
-       let newPassword = $state('');
-       let confirmNewPassword = $state('');
-       let changePasswordNotEqual = $state(false);
-       let isChangingPassword = $state(false);
-       let changingPasswordSuccess = $state(false);
-       let changingPasswordError = $state(false);
-       let changingPasswordIncorrect = $state(false);
-
-       function changePassword() {
-               changePasswordNotEqual = false;
-               changingPasswordSuccess = false;
-               changingPasswordError = false;
-               changingPasswordIncorrect = false;
-
-               if (newPassword !== confirmNewPassword) {
-                       changePasswordNotEqual = true;
-                       return;
-               }
-
-               if (isChangingPassword) return;
-               isChangingPassword = true;
-
-               axios
-                       .post(API_URL + '/users/changePassword', {
-                               old_password: currentPassword,
-                               new_password: newPassword
-                       })
-                       .then((response) => {
-                               if (response.data.success) {
-                                       changingPasswordSuccess = true;
-                               } else {
-                                       changingPasswordError = true;
-                                       console.error('Error changing password');
-                                       if (response.data.password_incorrect) {
-                                               changingPasswordIncorrect = true;
-                                       }
-                               }
-                       })
-                       .catch((error) => {
-                               console.error(error);
-                               console.log('Error on Changing password:', error.response.data.message);
-                               changingPasswordError = true;
-                       })
-                       .finally(() => {
-                               isChangingPassword = false;
-                       });
-       }
+       let routeToFromLoginKey = $derived(page.url.pathname === '/login');
 </script>
 
 <main class="d-flex flex-column">
-       <nav class="navbar navbar-expand-lg bg-body-tertiary">
-               <div class="row w-100">
-                       <div class="col-lg-4 col-sm-5 col d-flex flex-row justify-content-start align-items-center">
-                               {#if !$alwaysShowSidenav}
-                                       <button
-                                               class="btn d-xl-none"
-                                               type="button"
-                                               data-bs-toggle="offcanvas"
-                                               data-bs-target="#sidenav"
-                                               aria-controls="sidenav">menü</button
-                                       >
-                               {/if}
-
-                               <div class="form-check form-switch d-flex flex-row">
-                                       <label class="me-3" for="selectMode"><Fa icon={faPencil} size="1.5x" /></label>
-                                       <div class="form-check form-switch">
-                                               <input
-                                                       class="form-check-input"
-                                                       bind:checked={$readingMode}
-                                                       type="checkbox"
-                                                       role="switch"
-                                                       id="selectMode"
-                                                       style="transform: scale(1.3);"
-                                               />
-                                       </div>
-                                       <label class="ms-2" for="selectMode"><Fa icon={faGlasses} size="1.5x" /></label>
-                               </div>
-                       </div>
-
-                       <div class="col-lg-4 col-sm-2 col d-flex flex-row justify-content-center align-items-center">
-                               Center-LOGO
-                       </div>
-
-                       <div class="col-lg-4 col-sm-5 col pe-0 d-flex flex-row justify-content-end">
-                               <button class="btn btn-outline-secondary me-2" onclick={openSettingsModal}
-                                       ><Fa icon={faSliders} /></button
-                               >
-                               <button class="btn btn-outline-secondary" onclick={logout}
-                                       ><Fa icon={faRightFromBracket} /></button
-                               >
-                       </div>
-               </div>
-       </nav>
-
        <div class="wrapper h-100">
-               {#key page.data}
+               {#key routeToFromLoginKey}
                        <div
                                class="transition-wrapper h-100"
                                out:blur={{ duration: outDuration }}
                        </div>
                {/key}
        </div>
-
-       <TagModal
-               bind:this={editTagModal}
-               createTag={false}
-               bind:editTag
-               isSaving={isSavingEditedTag}
-               {saveEditedTag}
-       />
-
-       <!-- Full screen modal -->
-       <div class="modal fade" data-bs-backdrop="static" id="settingsModal">
-               <div
-                       class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-xl modal-fullscreen-sm-down"
-               >
-                       <!--  -->
-                       <div class="modal-content shadow-lg">
-                               <div class="modal-header">
-                                       <h1>Settings</h1>
-                                       <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"
-                                       ></button>
-                               </div>
-                               <div class="modal-body" id="modal-body">
-                                       <div class="row">
-                                               <div class="col-4 overflow-y-auto">
-                                                       <nav class="flex-column align-items-stretch" id="settings-nav">
-                                                               <nav class="nav nav-pills flex-column">
-                                                                       <a class="nav-link mb-1" href="#appearance">Aussehen</a>
-                                                                       <!-- <a href="#lightdark" class="ms-3 mb-1 nav-link">Light/Dark-Mode</a>
-                                                                       <a href="#background" class="ms-3 mb-1 nav-link">Hintergrund</a> -->
-                                                                       <a class="nav-link mb-1" href="#functions">Funktionen</a>
-                                                                       <!-- <nav class="nav nav-pills flex-column">
-                                                                               <a href="#language" class="ms-3 mb-1 nav-link">Sprache</a>
-                                                                               <a href="#timezone" class="ms-3 mb-1 nav-link">Zeitzone</a>
-                                                                               <a href="#onthisday" class="ms-3 mb-1 nav-link">An diesem Tag</a>
-                                                                               <a href="#loginonreload" class="ms-3 mb-1 nav-link">Login bei Reload</a>
-                                                                       </nav> -->
-                                                                       <a class="nav-link mb-1" href="#tags">Tags</a>
-                                                                       <a class="nav-link mb-1" href="#templates">Vorlagen</a>
-                                                                       <a class="nav-link mb-1" href="#data">Daten</a>
-                                                                       <!-- <nav class="nav nav-pills flex-column">
-                                                                               <a href="#export" class="ms-3 nav-link mb-1">Export</a>
-                                                                               <a href="#import" class="ms-3 nav-link mb-1">Import</a>
-                                                                       </nav> -->
-                                                                       <a class="nav-link mb-1" href="#security">Sicherheit</a>
-                                                                       <!-- <nav class="nav nav-pills flex-column">
-                                                                               <a href="#password" class="ms-3 mb-1 nav-link">Password ändern</a>
-                                                                               <a href="#backupkeys" class="ms-3 mb-1 nav-link">Backup-Keys</a>
-                                                                               <a href="#username" class="ms-3 mb-1 nav-link">Username ändern</a>
-                                                                               <a href="#deleteaccount" class="ms-3 mb-1 nav-link">Konto löschen</a>
-                                                                       </nav> -->
-                                                                       <a class="nav-link mb-1" href="#about">About</a>
-                                                               </nav>
-                                                       </nav>
-                                               </div>
-                                               <div class="col-8">
-                                                       <div
-                                                               class="settings-content overflow-y-auto"
-                                                               data-bs-spy="scroll"
-                                                               data-bs-target="#settings-nav"
-                                                               data-bs-smooth-scroll="true"
-                                                               id="settings-content"
-                                                       >
-                                                               <div id="appearance">
-                                                                       <h3 class="text-primary">🎨 Aussehen</h3>
-                                                                       <div id="lightdark">
-                                                                               <h5>Light/Dark-Mode</h5>
-                                                                               Bla<br />
-                                                                               blub <br />
-                                                                               bla <br />
-                                                                               blub <br />
-                                                                       </div>
-                                                                       <div id="background">
-                                                                               <h5>Hintergrund</h5>
-                                                                               <div class="d-flex flex-row justify-content-start">
-                                                                                       <label for="trianglifyOpacity" class="form-label"
-                                                                                               >Transparenz der Dreiecke</label
-                                                                                       >
-                                                                                       <input
-                                                                                               bind:value={$trianglifyOpacity}
-                                                                                               type="range"
-                                                                                               class="mx-3 form-range"
-                                                                                               id="trianglifyOpacity"
-                                                                                               min="0"
-                                                                                               max="1"
-                                                                                               step="0.01"
-                                                                                       />
-                                                                                       <input
-                                                                                               bind:value={$trianglifyOpacity}
-                                                                                               type="number"
-                                                                                               id="trianglifyOpacityNumber"
-                                                                                       />
-                                                                               </div>
-                                                                       </div>
-                                                               </div>
-
-                                                               <div id="functions">
-                                                                       <h3 class="text-primary">🛠️ Funktionen</h3>
-
-                                                                       <div id="autoLoadImages">
-                                                                               {#if $tempSettings.setAutoloadImagesPerDevice !== $settings.setAutoloadImagesPerDevice || $tempSettings.autoloadImagesByDefault !== $settings.autoloadImagesByDefault}
-                                                                                       <div class="unsaved-changes" transition:slide></div>
-                                                                               {/if}
-
-                                                                               <h5>Bilder automatisch laden</h5>
-                                                                               <ul>
-                                                                                       <li>
-                                                                                               Beim Laden eines Textes können hochgeladene Bilder (sofern vorhanden)
-                                                                                               automatisch geladen werden. <em>Erhöhter Datenverbrauch!</em>
-                                                                                       </li>
-                                                                                       <li>Alternativ wird ein Button zum Nachladen aller Bilder angezeigt.</li>
-                                                                               </ul>
-
-                                                                               <div class="form-check form-switch">
-                                                                                       <input
-                                                                                               class="form-check-input"
-                                                                                               bind:checked={$tempSettings.setAutoloadImagesPerDevice}
-                                                                                               type="checkbox"
-                                                                                               role="switch"
-                                                                                               id="setImageLoadingPerDeviceSwitch"
-                                                                                       />
-                                                                                       <label class="form-check-label" for="setImageLoadingPerDeviceSwitch">
-                                                                                               Für jedes Gerät einzeln festlegen, ob die Bilder automatisch geladen werden
-                                                                                               sollen</label
-                                                                                       >
-                                                                               </div>
-
-                                                                               <div class="form-check form-switch ms-3">
-                                                                                       <input
-                                                                                               class="form-check-input"
-                                                                                               bind:checked={$autoLoadImagesThisDevice}
-                                                                                               type="checkbox"
-                                                                                               role="switch"
-                                                                                               id="loadImagesThisDeviceSwitch"
-                                                                                               disabled={!$tempSettings.setAutoloadImagesPerDevice}
-                                                                                       />
-                                                                                       <label class="form-check-label" for="loadImagesThisDeviceSwitch">
-                                                                                               {#if $autoLoadImagesThisDevice}
-                                                                                                       Bilder werden auf <b>diesem Gerät</b> automatisch geladen
-                                                                                               {:else}
-                                                                                                       Bilder werden auf <b>diesem Gerät <u>nicht</u></b> automatisch geladen
-                                                                                               {/if}</label
-                                                                                       >
-                                                                               </div>
-
-                                                                               <div class="form-check form-switch mt-3">
-                                                                                       <input
-                                                                                               class="form-check-input"
-                                                                                               bind:checked={$tempSettings.autoloadImagesByDefault}
-                                                                                               type="checkbox"
-                                                                                               role="switch"
-                                                                                               id="autoLoadImagesSwitch"
-                                                                                               disabled={$tempSettings.setAutoloadImagesPerDevice}
-                                                                                       />
-                                                                                       <label class="form-check-label" for="autoLoadImagesSwitch">
-                                                                                               {#if $tempSettings.autoloadImagesByDefault}
-                                                                                                       Bilder werden (auf jedem Gerät) automatisch geladen
-                                                                                               {:else}
-                                                                                                       Bilder werden (auf jedem Gerät) <b>nicht</b> automatisch geladen
-                                                                                               {/if}</label
-                                                                                       >
-                                                                               </div>
-                                                                       </div>
-
-                                                                       <div id="language">
-                                                                               <h5>Sprache</h5>
-                                                                               Bla<br />
-                                                                               blub <br />
-                                                                               bla <br />
-                                                                               blub <br />
-                                                                       </div>
-                                                                       <div id="timezone">
-                                                                               {#if $tempSettings.useBrowserTimezone !== $settings.useBrowserTimezone || ($tempSettings.timezone !== undefined && $tempSettings.timezone?.value !== $settings.timezone?.value)}
-                                                                                       <div class="unsaved-changes" transition:slide></div>
-                                                                               {/if}
-                                                                               <h5>Zeitzone</h5>
-                                                                               Stelle die Zeitzone ein, die für den Timestamp ("Geschrieben am") genutzt werden
-                                                                               soll.
-
-                                                                               <div class="form-check mt-2">
-                                                                                       <input
-                                                                                               class="form-check-input"
-                                                                                               type="radio"
-                                                                                               name="timezone"
-                                                                                               id="timezone1"
-                                                                                               value={true}
-                                                                                               bind:group={$tempSettings.useBrowserTimezone}
-                                                                                       />
-                                                                                       <label class="form-check-label" for="timezone1">
-                                                                                               Zeitzone automatisch anhand des Browsers ermitteln.
-                                                                                       </label>
-                                                                                       <br />
-                                                                                       Aktuell: <code>{new Intl.DateTimeFormat().resolvedOptions().timeZone}</code>
-                                                                               </div>
-                                                                               <div class="form-check">
-                                                                                       <input
-                                                                                               class="form-check-input"
-                                                                                               type="radio"
-                                                                                               name="timezone"
-                                                                                               id="timezone2"
-                                                                                               value={false}
-                                                                                               bind:group={$tempSettings.useBrowserTimezone}
-                                                                                       />
-                                                                                       <label class="form-check-label" for="timezone2">
-                                                                                               Für diesen Account immer die folgende Zeitzone verwenden:
-                                                                                       </label>
-                                                                                       <br />
-                                                                                       <SelectTimezone />
-                                                                                       {#if !$tempSettings.useBrowserTimezone}
-                                                                                               <span transition:fade>
-                                                                                                       Ausgewählt: <code>{$tempSettings.timezone}</code>
-                                                                                               </span>
-                                                                                       {/if}
-                                                                               </div>
-
-                                                                               <div class="form-text mt-3">
-                                                                                       Wenn man auf Reisen ist, kann es sinnvoll sein, die Zeitzone anhand des
-                                                                                       Browsers zu ermitteln. Dann werden Datum und Uhrzeit am Zielort
-                                                                                       vorraussichtlich besser erkannt.<br />
-                                                                                       Wenn man hingegen zuhause im privaten Browser teils andere Zeitzonen (z. B. immer
-                                                                                       UTC) verwendet, kann es sinnvoll sein, hier eine bestimmte Zeitzone festzulegen.
-                                                                               </div>
-                                                                       </div>
-
-                                                                       <div id="onthisday">
-                                                                               {#if $tempSettings.useOnThisDay !== $settings.useOnThisDay || JSON.stringify(onThisDayYears
-                                                                                                       .trim()
-                                                                                                       .split(',')
-                                                                                                       .map( (year) => parseInt(year.trim()) )) !== JSON.stringify($settings.onThisDayYears)}
-                                                                                       <div class="unsaved-changes" transition:slide></div>
-                                                                               {/if}
-
-                                                                               <h5>Ein Blick zurück</h5>
-                                                                               <ul>
-                                                                                       <li>
-                                                                                               Lege fest, aus welchen vergangenen Jahren Tagebucheinträge desselben
-                                                                                               Kalendertags angezeigt werden sollen.
-                                                                                       </li>
-                                                                                       <li>Gilt nur für den Schreibmodus.</li>
-                                                                                       <li>
-                                                                                               Beispiel: <code>1,5,10</code> sorgt dafür, dass du unter dem Textfeld noch die
-                                                                                               Einträge von vor 1 Jahr, vor 5 Jahren und vor 10 Jahren angezeigt bekommst (sofern
-                                                                                               vorhanden).
-                                                                                       </li>
-                                                                               </ul>
-                                                                               <div class="form-check form-switch">
-                                                                                       <input
-                                                                                               class="form-check-input"
-                                                                                               bind:checked={$tempSettings.useOnThisDay}
-                                                                                               type="checkbox"
-                                                                                               role="switch"
-                                                                                               id="useOnThisDaySwitch"
-                                                                                       />
-                                                                                       <label class="form-check-label" for="useOnThisDaySwitch">
-                                                                                               {#if $tempSettings.useOnThisDay}
-                                                                                                       Einträge desselben Tags aus der Vergangenheit anzeigen
-                                                                                               {:else}
-                                                                                                       Einträge desselben Tags aus der Vergangenheit <b>nicht</b> anzeigen
-                                                                                               {/if}</label
-                                                                                       >
-                                                                               </div>
-
-                                                                               <div>
-                                                                                       <!-- <label for="useOnThisDayYears" class="form-label">Jahre</label> -->
-                                                                                       <input
-                                                                                               type="text"
-                                                                                               id="useOnThisDayYears"
-                                                                                               class="form-control {onThisDayYearsInvalid ? 'is-invalid' : ''}"
-                                                                                               aria-describedby="useOnThisDayHelpBlock"
-                                                                                               disabled={!$tempSettings.useOnThisDay}
-                                                                                               placeholder="Jahre, mit Komma getrennt"
-                                                                                               bind:value={onThisDayYears}
-                                                                                               invalid
-                                                                                       />
-                                                                                       {#if onThisDayYearsInvalid}
-                                                                                               <div class="alert alert-danger mt-2" role="alert" transition:slide>
-                                                                                                       Bitte nur Zahlen eingeben, die durch Kommas getrennt sind.
-                                                                                               </div>
-                                                                                       {/if}
-                                                                                       <div id="useOnThisDayHelpBlock" class="form-text">
-                                                                                               Trage hier alle vergangenen Jahre ein, die angezeigt werden sollen.
-                                                                                               Beispiel: <code>1,5,10</code>. Benutze Komma zur Trennung, verzichte auf
-                                                                                               Leerzeichen.
-                                                                                       </div>
-                                                                               </div>
-                                                                       </div>
-                                                                       <div id="loginonreload">
-                                                                               <h5>Login bei Reload</h5>
-                                                                               Bla<br />
-                                                                               blub <br />
-                                                                               bla <br />
-                                                                               blub <br />
-                                                                       </div>
-                                                               </div>
-
-                                                               <div id="tags">
-                                                                       <h3 class="text-primary">#️⃣ Tags</h3>
-                                                                       <div>
-                                                                               Hier können Tags bearbeitet oder auch vollständig aus DailyTxT gelöscht werden.
-                                                                               <div class="d-flex flex-column tagColumn mt-1">
-                                                                                       {#each $tags as tag}
-                                                                                               <Tag
-                                                                                                       {tag}
-                                                                                                       isEditable
-                                                                                                       editTag={openTagModal}
-                                                                                                       isDeletable
-                                                                                                       deleteTag={askDeleteTag}
-                                                                                               />
-                                                                                               {#if deleteTagId === tag.id}
-                                                                                                       <div class="alert alert-danger align-items-center" role="alert">
-                                                                                                               <div>
-                                                                                                                       <Fa icon={faTriangleExclamation} fw /> <b>Tag dauerhaft löschen?</b>
-                                                                                                                       Dies kann einen Moment dauern, da jeder Eintrag nach potenziellen Verlinkungen
-                                                                                                                       durchsucht werden muss. Änderungen werden zudem u. U. erst nach einem Neuladen
-                                                                                                                       im Browser angezeigt.
-                                                                                                               </div>
-                                                                                                               <!-- svelte-ignore a11y_consider_explicit_label -->
-                                                                                                               <div class="d-flex flex-row mt-2">
-                                                                                                                       <button class="btn btn-secondary" onclick={() => (deleteTagId = null)}
-                                                                                                                               >Abbrechen
-                                                                                                                       </button>
-                                                                                                                       <button
-                                                                                                                               disabled={isDeletingTag}
-                                                                                                                               class="btn btn-danger ms-3"
-                                                                                                                               onclick={() => deleteTag(tag.id)}
-                                                                                                                               >Löschen
-                                                                                                                               {#if isDeletingTag}
-                                                                                                                                       <span
-                                                                                                                                               class="spinner-border spinner-border-sm ms-2"
-                                                                                                                                               role="status"
-                                                                                                                                               aria-hidden="true"
-                                                                                                                                       ></span>
-                                                                                                                               {/if}
-                                                                                                                       </button>
-                                                                                                               </div>
-                                                                                                       </div>
-                                                                                               {/if}
-                                                                                       {/each}
-                                                                               </div>
-                                                                       </div>
-                                                               </div>
-
-                                                               <div id="templates">
-                                                                       <h3 class="text-primary">📝 Vorlagen</h3>
-                                                                       <div>
-                                                                               {#if oldTemplateName !== templateName || oldTemplateText !== templateText}
-                                                                                       <div class="unsaved-changes" transition:slide></div>
-                                                                               {/if}
-
-                                                                               <div class="d-flex flex-column">
-                                                                                       <select
-                                                                                               bind:value={selectedTemplate}
-                                                                                               class="form-select"
-                                                                                               aria-label="Select template"
-                                                                                               onchange={updateSelectedTemplate}
-                                                                                       >
-                                                                                               <option value="-1" selected={selectedTemplate === '-1'}>
-                                                                                                       Neue Vorlage erstellen...
-                                                                                               </option>
-                                                                                               {#each $templates as template, index}
-                                                                                                       <option value={index} selected={index === selectedTemplate}>
-                                                                                                               {template.name}
-                                                                                                       </option>
-                                                                                               {/each}
-                                                                                       </select>
-                                                                               </div>
-
-                                                                               <hr />
-
-                                                                               {#if confirmDeleteTemplate}
-                                                                                       <div transition:slide class="d-flex flex-row align-items-center mb-2">
-                                                                                               <span
-                                                                                                       >Vorlage <b>{$templates[selectedTemplate]?.name}</b> wirklich löschen?</span
-                                                                                               >
-                                                                                               <button
-                                                                                                       type="button"
-                                                                                                       class="btn btn-secondary ms-2"
-                                                                                                       onclick={() => (confirmDeleteTemplate = false)}>Abbrechen</button
-                                                                                               >
-                                                                                               <button
-                                                                                                       type="button"
-                                                                                                       class="btn btn-danger ms-2"
-                                                                                                       onclick={() => {
-                                                                                                               deleteTemplate();
-                                                                                                       }}
-                                                                                                       disabled={isDeletingTemplate}
-                                                                                                       >Löschen
-                                                                                                       {#if isDeletingTemplate}
-                                                                                                               <span
-                                                                                                                       class="spinner-border spinner-border-sm ms-2"
-                                                                                                                       role="status"
-                                                                                                                       aria-hidden="true"
-                                                                                                               ></span>
-                                                                                                       {/if}
-                                                                                               </button>
-                                                                                       </div>
-                                                                               {/if}
-                                                                               <div class="d-flex flex-row">
-                                                                                       <input
-                                                                                               disabled={selectedTemplate === null}
-                                                                                               type="text"
-                                                                                               bind:value={templateName}
-                                                                                               class="form-control"
-                                                                                               placeholder="Name der Vorlage"
-                                                                                       />
-                                                                                       <button
-                                                                                               disabled={selectedTemplate === '-1' || selectedTemplate === null}
-                                                                                               type="button"
-                                                                                               class="btn btn-outline-danger ms-5"
-                                                                                               onclick={() => {
-                                                                                                       confirmDeleteTemplate = !confirmDeleteTemplate;
-                                                                                               }}><Fa fw icon={faTrash} /></button
-                                                                                       >
-                                                                               </div>
-                                                                               <textarea
-                                                                                       disabled={selectedTemplate === null}
-                                                                                       bind:value={templateText}
-                                                                                       class="form-control mt-2"
-                                                                                       rows="10"
-                                                                                       placeholder="Inhalt der Vorlage"
-                                                                               >
-                                                                               </textarea>
-                                                                               <div class="d-flex justify-content-end">
-                                                                                       <button
-                                                                                               disabled={(oldTemplateName === templateName &&
-                                                                                                       oldTemplateText === templateText) ||
-                                                                                                       isSavingTemplate}
-                                                                                               type="button"
-                                                                                               class="btn btn-primary mt-2"
-                                                                                               onclick={saveTemplate}
-                                                                                       >
-                                                                                               Vorlage speichern
-                                                                                               {#if isSavingTemplate}
-                                                                                                       <span
-                                                                                                               class="spinner-border spinner-border-sm ms-2"
-                                                                                                               role="status"
-                                                                                                               aria-hidden="true"
-                                                                                                       ></span>
-                                                                                               {/if}
-                                                                                       </button>
-                                                                               </div>
-                                                                       </div>
-                                                               </div>
-
-                                                               <div id="data">
-                                                                       <h3 class="text-primary">📁 Daten</h3>
-                                                                       <div id="export"><h5>Export</h5></div>
-                                                                       <div id="import"><h5>Import</h5></div>
-                                                               </div>
-
-                                                               <div id="security">
-                                                                       <h3 class="text-primary">🔒 Sicherheit</h3>
-                                                                       <div id="password">
-                                                                               <h5>Password ändern</h5>
-                                                                               <form onsubmit={changePassword}>
-                                                                                       <div class="form-floating mb-3">
-                                                                                               <input
-                                                                                                       type="password"
-                                                                                                       class="form-control"
-                                                                                                       id="currentPassword"
-                                                                                                       placeholder="Aktuelles Passwort"
-                                                                                                       bind:value={currentPassword}
-                                                                                               />
-                                                                                               <label for="currentPassword">Aktuelles Passwort</label>
-                                                                                       </div>
-                                                                                       <div class="form-floating mb-3">
-                                                                                               <input
-                                                                                                       type="password"
-                                                                                                       class="form-control"
-                                                                                                       id="newPassword"
-                                                                                                       placeholder="Neues Passwort"
-                                                                                                       bind:value={newPassword}
-                                                                                               />
-                                                                                               <label for="newPassword">Neues Passwort</label>
-                                                                                       </div>
-                                                                                       <div class="form-floating mb-3">
-                                                                                               <input
-                                                                                                       type="password"
-                                                                                                       class="form-control"
-                                                                                                       id="confirmNewPassword"
-                                                                                                       placeholder="Neues Passwort bestätigen"
-                                                                                                       bind:value={confirmNewPassword}
-                                                                                               />
-                                                                                               <label for="confirmNewPassword">Neues Passwort bestätigen</label>
-                                                                                       </div>
-                                                                                       <button class="btn btn-primary" onclick={changePassword}>
-                                                                                               {#if isChangingPassword}
-                                                                                                       <!-- svelte-ignore a11y_no_static_element_interactions -->
-                                                                                                       <div class="spinner-border" role="status">
-                                                                                                               <span class="visually-hidden">Loading...</span>
-                                                                                                       </div>
-                                                                                               {/if}
-                                                                                               Passwort ändern
-                                                                                       </button>
-                                                                               </form>
-                                                                               {#if changePasswordNotEqual}
-                                                                                       <div class="alert alert-danger mt-2" role="alert" transition:slide>
-                                                                                               Die neuen Passwörter stimmen nicht überein!
-                                                                                       </div>
-                                                                               {/if}
-                                                                               {#if changingPasswordSuccess}
-                                                                                       <div class="alert alert-success mt-2" role="alert" transition:slide>
-                                                                                               Das Passwort wurde erfolgreich geändert!<br />
-                                                                                               Backup-Keys wurden ungültig gemacht (sofern vorhanden), und müssen neu erstellt
-                                                                                               werden.
-                                                                                       </div>
-                                                                               {/if}
-                                                                               {#if changingPasswordIncorrect}
-                                                                                       <div class="alert alert-danger mt-2" role="alert" transition:slide>
-                                                                                               Das aktuelle Passwort ist falsch!
-                                                                                       </div>
-                                                                               {:else if changingPasswordError}
-                                                                                       <div class="alert alert-danger mt-2" role="alert" transition:slide>
-                                                                                               Fehler beim Ändern des Passworts!
-                                                                                       </div>
-                                                                               {/if}
-                                                                       </div>
-                                                                       <div id="backupkeys"><h5>Backup-Keys</h5></div>
-                                                                       <div id="username"><h5>Username ändern</h5></div>
-                                                                       <div id="deleteaccount"><h5>Konto löschen</h5></div>
-                                                               </div>
-
-                                                               <div id="about">
-                                                                       <h3 class="text-primary">💡 About</h3>
-                                                                       Version:<br />
-                                                                       Changelog: <br />
-                                                                       Link zu github
-                                                               </div>
-                                                       </div>
-                                               </div>
-                                       </div>
-                               </div>
-                               <div class="modal-footer">
-                                       {#if settingsHaveChanged}
-                                               <div class="footer-unsaved-changes" transition:fade={{ duration: 100 }}>
-                                                       Ungespeicherte Änderungen!
-                                               </div>
-                                       {/if}
-                                       <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
-                                       <button
-                                               type="button"
-                                               class="btn btn-primary"
-                                               onclick={saveUserSettings}
-                                               disabled={isSaving || !settingsHaveChanged}
-                                               >Speichern
-                                               {#if isSaving}
-                                                       <span class="spinner-border spinner-border-sm ms-2" role="status" aria-hidden="true"
-                                                       ></span>
-                                               {/if}
-                                       </button>
-                               </div>
-                       </div>
-               </div>
-       </div>
-
-       <div class="toast-container position-fixed bottom-0 end-0 p-3">
-               <div
-                       id="toastSuccessEditTag"
-                       class="toast align-items-center text-bg-success"
-                       role="alert"
-                       aria-live="assertive"
-                       aria-atomic="true"
-               >
-                       <div class="d-flex">
-                               <div class="toast-body">Änderungen wurden gespeichert!</div>
-                       </div>
-               </div>
-
-               <div
-                       id="toastErrorEditTag"
-                       class="toast align-items-center text-bg-danger"
-                       role="alert"
-                       aria-live="assertive"
-                       aria-atomic="true"
-               >
-                       <div class="d-flex">
-                               <div class="toast-body">Fehler beim Speichern der Änderungen!</div>
-                       </div>
-               </div>
-
-               <div
-                       id="toastErrorDeleteTag"
-                       class="toast align-items-center text-bg-danger"
-                       role="alert"
-                       aria-live="assertive"
-                       aria-atomic="true"
-               >
-                       <div class="d-flex">
-                               <div class="toast-body">Fehler beim Löschen des Tags!</div>
-                       </div>
-               </div>
-
-               <div
-                       id="toastSuccessSaveSettings"
-                       class="toast align-items-center text-bg-success"
-                       role="alert"
-                       aria-live="assertive"
-                       aria-atomic="true"
-               >
-                       <div class="d-flex">
-                               <div class="toast-body">Einstellungen gespeichert!</div>
-                       </div>
-               </div>
-
-               <div
-                       id="toastErrorSaveSettings"
-                       class="toast align-items-center text-bg-danger"
-                       role="alert"
-                       aria-live="assertive"
-                       aria-atomic="true"
-               >
-                       <div class="d-flex">
-                               <div class="toast-body">Fehler beim Speichern der Einstellungen!</div>
-                       </div>
-               </div>
-
-               <div
-                       id="toastErrorInvalidTemplateEmpty"
-                       class="toast align-items-center text-bg-danger"
-                       role="alert"
-                       aria-live="assertive"
-                       aria-atomic="true"
-               >
-                       <div class="d-flex">
-                               <div class="toast-body">Name oder Inhalt einer Vorlage dürfen nicht leer sein!</div>
-                       </div>
-               </div>
-
-               <div
-                       id="toastErrorInvalidTemplateDouble"
-                       class="toast align-items-center text-bg-danger"
-                       role="alert"
-                       aria-live="assertive"
-                       aria-atomic="true"
-               >
-                       <div class="d-flex">
-                               <div class="toast-body">Name der Vorlage existiert bereits</div>
-                       </div>
-               </div>
-
-               <div
-                       id="toastSuccessSaveTemplate"
-                       class="toast align-items-center text-bg-success"
-                       role="alert"
-                       aria-live="assertive"
-                       aria-atomic="true"
-               >
-                       <div class="d-flex">
-                               <div class="toast-body">Vorlage gespeichert</div>
-                       </div>
-               </div>
-
-               <div
-                       id="toastErrorDeletingTemplate"
-                       class="toast align-items-center text-bg-danger"
-                       role="alert"
-                       aria-live="assertive"
-                       aria-atomic="true"
-               >
-                       <div class="d-flex">
-                               <div class="toast-body">Fehler beim Löschen der Vorlage</div>
-                       </div>
-               </div>
-
-               <div
-                       id="toastSuccessDeletingTemplate"
-                       class="toast align-items-center text-bg-success"
-                       role="alert"
-                       aria-live="assertive"
-                       aria-atomic="true"
-               >
-                       <div class="d-flex">
-                               <div class="toast-body">Vorlage gelöscht</div>
-                       </div>
-               </div>
-       </div>
 </main>
 
 <style>
-       .footer-unsaved-changes {
-               background-color: orange;
-               color: black;
-               padding: 0.25rem 0.5rem;
-               border-radius: 10px;
-               margin-left: auto;
-               margin-right: 2rem;
-               font-style: italic;
-       }
-
-       div:has(> .unsaved-changes) {
-               outline: 1px solid orange;
-       }
-
-       .unsaved-changes {
-               background-color: orange;
-               margin-top: -0.5rem;
-               margin-left: -0.5rem;
-               margin-right: -0.5rem;
-               border-top-left-radius: 10px;
-               border-top-right-radius: 10px;
-               padding-left: 0.5rem;
-               margin-bottom: 0.5rem;
-       }
-
-       .unsaved-changes::before {
-               content: 'Ungespeicherte Änderungen';
-       }
-
-       :global(.tagColumn > span) {
-               width: min-content;
-       }
-
-       .tagColumn {
-               gap: 0.5rem;
-               /* width: min-content; */
-       }
-
-       #selectMode:checked {
-               border-color: #da880e;
-               background-color: #da880e;
-       }
-
-       #selectMode:not(:checked) {
-               background-color: #2196f3;
-               background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba(255, 255, 255, 1)'/></svg>");
-       }
-
-       .settings-content > div {
-               padding: 0.5rem;
-       }
-
-       #settings-content > div > div {
-               background-color: #bdbdbd5d;
-               padding: 0.5rem;
-               border-radius: 10px;
-               margin-bottom: 1rem;
-       }
-
-       h3.text-primary {
-               font-weight: 700;
-               position: sticky;
-               top: 0;
-               backdrop-filter: blur(10px) saturate(150%);
-               background-color: rgba(240, 240, 240, 0.9);
-               padding: 4px;
-               border-radius: 5px;
-       }
-
-       #trianglifyOpacity {
-               max-width: 300px;
-       }
-
-       #trianglifyOpacityNumber {
-               width: 80px;
-       }
-
-       .modal-body {
-               overflow-y: hidden;
-       }
-
-       .modal-content {
-               backdrop-filter: blur(10px) saturate(150%);
-               /* background-color: rgba(43, 56, 78, 0.75); */
-               background-color: rgba(208, 208, 208, 0.61);
-               /* color: rgb(22, 22, 22); */
-       }
-
-       .modal-header {
-               border-bottom: 1px solid rgba(255, 255, 255, 0.2);
-       }
-
-       .modal-footer {
-               border-top: 1px solid rgba(255, 255, 255, 0.2);
-       }
-
        main {
                height: 100vh;
 
git clone https://git.99rst.org/PROJECT