N

Nokfa Docs

ไม่มีชื่อบทความ

การสร้างฟอร์มลงเวลา TimeClockForm.js

1. ตำแหน่งไฟล์

สร้างไฟล์ใหม่ที่:

src/components/TimeClockForm.js

ใช้ Client Component ของ Next.js (มี 'use client' ด้านบน)

2. โค้ดตัวอย่างเต็ม

'use client';

import { useState } from 'react';

// Mock data ชื่อพนักงาน
const employeeList = [
  { fullName: 'สมชาย ใจดี', employeeCode: 'E123' },
  { fullName: 'สุดา รักดี', employeeCode: 'E124' },
];

export default function TimeClockForm() {
  const [selectedEmployee, setSelectedEmployee] = useState('');
  const [action, setAction] = useState('Check-in');
  const [status, setStatus] = useState('idle'); // idle, loading, success, error

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!selectedEmployee) return;

    setStatus('loading');

    try {
      const { fullName, employeeCode } = employeeList.find(emp => emp.employeeCode === selectedEmployee);

      const res = await fetch('/api/clock', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ fullName, employeeCode, action }),
      });

      if (res.ok) {
        setStatus('success');
      } else {
        setStatus('error');
      }
    } catch (error) {
      console.warn('Submit Error:', error);
      setStatus('error');
    }
  };

  return (
    <form onSubmit={handleSubmit} className="max-w-md mx-auto p-4 space-y-4">
      <div>
        <label className="block mb-1">ชื่อพนักงาน</label>
        <select
          className="w-full border rounded p-2"
          value={selectedEmployee}
          onChange={(e) => setSelectedEmployee(e.target.value)}
          required
        >
          <option value="">-- เลือกชื่อ --</option>
          {employeeList.map((emp) => (
            <option key={emp.employeeCode} value={emp.employeeCode}>
              {emp.fullName}
            </option>
          ))}
        </select>
      </div>

      <div>
        <label className="block mb-1">เลือกการลงเวลา</label>
        <select
          className="w-full border rounded p-2"
          value={action}
          onChange={(e) => setAction(e.target.value)}
        >
          <option value="Check-in">เข้างาน</option>
          <option value="Check-out">ออกงาน</option>
        </select>
      </div>

      <button
        type="submit"
        disabled={status === 'loading'}
        className="w-full bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded"
      >
        {status === 'loading' ? 'กำลังบันทึก...' : 'ลงเวลา'}
      </button>

      {status === 'success' && (
        <p className="text-green-500 text-center">บันทึกสำเร็จ!</p>
      )}
      {status === 'error' && (
        <p className="text-red-500 text-center">เกิดข้อผิดพลาด กรุณาลองใหม่</p>
      )}
    </form>
  );
}

3. ตัวอย่างการใช้งานใน app/page.js

สร้างไฟล์หรือแก้ไข src/app/page.js ให้มีการใช้ฟอร์มนี้:

import TimeClockForm from '@/components/TimeClockForm';

export default function Home() {
  return (
    <main className="min-h-screen flex items-center justify-center">
      <TimeClockForm />
    </main>
  );
}

4. สรุป Feature ของฟอร์มนี้

  • Dropdown ชื่อพนักงาน (mock array)
  • Dropdown ประเภทการลงเวลา (Check-in/Check-out)
  • ปุ่ม Submit พร้อมสถานะ Loading / Success / Error
  • ใช้ Tailwind v3 minimal สไตล์
  • ส่งข้อมูลไป API /api/clock แบบ POST

5. หมายเหตุเพิ่มเติม

  • ถ้าในอนาคตต้องการใช้ API ดึงรายชื่อพนักงานจริง สามารถแทนที่ employeeList ได้ทันที
  • แนะนำเพิ่มฟีเจอร์ auto-reset ฟอร์มหลัง success หากต้องการ UX ที่ลื่นไหลขึ้น

หมายเหตุ: หลังขั้นตอนนี้ ผู้ใช้สามารถเลือกชื่อ ลงเวลา และส่งข้อมูลไปบันทึกใน Google Calendar ได้สำเร็จ