142 lines
4.9 KiB
Vue
142 lines
4.9 KiB
Vue
<script setup lang="ts">
|
|
definePageMeta({
|
|
layout: 'default'
|
|
})
|
|
|
|
useHead({
|
|
title: 'Loading Demo - e-Learning'
|
|
})
|
|
|
|
const isLoading = ref(false)
|
|
const showFullPageLoading = ref(false)
|
|
|
|
const simulateLoading = () => {
|
|
isLoading.value = true
|
|
setTimeout(() => isLoading.value = false, 2000)
|
|
}
|
|
|
|
const simulateFullPageLoading = () => {
|
|
showFullPageLoading.value = true
|
|
setTimeout(() => showFullPageLoading.value = false, 2000)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<LoadingSpinner v-if="showFullPageLoading" full-page text="กำลังโหลดหน้า..." />
|
|
|
|
<h1 style="font-size: 28px; font-weight: 700; margin-bottom: 8px;">UI Loading & Validation Demo</h1>
|
|
<p class="text-muted mb-8">หน้านี้แสดง component สำหรับ Loading states และ Form Validation</p>
|
|
|
|
<div class="grid-12">
|
|
<!-- Loading Spinners -->
|
|
<div class="col-span-6">
|
|
<div class="card mb-6">
|
|
<h2 class="font-bold mb-4">Loading Spinners</h2>
|
|
<div class="flex items-center gap-8 mb-6">
|
|
<div class="text-center">
|
|
<LoadingSpinner size="sm" />
|
|
<p class="text-xs text-muted mt-2">Small</p>
|
|
</div>
|
|
<div class="text-center">
|
|
<LoadingSpinner size="md" />
|
|
<p class="text-xs text-muted mt-2">Medium</p>
|
|
</div>
|
|
<div class="text-center">
|
|
<LoadingSpinner size="lg" />
|
|
<p class="text-xs text-muted mt-2">Large</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-4">
|
|
<button class="btn btn-primary" :disabled="isLoading" @click="simulateLoading">
|
|
<LoadingSpinner v-if="isLoading" size="sm" />
|
|
<span v-else>Submit Button</span>
|
|
</button>
|
|
<button class="btn btn-secondary" @click="simulateFullPageLoading">
|
|
Show Full Page Loading
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Skeleton Loaders -->
|
|
<div class="col-span-6">
|
|
<div class="card mb-6">
|
|
<h2 class="font-bold mb-4">Skeleton Loaders</h2>
|
|
<div class="mb-4">
|
|
<p class="text-sm text-muted mb-2">Text Skeleton:</p>
|
|
<LoadingSkeleton type="text" :count="3" />
|
|
</div>
|
|
<div class="mb-4">
|
|
<p class="text-sm text-muted mb-2">Avatar + Button:</p>
|
|
<div class="flex items-center gap-4">
|
|
<LoadingSkeleton type="avatar" />
|
|
<LoadingSkeleton type="button" width="100px" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Card Skeleton -->
|
|
<div class="col-span-12">
|
|
<div class="card mb-6">
|
|
<h2 class="font-bold mb-4">Card Skeleton</h2>
|
|
<div class="course-grid">
|
|
<LoadingSkeleton type="card" />
|
|
<LoadingSkeleton type="card" />
|
|
<LoadingSkeleton type="card" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Validation Demo -->
|
|
<div class="col-span-12">
|
|
<div class="card">
|
|
<h2 class="font-bold mb-4">Form Validation Demo</h2>
|
|
<p class="text-muted mb-6">ลองกด Submit โดยไม่กรอกข้อมูลเพื่อดู validation error messages</p>
|
|
|
|
<div class="grid-12">
|
|
<div class="col-span-6">
|
|
<FormInput
|
|
model-value=""
|
|
label="อีเมล"
|
|
type="email"
|
|
placeholder="student@example.com"
|
|
error="รูปแบบอีเมลไม่ถูกต้อง"
|
|
required
|
|
/>
|
|
</div>
|
|
<div class="col-span-6">
|
|
<FormInput
|
|
model-value=""
|
|
label="รหัสผ่าน"
|
|
type="password"
|
|
placeholder="••••••••"
|
|
error="รหัสผ่านต้องมีอย่างน้อย 8 ตัวอักษร"
|
|
required
|
|
/>
|
|
</div>
|
|
<div class="col-span-6">
|
|
<FormInput
|
|
model-value="สมชาย"
|
|
label="ชื่อ-นามสกุล"
|
|
placeholder="สมชาย ใจดี"
|
|
required
|
|
/>
|
|
<p class="text-xs text-success">✓ กรอกถูกต้อง (ไม่มี error)</p>
|
|
</div>
|
|
<div class="col-span-6">
|
|
<FormInput
|
|
model-value=""
|
|
label="เบอร์โทรศัพท์ (ไม่บังคับ)"
|
|
placeholder="081-234-5678"
|
|
/>
|
|
<p class="text-xs text-muted">กรอกหรือไม่กรอกก็ได้</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|