feat: add initial styling and layout for portal views

- Created a global CSS file for consistent styling across the application.
- Implemented the Explore, Home, Topics, and various user views with responsive design.
- Added a Login view with OTP functionality and a Checkout view for order processing.
- Developed a NotFound view for handling 404 errors.
- Established a configuration file for Vite with Tailwind CSS integration.
This commit is contained in:
2025-12-26 09:18:41 +08:00
parent a4262b4a52
commit bcbd3327ea
40 changed files with 3795 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
<template>
<div class="bg-white rounded-2xl shadow-xl w-full max-w-4xl overflow-hidden flex min-h-[550px]">
<!-- Left Brand Area -->
<div class="hidden md:flex w-1/2 bg-slate-900 relative p-12 flex-col justify-between text-white">
<!-- Decor/Bg could be here -->
<div class="z-10">
<div class="flex items-center gap-2 mb-8">
<div class="w-8 h-8 bg-white/20 rounded flex items-center justify-center font-bold">Q</div>
<span class="text-xl font-bold">Quyun</span>
</div>
<h1 class="text-4xl font-bold leading-tight mb-4">探索戏曲的<br>无限可能</h1>
<p class="text-slate-400">专业的租户管理与内容交付平台连接创作者与用户</p>
</div>
<div class="text-xs text-slate-500 z-10">© 2025 Quyun. All rights reserved.</div>
</div>
<!-- Right Form Area -->
<div class="w-full md:w-1/2 p-8 sm:p-12 flex flex-col justify-center bg-white relative">
<div v-if="step === 1">
<h2 class="text-2xl font-bold text-slate-900 mb-2">欢迎回来</h2>
<p class="text-sm text-slate-500 mb-8">未注册的手机号验证后将自动创建账号</p>
<form @submit.prevent="getOTP">
<div class="mb-6">
<label class="block text-sm font-medium text-slate-700 mb-2">手机号码</label>
<div class="flex">
<span class="inline-flex items-center px-4 rounded-l-lg border border-r-0 border-slate-300 bg-slate-50 text-slate-500 text-sm">+86</span>
<input
v-model="phone"
type="tel"
class="flex-1 block w-full rounded-r-lg border-slate-300 focus:border-primary-500 focus:ring-primary-500 sm:text-lg py-3"
placeholder="请输入手机号"
required
>
</div>
</div>
<div class="flex items-start mb-6">
<div class="flex items-center h-5">
<input id="terms" v-model="agreed" type="checkbox" class="w-5 h-5 rounded border-slate-300 text-primary-600 focus:ring-primary-500">
</div>
<label for="terms" class="ml-3 text-sm text-slate-500">
我已阅读并同意 <a href="#" class="text-primary-600 hover:underline">用户协议</a> <a href="#" class="text-primary-600 hover:underline">隐私政策</a>
</label>
</div>
<button
type="submit"
class="w-full flex justify-center py-3 px-4 border border-transparent rounded-lg shadow-sm text-lg font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 disabled:opacity-50 disabled:cursor-not-allowed"
:disabled="!agreed || !phone"
>
获取验证码
</button>
</form>
<div class="mt-8">
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-slate-200"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white text-slate-500">其他方式登录</span>
</div>
</div>
<div class="mt-6 flex justify-center gap-6">
<button class="w-10 h-10 rounded-full bg-slate-50 border border-slate-200 flex items-center justify-center hover:bg-slate-100 text-green-600"><i class="pi pi-wechat text-xl"></i></button>
<button class="w-10 h-10 rounded-full bg-slate-50 border border-slate-200 flex items-center justify-center hover:bg-slate-100 text-slate-800"><i class="pi pi-github text-xl"></i></button>
</div>
</div>
</div>
<div v-else-if="step === 2">
<button @click="step = 1" class="absolute top-8 left-8 text-slate-400 hover:text-slate-600"><i class="pi pi-arrow-left mr-1"></i> 返回</button>
<h2 class="text-2xl font-bold text-slate-900 mb-2">输入验证码</h2>
<p class="text-sm text-slate-500 mb-8">验证码已发送至 +86 {{ phone }}</p>
<div class="flex gap-3 mb-8 justify-center">
<input
v-for="i in 6" :key="i"
type="text"
maxlength="1"
class="w-12 h-14 text-center text-2xl font-bold border border-slate-300 rounded-lg focus:border-primary-500 focus:ring-2 focus:ring-primary-200"
>
</div>
<div class="text-center mb-8">
<button class="text-sm text-slate-500 hover:text-primary-600">59s 后重新获取</button>
</div>
<button
@click="login"
class="w-full flex justify-center py-3 px-4 border border-transparent rounded-lg shadow-sm text-lg font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
>
登录 / 注册
</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const step = ref(1);
const phone = ref('');
const agreed = ref(false);
const getOTP = () => {
if(!agreed.value) return;
// Simulate API call
setTimeout(() => {
step.value = 2;
}, 500);
};
const login = () => {
// Simulate Login
setTimeout(() => {
router.push('/');
}, 800);
};
</script>