feat: Implement initial e-learning platform frontend structure including dashboard, course management, authentication, and common UI components.
This commit is contained in:
parent
aceeb80d9a
commit
ad11c6b7c5
44 changed files with 720 additions and 578 deletions
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
/**
|
||||
* @file reset-password.vue
|
||||
* @description Reset Password Page.
|
||||
* Allows user to set a new password after verifying their email link (simulated).
|
||||
* @description หน้าตั้งรหัสผ่านใหม่ (Reset Password Page.
|
||||
* อนุญาตให้ผู้ใช้ตั้งรหัสผ่านใหม่หลังจากยืนยันลิงก์อีเมล)
|
||||
*/
|
||||
|
||||
definePageMeta({
|
||||
|
|
@ -44,9 +44,9 @@ const handlePasswordInput = (field: keyof typeof resetForm, val: string) => {
|
|||
resetForm[field] = val
|
||||
if (/[\u0E00-\u0E7F]/.test(val)) {
|
||||
if (field === 'password') errors.value.password = 'ห้ามใส่ภาษาไทย'
|
||||
// We don't necessarily need to flag confirmPassword individually if it just needs to match, but let's be consistent if we want
|
||||
// ไม่จำเป็นต้องแจ้งเตือน confirmPassword แยกต่างหากถ้ามันแค่ต้องตรงกัน แต่เพื่อให้สอดคล้องกันเราก็ควรทำ (We don't necessarily need to flag confirmPassword individually if it just needs to match, but let's be consistent if we want)
|
||||
} else {
|
||||
// Clear error if it was "Thai characters"
|
||||
// ลบข้อผิดพลาดถ้าเป็น "ห้ามใส่ภาษาไทย" (Clear error if it was "Thai characters")
|
||||
if (field === 'password' && errors.value.password === 'ห้ามใส่ภาษาไทย') {
|
||||
clearFieldError('password')
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ onMounted(() => {
|
|||
const resetPassword = async () => {
|
||||
if (!validate(resetForm, resetRules)) return
|
||||
|
||||
// Extract token from query
|
||||
// ดึงโทเคนจาก URL query (Extract token from query)
|
||||
const token = route.query.token as string
|
||||
|
||||
if (!token) {
|
||||
|
|
@ -92,7 +92,7 @@ const resetPassword = async () => {
|
|||
<template>
|
||||
<div class="relative min-h-screen w-full flex items-center justify-center p-4 overflow-hidden bg-slate-50 transition-colors">
|
||||
<!-- ==========================================
|
||||
BACKGROUND EFFECTS (Light Mode Only)
|
||||
เอฟเฟกต์พื้นหลัง (แสดงเฉพาะโหมดสว่าง) (BACKGROUND EFFECTS (Light Mode Only))
|
||||
========================================== -->
|
||||
<div class="fixed inset-0 overflow-hidden pointer-events-none -z-10">
|
||||
<div class="absolute inset-0 bg-gradient-to-br from-white via-slate-50 to-blue-50/50"></div>
|
||||
|
|
@ -101,11 +101,11 @@ const resetPassword = async () => {
|
|||
</div>
|
||||
|
||||
<!-- ==========================================
|
||||
RESET PASSWORD CARD
|
||||
การ์ดตั้งรหัสผ่านใหม่ (RESET PASSWORD CARD)
|
||||
========================================== -->
|
||||
<div class="w-full max-w-[460px] relative z-10 slide-up">
|
||||
|
||||
<!-- Header / Logo -->
|
||||
<!-- หัวข้อ / โลโก้ (Header / Logo) -->
|
||||
<div class="text-center mb-8">
|
||||
<div class="inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-gradient-to-tr from-blue-600 to-indigo-600 text-white shadow-lg shadow-blue-600/20 mb-6">
|
||||
<span class="font-black text-2xl">E</span>
|
||||
|
|
@ -116,10 +116,10 @@ const resetPassword = async () => {
|
|||
|
||||
<div class="bg-white rounded-[2rem] p-8 md:p-10 shadow-xl shadow-slate-200/50 border border-slate-100 relative overflow-hidden">
|
||||
|
||||
<!-- Form -->
|
||||
<!-- ฟอร์ม (Form) -->
|
||||
<form @submit.prevent="resetPassword" class="flex flex-col gap-6">
|
||||
|
||||
<!-- New Password -->
|
||||
<!-- รหัสผ่านใหม่ (New Password) -->
|
||||
<div>
|
||||
<label class="block text-sm font-semibold text-slate-700 mb-2 ml-1">รหัสผ่านใหม่ <span class="text-red-500">*</span></label>
|
||||
<div class="relative group">
|
||||
|
|
@ -145,7 +145,7 @@ const resetPassword = async () => {
|
|||
<span v-if="errors.password" class="text-xs text-red-500 font-medium ml-1 mt-1 block slide-up-sm">{{ errors.password }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Confirm Password -->
|
||||
<!-- ยืนยันรหัสผ่านใหม่ (Confirm Password) -->
|
||||
<div>
|
||||
<label class="block text-sm font-semibold text-slate-700 mb-2 ml-1">ยืนยันรหัสผ่านใหม่ <span class="text-red-500">*</span></label>
|
||||
<div class="relative group">
|
||||
|
|
@ -171,7 +171,7 @@ const resetPassword = async () => {
|
|||
<span v-if="errors.confirmPassword" class="text-xs text-red-500 font-medium ml-1 mt-1 block slide-up-sm">{{ errors.confirmPassword }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<!-- ปุ่มยืนยัน (Submit Button) -->
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="isLoading"
|
||||
|
|
@ -183,7 +183,7 @@ const resetPassword = async () => {
|
|||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Back Link -->
|
||||
<!-- ลิงก์ย้อนกลับ (Back Link) -->
|
||||
<div class="mt-8 text-center text-slate-500">
|
||||
<NuxtLink to="/auth/login" class="inline-flex items-center gap-2 text-sm font-medium hover:text-slate-800 transition-colors group px-4 py-2 rounded-lg hover:bg-white/50">
|
||||
<span class="group-hover:-translate-x-1 transition-transform">←</span> กลับไปหน้าเข้าสู่ระบบ
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue