This commit is contained in:
2026-07-16 09:53:14 +07:00
parent 0fc112a2e8
commit 29cec708a3
1236 changed files with 212848 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
# Training Hours TimePicker Review
## 1. Summary
เปลี่ยนช่อง `submitted hours` ในฟอร์ม Create/Edit Training Record จาก `number input` เป็น `TimePicker-style input` โดยใช้ `Input type="time"` ที่มีอยู่แล้วในระบบ เพื่อหลีกเลี่ยงการเพิ่มโครงสร้างใหม่และลดผลกระทบกับโมดูลเดิม
ค่าที่ผู้ใช้เลือกใน UI จะถูกแปลงเป็น `decimal hours` ก่อน submit และยังคงบันทึกลงฐานข้อมูลในฟิลด์ `hours` แบบเดิม ไม่มีการแก้ schema หรือ API contract
## 2. Files Changed
- `src/features/training-records/components/training-record-form.tsx`
- `src/features/training-records/schemas/training-record.ts`
- `src/features/training-records/utils/time-utils.ts`
## 3. UI Changes
- เปลี่ยนช่องกรอกชั่วโมงอบรมเป็นตัวเลือกเวลาแบบ `HH:mm`
- เปลี่ยน label เป็น `จำนวนชั่วโมงอบรม *`
- เพิ่ม helper text:
- `เลือกระยะเวลาอบรม เช่น 01:30 = 1.5 ชั่วโมง`
- เพิ่มข้อความสรุปค่าที่คำนวณแล้วใต้ input:
- `รวม X ชั่วโมง`
## 4. TimePicker Behavior
- ใช้ `Input type="time"` เพื่อให้ได้พฤติกรรม TimePicker ตาม browser/device มาตรฐาน
- กำหนด `step={900}` เพื่อรองรับการเลือกทีละ 15 นาที
- ตัวอย่าง:
- `00:30 -> 0.5`
- `01:00 -> 1`
- `01:30 -> 1.5`
- `02:15 -> 2.25`
- `07:30 -> 7.5`
## 5. Decimal Conversion Logic
เพิ่ม helper ที่ `src/features/training-records/utils/time-utils.ts`
- `decimalHoursToDate(hours: number): Date`
- `dateToDecimalHours(date: Date): number`
- `timeInputValueToDate(value: string): Date | undefined`
- `dateToTimeInputValue(date?: Date): string`
- `formatDecimalHours(hours?: number): string`
หลักการ:
- ใช้ base date คงที่ `1970-01-01`
- UI ใช้ `Date` ชั่วคราวเฉพาะในฟอร์ม
- ก่อน submit แปลงเป็น `hours + minutes / 60`
- ตอน edit แปลงค่าจาก decimal กลับเป็น `HH:mm`
## 6. Validation Rules
ปรับ validation ให้ชัดเจนทั้งใน schema และ field-level validator
- required
- มากกว่า `0`
- ไม่เกิน `24`
ข้อความ validation:
- `กรุณาระบุจำนวนชั่วโมงอบรม`
- `จำนวนชั่วโมงอบรมต้องมากกว่า 0`
- `จำนวนชั่วโมงอบรมต้องไม่เกิน 24 ชั่วโมง`
## 7. Edit Mode Behavior
- ถ้าเปิดฟอร์มแก้ไขและมีค่าเดิม เช่น `1.5`
- ระบบจะแปลงกลับเป็น `01:30` ในช่องเวลาอัตโนมัติ
- ถ้าเลือกหลักสูตรที่มี `standard_hours` ระบบจะเติมค่าเวลาให้ฟอร์มอัตโนมัติด้วย
## 8. Dashboard/Report Impact
ไม่มีผลกระทบกับ dashboard, review flow หรือ report calculation เพราะระบบ backend ยังรับและเก็บ `hours` เป็นเลข decimal เหมือนเดิม
## 9. Manual Test Checklist
- [ ] Create form shows TimePicker for training hours
- [ ] Selecting `01:30` saves `1.5` hours
- [ ] Selecting `02:00` saves `2` hours
- [ ] Selecting `02:15` saves `2.25` hours
- [ ] Empty value is blocked
- [ ] `00:00` is blocked
- [ ] Value above `24` hours is blocked
- [ ] Edit form converts `1.5` back to `01:30`
- [ ] Dashboard still calculates approved hours correctly
- [ ] Reports still export decimal hours correctly
- [ ] Mobile layout works
## 10. Known Limitations
- Native `time` input แสดงผลต่างกันเล็กน้อยตาม browser และ OS
- `placeholder` ไม่ใช่พฤติกรรมหลักของ `input[type="time"]` ในหลาย browser จึงใช้ helper text ใต้ช่องแทน
- เวลาที่ใช้ในฟอร์มเป็น UI-only state และไม่ได้ถูกเก็บเป็น `Date` ลงฐานข้อมูล