Added infrastructure for editable properties in settings page.
This commit is contained in:
parent
40891656d0
commit
88089f2e11
|
@ -127,10 +127,20 @@ class AuthModule {
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async updateMyPersonalDetails(authStore: AuthStoreType, newPersonalDetails: UserPersonalDetails): Promise<UserPersonalDetails> {
|
||||||
|
const response = await api.post('/auth/me/personal-details', newPersonalDetails, authStore.axiosConfig);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
public async getMyPreferences(authStore: AuthStoreType): Promise<UserPreferences> {
|
public async getMyPreferences(authStore: AuthStoreType): Promise<UserPreferences> {
|
||||||
const response = await api.get('/auth/me/preferences', authStore.axiosConfig);
|
const response = await api.get('/auth/me/preferences', authStore.axiosConfig);
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async updateMyPreferences(authStore: AuthStoreType, newPreferences: UserPreferences): Promise<UserPreferences> {
|
||||||
|
const response = await api.post('/auth/me/preferences', newPreferences, authStore.axiosConfig);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AuthModule;
|
export default AuthModule;
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<template>
|
||||||
|
<div class="row justify-between">
|
||||||
|
<span class="property-label">{{ label }}</span>
|
||||||
|
|
||||||
|
<div v-if="typeof modelValue === 'string'">
|
||||||
|
<q-input
|
||||||
|
:model-value="modelValue"
|
||||||
|
@update:modelValue="onValueUpdated"
|
||||||
|
:type="inputType"
|
||||||
|
dense
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="typeof modelValue === 'boolean'">
|
||||||
|
<q-toggle :model-value="modelValue" @update:modelValue="onValueUpdated"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {DateTime} from 'luxon';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
label: string;
|
||||||
|
inputType?: any;
|
||||||
|
modelValue: string | number | boolean | DateTime;
|
||||||
|
}
|
||||||
|
defineProps<Props>();
|
||||||
|
const emits = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
|
function onValueUpdated(newValue: string) {
|
||||||
|
emits('update:modelValue', newValue);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.property-label {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: auto;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -47,7 +47,15 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
userSettingsPage: {
|
userSettingsPage: {
|
||||||
title: 'Account Settings'
|
title: 'Account Settings',
|
||||||
|
personalDetails: {
|
||||||
|
birthDate: 'Date of Birth'
|
||||||
|
},
|
||||||
|
preferences: {
|
||||||
|
accountPrivate: 'Private Account'
|
||||||
|
},
|
||||||
|
save: 'Save',
|
||||||
|
undo: 'Undo'
|
||||||
},
|
},
|
||||||
accountMenuItem: {
|
accountMenuItem: {
|
||||||
logIn: 'Login',
|
logIn: 'Login',
|
||||||
|
|
|
@ -3,33 +3,105 @@
|
||||||
<StandardCenteredPage>
|
<StandardCenteredPage>
|
||||||
<h3>{{ $t('userSettingsPage.title') }}</h3>
|
<h3>{{ $t('userSettingsPage.title') }}</h3>
|
||||||
<hr>
|
<hr>
|
||||||
<q-form>
|
<div v-if="personalDetails">
|
||||||
|
<h4>Personal Information</h4>
|
||||||
|
<EditablePropertyRow
|
||||||
|
v-model="personalDetails.birthDate"
|
||||||
|
:label="$t('userSettingsPage.personalDetails.birthDate')"
|
||||||
|
input-type="date"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div v-if="personalDetailsChanged">
|
||||||
|
<q-btn :label="$t('userSettingsPage.save')" color="positive" @click="savePersonalDetails"/>
|
||||||
|
<q-btn :label="$t('userSettingsPage.undo')" color="secondary" @click="undoPersonalDetailsChanges"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="preferences">
|
||||||
|
<h4>Preferences</h4>
|
||||||
|
|
||||||
|
<EditablePropertyRow
|
||||||
|
v-model="preferences.accountPrivate"
|
||||||
|
:label="$t('userSettingsPage.preferences.accountPrivate')"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div v-if="preferencesChanged">
|
||||||
|
<q-btn :label="$t('userSettingsPage.save')" color="positive" @click="savePreferences"/>
|
||||||
|
<q-btn :label="$t('userSettingsPage.undo')" color="secondary" @click="undoPreferencesChanges"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</q-form>
|
|
||||||
</StandardCenteredPage>
|
</StandardCenteredPage>
|
||||||
</q-page>
|
</q-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import StandardCenteredPage from 'components/StandardCenteredPage.vue';
|
import StandardCenteredPage from 'components/StandardCenteredPage.vue';
|
||||||
import { User } from 'src/api/main/auth';
|
|
||||||
import { getUserRoute } from 'src/router/user-routing';
|
|
||||||
import { useAuthStore } from 'src/stores/auth-store';
|
|
||||||
import { onMounted } from 'vue';
|
|
||||||
import {useRoute, useRouter} from 'vue-router';
|
import {useRoute, useRouter} from 'vue-router';
|
||||||
|
import {useAuthStore} from 'stores/auth-store';
|
||||||
|
import {computed, onMounted, ref, Ref, toRaw} from 'vue';
|
||||||
|
import {UserPersonalDetails, UserPreferences} from 'src/api/main/auth';
|
||||||
|
import api from 'src/api/main';
|
||||||
|
import EditablePropertyRow from 'components/EditablePropertyRow.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
|
const personalDetails: Ref<UserPersonalDetails | undefined> = ref();
|
||||||
|
const preferences: Ref<UserPreferences | undefined> = ref();
|
||||||
|
|
||||||
|
let initialPersonalDetails: UserPersonalDetails | null = null;
|
||||||
|
let initialPreferences: UserPreferences | null = null;
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// If the user isn't on their own settings page, redirect them back to the user's profile page.
|
// Redirect away from the page if the user isn't viewing their own settings.
|
||||||
const userId = route.params.userId as string;
|
const userId = route.params.userId as string;
|
||||||
if (authStore.user?.id !== userId) {
|
if (!authStore.user || authStore.user.id !== userId) {
|
||||||
await router.push(`/users/${userId}`);
|
await router.push(`/users/${userId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
personalDetails.value = await api.auth.getMyPersonalDetails(authStore);
|
||||||
|
initialPersonalDetails = structuredClone(toRaw(personalDetails.value));
|
||||||
|
|
||||||
|
preferences.value = await api.auth.getMyPreferences(authStore);
|
||||||
|
initialPreferences = structuredClone(toRaw(preferences.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const personalDetailsChanged = computed(() => {
|
||||||
|
return initialPersonalDetails !== null &&
|
||||||
|
JSON.stringify(initialPersonalDetails) !== JSON.stringify(personalDetails.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
const preferencesChanged = computed(() => {
|
||||||
|
return initialPreferences !== null &&
|
||||||
|
JSON.stringify(initialPreferences) !== JSON.stringify(preferences.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function savePersonalDetails() {
|
||||||
|
if (personalDetails.value) {
|
||||||
|
personalDetails.value = await api.auth.updateMyPersonalDetails(authStore, personalDetails.value);
|
||||||
|
initialPersonalDetails = structuredClone(toRaw(personalDetails.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function undoPersonalDetailsChanges() {
|
||||||
|
personalDetails.value = structuredClone(initialPersonalDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function savePreferences() {
|
||||||
|
if (preferences.value) {
|
||||||
|
preferences.value = await api.auth.updateMyPreferences(authStore, preferences.value);
|
||||||
|
initialPreferences = structuredClone(toRaw(preferences.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function undoPreferencesChanges() {
|
||||||
|
preferences.value = structuredClone(initialPreferences);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
</style>
|
</style>
|
Loading…
Reference in New Issue