Tutorial Implementasi UI Modern - Attendance System
Overview Perubahan
Sebelum (Old UI):
• TextBox untuk NIP, Nama, Instansi (editable)
• Dropdown Instansi (manual)
• Layout kurang terstruktur
• Tampilan kurang modern
Sesudah (New UI):
• Input NIP dengan validasi
• Label-based display (read-only)
• Card-based layout
• Modern color scheme
• Responsive validation
Step-by-Step Implementation
STEP 1: Backup File Lama
bash
# Backup [Link]
copy [Link] [Link]
# Backup [Link]
copy [Link] [Link]
STEP 2: Update Designer File
1. Buka [Link]
2. Replace ENTIRE CONTENT dengan kode dari artifact [Link] - Modern UI
3. Save file
PENTING: Pastikan semua using statements ada:
csharp
using System;
using [Link];
using [Link];
using [Link];
using [Link];
STEP 3: Update Code-Behind File
1. Buka [Link]
2. Tambahkan field baru di bagian atas class:
csharp
// Field untuk Label-based UI
private int currentPegawaiId = 0;
private Bitmap lastCapturedFace = null;
private string lastCapturedFaceBase64 = null;
private int selectedTipeAbsen = 1; // Default: Masuk
3. Replace method-method berikut dengan kode dari artifact [Link] - Updated Methods :
• SetInitialUIState()
• bunifuButton1_Click()
• LoadEmployeeDataFromAPI()
• OnFaceVerificationSuccess()
• btnAttendance_Click()
• ResetForm()
4. Tambahkan method-method baru:
• ShowVerificationSuccess()
• ResetNIPInput()
• radioMasuk_CheckedChanged()
• radioPulang_CheckedChanged()
STEP 4: Update ApiService Method
File: [Link]
Modify: SubmitPresenceWithPhotoAsync untuk accept parameter tipe
csharp
public async Task<bool> SubmitPresenceWithPhotoAsync(
string nip,
string nama,
string instansi,
bool livenessVerified,
string fotoBase64,
int tipe = 1) // NEW PARAMETER
{
try
{
var payload = new
{
nip = nip,
nama = nama,
instansi = instansi,
liveness_verified = livenessVerified,
foto = fotoBase64,
tipe = tipe // INCLUDE IN PAYLOAD
};
var json = [Link](payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync("/api/presence/submit", content);
if ([Link])
{
[Link]($"[API] Presence submitted: {nip}, Tipe: {tipe}");
return true;
}
[Link]($"[API] Submit failed: {[Link]}");
return false;
}
catch (Exception ex)
{
[Link]($"[API] Submit error: {[Link]}");
return false;
}
}
STEP 5: Build dan Test
1. Clean Solution
Build → Clean Solution
2. Rebuild Solution
Build → Rebuild Solution
3. Check for Errors
• Jika ada error terkait BunifuLabel , pastikan Bunifu UI package terinstall
• Jika ada error namespace, tambahkan using statement yang diperlukan
4. Run Application
F5 atau Debug → Start Debugging
Testing Checklist
Test Case 1: NIP Validation
Steps:
1. Jalankan aplikasi
2. Input NIP < 18 digit
3. Tekan "✓"
Expected:
• Error message: "Format NIP tidak valid!"
Test Case 2: Successful Verification
Steps:
1. Input NIP valid (18 digit)
2. Tekan "✓"
3. Model berhasil di-load
Expected:
• NIP field disabled
• Employee data muncul (NIP, Nama, Instansi)
• Camera button enabled
Test Case 3: Face Recognition Flow
Steps:
1. Tekan " Buka Kamera"
2. Tekan " Deteksi Wajah"
3. Lakukan liveness detection
4. Tunggu face recognition
Expected:
• Liveness success → Face recognition
• Face verified → Tipe Absen muncul
• Smart default terpilih
Test Case 4: Duplicate Absen Masuk
Steps:
1. Absen MASUK berhasil
2. Restart form
3. Input NIP yang sama
4. Verify face
5. Pilih MASUK lagi
Expected:
• Warning: "Anda sudah absen MASUK hari ini!"
• Auto-switch ke PULANG
Test Case 5: Submit Attendance
Steps:
1. Setelah face verified
2. Pilih tipe absen
3. Tekan " Konfirmasi Absensi"
Expected:
• Loading indicator
• Success message dengan detail
• Form reset
UI Customization Guide
Color Scheme
csharp
// Primary Colors
[Link](99, 30, 213) // Purple header
[Link](33, 150, 243) // Blue (info)
[Link](76, 175, 80) // Green (success)
[Link](244, 67, 54) // Red (error)
[Link](255, 152, 0) // Orange (warning)
// Background
[Link](245, 245, 245) // Light gray
[Link] // Card background
Font Scheme
csharp
// Headers
new Font("Segoe UI", 22F, [Link])
// Subheaders
new Font("Segoe UI", 12F, [Link])
// Body
new Font("Segoe UI", 11F, [Link])
// Labels
new Font("Segoe UI", 10F, [Link])
Button Styles
csharp
// Primary Button (Blue)
IdleBorderRadius = 10
IdleFillColor = [Link](33, 150, 243)
// Success Button (Green)
IdleBorderRadius = 8
IdleFillColor = [Link](76, 175, 80)
// Warning Button (Orange)
IdleBorderRadius = 10
IdleFillColor = [Link](255, 152, 0)
Troubleshooting
Error: 'lblNIPValue' does not exist
Solution:
csharp
// Pastikan di [Link] ada:
private [Link] lblNIPValue;
// Di InitializeComponent():
[Link] = new [Link]();
Error: Method 'radioMasuk_CheckedChanged' not found
Solution:
csharp
// Tambahkan di [Link]:
private void radioMasuk_CheckedChanged(object sender, EventArgs e)
{
if ([Link])
{
selectedTipeAbsen = 1;
LogDebug("Tipe absen: MASUK");
}
}
private void radioPulang_CheckedChanged(object sender, EventArgs e)
{
if ([Link])
{
selectedTipeAbsen = 2;
LogDebug("Tipe absen: PULANG");
}
}
Layout Berantakan
Solution:
1. Buka form di Designer view
2. Adjust panel sizes:
• panelCameraCard : 550 x 600
• panelEmployeeCard : 560 x 600
3. Check spacing:
• Left margin: 30px
• Top margin: 100px
• Gap between panels: 30px
Performance Optimization
1. Lazy Loading
csharp
// Load departments hanya saat diperlukan
private async Task LoadDepartmentsIfNeeded()
{
if ([Link] == 0)
{
await PopulateComboboxDepts();
}
}
2. Dispose Pattern
csharp
protected override void OnFormClosing(FormClosingEventArgs e)
{
// Cleanup resources
lastCapturedFace?.Dispose();
individualRecognizer?.Dispose();
camera?.Dispose();
[Link](e);
}
3. Async/Await Best Practices
csharp
// BAD
private void btnConfirmNIP_Click(object sender, EventArgs e)
{
var result = [Link](nip).Result; // BLOCKING!
}
// GOOD
private async void btnConfirmNIP_Click(object sender, EventArgs e)
{
var result = await [Link](nip);
}
API Integration Notes
Required API Endpoints:
1. GET /api/face-biometrik/{nip}
• Returns: Model data (Base64 XML)
2. GET /api/employees/{nip}
• Returns: Employee details
3. GET /api/presence/today/{nip}
• Returns: Today's presence records
4. POST /api/presence/submit
• Payload: { nip, nama, instansi, liveness_verified, foto, tipe }
• Returns: Success/Failure
Completion Checklist
Designer file updated
Code-behind file updated
ApiService modified
Solution builds without errors
All test cases pass
UI looks correct
No memory leaks
Validation works
API integration works
Documentation updated
Additional Resources
• Bunifu UI Documentation
• Emgu CV Documentation
• C# Async/Await Best Practices
Support
Jika ada masalah saat implementasi:
1. Check Error Log: [Link]() output
2. Verify API: Test endpoints dengan Postman
3. Check Dependencies: Ensure all NuGet packages installed
4. Review Code: Compare dengan backup files
Congratulations!
Setelah implementasi selesai, Anda akan memiliki:
Modern, clean UI
Label-based employee display
Smart attendance validation
Improved UX flow
Better error handling
Photo capture integration
Happy Coding!