Add:api-login

This commit is contained in:
supalerk-ar66 2026-01-14 15:15:31 +07:00
parent a6cddc6318
commit c411f2a8a4
20 changed files with 434 additions and 185 deletions

View file

@ -27,14 +27,22 @@ const forgotRules = {
email: { rules: { required: true, email: true }, label: 'อีเมล' }
}
const { requestPasswordReset } = useAuth()
const sendResetLink = async () => {
if (!validate(forgotForm, forgotRules)) return
isLoading.value = true
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 1500))
const result = await requestPasswordReset(forgotForm.email)
isLoading.value = false
forgotStep.value = 'success'
if (result.success) {
forgotStep.value = 'success'
} else {
alert(result.error || 'ไม่สามารถส่งลิงก์รีเซ็ตได้ กรุณาลองใหม่')
}
}
</script>

View file

@ -16,7 +16,7 @@ useHead({
})
const router = useRouter()
const { login } = useAuth()
const { login, user } = useAuth()
const { errors, validate, clearFieldError } = useFormValidation()
const isLoading = ref(false)
@ -41,17 +41,28 @@ const handleLogin = async () => {
if (!validate(loginForm, loginRules)) return
isLoading.value = true
// Simulate API call delay
await new Promise(resolve => setTimeout(resolve, 1500))
// Demo credential check
if (loginForm.email === 'student@example.com' && loginForm.password === '123456') {
login() // Set token via auth composable
isLoading.value = false
router.push('/dashboard')
const result = await login({
email: loginForm.email,
password: loginForm.password
})
isLoading.value = false
if (result.success) {
// Redirect based on user role
const role = user.value?.role?.code
if (role === 'ADMIN') {
router.push('/admin')
} else if (role === 'INSTRUCTOR') {
router.push('/instructor')
} else {
router.push('/dashboard')
}
} else {
isLoading.value = false
alert('อีเมลหรือรหัสผ่านไม่ถูกต้อง! (Demo: student@example.com / 123456)')
// Show error from API or fallback
alert(result.error || 'อีเมลหรือรหัสผ่านไม่ถูกต้อง')
}
}
</script>
@ -109,12 +120,8 @@ const handleLogin = async () => {
<span v-else>เข้าสู่ระบบ</span>
</button>
<!-- Demo Credentials Hint (For Development Only) -->
<div style="background: var(--neutral-100); padding: 12px; border-radius: 8px; margin-bottom: 16px; border: 1px dashed var(--primary);">
<p class="text-xs font-bold text-primary mb-1">🔑 ญชทดสอบ:</p>
<p class="text-xs text-muted">เมล: student@example.com</p>
<p class="text-xs text-muted">รหสผาน: 123456</p>
</div>
<!-- Social Login (Google) -->
<button type="button" class="btn-google w-full mb-6 flex items-center justify-center gap-3">

View file

@ -15,6 +15,7 @@ useHead({
});
const router = useRouter();
const { register } = useAuth(); // Import register from useAuth
const { errors, validate, clearFieldError } = useFormValidation();
const isLoading = ref(false);
@ -52,10 +53,37 @@ const handleRegister = async () => {
if (!validate(registerForm, registerRules)) return;
isLoading.value = true;
// Simulate API delay
await new Promise((resolve) => setTimeout(resolve, 1500));
// Map prefix to { th, en }
const prefixMap: Record<string, string> = {
'นาย': 'Mr.',
'นาง': 'Mrs.',
'นางสาว': 'Ms.'
};
const payload = {
username: registerForm.username,
email: registerForm.email,
password: registerForm.password,
first_name: registerForm.firstName,
last_name: registerForm.lastName,
prefix: {
th: registerForm.prefix,
en: prefixMap[registerForm.prefix] || 'Mr.'
},
phone: registerForm.phone
};
const result = await register(payload);
isLoading.value = false;
router.push("/dashboard");
if (result.success) {
alert('สมัครสมาชิกสำเร็จ! กรุณาเข้าสู่ระบบ');
router.push("/auth/login");
} else {
alert(result.error || 'การลงทะเบียนล้มเหลว');
}
};
</script>

View file

@ -13,7 +13,9 @@ useHead({
title: 'ตั้งรหัสผ่านใหม่ - e-Learning'
})
const route = useRoute()
const router = useRouter()
const { confirmResetPassword } = useAuth()
const { errors, validate, clearFieldError } = useFormValidation()
const isLoading = ref(false)
@ -28,14 +30,41 @@ const resetRules = {
confirmPassword: { rules: { required: true, match: 'password' }, label: 'ยืนยันรหัสผ่าน' }
}
onMounted(() => {
if (!route.query.token || !route.query.id) {
alert('ลิงก์รีเซ็ตรหัสผ่านไม่ถูกต้องหรือหมดอายุ')
router.push('/auth/login')
}
})
const resetPassword = async () => {
if (!validate(resetForm, resetRules)) return
// Extract token and id from query
const token = route.query.token as string
const id = Number(route.query.id)
if (!token || !id) {
alert('ข้อมูลสำหรับรีเซ็ตไม่ครบถ้วน')
return
}
isLoading.value = true
await new Promise(resolve => setTimeout(resolve, 1500))
const result = await confirmResetPassword({
id,
token,
password: resetForm.password
})
isLoading.value = false
alert('รีเซ็ตรหัสผ่านสำเร็จ!')
router.push('/auth/login')
if (result.success) {
alert('รีเซ็ตรหัสผ่านสำเร็จ! กรุณาเข้าสู่ระบบด้วยรหัสผ่านใหม่')
router.push('/auth/login')
} else {
alert(result.error || 'เกิดข้อผิดพลาดในการรีเซ็ตรหัสผ่าน')
}
}
</script>

View file

@ -66,11 +66,11 @@ onUnmounted(() => {
</script>
<template>
<div class="quiz-shell min-h-screen bg-white dark:bg-[#0b0f1a] text-slate-900 dark:text-slate-200 font-main antialiased selection:bg-blue-500/20 transition-colors">
<!-- Header: Precise matching of the image -->
<header class="h-14 bg-white dark:bg-[#161b22] fixed top-0 inset-x-0 z-[100] flex items-center px-6 border-b border-slate-300 dark:border-white/5 transition-colors">
<div class="quiz-shell min-h-screen bg-slate-50 dark:bg-[#0b0f1a] text-slate-900 dark:text-slate-200 font-main antialiased selection:bg-blue-500/20 transition-colors">
<!-- Header -->
<header class="h-14 bg-white dark:bg-[#161b22] fixed top-0 inset-x-0 z-[100] flex items-center px-6 border-b border-slate-200 dark:border-white/5 transition-colors">
<div class="flex items-center">
<button class="flex items-center gap-2 text-sm font-bold text-slate-700 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors" @click="confirmExit">
<button class="flex items-center gap-2 text-sm font-bold text-slate-500 hover:text-slate-800 dark:text-slate-400 dark:hover:text-white transition-colors" @click="confirmExit">
<span></span>
<span>ออกจากแบบทดสอบ</span>
</button>
@ -82,15 +82,14 @@ onUnmounted(() => {
<!-- Main Content Area -->
<main class="pt-14 h-screen flex items-center justify-center overflow-y-auto px-4 custom-scrollbar">
<!-- 1. START SCREEN (MATCHING IMAGE) -->
<!-- Displays quiz info, instructions, and start button -->
<!-- 1. START SCREEN -->
<div v-if="currentScreen === 'start'" class="w-full max-w-[640px] animate-fade-in py-12">
<div class="bg-white dark:bg-[#1e293b]/50 border border-slate-300 dark:border-white/5 rounded-[32px] p-8 md:p-14 shadow-lg dark:shadow-2xl dark:backdrop-blur-sm relative overflow-hidden transition-colors">
<div class="bg-white dark:!bg-[#1e293b] border border-slate-200 dark:border-white/5 rounded-[32px] p-8 md:p-14 shadow-lg dark:shadow-2xl relative overflow-hidden transition-colors">
<!-- Top Icon Wrapper -->
<div class="flex justify-center mb-10">
<div class="w-20 h-20 rounded-3xl bg-blue-500/10 border border-blue-500/20 flex items-center justify-center shadow-inner">
<svg xmlns="http://www.w3.org/2000/svg" class="w-10 h-10 text-blue-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<div class="w-20 h-20 rounded-3xl bg-blue-50 dark:bg-blue-500/10 border border-blue-100 dark:border-blue-500/20 flex items-center justify-center shadow-inner">
<svg xmlns="http://www.w3.org/2000/svg" class="w-10 h-10 text-blue-600 dark:text-blue-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/>
<polyline points="14 2 14 8 20 8"/>
<path d="M10 12h4"/><path d="M10 16h4"/><path d="M10 8h1"/>
@ -101,36 +100,36 @@ onUnmounted(() => {
<div class="text-center mb-10">
<h2 class="text-[32px] font-black text-slate-900 dark:text-white mb-2 tracking-tight">แบบทดสอบทายบท</h2>
<p class="text-[13px] font-bold text-slate-700 dark:text-slate-500 uppercase tracking-widest leading-none">เบองตนการออกแบบ UX/UI</p>
<p class="text-[13px] font-bold text-slate-500 dark:text-slate-400 uppercase tracking-widest leading-none">เบองตนการออกแบบ UX/UI</p>
</div>
<!-- Instruction Box -->
<div class="bg-[#0b121f]/80 p-8 rounded-3xl mb-8 border border-white/5">
<h3 class="text-[12px] font-black text-slate-400 mb-6 uppercase tracking-[0.2em] flex items-center gap-2">
<div class="bg-slate-50 dark:bg-[#0b121f]/80 p-8 rounded-3xl mb-8 border border-slate-100 dark:border-white/5">
<h3 class="text-[12px] font-black text-slate-500 dark:text-slate-400 mb-6 uppercase tracking-[0.2em] flex items-center gap-2">
คำชแจง
</h3>
<ul class="space-y-4">
<li class="flex items-start gap-3">
<span class="w-1.5 h-1.5 rounded-full bg-blue-500 mt-1.5 flex-shrink-0"/>
<span class="text-[14px] text-slate-300 font-medium leading-relaxed">แบบทดสอบนงหมด <strong class="text-white">10 </strong></span>
<span class="text-[14px] text-slate-600 dark:text-slate-300 font-medium leading-relaxed">แบบทดสอบนงหมด <strong class="text-slate-900 dark:text-white">10 </strong></span>
</li>
<li class="flex items-start gap-3">
<span class="w-1.5 h-1.5 rounded-full bg-blue-500 mt-1.5 flex-shrink-0"/>
<span class="text-[14px] text-slate-300 font-medium leading-relaxed">เกณฑการผาน <strong class="text-white">80% นไป</strong></span>
<span class="text-[14px] text-slate-600 dark:text-slate-300 font-medium leading-relaxed">เกณฑการผาน <strong class="text-slate-900 dark:text-white">80% นไป</strong></span>
</li>
<li class="flex items-start gap-3">
<span class="w-1.5 h-1.5 rounded-full bg-blue-500 mt-1.5 flex-shrink-0"/>
<span class="text-[14px] text-slate-300 font-medium leading-relaxed">เวลาในการทำ: <strong class="text-white">30 นาท</strong></span>
<span class="text-[14px] text-slate-600 dark:text-slate-300 font-medium leading-relaxed">เวลาในการทำ: <strong class="text-slate-900 dark:text-white">30 นาท</strong></span>
</li>
<li class="flex items-start gap-3">
<span class="w-1.5 h-1.5 rounded-full bg-blue-500 mt-1.5 flex-shrink-0"/>
<span class="text-[14px] text-slate-300 font-medium leading-relaxed">ไมสามารถหยดเวลาชวคราวไดเมอเรมทำแบบทดสอบแล</span>
<span class="text-[14px] text-slate-600 dark:text-slate-300 font-medium leading-relaxed">ไมสามารถหยดเวลาชวคราวไดเมอเรมทำแบบทดสอบแล</span>
</li>
</ul>
</div>
<div class="text-[13px] font-black text-slate-500 mb-10 flex items-center justify-between px-2">
<span>คะแนนท: <span class="text-white">-</span></span>
<div class="text-[13px] font-black text-slate-400 dark:text-slate-500 mb-10 flex items-center justify-between px-2">
<span>คะแนนท: <span class="text-slate-900 dark:text-white">-</span></span>
</div>
<!-- Action Button -->
@ -144,70 +143,68 @@ onUnmounted(() => {
</div>
<!-- 2. TAKING SCREEN -->
<!-- Quiz Interface with Timer, Question, and Options -->
<div v-if="currentScreen === 'taking'" class="w-full max-w-[840px] animate-fade-in py-12">
<div class="bg-[#1e293b]/50 border border-white/5 rounded-[32px] p-8 md:p-14 shadow-2xl backdrop-blur-sm">
<div class="flex items-center justify-between mb-10 pb-6 border-b border-white/5">
<div class="bg-white dark:!bg-[#1e293b] border border-slate-200 dark:border-white/5 rounded-[32px] p-8 md:p-14 shadow-2xl backdrop-blur-sm">
<div class="flex items-center justify-between mb-10 pb-6 border-b border-slate-100 dark:border-white/5">
<div>
<div class="text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] mb-2">อท 1 จาก 10</div>
<div class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-[0.2em] mb-2">อท 1 จาก 10</div>
<!-- Progress Line -->
<div class="w-48 h-1 bg-white/5 rounded-full overflow-hidden">
<div class="w-48 h-1 bg-slate-100 dark:bg-white/5 rounded-full overflow-hidden">
<div class="h-full bg-blue-500" style="width: 10%;"/>
</div>
</div>
<!-- Timer Display -->
<div class="flex items-center gap-3 px-5 py-2.5 bg-amber-500/10 border border-amber-500/20 rounded-2xl text-amber-500">
<div class="flex items-center gap-3 px-5 py-2.5 bg-amber-50 dark:bg-amber-500/10 border border-amber-200 dark:border-amber-500/20 rounded-2xl text-amber-600 dark:text-amber-500">
<span class="text-sm"></span>
<span class="text-[15px] font-black font-mono tracking-widest">{{ timerDisplay }}</span>
</div>
</div>
<div class="mb-12">
<h2 class="text-[22px] font-black text-white leading-tight mb-8">อใดตอไปนอหลกการแรกของ User Experience (UX) ตามโมเดลของ Peter Morville?</h2>
<h2 class="text-[22px] font-black text-slate-900 dark:text-white leading-tight mb-8">อใดตอไปนอหลกการแรกของ User Experience (UX) ตามโมเดลของ Peter Morville?</h2>
<!-- Question Options -->
<div class="space-y-4">
<button v-for="i in 4" :key="i" class="w-full p-6 text-left rounded-2xl border border-white/5 bg-white/5 hover:bg-white/10 transition-all flex items-center gap-4 group">
<div class="w-6 h-6 rounded-full border-2 border-slate-700 flex items-center justify-center group-hover:border-blue-500 transition-colors">
<button v-for="i in 4" :key="i" class="w-full p-6 text-left rounded-2xl border border-slate-200 dark:border-white/5 bg-slate-50 dark:bg-white/5 hover:bg-white hover:border-blue-500 hover:shadow-lg dark:hover:bg-white/10 transition-all flex items-center gap-4 group">
<div class="w-6 h-6 rounded-full border-2 border-slate-300 dark:border-slate-700 flex items-center justify-center group-hover:border-blue-500 transition-colors">
<div class="w-2.5 h-2.5 rounded-full bg-blue-500 opacity-0 group-focus:opacity-100"/>
</div>
<span class="text-[15px] font-medium text-slate-300">วเลอกท {{ i }} สำหรบคำตอบทเปนไปได</span>
<span class="text-[15px] font-medium text-slate-700 dark:text-slate-300 group-hover:text-slate-900 dark:group-hover:text-white">วเลอกท {{ i }} สำหรบคำตอบทเปนไปได</span>
</button>
</div>
</div>
<div class="flex justify-between items-center">
<button class="px-8 py-3 text-slate-500 font-bold hover:text-white transition-colors">อนกล</button>
<button class="px-8 py-3 text-slate-400 dark:text-slate-500 font-bold hover:text-slate-600 dark:hover:text-white transition-colors">อนกล</button>
<button class="px-10 py-4 bg-blue-600 text-white rounded-2xl font-black text-sm shadow-lg shadow-blue-600/20" @click="submitQuiz(false)">ถัดไป</button>
</div>
</div>
</div>
<!-- 3. RESULT SCREEN (MATCHING IMAGE) -->
<!-- Displays score, status, and summary stats -->
<!-- 3. RESULT SCREEN -->
<div v-if="currentScreen === 'result'" class="w-full max-w-[640px] animate-fade-in py-12">
<div class="bg-[#1e293b]/50 border border-white/5 rounded-[40px] p-10 md:p-14 shadow-2xl text-center backdrop-blur-sm">
<div class="bg-white dark:!bg-[#1e293b] border border-slate-200 dark:border-white/5 rounded-[40px] p-10 md:p-14 shadow-2xl text-center backdrop-blur-sm">
<!-- Trophy Icon -->
<div class="w-20 h-20 rounded-full bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center mx-auto mb-10 shadow-inner">
<span class="text-4xl">🏆</span>
</div>
<h2 class="text-[32px] font-black text-white mb-2 tracking-tight">นดวยคณสอบผาน!</h2>
<p class="text-[13px] font-bold text-slate-500 uppercase tracking-widest mb-12">ณทำคะแนนไดยอดเยยมและผานเกณฑการทดสอบ</p>
<h2 class="text-[32px] font-black text-slate-900 dark:text-white mb-2 tracking-tight">นดวยคณสอบผาน!</h2>
<p class="text-[13px] font-bold text-slate-500 dark:text-slate-500 uppercase tracking-widest mb-12">ณทำคะแนนไดยอดเยยมและผานเกณฑการทดสอบ</p>
<!-- Stats Boxes -->
<div class="grid grid-cols-3 gap-4 mb-14">
<div class="p-6 rounded-[24px] bg-[#0b121f]/60 border border-white/5 shadow-inner">
<div class="text-[9px] font-black text-slate-500 uppercase tracking-[0.2em] mb-3">คะแนน</div>
<div class="text-[20px] font-black text-blue-500">90%</div>
<div class="p-6 rounded-[24px] bg-slate-50 dark:bg-[#0b121f]/60 border border-slate-100 dark:border-white/5 shadow-inner">
<div class="text-[9px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-[0.2em] mb-3">คะแนน</div>
<div class="text-[20px] font-black text-blue-600 dark:text-blue-500">90%</div>
</div>
<div class="p-6 rounded-[24px] bg-[#0b121f]/60 border border-white/5 shadow-inner">
<div class="text-[9px] font-black text-slate-500 uppercase tracking-[0.2em] mb-3">ตอบถ</div>
<div class="text-[20px] font-black text-emerald-500">9/10</div>
<div class="p-6 rounded-[24px] bg-slate-50 dark:bg-[#0b121f]/60 border border-slate-100 dark:border-white/5 shadow-inner">
<div class="text-[9px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-[0.2em] mb-3">ตอบถ</div>
<div class="text-[20px] font-black text-emerald-600 dark:text-emerald-500">9/10</div>
</div>
<div class="p-6 rounded-[24px] bg-[#0b121f]/60 border border-white/5 shadow-inner">
<div class="text-[9px] font-black text-slate-500 uppercase tracking-[0.2em] mb-3">เวลาทใช</div>
<div class="text-[20px] font-black text-white">12:45</div>
<div class="p-6 rounded-[24px] bg-slate-50 dark:bg-[#0b121f]/60 border border-slate-100 dark:border-white/5 shadow-inner">
<div class="text-[9px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-[0.2em] mb-3">เวลาทใช</div>
<div class="text-[20px] font-black text-slate-900 dark:text-white">12:45</div>
</div>
</div>
@ -221,7 +218,7 @@ onUnmounted(() => {
</button>
<NuxtLink
to="/dashboard"
class="w-full py-5 bg-[#1e293b] hover:bg-[#253347] text-slate-400 hover:text-white rounded-[24px] font-black text-[14px] tracking-wider transition-all border border-white/5 block"
class="w-full py-5 bg-slate-100 dark:bg-[#1e293b] hover:bg-slate-200 dark:hover:bg-[#253347] text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white rounded-[24px] font-black text-[14px] tracking-wider transition-all border border-slate-200 dark:border-white/5 block"
>
กลบไปหนาหล
</NuxtLink>
@ -229,62 +226,61 @@ onUnmounted(() => {
</div>
</div>
<!-- 4. REVIEW (เฉลย) SCREEN -->
<!-- Detailed review of questions with correct/incorrect indicators and explanations -->
<!-- 4. REVIEW SCREEN -->
<div v-if="currentScreen === 'review'" class="w-full max-w-[840px] animate-fade-in py-12">
<div class="mb-10 flex items-center justify-between">
<h2 class="text-[24px] font-black text-white tracking-tight">เฉลยและทบทวนรายข</h2>
<button class="text-[13px] font-black text-slate-400 hover:text-white transition-colors flex items-center gap-2" @click="currentScreen = 'result'"/>
<h2 class="text-[24px] font-black text-slate-900 dark:text-white tracking-tight">เฉลยและทบทวนรายข</h2>
<button class="text-[13px] font-black text-slate-400 hover:text-slate-600 dark:hover:text-white transition-colors flex items-center gap-2" @click="currentScreen = 'result'"/>
</div>
<div class="space-y-6">
<!-- Review Item: Correct Answer -->
<div class="bg-[#1e293b]/40 border border-emerald-500/20 rounded-[32px] p-8 md:p-10 shadow-xl backdrop-blur-sm relative overflow-hidden group">
<div class="bg-white dark:bg-[#1e293b]/40 border border-emerald-500/20 rounded-[32px] p-8 md:p-10 shadow-xl backdrop-blur-sm relative overflow-hidden group">
<div class="absolute left-0 top-0 bottom-0 w-1.5 bg-emerald-500"/>
<div class="flex items-center gap-2 mb-6 text-[10px] font-black uppercase tracking-widest">
<span class="text-emerald-500"> ตอบถ</span>
<span class="text-slate-600"> อท 1</span>
<span class="text-slate-600 dark:text-slate-500"> อท 1</span>
</div>
<h3 class="text-[18px] font-black text-white leading-tight mb-8">อใดตอไปนอธบายกระบวนการออกแบบ "Double Diamond" ได?</h3>
<h3 class="text-[18px] font-black text-slate-900 dark:text-white leading-tight mb-8">อใดตอไปนอธบายกระบวนการออกแบบ "Double Diamond" ได?</h3>
<div class="space-y-3 mb-8">
<div class="p-5 rounded-2xl bg-emerald-500/5 border border-emerald-500/20 text-emerald-400 font-bold text-[14px] flex items-center justify-between">
<div class="p-5 rounded-2xl bg-emerald-50 dark:bg-emerald-500/5 border border-emerald-500/20 text-emerald-600 dark:text-emerald-400 font-bold text-[14px] flex items-center justify-between">
<span>กระบวนการแตกประเดนเพอคนหา/ฒนา และสรปประเดนเพอกำหนด/งมอบ</span>
<span class="text-xs"></span>
</div>
</div>
<div class="bg-[#0b121f]/60 p-6 rounded-2xl border border-white/5">
<h4 class="text-[11px] font-black text-slate-500 uppercase tracking-widest mb-3">คำอธบาย:</h4>
<p class="text-[14px] text-slate-400 leading-relaxed font-medium">
<div class="bg-slate-50 dark:bg-[#0b121f]/60 p-6 rounded-2xl border border-slate-100 dark:border-white/5">
<h4 class="text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-3">คำอธบาย:</h4>
<p class="text-[14px] text-slate-600 dark:text-slate-400 leading-relaxed font-medium">
Double Diamond ประกอบดวย 4 นตอนหล: Discover, Define, Develop และ Deliver งเนนการสลบกนระหวางความคดสรางสรรคแบบเปดกวาง (Divergent) และการคดกรองเพอใหไดอสร (Convergent)
</p>
</div>
</div>
<!-- Review Item: Incorrect Answer -->
<div class="bg-[#1e293b]/40 border border-red-500/20 rounded-[32px] p-8 md:p-10 shadow-xl backdrop-blur-sm relative overflow-hidden">
<div class="bg-white dark:bg-[#1e293b]/40 border border-red-500/20 rounded-[32px] p-8 md:p-10 shadow-xl backdrop-blur-sm relative overflow-hidden">
<div class="absolute left-0 top-0 bottom-0 w-1.5 bg-red-500"/>
<div class="flex items-center gap-2 mb-6 text-[10px] font-black uppercase tracking-widest">
<span class="text-red-500"> ตอบผ</span>
<span class="text-slate-600"> อท 2</span>
<span class="text-slate-600 dark:text-slate-500"> อท 2</span>
</div>
<h3 class="text-[18px] font-black text-white leading-tight mb-8">เปาหมายหลกของ User Research ออะไร?</h3>
<h3 class="text-[18px] font-black text-slate-900 dark:text-white leading-tight mb-8">เปาหมายหลกของ User Research ออะไร?</h3>
<div class="space-y-3 mb-8">
<div class="p-5 rounded-2xl bg-white/5 border border-red-500/30 text-red-400 font-medium text-[14px]">
<div class="p-5 rounded-2xl bg-red-50 dark:bg-white/5 border border-red-500/30 text-red-500 dark:text-red-400 font-medium text-[14px]">
<span class="opacity-50 line-through">เพอใหแนใจวาดไซนทำออกมาสวยงามท</span>
<span class="ml-2 text-[10px] bg-red-500/20 px-2 py-0.5 rounded text-red-500">คำตอบของค</span>
<span class="ml-2 text-[10px] bg-red-500/20 px-2 py-0.5 rounded text-red-600 dark:text-red-500">คำตอบของค</span>
</div>
<div class="p-5 rounded-2xl bg-emerald-500/5 border border-emerald-500/20 text-emerald-400 font-bold text-[14px] flex items-center justify-between">
<div class="p-5 rounded-2xl bg-emerald-50 dark:bg-emerald-500/5 border border-emerald-500/20 text-emerald-600 dark:text-emerald-400 font-bold text-[14px] flex items-center justify-between">
<span>เพอทำความเขาใจความตองการ ญหา และพฤตกรรมของผใชแทจร</span>
<span class="text-[10px] bg-emerald-500/20 px-2 py-0.5 rounded text-emerald-400">คำตอบทกตอง</span>
<span class="text-[10px] bg-emerald-500/20 px-2 py-0.5 rounded text-emerald-600 dark:text-emerald-400">คำตอบทกตอง</span>
</div>
</div>
<div class="bg-[#0b121f]/60 p-6 rounded-2xl border border-white/5">
<h4 class="text-[11px] font-black text-slate-500 uppercase tracking-widest mb-3">คำอธบาย:</h4>
<p class="text-[14px] text-slate-400 leading-relaxed font-medium">
<div class="bg-slate-50 dark:bg-[#0b121f]/60 p-6 rounded-2xl border border-slate-100 dark:border-white/5">
<h4 class="text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-3">คำอธบาย:</h4>
<p class="text-[14px] text-slate-600 dark:text-slate-400 leading-relaxed font-medium">
User Research ไมใชแคการดความสวยงาม แตอการหา "Insights" เพอนำมาแกญหาใหตรงจ ลดความเสยงในการสรางของทใชงานไมไดองการจรงๆ
</p>
</div>
@ -293,7 +289,7 @@ onUnmounted(() => {
</div>
<div class="mt-12 flex justify-center">
<button class="px-10 py-4 bg-white/5 hover:bg-white/10 text-slate-400 hover:text-white rounded-[20px] font-black text-sm border border-white/5 transition-all" @click="currentScreen = 'result'">กลบไปหนาสรปผล</button>
<button class="px-10 py-4 bg-slate-100 hover:bg-slate-200 dark:bg-white/5 dark:hover:bg-white/10 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white rounded-[20px] font-black text-sm border border-slate-200 dark:border-white/5 transition-all" @click="currentScreen = 'result'">กลบไปหนาสรปผล</button>
</div>
</div>
</main>

View file

@ -21,9 +21,9 @@ const isEditing = ref(false)
// User Profile Data Management
const userData = ref({
firstName: currentUser.value.firstName,
lastName: currentUser.value.lastName,
email: currentUser.value.email,
firstName: currentUser.value?.firstName || '',
lastName: currentUser.value?.lastName || '',
email: currentUser.value?.email || '',
phone: '0812345678',
joinDate: '12 ธ.ค. 2024',
photoURL: '',