toolshed/frontend/src/views/Settings.vue
2026-08-31 13:02:06 +02:00

111 lines
No EOL
5 KiB
Vue

<template>
<BaseLayout>
<main class="content">
<div class="container-fluid p-0">
<h1 class="h3 mb-3">Settings</h1>
<div v-if="deleteError" class="alert alert-danger">{{ deleteError }}</div>
<div v-if="deleteSuccess" class="alert alert-success">
Your account has been permanently deleted. Signing you out...
</div>
<div class="row">
<div class="col-md-3 col-xl-2">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Profile Settings</h5>
</div>
<div class="list-group list-group-flush" role="tablist">
<router-link class="list-group-item list-group-item-action" :to="{name: 'account'}"
active-class="dummy" exact-active-class="active">Account
</router-link>
<router-link class="list-group-item list-group-item-action" :to="{name: 'password'}"
active-class="active">Password
</router-link>
<router-link class="list-group-item list-group-item-action" :to="{name: 'privacy'}"
active-class="active">Privacy and safety
</router-link>
<router-link class="list-group-item list-group-item-action" :to="{name: 'email'}"
active-class="active">Email notifications
</router-link>
<router-link class="list-group-item list-group-item-action"
:to="{name: 'notifications'}" active-class="active">Web notifications
</router-link>
<router-link class="list-group-item list-group-item-action" :to="{name: 'preferences'}"
active-class="active">Preferences
</router-link>
<router-link class="list-group-item list-group-item-action" :to="{name: 'data'}"
active-class="active">Your data
</router-link>
<a class="list-group-item list-group-item-action delete" @click="deleteAccount"
href="#">
Delete account
</a>
</div>
</div>
</div>
<div class="col-md-9 col-xl-10">
<div class="tab-content">
<router-view></router-view>
</div>
</div>
</div>
</div>
</main>
</BaseLayout>
</template>
<script>
import BaseLayout from "@/components/BaseLayout.vue";
import {mapActions, mapGetters, mapMutations} from "vuex";
export default {
name: 'Settings',
components: {BaseLayout},
data() {
return {
deleteError: null,
deleteSuccess: false
}
},
computed: {
...mapGetters(['signAuth'])
},
methods: {
...mapActions(['getHomeServers']),
...mapMutations(['logout']),
async deleteAccount() {
this.deleteError = null;
if (!confirm('Are you sure you want to permanently delete your account? ' +
'All your data will be deleted and you will not be able to log back in. This cannot be undone.')) {
return;
}
try {
const servers = await this.getHomeServers();
const response = await servers.delete(this.signAuth, '/api/v1/account/');
if (!response || !response.ok) {
const errorBody = response ? await response.json().catch(() => ({})) : {};
this.deleteError = 'Account deletion failed: ' + (errorBody.detail || response?.statusText || 'unknown error');
return;
}
this.deleteSuccess = true;
// logout() redirects to /login right away - give the user a moment to read the
// confirmation above before that navigation happens.
setTimeout(() => this.logout(), 2000);
} catch (error) {
console.error('Account deletion failed', error);
this.deleteError = 'Account deletion failed: ' + error;
}
},
}
}
</script>
<style scoped>
.delete {
color: var(--bs-danger);
}
.delete:hover {
color: var(--bs-light);
background-color: var(--bs-danger);
}
</style>