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