Files
takerofnotes-app/src/renderer/src/views/Preferences.vue
2026-04-09 14:58:06 -04:00

116 lines
2.6 KiB
Vue

<template>
<main class="preferences layout-block">
<h1 class="title">Preferences</h1>
<div class="sections">
<preferences-general />
<preferences-encryption ref="encryption" />
<suspense @resolve="ready = true">
<preferences-storage ref="storage" />
</suspense>
</div>
<p v-if="validationError" class="error">{{ validationError }}</p>
<button @click="save" class="save-btn" :disabled="!ready">
<svg-spinner v-if="saving" />
<span v-else-if="saved">Saved</span>
<span v-else>Save</span>
</button>
</main>
</template>
<script setup>
import PreferencesEncryption from '@/components/preferences/Encryption.vue'
import PreferencesGeneral from '@/components/preferences/General.vue'
import PreferencesStorage from '@/components/preferences/Storage.vue'
import SvgSpinner from '@/components/svg/Spinner.vue'
import { ref } from 'vue'
const ready = ref(false)
const saving = ref(false)
const saved = ref(false)
const validationError = ref('')
// Sections
const storage = ref()
const encryption = ref()
const save = async () => {
saving.value = true
saved.value = false
validationError.value = ''
try {
await storage.value.validate()
await encryption.value.validate()
saved.value = true
setTimeout(() => {
saved.value = false
}, 2000)
} catch (error) {
console.error(error.message)
validationError.value = error.message
} finally {
saving.value = false
}
}
</script>
<style lang="scss">
.preferences {
padding-top: var(--nav-height);
padding-bottom: 60px;
position: relative;
.title {
margin-bottom: 25px;
}
.sections {
display: flex;
flex-direction: column;
gap: 30px;
max-width: 500px;
}
.section-title {
margin-bottom: 20px;
}
.error {
position: fixed;
top: 0;
left: 0;
right: 0;
background: #ba3632;
padding: 5px var(--layout-margin);
text-align: center;
}
.save-btn {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 16px 0;
text-align: center;
border-top: 1px dashed currentColor;
background: var(--theme-bg);
.svg-spinner {
width: 1em;
height: 1em;
}
&:hover {
color: var(--theme-accent);
}
&:disabled {
opacity: 0.5;
cursor: default;
}
}
}
</style>