mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-02-23 14:40:49 +08:00
Merge pull request #108 from nagisa77/codex/create-input-components-for-auth-pages
Refactor auth inputs and avatar style
This commit is contained in:
63
open-isle-cli/src/components/BaseInput.vue
Normal file
63
open-isle-cli/src/components/BaseInput.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div class="base-input">
|
||||
<i v-if="icon" :class="['base-input-icon', icon]"></i>
|
||||
<component
|
||||
:is="textarea ? 'textarea' : 'input'"
|
||||
class="base-input-text"
|
||||
:type="type"
|
||||
v-model="innerValue"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'BaseInput',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
modelValue: { type: [String, Number], default: '' },
|
||||
icon: { type: String, default: '' },
|
||||
type: { type: String, default: 'text' },
|
||||
textarea: { type: Boolean, default: false }
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
computed: {
|
||||
innerValue: {
|
||||
get() {
|
||||
return this.modelValue
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:modelValue', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.base-input {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: calc(100% - 40px);
|
||||
padding: 15px 20px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #ccc;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.base-input-icon {
|
||||
opacity: 0.5;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.base-input-text {
|
||||
border: none;
|
||||
outline: none;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -8,25 +8,18 @@
|
||||
</div>
|
||||
|
||||
<div class="email-login-page-content">
|
||||
<div class="login-page-input">
|
||||
<i class="login-page-input-icon fas fa-envelope"></i>
|
||||
<input
|
||||
class="login-page-input-text"
|
||||
v-model="username"
|
||||
type="text"
|
||||
placeholder="邮箱/用户名"
|
||||
>
|
||||
</div>
|
||||
<BaseInput
|
||||
icon="fas fa-envelope"
|
||||
v-model="username"
|
||||
placeholder="邮箱/用户名"
|
||||
/>
|
||||
|
||||
<div class="login-page-input">
|
||||
<i class="login-page-input-icon fas fa-lock"></i>
|
||||
<input
|
||||
class="login-page-input-text"
|
||||
v-model="password"
|
||||
type="password"
|
||||
placeholder="密码"
|
||||
>
|
||||
</div>
|
||||
<BaseInput
|
||||
icon="fas fa-lock"
|
||||
v-model="password"
|
||||
type="password"
|
||||
placeholder="密码"
|
||||
/>
|
||||
|
||||
|
||||
<div v-if="!isWaitingForLogin" class="login-page-button-primary" @click="submitLogin">
|
||||
@@ -58,8 +51,10 @@
|
||||
import { API_BASE_URL, toast } from '../main'
|
||||
import { setToken } from '../utils/auth'
|
||||
import { googleSignIn } from '../utils/google'
|
||||
import BaseInput from '../components/BaseInput.vue'
|
||||
export default {
|
||||
name: 'LoginPageView',
|
||||
components: { BaseInput },
|
||||
data() {
|
||||
return {
|
||||
username: '',
|
||||
|
||||
@@ -3,16 +3,26 @@
|
||||
<div class="settings-title">设置</div>
|
||||
<div class="profile-section">
|
||||
<div class="avatar-row">
|
||||
<img :src="avatar" class="avatar-preview" />
|
||||
<input type="file" @change="onAvatarChange" />
|
||||
<!-- label 充当点击区域,内部隐藏 input -->
|
||||
<label class="avatar-container">
|
||||
<img :src="avatar" class="avatar-preview" />
|
||||
<!-- 半透明蒙层:hover 时出现 -->
|
||||
<div class="avatar-overlay">更换头像</div>
|
||||
<input
|
||||
type="file"
|
||||
class="avatar-input"
|
||||
accept="image/*"
|
||||
@change="onAvatarChange"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>用户名</label>
|
||||
<input v-model="username" type="text" />
|
||||
<BaseInput v-model="username" />
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>自我介绍</label>
|
||||
<textarea v-model="introduction" rows="3" />
|
||||
<BaseInput v-model="introduction" textarea rows="3" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="role === 'ADMIN'" class="admin-section">
|
||||
@@ -42,8 +52,10 @@
|
||||
<script>
|
||||
import { API_BASE_URL, toast } from '../main'
|
||||
import { getToken, fetchCurrentUser } from '../utils/auth'
|
||||
import BaseInput from '../components/BaseInput.vue'
|
||||
export default {
|
||||
name: 'SettingsPageView',
|
||||
components: { BaseInput },
|
||||
data() {
|
||||
return {
|
||||
username: '',
|
||||
@@ -163,4 +175,36 @@ export default {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* 容器:定位 + 光标 */
|
||||
.avatar-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* 隐藏默认文件选择按钮 */
|
||||
.avatar-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 蒙层:初始透明,hover 时渐显 */
|
||||
.avatar-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 40px;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
/* hover 触发 */
|
||||
.avatar-container:hover .avatar-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -8,51 +8,36 @@
|
||||
</div>
|
||||
|
||||
<div v-if="emailStep === 0" class="email-signup-page-content">
|
||||
<div class="signup-page-input">
|
||||
<i class="signup-page-input-icon fas fa-envelope"></i>
|
||||
<input
|
||||
class="signup-page-input-text"
|
||||
v-model="email"
|
||||
@input="emailError = ''"
|
||||
type="text"
|
||||
placeholder="邮箱"
|
||||
>
|
||||
</div>
|
||||
<BaseInput
|
||||
icon="fas fa-envelope"
|
||||
v-model="email"
|
||||
@input="emailError = ''"
|
||||
placeholder="邮箱"
|
||||
/>
|
||||
<div v-if="emailError" class="error-message">{{ emailError }}</div>
|
||||
|
||||
<div class="signup-page-input">
|
||||
<i class="signup-page-input-icon fas fa-user"></i>
|
||||
<input
|
||||
class="signup-page-input-text"
|
||||
v-model="username"
|
||||
@input="usernameError = ''"
|
||||
type="text"
|
||||
placeholder="用户名"
|
||||
>
|
||||
</div>
|
||||
<BaseInput
|
||||
icon="fas fa-user"
|
||||
v-model="username"
|
||||
@input="usernameError = ''"
|
||||
placeholder="用户名"
|
||||
/>
|
||||
<div v-if="usernameError" class="error-message">{{ usernameError }}</div>
|
||||
|
||||
<div class="signup-page-input">
|
||||
<i class="signup-page-input-icon fas fa-lock"></i>
|
||||
<input
|
||||
class="signup-page-input-text"
|
||||
v-model="password"
|
||||
@input="passwordError = ''"
|
||||
type="password"
|
||||
placeholder="密码"
|
||||
>
|
||||
</div>
|
||||
<BaseInput
|
||||
icon="fas fa-lock"
|
||||
v-model="password"
|
||||
@input="passwordError = ''"
|
||||
type="password"
|
||||
placeholder="密码"
|
||||
/>
|
||||
<div v-if="passwordError" class="error-message">{{ passwordError }}</div>
|
||||
|
||||
<div class="signup-page-input">
|
||||
<i class="signup-page-input-icon fas fa-user"></i>
|
||||
<input
|
||||
class="signup-page-input-text"
|
||||
v-model="nickname"
|
||||
type="text"
|
||||
placeholder="昵称 (可选)"
|
||||
>
|
||||
</div>
|
||||
<BaseInput
|
||||
icon="fas fa-user"
|
||||
v-model="nickname"
|
||||
placeholder="昵称 (可选)"
|
||||
/>
|
||||
|
||||
<div v-if="!isWaitingForEmailSent" class="signup-page-button-primary" @click="sendVerification">
|
||||
<div class="signup-page-button-text">验证邮箱</div>
|
||||
@@ -69,15 +54,11 @@
|
||||
</div>
|
||||
|
||||
<div v-if="emailStep === 1" class="email-signup-page-content">
|
||||
<div class="signup-page-input">
|
||||
<i class="signup-page-input-icon fas fa-envelope"></i>
|
||||
<input
|
||||
class="signup-page-input-text"
|
||||
v-model="code"
|
||||
type="text"
|
||||
placeholder="邮箱验证码"
|
||||
>
|
||||
</div>
|
||||
<BaseInput
|
||||
icon="fas fa-envelope"
|
||||
v-model="code"
|
||||
placeholder="邮箱验证码"
|
||||
/>
|
||||
<div v-if="!isWaitingForEmailVerified" class="signup-page-button-primary" @click="verifyCode">
|
||||
<div class="signup-page-button-text">注册</div>
|
||||
</div>
|
||||
@@ -102,8 +83,10 @@
|
||||
<script>
|
||||
import { API_BASE_URL, toast } from '../main'
|
||||
import { googleSignIn } from '../utils/google'
|
||||
import BaseInput from '../components/BaseInput.vue'
|
||||
export default {
|
||||
name: 'SignupPageView',
|
||||
components: { BaseInput },
|
||||
|
||||
data() {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user