renamed account page to settings page and improved layout

This commit is contained in:
2026-01-03 23:32:54 +01:00
parent 53b854d03a
commit 9e855d52c7
9 changed files with 118 additions and 110 deletions

View File

@@ -2,8 +2,8 @@ import { UpdateUserResponse } from '../types';
import { apiFetch } from './client' import { apiFetch } from './client'
// import type { User } from '../types' // import type { User } from '../types'
export function updateAccount(username: string, email: string, password: string) { export function updateSettings(username: string, email: string, password: string) {
return apiFetch<UpdateUserResponse>('/account', { return apiFetch<UpdateUserResponse>('/settings', {
method: 'PUT', method: 'PUT',
body: JSON.stringify({ username, email, password }), body: JSON.stringify({ username, email, password }),
}); });

View File

@@ -14,7 +14,7 @@
<span v-if="totalCount > 0" class="badge">{{ totalCount }}</span> <span v-if="totalCount > 0" class="badge">{{ totalCount }}</span>
</router-link> </router-link>
<router-link to="/account" class="nav-item"> <router-link to="/settings" class="nav-item">
<i class="fa-solid fa-circle-user"></i> <i class="fa-solid fa-circle-user"></i>
</router-link> </router-link>
</nav> </nav>

View File

@@ -1,8 +1,8 @@
<template> <template>
<div class="backdrop" @click.self="emit('close')"> <div class="backdrop" @click.self="emit('close')">
<form class="modal" @submit.prevent="submit"> <form class="modal" @submit.prevent="submit">
<h2>{{ $t('account-update-modal-title') }}</h2> <h2>{{ $t('settings-account-update-modal-title') }}</h2>
<p class="subtitle">{{ $t('account-update-subtitle') }}</p> <p class="subtitle">{{ $t('settings-account-update-subtitle') }}</p>
<p v-if="errorMessage" class="error-message">{{ errorMessage }}</p> <p v-if="errorMessage" class="error-message">{{ errorMessage }}</p>
@@ -17,9 +17,9 @@
</div> </div>
<div class="input-group"> <div class="input-group">
<label>{{ $t('account-new-password') }}</label> <label>{{ $t('settings-new-password') }}</label>
<input v-model="password" type="password" placeholder="..." /> <input v-model="password" type="password" :placeholder="$t('settings-new-password')" />
<input v-model="confirmPassword" type="password" :placeholder="$t('account-new-password-confirm')" /> <input v-model="confirmPassword" type="password" :placeholder="$t('settings-new-password-confirm')" />
</div> </div>
<div class="actions"> <div class="actions">
@@ -28,7 +28,7 @@
</button> </button>
<button type="submit" :disabled="isSubmitting"> <button type="submit" :disabled="isSubmitting">
{{ isSubmitting ? $t('account-updating') : $t('account-update-save') }} {{ isSubmitting ? $t('settings-updating') : $t('settings-update-save') }}
</button> </button>
</div> </div>
</form> </form>
@@ -37,7 +37,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import { updateAccount } from '../api/account' import { updateSettings } from '../api/account'
import { updateLocalUser } from '../authStore' import { updateLocalUser } from '../authStore'
import type { User } from '../types' import type { User } from '../types'
import { useFluent } from 'fluent-vue'; import { useFluent } from 'fluent-vue';
@@ -65,7 +65,7 @@ async function submit() {
// Prevent empty submission // Prevent empty submission
if (!username.value || !email.value) { if (!username.value || !email.value) {
errorMessage.value = $t('account-error-required') errorMessage.value = $t('settings-error-required')
return return
} }
@@ -73,7 +73,7 @@ async function submit() {
errorMessage.value = '' errorMessage.value = ''
try { try {
const updatedData = await updateAccount( const updatedData = await updateSettings(
username.value.trim(), username.value.trim(),
email.value.trim(), email.value.trim(),
password.value password.value
@@ -84,7 +84,7 @@ async function submit() {
emit('updated') emit('updated')
emit('close') emit('close')
} catch (err: any) { } catch (err: any) {
errorMessage.value = err?.message || $t('account-error-failed') errorMessage.value = err?.message || $t('settings-error-failed')
} finally { } finally {
isSubmitting.value = false isSubmitting.value = false
} }

View File

@@ -5,7 +5,7 @@ language = English
nav-chat = Chat nav-chat = Chat
nav-friends = Friendlist nav-friends = Friendlist
nav-notifications = Notifications nav-notifications = Notifications
nav-account = Account nav-settings = Settings
## Auth ## Auth
auth-login-title = Login auth-login-title = Login
@@ -57,22 +57,23 @@ notifications-invite-from = from: {$user}
notifications-error-friend = An error occurred while accepting the request. notifications-error-friend = An error occurred while accepting the request.
notifications-error-room = An error occurred while accepting the invite. notifications-error-room = An error occurred while accepting the invite.
## Account page ## Settings page
account-title = Your Account settings-title = Settings
account-label-username = Username: settings-account = Account
account-label-email = Email: settings-language = Language
account-update-btn = Update settings-label-username = Username:
account-logout-btn = Logout settings-label-email = Email:
account-loading = Loading account details... settings-update-btn = Update
account-update-modal-title = Update your Account settings-logout-btn = Logout
account-update-subtitle = Only fill in the fields you wish to change. settings-account-loading = Loading account details...
account-new-password = New Password settings-account-update-modal-title = Update your Account
account-new-password-confirm = Confirm new password settings-account-update-subtitle = Only fill in the fields you wish to change.
account-update-save = Save Changes settings-new-password = New Password
account-updating = Updating... settings-new-password-confirm = Confirm new password
account-language = Language settings-update-save = Save Changes
account-error-required = Username and Email are required. settings-updating = Updating...
account-error-failed = Update failed settings-error-required = Username and Email are required.
settings-error-failed = Update failed
## Shared ## Shared
shared-cancel = Cancel shared-cancel = Cancel

View File

@@ -5,7 +5,7 @@ language = Français
nav-chat = Messagerie nav-chat = Messagerie
nav-friends = Amis nav-friends = Amis
nav-notifications = Notifications nav-notifications = Notifications
nav-account = Compte nav-settings = Compte
## Auth ## Auth
auth-login-title = Connexion auth-login-title = Connexion
@@ -56,22 +56,23 @@ notifications-invite-from = de : {$user}
notifications-error-friend = Erreur lors de l'acceptation de la demande. notifications-error-friend = Erreur lors de l'acceptation de la demande.
notifications-error-room = Erreur lors de l'acceptation de l'invitation. notifications-error-room = Erreur lors de l'acceptation de l'invitation.
## Account page ## Settings page
account-title = Votre Compte settings-title = Paramètres
account-label-username = Nom d'utilisateur : settings-account = Compte
account-label-email = Email : settings-language = Langue
account-update-btn = Modifier settings-label-username = Nom d'utilisateur :
account-logout-btn = Déconnexion settings-label-email = Email :
account-loading = Chargement du compte... settings-update-btn = Modifier
account-update-modal-title = Modifier votre compte settings-logout-btn = Déconnexion
account-update-subtitle = Remplissez uniquement ce que vous souhaitez changer. settings-account-loading = Chargement du compte...
account-new-password = Nouveau mot de passe settings-account-update-modal-title = Modifier votre compte
account-new-password-confirm = Confirmer le mot de passe settings-account-update-subtitle = Remplissez uniquement ce que vous souhaitez changer.
account-update-save = Enregistrer settings-new-password = Nouveau mot de passe
account-updating = Mise à jour... settings-new-password-confirm = Confirmer le mot de passe
account-language = Langue settings-update-save = Enregistrer
account-error-required = Le nom d'utilisateur et l'email sont requis. settings-updating = Mise à jour...
account-error-failed = Échec de la mise à jour settings-error-required = Le nom d'utilisateur et l'email sont requis.
settings-error-failed = Échec de la mise à jour
## Shared ## Shared
shared-cancel = Annuler shared-cancel = Annuler

View File

@@ -1,22 +1,22 @@
<template> <template>
<div class="login-page"> <div class="login-page">
<form class="login-card" @submit.prevent="submit"> <form class="login-card" @submit.prevent="submit">
<h1>{{ $t('auth-login-title') }}</h1> <h1>{{ $t('auth-login-title') }}</h1>
<div class="input-group"> <div class="input-group">
<label>{{ $t('auth-email') }}</label> <label>{{ $t('auth-email') }}</label>
<input v-model="email" :placeholder="$t('auth-email').toLowerCase()" /> <input v-model="email" :placeholder="$t('auth-email').toLowerCase()" />
</div> </div>
<div class="input-group"> <div class="input-group">
<label>{{ $t('auth-password') }}</label> <label>{{ $t('auth-password') }}</label>
<input v-model="password" type="password" :placeholder="$t('auth-password').toLowerCase()" /> <input v-model="password" type="password" :placeholder="$t('auth-password').toLowerCase()" />
</div> </div>
<button type="submit">{{ $t('auth-login-btn') }}</button> <button type="submit">{{ $t('auth-login-btn') }}</button>
<p v-if="errorMessage" class="error-message">{{ errorMessage }}</p> <p v-if="errorMessage" class="error-message">{{ errorMessage }}</p>
<p class="register-link"> <p class="register-link">
{{ $t('auth-no-account') }} <router-link to="/register">{{ $t('auth-register-title') }}</router-link> {{ $t('auth-no-account') }} <router-link to="/register">{{ $t('auth-register-title') }}</router-link>
</p> </p>
</form> </form>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -34,58 +34,58 @@ const router = useRouter();
const { $t } = useFluent(); const { $t } = useFluent();
async function submit() { async function submit() {
errorMessage.value = ""; errorMessage.value = "";
try { try {
await login(email.value, "", password.value); await login(email.value, "", password.value);
router.push("/"); router.push("/");
} catch (err: any) { } catch (err: any) {
errorMessage.value = err?.message || $t('auth-error-unknown'); errorMessage.value = err?.message || $t('auth-error-unknown');
} }
} }
</script> </script>
<style scoped> <style scoped>
.login-page { .login-page {
height: 100%; height: 100%;
display: grid; display: grid;
place-items: center; place-items: center;
} }
.login-card { .login-card {
width: 100%; width: 100%;
max-width: 360px; max-width: 360px;
background: var(--panel); background: var(--panel);
border: 1px solid var(--border); border: 1px solid var(--border);
border-radius: var(--radius); border-radius: var(--radius);
padding: 2rem; padding: 2rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1rem; gap: 1rem;
} }
.login-card h1 { .login-card h1 {
font-size: 1.4rem; font-size: 1.4rem;
font-weight: 600; font-weight: 600;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
text-align: center; text-align: center;
} }
.register-link { .register-link {
font-size: 0.9rem; font-size: 0.9rem;
text-align: center; text-align: center;
color: var(--text-muted); color: var(--text-muted);
} }
.register-link a { .register-link a {
color: var(--accent); color: var(--accent);
margin-left: 5px; margin-left: 5px;
} }
.error-message { .error-message {
color: var(--error); color: var(--error);
font-size: 0.9rem; font-size: 0.9rem;
text-align: center; text-align: center;
margin-top: 0.5rem; margin-top: 0.5rem;
} }
</style> </style>

View File

@@ -22,7 +22,7 @@
<button type="submit">{{ $t('auth-register-btn') }}</button> <button type="submit">{{ $t('auth-register-btn') }}</button>
<p class="login-link"> <p class="login-link">
{{ $t('auth-has-account') }} <router-link to="/login">{{ $t('auth-login-title') }}</router-link> {{ $t('auth-has-settings') }} <router-link to="/login">{{ $t('auth-login-title') }}</router-link>
</p> </p>
<p v-if="errorMessage" class="error-message">{{ errorMessage }}</p> <p v-if="errorMessage" class="error-message">{{ errorMessage }}</p>

View File

@@ -1,20 +1,21 @@
<template> <template>
<div class="account-page"> <div class="settings-page">
<h1>{{ $t('account-title') }}</h1> <h1>{{ $t('settings-title') }}</h1>
<UpdateAccountModal v-if="showUpdateModal" :user="user" @close="showUpdateModal = false" @updated="fetchUserData" /> <UpdateAccountModal v-if="showUpdateModal" :user="user" @close="showUpdateModal = false" @updated="fetchUserData" />
<h2>{{ $t('settings-account') }}</h2>
<div v-if="user" class="info-card"> <div v-if="user" class="info-card">
<button class="update-btn" @click="showUpdateModal = true">{{ $t('account-update-btn') }}</button> <button class="update-btn" @click="showUpdateModal = true">{{ $t('settings-update-btn') }}</button>
<p><strong>{{ $t('account-label-username') }}</strong> {{ user.username }}</p> <p><strong>{{ $t('settings-label-username') }}</strong> {{ user.username }}</p>
<p><strong>{{ $t('account-label-email') }}</strong> {{ user.email }}</p> <p><strong>{{ $t('settings-label-email') }}</strong> {{ user.email }}</p>
</div> </div>
<div v-else class="loading-state"> <div v-else class="loading-state">
<p>{{ $t('account-loading') }}</p> <p>{{ $t('settings-loading') }}</p>
</div> </div>
<h2>{{ $t('settings-language') }}</h2>
<div class="input-group"> <div class="input-group">
<span>{{ $t('account-language') }}</span>
<div class="lang-grid"> <div class="lang-grid">
<button v-for="lang in languages" :key="lang.code" class="lang-btn" <button v-for="lang in languages" :key="lang.code" class="lang-btn"
:class="{ active: currentLang === lang.code }" @click="changeLanguage(lang.code)"> :class="{ active: currentLang === lang.code }" @click="changeLanguage(lang.code)">
@@ -25,7 +26,7 @@
<button class="logout-btn" @click="logout"> <button class="logout-btn" @click="logout">
<i class="fa-solid fa-right-from-bracket"></i> <i class="fa-solid fa-right-from-bracket"></i>
<span>{{ $t('account-logout-btn') }}</span> <span>{{ $t('settings-logout-btn') }}</span>
</button> </button>
</div> </div>
</template> </template>
@@ -79,13 +80,17 @@ function logout() {
</script> </script>
<style scoped> <style scoped>
.account-page { .settings-page {
max-width: 720px; max-width: 720px;
margin: 0 auto; margin: 0 auto;
padding: 2rem 1.5rem; padding: 2rem 1.5rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 2rem; gap: 1rem;
}
h2 {
margin-top: 20px;
} }
.info-card { .info-card {
@@ -127,6 +132,7 @@ function logout() {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
margin-top: 30px;
padding: 10px 20px; padding: 10px 20px;
color: var(--text); color: var(--text);
background-color: transparent; background-color: transparent;

View File

@@ -6,7 +6,7 @@ import RegisterPage from './pages/RegisterPage.vue'
import ChatPage from './pages/ChatPage.vue' import ChatPage from './pages/ChatPage.vue'
import FriendListPage from './pages/FriendListPage.vue' import FriendListPage from './pages/FriendListPage.vue'
import NofificationsPage from './pages/NotificationsPage.vue' import NofificationsPage from './pages/NotificationsPage.vue'
import AccountPage from './pages/AccountPage.vue' import SettingsPage from './pages/SettingsPage.vue'
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
@@ -32,7 +32,7 @@ const router = createRouter({
}, },
{ path: '/friendlist', component: FriendListPage }, { path: '/friendlist', component: FriendListPage },
{ path: '/notifications', component: NofificationsPage }, { path: '/notifications', component: NofificationsPage },
{ path: '/account', component: AccountPage } { path: '/settings', component: SettingsPage }
], ],
}) })