# สรุปข้อกำหนด: ระบบแสดง Icon Status บนการ์ดพนักงาน

## ภาพรวม

พัฒนาระบบแสดงไอคอนและป้ายสถานะ (Status Icon & Label) บนการ์ดพนักงานในหน้าเลือกช่างซ่อมบำรุง (AssignMaintenanceSupportDrawer) แทนที่ placeholder "ICON" และ "STATUS" ที่มีอยู่ใน `EmployeeItem` component

## ที่มาของข้อมูลสถานะ

ข้อมูลสถานะมาจาก API (`/call-terminal/employee`) ซึ่ง query จาก DB โดยตรง:

- **is_available** (boolean): `true` = ไม่มีงาน `during work` ที่ active อยู่ (ว่างรับงานได้)
- **is_working** (boolean): `true` = มีงาน `during work` ที่ active และไม่ถูก suspend (กำลังทำงานอยู่)
- **Off Shift**: คำนวณจาก `ms_shift` — พนักงานไม่อยู่ในช่วงเวลากะที่ตั้งไว้ (`start_ts` / `end_ts`)

> ⚠️ ปัจจุบัน API ยังไม่มี field `is_off_shift` — ต้องเพิ่ม logic คำนวณจาก `ms_shift` (เทียบเวลาปัจจุบันกับ `start_ts`/`end_ts` ของกะที่ผูกกับพนักงานผ่าน `work_shift_id`)

### SQL Query ปัจจุบัน (employee.repository.ts)

```sql
-- is_available: ไม่มีงาน during work
NOT EXISTS (
  SELECT 1 FROM mp_request_work_worker mp
  JOIN request_work rw ON rw.id = mp.request_work_id
  WHERE mp.employee_id = me.id
    AND mp.worker_type = 'employee'
    AND mp.is_active = TRUE
    AND rw.current_status = 'during work'
) AS is_available

-- is_working: มีงาน during work ที่ไม่ถูก suspend
EXISTS (
  SELECT 1 FROM mp_request_work_worker mp
  JOIN request_work rw ON rw.id = mp.request_work_id
  WHERE mp.employee_id = me.id
    AND mp.worker_type = 'employee'
    AND mp.is_active = TRUE
    AND rw.current_status = 'during work'
    AND rw.is_suspension = FALSE
) AS is_working
```

### ตรรกะ Off Shift (ต้องเพิ่มใหม่)

```
Off Shift = เวลาปัจจุบัน ไม่อยู่ในช่วง ms_shift.start_ts ~ ms_shift.end_ts
            ของกะที่ผูกกับพนักงาน (ms_employee.work_shift_id → ms_shift.id)
```

## เลย์เอาต์การ์ดพนักงาน

### โครงสร้างทั่วไป

```
┌─────────────────────────────────┐
│  ชื่อ นามสกุล (bold)        ● ← จุดสี (Status Dot)
│                                 │
│  ⊙ Available                    │  ← ไอคอน + ข้อความสถานะ
└─────────────────────────────────┘
```

- **แถวบน**: ชื่อพนักงาน (ซ้าย) + วงกลมสีทึบ 16x16px (ขวา)
- **แถวล่าง**: ไอคอน 16x16px + ข้อความสถานะ (ชิดซ้าย, gap-2)

### ตัวอย่างการ์ดแต่ละสถานะ

#### ✅ Available (ว่าง) — สีเขียว

```
┌─────────────────────────────────┐
│                                 │
│  Anupong Chaiya             🟢  │  ← bg-green-500
│                                 │
│  ✓ Available                    │  ← CheckCircle + text-green-600
│                                 │
└─────────────────────────────────┘
  border: border-gray-300 (ปกติ)
  bg: bg-white
```

#### 🔧 Working (กำลังทำงาน) — สีน้ำเงิน

```
┌─────────────────────────────────┐
│                                 │
│  Chaiyong Siripong          🔵  │  ← bg-blue-500
│                                 │
│  🕐 Working                     │  ← Clock + text-blue-600
│                                 │
└─────────────────────────────────┘
  border: border-gray-300 (ปกติ)
  bg: bg-white
```

#### 🚫 Off Shift (ไม่อยู่กะ) — สีเทา

```
┌─────────────────────────────────┐
│                                 │
│  Somchai Three              ⚪  │  ← bg-gray-400
│                                 │
│  ⊘ Off Shift                    │  ← MinusCircle + text-gray-400
│                                 │
└─────────────────────────────────┘
  border: border-gray-300 (ปกติ)
  bg: bg-white
```

#### 🔲 เมื่อถูกเลือก (Selected) — ทุกสถานะเหมือนกัน

```
┌═════════════════════════════════┐
│                                 │  ← border-blue-600 (เส้นขอบน้ำเงิน)
│  Sakchai Rattana            🟢  │     bg-blue-50 (พื้นหลังฟ้าอ่อน)
│                                 │
│  ✓ Available                    │
│                                 │
└═════════════════════════════════┘
  border: border-blue-600 (เลือกแล้ว)
  bg: bg-blue-50
```

### ตัวอย่างหน้าจอรวม (Grid 4 คอลัมน์)

```
⚡ Electrician  12
┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐
│ Anupong Chaiya 🟢│  │ Ganya Ratchada 🟢│  │ Sakchai Rattan 🟢│  │ Chaiyong Siri  🔵│
│ ✓ Available      │  │ ✓ Available      │  │ ✓ Available      │  │ 🕐 Working       │
└──────────────────┘  └──────────────────┘  └──────────────────┘  └──────────────────┘

🔧 Mechanic  5
┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐
│ Somchai Three  ⚪│  │ User One       🟢│  │ Prasit Kaew    🔵│  │ Wichai Suk     ⚪│
│ ⊘ Off Shift      │  │ ✓ Available      │  │ 🕐 Working       │  │ ⊘ Off Shift      │
└──────────────────┘  └──────────────────┘  └──────────────────┘  └──────────────────┘
```

### ตัวอย่างปุ่มกรองสถานะ

```
┌───────────────────────────────────────────────────────────────────────────────────┐
│  🔍 Search maintenance staff...     [  All  ] [ Available ] [ Working ] [Off Shift]│
│                                      (red)     (green)       (blue)     (gray)    │
└───────────────────────────────────────────────────────────────────────────────────┘
```

- **All** (แดง): แสดงทุกคน
- **Available** (เขียว): แสดงเฉพาะ `is_available = true` AND `is_off_shift = false`
- **Working** (น้ำเงิน): แสดงเฉพาะ `is_working = true` AND `is_off_shift = false`
- **Off Shift** (เทา): แสดงเฉพาะ `is_off_shift = true`

## สถานะทั้ง 3 แบบ (Priority: Off Shift > Working > Available)

| สถานะ | เงื่อนไข | สี Dot | ไอคอน | ข้อความ | สีข้อความ/ไอคอน |
|---|---|---|---|---|---|
| Off Shift | ไม่อยู่ในเวลากะ (`is_off_shift = true`) | ⚪ bg-gray-400 | MinusCircle | "Off Shift" | text-gray-400 |
| Working | ถูก assign เครื่อง + งานเป็น `during work` (`is_working = true`) | 🔵 bg-blue-500 | Clock | "Working" | text-blue-600 |
| Available | อยู่ในกะ + ไม่ได้ทำงาน (`is_available = true` AND `is_off_shift = false`) | 🟢 bg-green-500 | CheckCircle | "Available" | text-green-600 |

> Priority: ถ้า Off Shift → แสดง Off Shift เสมอ (แม้จะมีงาน assign อยู่)

## ไฟล์ที่เกี่ยวข้อง

### Frontend (Web)

| ไฟล์ | สิ่งที่ต้องทำ |
|---|---|
| `EmployeeItem.tsx` | แทนที่ placeholder ด้วย status dot, icon, label จริง |
| `assign-maintenance.model.ts` | เพิ่ม `is_available`, `is_working`, `is_off_shift` ใน EmployeeRecordData interface |
| `useInteralAssignMaintenanceDrawer.ts` | เพิ่ม filter logic สำหรับ "offShift" โดยใช้ `is_off_shift` |

### Backend (API)

| ไฟล์ | สิ่งที่ต้องทำ |
|---|---|
| `employee.repository.ts` | เพิ่ม SQL คำนวณ `is_off_shift` จาก `ms_shift` (เทียบ `start_ts`/`end_ts` กับเวลาปัจจุบัน) |
| `employee.model.ts` | เพิ่ม `is_off_shift: boolean` ใน `EmployeeForGroupByWorkType` interface |

## รายการข้อกำหนด (8 ข้อ)

### 1. เพิ่ม is_off_shift ใน API (Backend)
- เพิ่ม SQL subquery ใน `employee.repository.ts` เพื่อคำนวณ `is_off_shift`
- เทียบเวลาปัจจุบันกับ `ms_shift.start_ts` / `ms_shift.end_ts` ผ่าน `ms_employee.work_shift_id`
- เพิ่ม `is_off_shift: boolean` ใน `EmployeeForGroupByWorkType` interface (API model)

### 2. ขยาย EmployeeRecordData Model (Frontend)
- เพิ่มฟิลด์ `is_available: boolean`, `is_working: boolean`, `is_off_shift: boolean` ใน interface
- ให้ EmployeeItem ใช้งานได้โดยไม่มี type error

### 3. ตรรกะคำนวณสถานะ (Status Derivation Logic)
- `is_off_shift = true` → "offShift" (priority สูงสุด)
- `is_working = true` → "working"
- `is_available = true` AND `is_off_shift = false` → "available"
- Working = ช่างที่ถูก assign เครื่องไว้ + สถานะงาน `during work`
- Off Shift = ไม่อยู่ในเวลาที่ตั้งไว้ใน `ms_shift`

### 4. วงกลมสีสถานะ (Status Dot)
- แสดงจุดกลมทึบ 16x16px ที่มุมขวาบนของการ์ด
- สี: เขียว (available), น้ำเงิน (working), เทา (offShift)

### 5. ไอคอนสถานะ (Status Icon)
- แสดงใต้ชื่อพนักงาน ฝั่งซ้าย ขนาด 16x16px
- ไอคอน: CheckCircle (available), Clock (working), MinusCircle (offShift)
- ใช้ lucide-react

### 6. ข้อความสถานะ (Status Label)
- แสดงคู่กับไอคอน: "Available", "Working", "Off Shift"
- สีตรงกับสถานะ

### 7. เลือกได้ทุกสถานะ — ไม่ล็อก
- พนักงานทุกสถานะ (available, working, offShift) กดเลือกได้หมด
- เมื่อเลือกแล้วแสดง border-blue-600, bg-blue-50 เหมือนกันทุกสถานะ

### 8. ตัวกรอง Off Shift
- เพิ่ม filter logic: เมื่อเลือก "Off Shift" → แสดงเฉพาะพนักงานที่ `is_off_shift = true`
- ปุ่มกรองที่มีอยู่แล้ว: All, Available, Working, Off Shift
