feat: integrate DetailDailyChecklistContent component to API

This commit is contained in:
ValdiANS
2026-01-09 14:13:14 +07:00
parent ceb7cb6b2d
commit c9c618e3f8
@@ -17,8 +17,9 @@ import {
DialogFooter,
} from '@/figma-make/components/base/dialog';
import { toast } from 'sonner';
import { supabase, isSupabaseConfigured } from '@/figma-make/lib/supabase';
import { useRouter, useSearchParams } from 'next/navigation';
import { DailyChecklistApi } from '@/services/api/daily-checklist/daily-checklist';
import { isResponseError } from '@/lib/api-helper';
interface ChecklistDetailRow {
checklist_id: string;
@@ -85,23 +86,6 @@ interface ChecklistData {
};
}
interface TaskQueryResult {
id: number;
phase_id: string;
phase_activity_id: string;
time_type: string;
notes: string | null;
phases: {
id: number;
name: string;
} | null;
phase_activities: {
id: number;
name: string;
description: string | null;
} | null;
}
interface AssignmentQueryResult {
task_id: number;
employee_id: string;
@@ -120,13 +104,13 @@ const CATEGORY_LABELS: { [key: string]: string } = {
produksi_close: 'Produksi Close',
};
const TIME_TYPE_ORDER = ['umum', 'pagi', 'siang', 'sore', 'malam'];
const TIME_TYPE_ORDER = ['Umum', 'Pagi', 'Siang', 'Sore', 'Malam'];
const TIME_TYPE_LABELS: { [key: string]: string } = {
umum: 'Umum',
pagi: 'Pagi',
siang: 'Siang',
sore: 'Sore',
malam: 'Malam',
Umum: 'Umum',
Pagi: 'Pagi',
Siang: 'Siang',
Sore: 'Sore',
Malam: 'Malam',
};
export function DetailDailyChecklistContent() {
@@ -155,8 +139,8 @@ export function DetailDailyChecklistContent() {
}, [checklistId]);
const fetchChecklistDetail = async () => {
if (!isSupabaseConfigured() || !checklistId) {
console.warn('Supabase not configured or checklistId missing');
if (!checklistId) {
console.warn('checklistId missing');
setLoading(false);
return;
}
@@ -164,69 +148,34 @@ export function DetailDailyChecklistContent() {
try {
setLoading(true);
// ✅ Fetch checklist header with kandang name
const { data: checklistData, error: checklistError } = await supabase
.from('daily_checklists')
.select(
`
id,
date,
kandang_id,
category,
status,
reject_reason,
kandang:kandang_id (
id,
name
)
`
)
.eq('id', checklistId)
.single();
const checklistDataRes =
await DailyChecklistApi.getOneDailyChecklist(checklistId);
if (checklistError || !checklistData) {
console.error('Error fetching checklist:', checklistError);
if (isResponseError(checklistDataRes)) {
console.error('Error fetching checklist:', checklistDataRes.message);
toast.error('Data checklist tidak ditemukan');
router.push('/daily-checklist/list-daily-checklist');
return;
}
// ✅ Fetch all tasks with their phase_activity details
const { data: tasks, error: tasksError } = await supabase
.from('daily_checklist_activity_tasks')
.select(
`
id,
phase_id,
phase_activity_id,
time_type,
notes,
phases:phase_id (
id,
name
),
phase_activities:phase_activity_id (
id,
name,
description
)
`
)
.eq('checklist_id', checklistId);
const rawDetailChecklist = checklistDataRes?.data;
if (tasksError) {
console.error('Error fetching tasks:', tasksError);
toast.error('Gagal memuat detail checklist');
router.push('/daily-checklist/list-daily-checklist');
return;
}
const checklistData = {
id: rawDetailChecklist?.id,
date: rawDetailChecklist?.date,
kandang_id: rawDetailChecklist?.kandang.id,
category: rawDetailChecklist?.category,
status: rawDetailChecklist?.status,
reject_reason: rawDetailChecklist?.reject_reason,
kandang: rawDetailChecklist?.kandang,
};
const castedTasks = (tasks as unknown as TaskQueryResult[]) || [];
const tasks = rawDetailChecklist?.tasks;
const castedChecklistData =
checklistData as unknown as ChecklistData | null;
if (!castedTasks || castedTasks.length === 0) {
if (!tasks || tasks.length === 0) {
toast.info('Checklist belum memiliki aktivitas');
setHeader({
date: castedChecklistData?.date || '-',
@@ -242,36 +191,32 @@ export function DetailDailyChecklistContent() {
return;
}
// ✅ Fetch all assignments for these tasks
const taskIds = castedTasks.map((t) => t.id);
const { data: assignments, error: assignmentsError } = await supabase
.from('daily_checklist_activity_task_assignments')
.select(
`
task_id,
employee_id,
checked,
note,
employees:employee_id (
id,
name
)
`
)
.in('task_id', taskIds);
const assignments: {
task_id: number;
checked: boolean;
note: string | null;
employee: {
id: number;
name: string;
};
}[] = [];
if (assignmentsError) {
console.error('Error fetching assignments:', assignmentsError);
}
const castedAssignments =
(assignments as unknown as AssignmentQueryResult[]) || [];
tasks.forEach((task) => {
task.assignments.forEach((assignment) => {
assignments.push({
task_id: task.id,
checked: assignment.checked,
note: assignment.note,
employee: assignment.employee,
});
});
});
// ✅ Build detail rows from tasks and assignments
const detailRows: ChecklistDetailRow[] = [];
castedTasks.forEach((task) => {
const taskAssignments = (castedAssignments || []).filter(
tasks.forEach((task) => {
const taskAssignments = assignments.filter(
(a) => a.task_id === task.id
);
@@ -283,14 +228,14 @@ export function DetailDailyChecklistContent() {
category: castedChecklistData?.category || '-',
status: castedChecklistData?.status || '-',
reject_reason: castedChecklistData?.reject_reason || '-',
phase_id: task.phase_id,
phase_name: task.phases?.name || '-',
activity_id: task.phase_activity_id,
activity_name: task.phase_activities?.name || '-',
activity_description: task.phase_activities?.description || null,
phase_id: String(task.phase_id),
phase_name: task.phase?.name || '-',
activity_id: String(task.phase_activity_id),
activity_name: task.phase_activity?.name || '-',
activity_description: task.phase_activity?.description || null,
time_type: task.time_type,
employee_id: assignment.employee_id,
employee_name: assignment.employees?.name || '-',
employee_id: String(assignment.employee.id),
employee_name: assignment.employee?.name || '-',
checked: assignment.checked,
note: assignment.note,
});
@@ -306,8 +251,8 @@ export function DetailDailyChecklistContent() {
status: castedChecklistData?.status || '-',
reject_reason: castedChecklistData?.reject_reason || '-',
progress_percent: 0,
total_phases: new Set(castedTasks.map((t) => t.phase_id)).size,
total_activities: castedTasks.length,
total_phases: new Set(tasks.map((t) => t.phase_id)).size,
total_activities: tasks.length,
});
setLoading(false);
return;
@@ -471,22 +416,15 @@ export function DetailDailyChecklistContent() {
};
const confirmApprove = async () => {
if (!checklistId || !isSupabaseConfigured()) return;
if (!checklistId) return;
try {
setActionLoading(true);
const { error } = await supabase
.from('daily_checklists')
.update({
status: 'APPROVED',
updated_at: new Date().toISOString(),
})
.eq('id', checklistId);
const approveRes = await DailyChecklistApi.approve(String(checklistId));
if (error) {
console.error('Error approving checklist:', error);
toast.error('Gagal approve checklist');
if (isResponseError(approveRes)) {
toast.error('Gagal approve checklist: ' + approveRes.message);
return;
}
@@ -502,7 +440,7 @@ export function DetailDailyChecklistContent() {
};
const confirmReject = async () => {
if (!checklistId || !isSupabaseConfigured()) return;
if (!checklistId) return;
if (!rejectReason.trim()) {
toast.error('Alasan reject harus diisi');
@@ -512,18 +450,13 @@ export function DetailDailyChecklistContent() {
try {
setActionLoading(true);
const { error } = await supabase
.from('daily_checklists')
.update({
status: 'REJECTED',
reject_reason: rejectReason,
updated_at: new Date().toISOString(),
})
.eq('id', checklistId);
const rejectRes = await DailyChecklistApi.reject(
String(checklistId),
rejectReason
);
if (error) {
console.error('Error rejecting checklist:', error);
toast.error('Gagal reject checklist');
if (isResponseError(rejectRes)) {
toast.error('Gagal reject checklist: ' + rejectRes.message);
return;
}