Revert "feat(frontend): unify ui with slate control center"

This reverts commit 91aa6e83ca.
This commit is contained in:
yinjianm
2026-03-25 05:21:34 +08:00
parent b9a4917467
commit d8a99e55b8
20 changed files with 1638 additions and 2733 deletions
+105 -82
View File
@@ -1,14 +1,98 @@
<template>
<!-- Page Container with Subtle Dot Background -->
<div class="flex items-center justify-center min-h-screen bg-background p-4 bg-[radial-gradient(theme(colors.border)_1px,transparent_1px)] bg-[size:16px_16px]">
<!-- Setup Card -->
<div class="flex w-full max-w-4xl rounded-xl shadow-2xl overflow-hidden bg-background border border-border/20">
<!-- Left Panel (Brand) - Hidden on small screens -->
<div class="hidden md:flex w-2/5 bg-gradient-to-br from-primary to-primary-dark flex-col items-center justify-center p-10 text-white relative">
<!-- Subtle pattern or overlay could go here -->
<div class="z-10 text-center">
<img src="../assets/logo.png" alt="Project Logo" class="h-20 w-auto mb-5 mx-auto">
<h1 class="text-3xl font-bold mb-2">{{ $t('projectName') }}</h1>
<p class="text-base opacity-80">{{ $t('setup.description') }}</p> <!-- Moved description here -->
</div>
</div>
<!-- Right Panel (Setup Form) -->
<div class="w-full md:w-3/5 flex flex-col justify-center p-8 sm:p-12">
<!-- Mobile Logo & Title (optional) -->
<div class="flex flex-col items-center mb-6 md:hidden">
<img src="../assets/logo.png" alt="Project Logo" class="h-16 w-auto mb-3">
<h2 class="text-xl font-semibold text-foreground">{{ $t('setup.title') }}</h2>
<p class="text-sm text-text-secondary mt-1">{{ $t('setup.description') }}</p>
</div>
<!-- Desktop Title (Subtle) -->
<h2 class="text-2xl font-semibold mb-6 text-center text-foreground hidden md:block">{{ $t('setup.title') }}</h2>
<form @submit.prevent="handleSetup" class="space-y-5"> <!-- Reduced space slightly -->
<div>
<label for="username" class="block text-sm font-medium text-text-secondary mb-1">{{ $t('setup.username') }}</label>
<input
id="username"
v-model="username"
name="username"
type="text"
required
:disabled="isLoading"
:placeholder="$t('setup.usernamePlaceholder')"
class="w-full px-4 py-3 border border-border/50 rounded-lg bg-input text-foreground text-base shadow-sm focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition duration-150 ease-in-out disabled:bg-gray-100 disabled:cursor-not-allowed"
/>
</div>
<div>
<label for="password" class="block text-sm font-medium text-text-secondary mb-1">{{ $t('setup.password') }}</label>
<input
id="password"
v-model="password"
name="password"
type="password"
required
:disabled="isLoading"
:placeholder="$t('setup.passwordPlaceholder')"
class="w-full px-4 py-3 border border-border/50 rounded-lg bg-input text-foreground text-base shadow-sm focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition duration-150 ease-in-out disabled:bg-gray-100 disabled:cursor-not-allowed"
/>
</div>
<div>
<label for="confirmPassword" class="block text-sm font-medium text-text-secondary mb-1">{{ $t('setup.confirmPassword') }}</label>
<input
id="confirmPassword"
v-model="confirmPassword"
name="confirmPassword"
type="password"
required
:disabled="isLoading"
:placeholder="$t('setup.confirmPasswordPlaceholder')"
class="w-full px-4 py-3 border border-border/50 rounded-lg bg-input text-foreground text-base shadow-sm focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition duration-150 ease-in-out disabled:bg-gray-100 disabled:cursor-not-allowed"
/>
</div>
<div v-if="error" class="text-error bg-error/10 border border-error/20 px-4 py-2 rounded text-center text-sm"> <!-- Adjusted padding -->
{{ error }}
</div>
<div v-if="successMessage" class="text-success bg-success/10 border border-success/20 px-4 py-2 rounded text-center text-sm"> <!-- Adjusted padding -->
{{ successMessage }}
</div>
<button type="submit" :disabled="isLoading"
class="w-full py-3 px-4 bg-primary text-white border-none rounded-lg text-base font-semibold cursor-pointer shadow-md transition-colors duration-200 ease-in-out hover:bg-primary-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary disabled:bg-gray-400 disabled:opacity-70 disabled:cursor-not-allowed">
<span v-if="isLoading">{{ $t('setup.settingUp') }}</span>
<span v-else>{{ $t('setup.submitButton') }}</span>
</button>
</form>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import apiClient from '../utils/apiClient'; // 使用统一的 apiClient
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import AuthPanelLayout from '../components/AuthPanelLayout.vue';
import apiClient from '../utils/apiClient';
import { useAuthStore } from '../stores/auth.store';
import { useAuthStore } from '../stores/auth.store'; // *** 导入 Auth Store ***
const { t } = useI18n();
const router = useRouter();
const authStore = useAuthStore();
const authStore = useAuthStore(); // *** 获取 Auth Store 实例 ***
const username = ref('');
const password = ref('');
@@ -27,105 +111,44 @@ const handleSetup = async () => {
}
if (!username.value || !password.value) {
error.value = t('setup.error.fieldsRequired');
return;
error.value = t('setup.error.fieldsRequired');
return;
}
isLoading.value = true;
try {
await apiClient.post('/auth/setup', {
// 确保调用正确的后端 API 端点
await apiClient.post('/auth/setup', { // 使用 apiClient 并移除 base URL
username: username.value,
password: password.value,
confirmPassword: confirmPassword.value,
confirmPassword: confirmPassword.value
});
successMessage.value = t('setup.success');
// *** 手动更新 needsSetup 状态 ***
authStore.needsSetup = false;
// *** 重置认证状态,因为设置完成后需要重新登录 ***
authStore.isAuthenticated = false;
authStore.user = null;
// 禁用表单或按钮,防止重复提交
isLoading.value = true; // Keep loading state to disable button
// Redirect to login immediately after showing success message (removed setTimeout)
// The success message will be briefly visible before navigation.
router.push('/login');
} catch (err: any) {
console.error('Setup failed:', err);
if (err.response?.data?.message) {
// 尝试从后端响应中获取更具体的错误信息
error.value = err.response.data.message;
} else if (err.message) {
error.value = err.message;
error.value = err.message;
} else {
error.value = t('setup.error.generic');
error.value = t('setup.error.generic');
}
isLoading.value = false;
isLoading.value = false; // Re-enable button on error
}
// Removed finally block setting isLoading to false on success to keep button disabled
};
</script>
<template>
<AuthPanelLayout
:title="t('setup.title')"
:subtitle="t('setup.description')"
accent-label="Slate Bootstrap"
>
<el-alert
type="info"
:closable="false"
show-icon
class="mb-5"
:title="t('setup.bootstrapHint', '创建首个管理员账号后即可进入完整控制中心。')"
/>
<el-form label-position="top" @submit.prevent="handleSetup">
<div class="grid gap-5">
<el-form-item :label="t('setup.username')">
<el-input
v-model="username"
:disabled="isLoading"
:placeholder="t('setup.usernamePlaceholder')"
size="large"
clearable
>
<template #prefix>
<i class="fas fa-user text-text-secondary"></i>
</template>
</el-input>
</el-form-item>
<el-form-item :label="t('setup.password')">
<el-input
v-model="password"
:disabled="isLoading"
:placeholder="t('setup.passwordPlaceholder')"
type="password"
show-password
size="large"
>
<template #prefix>
<i class="fas fa-lock text-text-secondary"></i>
</template>
</el-input>
</el-form-item>
<el-form-item :label="t('setup.confirmPassword')">
<el-input
v-model="confirmPassword"
:disabled="isLoading"
:placeholder="t('setup.confirmPasswordPlaceholder')"
type="password"
show-password
size="large"
>
<template #prefix>
<i class="fas fa-check text-text-secondary"></i>
</template>
</el-input>
</el-form-item>
<el-alert v-if="error" :title="error" type="error" :closable="false" show-icon />
<el-alert v-if="successMessage" :title="successMessage" type="success" :closable="false" show-icon />
<el-button native-type="submit" type="primary" size="large" class="w-full" :loading="isLoading">
{{ t('setup.submitButton') }}
</el-button>
</div>
</el-form>
</AuthPanelLayout>
</template>
<!-- Copied styles from LoginView.vue -->