116 lines
2.6 KiB
Vue
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>
|