151 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
| // frontend/app/page.jsx
 | ||
| 'use client';
 | ||
| 
 | ||
| import { useEffect, useState } from 'react';
 | ||
| import Link from 'next/link';
 | ||
| import { useRouter } from 'next/navigation';
 | ||
| import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
 | ||
| import { Button } from '@/components/ui/button';
 | ||
| import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
 | ||
| import {
 | ||
|   Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription,
 | ||
| } from '@/components/ui/dialog';
 | ||
| import { Label } from '@/components/ui/label';
 | ||
| import { Input } from '@/components/ui/input';
 | ||
| import { login as authLogin, logout as authLogout, me as fetchMe, credentials, authHeaders } from '@/app/_auth/client';
 | ||
| 
 | ||
| export default function HomePage() {
 | ||
|   const router = useRouter();
 | ||
|   const [me, setMe] = useState(null);
 | ||
|   const [loading, setLoading] = useState(true);
 | ||
| 
 | ||
|   // login dialog states
 | ||
|   const [open, setOpen] = useState(false);
 | ||
|   const [username, setUsername] = useState('');
 | ||
|   const [password, setPassword] = useState('');
 | ||
|   const [submitting, setSubmitting] = useState(false);
 | ||
|   const [err, setErr] = useState('');
 | ||
| 
 | ||
|   // โหลดสถานะผู้ใช้แบบไม่ redirect
 | ||
|   useEffect(() => {
 | ||
|     let cancelled = false;
 | ||
|     (async () => {
 | ||
|       try {
 | ||
|         const user = await fetchMe();
 | ||
|         if (!cancelled) setMe(user);
 | ||
|       } finally {
 | ||
|         if (!cancelled) setLoading(false);
 | ||
|       }
 | ||
|     })();
 | ||
|     return () => { cancelled = true; };
 | ||
|   }, []);
 | ||
| 
 | ||
|   async function handleLogin(e) {
 | ||
|     e?.preventDefault();
 | ||
|     setSubmitting(true);
 | ||
|     setErr('');
 | ||
|     try {
 | ||
|       const user = await authLogin({ username, password });
 | ||
|       if (!user) {
 | ||
|         setErr('ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง');
 | ||
|         return;
 | ||
|       }
 | ||
|       setMe(user);
 | ||
|       setOpen(false);
 | ||
|       router.push('/dashboard');
 | ||
|     } catch {
 | ||
|       setErr('เกิดข้อผิดพลาดในการเชื่อมต่อเซิร์ฟเวอร์');
 | ||
|     } finally {
 | ||
|       setSubmitting(false);
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   async function handleLogout() {
 | ||
|     await authLogout().catch(() => {});
 | ||
|     setMe(null);
 | ||
|   }
 | ||
| 
 | ||
|   if (loading) {
 | ||
|     return (
 | ||
|       <div className="space-y-6">
 | ||
|         <div className="w-56 rounded h-7 bg-muted animate-pulse" />
 | ||
|         <div className="grid gap-4 md:grid-cols-3">
 | ||
|           {[...Array(3)].map((_, i) => <div key={i} className="rounded h-28 bg-muted animate-pulse" />)}
 | ||
|         </div>
 | ||
|       </div>
 | ||
|     );
 | ||
|   }
 | ||
| 
 | ||
|   return (
 | ||
|     <div className="space-y-6">
 | ||
|       <div className="flex items-center justify-between">
 | ||
|         <h2 className="text-2xl font-bold">Welcome to DMS</h2>
 | ||
| 
 | ||
|         {/* แถบสถานะล็อกอิน + ปุ่ม */}
 | ||
|         <div className="flex items-center gap-2">
 | ||
|           {me ? (
 | ||
|             <>
 | ||
|               <span className="text-sm text-muted-foreground">สวัสดี, <b>{me.first_name || me.username}</b></span>
 | ||
|               <Button variant="secondary" onClick={() => router.push('/dashboard')}>Go to Dashboard</Button>
 | ||
|               <Button variant="outline" onClick={handleLogout}>Logout</Button>
 | ||
|             </>
 | ||
|           ) : (
 | ||
|             <Dialog open={open} onOpenChange={setOpen}>
 | ||
|               <DialogTrigger asChild>
 | ||
|                 <Button>Login</Button>
 | ||
|               </DialogTrigger>
 | ||
|               <DialogContent className="sm:max-w-[420px]">
 | ||
|                 <DialogHeader>
 | ||
|                   <DialogTitle>เข้าสู่ระบบ</DialogTitle>
 | ||
|                   <DialogDescription>กรอกชื่อผู้ใช้และรหัสผ่านของคุณ</DialogDescription>
 | ||
|                 </DialogHeader>
 | ||
|                 <form onSubmit={handleLogin} className="grid gap-3">
 | ||
|                   <div className="grid gap-1.5">
 | ||
|                     <Label htmlFor="username">Username</Label>
 | ||
|                     <Input id="username" value={username} onChange={e => setUsername(e.target.value)} required />
 | ||
|                   </div>
 | ||
|                   <div className="grid gap-1.5">
 | ||
|                     <Label htmlFor="password">Password</Label>
 | ||
|                     <Input id="password" type="password" value={password} onChange={e => setPassword(e.target.value)} required />
 | ||
|                   </div>
 | ||
|                   {err && <p className="text-sm text-red-600">{err}</p>}
 | ||
|                   <Button type="submit" disabled={submitting}>{submitting ? 'กำลังเข้าสู่ระบบ...' : 'Login'}</Button>
 | ||
|                 </form>
 | ||
|               </DialogContent>
 | ||
|             </Dialog>
 | ||
|           )}
 | ||
|         </div>
 | ||
|       </div>
 | ||
| 
 | ||
|       {/* เนื้อหาอื่น ๆ (เหมือนเดิม) */}
 | ||
|       <Tabs defaultValue="overview" className="w-full">
 | ||
|         <TabsList>
 | ||
|           <TabsTrigger value="overview">Overview</TabsTrigger>
 | ||
|           <TabsTrigger value="activity">Activity</TabsTrigger>
 | ||
|         </TabsList>
 | ||
| 
 | ||
|         <TabsContent value="overview">
 | ||
|           <div className="grid gap-4 mt-4 md:grid-cols-3">
 | ||
|             <Card><CardHeader><CardTitle>📑 RFAs</CardTitle></CardHeader><CardContent><p className="text-3xl font-bold">24</p></CardContent></Card>
 | ||
|             <Card><CardHeader><CardTitle>📐 Drawings</CardTitle></CardHeader><CardContent><p className="text-3xl font-bold">112</p></CardContent></Card>
 | ||
|             <Card><CardHeader><CardTitle>📤 Transmittals</CardTitle></CardHeader><CardContent><p className="text-3xl font-bold">8</p></CardContent></Card>
 | ||
|           </div>
 | ||
|         </TabsContent>
 | ||
| 
 | ||
|         <TabsContent value="activity">
 | ||
|           <div className="mt-4 space-y-3">
 | ||
|             <p>✔️ User <b>editor01</b> uploaded Drawing D-2025-07</p>
 | ||
|             <p>✔️ Transmittal T-2025-02 issued to Contractor</p>
 | ||
|             <p>✔️ RFA R-2025-03 marked as Resolved</p>
 | ||
|           </div>
 | ||
|         </TabsContent>
 | ||
|       </Tabs>
 | ||
| 
 | ||
|       <div className="pt-2">
 | ||
|         <Button asChild disabled={!me}><Link href="/dashboard">Go to Dashboard</Link></Button>
 | ||
|         {!me && <span className="ml-2 text-sm text-muted-foreground">กรุณา Login ก่อน</span>}
 | ||
|       </div>
 | ||
|     </div>
 | ||
|   );
 | ||
| }
 |