|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
|
|
|
|
|
<head>
|
|
|
|
|
<meta name="description" content="User Profile">
|
|
|
|
|
<title>{{ $t('user.profile') }}</title>
|
|
|
|
|
<style>
|
|
|
|
|
body {
|
|
|
|
|
background-color: var(--bg-color);
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
padding-top: var(--spacing-xl);
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.profile-container {
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-width: 600px;
|
|
|
|
|
padding: var(--spacing-xl);
|
|
|
|
|
background: var(--bg-color-secondary);
|
|
|
|
|
border-radius: var(--radius-lg);
|
|
|
|
|
box-shadow: var(--shadow-sm);
|
|
|
|
|
border: 1px solid var(--border-color);
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: var(--spacing-lg);
|
|
|
|
|
height: fit-content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.avatar-section {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: var(--spacing-md);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.avatar {
|
|
|
|
|
width: 100px;
|
|
|
|
|
height: 100px;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
background: linear-gradient(135deg, var(--color-primary), var(--color-secondary));
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
font-size: 32px;
|
|
|
|
|
color: var(--color-primary-text);
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.form-content {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: var(--spacing-md);
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
<body>
|
|
|
|
|
<div class="profile-container">
|
|
|
|
|
<h2 style="text-align: center;">{{ $t('user.profile') }}</h2>
|
|
|
|
|
|
|
|
|
|
<div class="avatar-section">
|
|
|
|
|
<div class="avatar">
|
|
|
|
|
{{ user.username ? user.username.charAt(0).toUpperCase() : 'U' }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<form class="form-content" @submit.prevent="updateProfile">
|
|
|
|
|
<v-input label="Username" v:value="user.username" disabled></v-input>
|
|
|
|
|
<v-input label="Email" type="email" v:value="user.email" required></v-input>
|
|
|
|
|
<v-input label="Phone" type="tel" v:value="user.phone"></v-input>
|
|
|
|
|
|
|
|
|
|
<v-btn type="submit" color="primary" block style="margin-top: var(--spacing-sm);">
|
|
|
|
|
{{ $t('common.save') }}
|
|
|
|
|
</v-btn>
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
<div style="border-top: 1px solid var(--border-color); padding-top: var(--spacing-lg);">
|
|
|
|
|
<v-btn color="danger" variant="outline" block :click="handleLogout">
|
|
|
|
|
{{ $t('auth.logout') }}
|
|
|
|
|
</v-btn>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</body>
|
|
|
|
|
<script setup>
|
|
|
|
|
user = $env.$vbase.user || {};
|
|
|
|
|
|
|
|
|
|
// Fetch fresh data
|
|
|
|
|
loadUser = async () => {
|
|
|
|
|
try {
|
|
|
|
|
user = await $env.$vbase.fetchUser();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error(e);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
updateProfile = async () => {
|
|
|
|
|
try {
|
|
|
|
|
await $axios.patch('/api/auth/me', {
|
|
|
|
|
email: user.email,
|
|
|
|
|
phone: user.phone
|
|
|
|
|
});
|
|
|
|
|
$message.success("Profile updated");
|
|
|
|
|
loadUser();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
$message.error(e.message);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
handleLogout = async () => {
|
|
|
|
|
await $env.$vbase.logout('/login');
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<script>
|
|
|
|
|
$data.loadUser();
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
</html>
|