commit
This commit is contained in:
94
docs/management-change-training-hours-timepicker-review.md
Normal file
94
docs/management-change-training-hours-timepicker-review.md
Normal 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` ลงฐานข้อมูล
|
||||
Reference in New Issue
Block a user