chore: setting页面拆分
This commit is contained in:
235
src/views/setting/components/ProfileSection.vue
Normal file
235
src/views/setting/components/ProfileSection.vue
Normal file
@@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<SettingsSection
|
||||
:title="t('Settings.profile.title')"
|
||||
:description="t('Settings.profile.description')"
|
||||
>
|
||||
<div class="profile-header">
|
||||
<div class="avatar relative">
|
||||
<SvgIcon name="user_0" size="46" class="avatar-icon" />
|
||||
<img src="@/assets/images/edit.png" class="avatar-edit-icon" />
|
||||
</div>
|
||||
<div class="profile-summary">
|
||||
<div class="profile-name">{{ fullName }}</div>
|
||||
<div class="profile-email">{{ displayData.email }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="read-section">
|
||||
<div class="read-row two-column">
|
||||
<div class="read-item">
|
||||
<div class="read-label">{{ t('Settings.profile.firstName') }}</div>
|
||||
<div v-show="!isEditing" class="read-box">{{ displayData.firstName }}</div>
|
||||
<div v-show="isEditing" class="form-item-value name">
|
||||
<el-input
|
||||
:model-value="firstName"
|
||||
:placeholder="t('Settings.profile.firstNamePlaceholder')"
|
||||
@update:model-value="emit('update:firstName', String($event))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="read-item">
|
||||
<div class="read-label">{{ t('Settings.profile.lastName') }}</div>
|
||||
<div v-show="!isEditing" class="read-box">{{ displayData.lastName }}</div>
|
||||
<div v-show="isEditing" class="form-item-value name">
|
||||
<el-input
|
||||
:model-value="lastName"
|
||||
:placeholder="t('Settings.profile.lastNamePlaceholder')"
|
||||
@update:model-value="emit('update:lastName', String($event))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="read-row">
|
||||
<div class="read-label">{{ t('Settings.profile.username') }}</div>
|
||||
<div v-show="!isEditing" class="read-box">{{ displayData.username }}</div>
|
||||
<div v-show="isEditing" class="form-item-value">
|
||||
<el-input
|
||||
:model-value="username"
|
||||
:placeholder="t('Settings.profile.usernamePlaceholder')"
|
||||
@update:model-value="emit('update:username', String($event))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="read-tip">{{ t('Settings.profile.usernameTip') }}</div>
|
||||
|
||||
<div class="read-row role-row">
|
||||
<div class="read-label">{{ t('Settings.profile.role') }}</div>
|
||||
<div :class="{ 'readonly-radio-group': !isEditing }">
|
||||
<Radio multiple :max="2" v-model="roleSelection" :options="roleOptions" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="read-tip">{{ t('Settings.profile.roleTip') }}</div>
|
||||
</div>
|
||||
</SettingsSection>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import SettingsSection from './SettingsSection.vue'
|
||||
import Radio from './Radio.vue'
|
||||
import type { RoleOption, RoleValue, SettingsData } from '../types'
|
||||
|
||||
const props = defineProps<{
|
||||
displayData: SettingsData
|
||||
firstName: string
|
||||
lastName: string
|
||||
username: string
|
||||
fullName: string
|
||||
isEditing: boolean
|
||||
roleModel: RoleValue[]
|
||||
roleOptions: RoleOption[]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:firstName', value: string): void
|
||||
(event: 'update:lastName', value: string): void
|
||||
(event: 'update:username', value: string): void
|
||||
(event: 'update:roleModel', value: RoleValue[]): void
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const roleSelection = computed<RoleValue[]>({
|
||||
get: () => props.roleModel,
|
||||
set: (value) => {
|
||||
emit('update:roleModel', value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.field-text() {
|
||||
font-family: 'KaiseiOpti-Regular';
|
||||
font-size: 1.6rem;
|
||||
line-height: 2.4rem;
|
||||
color: #232323;
|
||||
}
|
||||
|
||||
.field-frame() {
|
||||
width: 100%;
|
||||
min-height: 4rem;
|
||||
border: 0.1rem solid #979797;
|
||||
}
|
||||
|
||||
.control-wrapper() {
|
||||
box-shadow: none;
|
||||
border-radius: 0;
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
.profile-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 2.6rem;
|
||||
margin-bottom: 3.6rem;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 8rem;
|
||||
height: 8rem;
|
||||
border-radius: 50%;
|
||||
border: 0.1rem solid #d8d0c7;
|
||||
}
|
||||
|
||||
.avatar-edit-icon {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
border: 0.1rem solid #fff;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.profile-summary {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 0.6rem;
|
||||
}
|
||||
|
||||
.profile-name {
|
||||
font-family: 'KaiseiOpti-Medium';
|
||||
font-size: 2.4rem;
|
||||
line-height: 3.6rem;
|
||||
color: #232323;
|
||||
}
|
||||
|
||||
.profile-email {
|
||||
font-family: 'KaiseiOpti-Regular';
|
||||
font-size: 1.8rem;
|
||||
line-height: 2.4rem;
|
||||
color: #979797;
|
||||
}
|
||||
|
||||
.read-section {
|
||||
width: 58rem;
|
||||
}
|
||||
|
||||
.read-label {
|
||||
margin-bottom: 0.8rem;
|
||||
font-family: 'KaiseiOpti-Medium';
|
||||
font-size: 1.4rem;
|
||||
line-height: 2.4rem;
|
||||
letter-spacing: 0.04em;
|
||||
color: #585858;
|
||||
}
|
||||
|
||||
.read-tip {
|
||||
margin-top: 0.8rem;
|
||||
font-family: 'KaiseiOpti-Regular';
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.6rem;
|
||||
color: #9f9f9f;
|
||||
}
|
||||
|
||||
.read-row + .read-row {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.read-row.two-column {
|
||||
display: grid;
|
||||
grid-template-columns: 28.4rem 28.4rem;
|
||||
column-gap: 2rem;
|
||||
}
|
||||
|
||||
.read-box {
|
||||
.field-frame();
|
||||
.field-text();
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.8rem 2rem;
|
||||
}
|
||||
|
||||
.form-item-value {
|
||||
.field-frame();
|
||||
|
||||
&.name {
|
||||
width: 28.4rem;
|
||||
}
|
||||
|
||||
:deep(.el-input) {
|
||||
width: 100%;
|
||||
min-height: 4rem;
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
.control-wrapper();
|
||||
min-height: 4rem;
|
||||
}
|
||||
|
||||
:deep(.el-input__inner) {
|
||||
.field-text();
|
||||
}
|
||||
}
|
||||
|
||||
.readonly-radio-group {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.role-row {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user