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 type { User } from '../types'
export function updateAccount(username: string, email: string, password: string) {
return apiFetch<UpdateUserResponse>('/account', {
export function updateSettings(username: string, email: string, password: string) {
return apiFetch<UpdateUserResponse>('/settings', {
method: 'PUT',
body: JSON.stringify({ username, email, password }),
});

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -22,7 +22,7 @@
<button type="submit">{{ $t('auth-register-btn') }}</button>
<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 v-if="errorMessage" class="error-message">{{ errorMessage }}</p>

View File

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

View File

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