mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 07:45:47 +00:00
feat: integrate MasterAktivitasContent component to API
This commit is contained in:
@@ -39,7 +39,14 @@ import {
|
|||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@/figma-make/components/base/dropdown-menu';
|
} from '@/figma-make/components/base/dropdown-menu';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { supabase, isSupabaseConfigured } from '@/figma-make/lib/supabase';
|
import useSWR from 'swr';
|
||||||
|
import { PhaseApi } from '@/services/api/daily-checklist/phase';
|
||||||
|
import { BaseApiResponse } from '@/types/api/api-general';
|
||||||
|
import { AxiosError } from 'axios';
|
||||||
|
import { httpClientFetcher, SWRHttpKey } from '@/services/http/client';
|
||||||
|
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||||
|
import { PhaseActivityApi } from '@/services/api/daily-checklist/phase-activity';
|
||||||
|
import { PhaseActivity } from '@/types/api/daily-checklist/phase-activity';
|
||||||
|
|
||||||
// Static categories - tidak bisa CRUD
|
// Static categories - tidak bisa CRUD
|
||||||
const CATEGORIES = [
|
const CATEGORIES = [
|
||||||
@@ -50,11 +57,11 @@ const CATEGORIES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const TIME_TYPES = [
|
const TIME_TYPES = [
|
||||||
{ value: 'umum', label: 'Umum' },
|
{ value: 'Umum', label: 'Umum' },
|
||||||
{ value: 'pagi', label: 'Pagi' },
|
{ value: 'Pagi', label: 'Pagi' },
|
||||||
{ value: 'siang', label: 'Siang' },
|
{ value: 'Siang', label: 'Siang' },
|
||||||
{ value: 'sore', label: 'Sore' },
|
{ value: 'Sore', label: 'Sore' },
|
||||||
{ value: 'malam', label: 'Malam' },
|
{ value: 'Malam', label: 'Malam' },
|
||||||
];
|
];
|
||||||
|
|
||||||
interface Phase {
|
interface Phase {
|
||||||
@@ -64,20 +71,46 @@ interface Phase {
|
|||||||
activityCount?: number;
|
activityCount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Activity {
|
|
||||||
id: string;
|
|
||||||
phase_id: string;
|
|
||||||
name: string;
|
|
||||||
description?: string;
|
|
||||||
time_type: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function MasterAktivitasContent() {
|
export function MasterAktivitasContent() {
|
||||||
const [selectedCategory, setSelectedCategory] = useState<string>('');
|
const [selectedCategory, setSelectedCategory] = useState<string>('');
|
||||||
const [phases, setPhases] = useState<Phase[]>([]);
|
|
||||||
const [activities, setActivities] = useState<Activity[]>([]);
|
|
||||||
const [selectedPhase, setSelectedPhase] = useState<Phase | null>(null);
|
const [selectedPhase, setSelectedPhase] = useState<Phase | null>(null);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: phases,
|
||||||
|
isLoading: isLoadingPhases,
|
||||||
|
mutate: refreshPhases,
|
||||||
|
} = useSWR<
|
||||||
|
BaseApiResponse<Phase[] | undefined>,
|
||||||
|
AxiosError<BaseApiResponse>,
|
||||||
|
SWRHttpKey
|
||||||
|
>(
|
||||||
|
selectedCategory
|
||||||
|
? `${PhaseApi.basePath}?page=1&limit=100&category=${selectedCategory}`
|
||||||
|
: '',
|
||||||
|
httpClientFetcher,
|
||||||
|
{
|
||||||
|
keepPreviousData: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: phaseActivities,
|
||||||
|
isLoading: isLoadingPhaseActivities,
|
||||||
|
mutate: refreshPhaseActivities,
|
||||||
|
} = useSWR<
|
||||||
|
BaseApiResponse<PhaseActivity[] | undefined>,
|
||||||
|
AxiosError<BaseApiResponse>,
|
||||||
|
SWRHttpKey
|
||||||
|
>(
|
||||||
|
selectedPhase?.id
|
||||||
|
? `${PhaseActivityApi.basePath}?page=1&limit=100&phase_id=${selectedPhase.id}`
|
||||||
|
: '',
|
||||||
|
httpClientFetcher,
|
||||||
|
{
|
||||||
|
keepPreviousData: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const [showPhaseModal, setShowPhaseModal] = useState(false);
|
const [showPhaseModal, setShowPhaseModal] = useState(false);
|
||||||
const [showActivityModal, setShowActivityModal] = useState(false);
|
const [showActivityModal, setShowActivityModal] = useState(false);
|
||||||
const [showPhaseDeleteConfirm, setShowPhaseDeleteConfirm] = useState(false);
|
const [showPhaseDeleteConfirm, setShowPhaseDeleteConfirm] = useState(false);
|
||||||
@@ -94,6 +127,16 @@ export function MasterAktivitasContent() {
|
|||||||
const [phaseModalMode, setPhaseModalMode] = useState<'create' | 'edit'>(
|
const [phaseModalMode, setPhaseModalMode] = useState<'create' | 'edit'>(
|
||||||
'create'
|
'create'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const filteredPhases =
|
||||||
|
(isResponseSuccess(phases) &&
|
||||||
|
phases?.data?.filter((phase) => {
|
||||||
|
return phase.name
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(phaseSearchQuery.toLowerCase());
|
||||||
|
})) ||
|
||||||
|
[];
|
||||||
|
|
||||||
const [activityModalMode, setActivityModalMode] = useState<'create' | 'edit'>(
|
const [activityModalMode, setActivityModalMode] = useState<'create' | 'edit'>(
|
||||||
'create'
|
'create'
|
||||||
);
|
);
|
||||||
@@ -114,115 +157,6 @@ export function MasterAktivitasContent() {
|
|||||||
setInitialLoading(false);
|
setInitialLoading(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Fetch phases when category changes
|
|
||||||
useEffect(() => {
|
|
||||||
if (selectedCategory) {
|
|
||||||
fetchPhases(selectedCategory);
|
|
||||||
} else {
|
|
||||||
setPhases([]);
|
|
||||||
setSelectedPhase(null);
|
|
||||||
setActivities([]);
|
|
||||||
}
|
|
||||||
}, [selectedCategory]);
|
|
||||||
|
|
||||||
// Fetch activities when phase changes
|
|
||||||
useEffect(() => {
|
|
||||||
if (selectedPhase) {
|
|
||||||
fetchActivities(selectedPhase.id);
|
|
||||||
} else {
|
|
||||||
setActivities([]);
|
|
||||||
}
|
|
||||||
}, [selectedPhase]);
|
|
||||||
|
|
||||||
const fetchPhases = async (
|
|
||||||
category: string,
|
|
||||||
preserveSelectedPhaseId?: string
|
|
||||||
) => {
|
|
||||||
if (!isSupabaseConfigured()) {
|
|
||||||
console.warn(
|
|
||||||
'Supabase not configured. Please add environment variables.'
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const { data, error } = await supabase
|
|
||||||
.from('phases')
|
|
||||||
.select('*')
|
|
||||||
.eq('category', category)
|
|
||||||
.order('id', { ascending: true }); // ✅ Urutan berdasarkan ID (yang paling awal diinput di atas)
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
console.error('Error fetching phases:', error);
|
|
||||||
toast.error('Gagal memuat data phase');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch activity counts for each phase
|
|
||||||
const phasesWithCounts = await Promise.all(
|
|
||||||
(data || []).map(async (phase) => {
|
|
||||||
const { count } = await supabase
|
|
||||||
.from('phase_activities')
|
|
||||||
.select('*', { count: 'exact', head: true })
|
|
||||||
.eq('phase_id', phase.id);
|
|
||||||
|
|
||||||
return { ...phase, activityCount: count || 0 };
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
setPhases(phasesWithCounts);
|
|
||||||
|
|
||||||
// Preserve selected phase if ID is provided
|
|
||||||
if (preserveSelectedPhaseId) {
|
|
||||||
const phaseToSelect = phasesWithCounts.find(
|
|
||||||
(p) => p.id === preserveSelectedPhaseId
|
|
||||||
);
|
|
||||||
if (phaseToSelect) {
|
|
||||||
setSelectedPhase(phaseToSelect);
|
|
||||||
} else if (phasesWithCounts.length > 0) {
|
|
||||||
setSelectedPhase(phasesWithCounts[0]);
|
|
||||||
} else {
|
|
||||||
setSelectedPhase(null);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Select first phase by default if exists
|
|
||||||
if (phasesWithCounts.length > 0) {
|
|
||||||
setSelectedPhase(phasesWithCounts[0]);
|
|
||||||
} else {
|
|
||||||
setSelectedPhase(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching phases:', error);
|
|
||||||
toast.error('Gagal memuat data phase');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchActivities = async (phaseId: string) => {
|
|
||||||
if (!isSupabaseConfigured()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const { data, error } = await supabase
|
|
||||||
.from('phase_activities')
|
|
||||||
.select('*')
|
|
||||||
.eq('phase_id', phaseId)
|
|
||||||
.order('id', { ascending: true }); // ✅ Urutan berdasarkan ID (yang paling awal diinput di atas)
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
console.error('Error fetching activities:', error);
|
|
||||||
toast.error('Gagal memuat data aktivitas');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setActivities(data || []);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching activities:', error);
|
|
||||||
toast.error('Gagal memuat data aktivitas');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Phase handlers
|
// Phase handlers
|
||||||
const handleAddPhase = () => {
|
const handleAddPhase = () => {
|
||||||
if (!selectedCategory) {
|
if (!selectedCategory) {
|
||||||
@@ -249,15 +183,13 @@ export function MasterAktivitasContent() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!selectedCategory) {
|
if (phaseForm.name.trim().length < 3) {
|
||||||
toast.error('Pilih kategori terlebih dahulu');
|
toast.error('Nama phase minimal 3 karakter!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSupabaseConfigured()) {
|
if (!selectedCategory) {
|
||||||
toast.error(
|
toast.error('Pilih kategori terlebih dahulu');
|
||||||
'Supabase belum dikonfigurasi. Tambahkan environment variables.'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,40 +197,40 @@ export function MasterAktivitasContent() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (phaseModalMode === 'create') {
|
if (phaseModalMode === 'create') {
|
||||||
const { error } = await supabase.from('phases').insert([
|
const createPhaseResponse = await PhaseApi.create({
|
||||||
{
|
category: selectedCategory,
|
||||||
name: phaseForm.name.trim(),
|
name: phaseForm.name.trim(),
|
||||||
category: selectedCategory,
|
});
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (error) {
|
if (isResponseError(createPhaseResponse)) {
|
||||||
console.error('Error creating phase:', error);
|
console.error('Error creating phase:', createPhaseResponse.message);
|
||||||
toast.error('Gagal menambahkan phase');
|
toast.error('Gagal menambahkan phase');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshPhases();
|
||||||
toast.success('Phase berhasil ditambahkan');
|
toast.success('Phase berhasil ditambahkan');
|
||||||
} else {
|
} else {
|
||||||
const { error } = await supabase
|
const updatePhaseResponse = await PhaseApi.update(
|
||||||
.from('phases')
|
Number(phaseForm.id),
|
||||||
.update({
|
{
|
||||||
name: phaseForm.name.trim(),
|
name: phaseForm.name.trim(),
|
||||||
})
|
}
|
||||||
.eq('id', phaseForm.id);
|
);
|
||||||
|
|
||||||
if (error) {
|
if (isResponseError(updatePhaseResponse)) {
|
||||||
console.error('Error updating phase:', error);
|
console.error('Error creating phase:', updatePhaseResponse.message);
|
||||||
toast.error('Gagal mengubah phase');
|
toast.error('Gagal menambahkan phase');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshPhases();
|
||||||
|
|
||||||
toast.success('Phase berhasil diubah');
|
toast.success('Phase berhasil diubah');
|
||||||
}
|
}
|
||||||
|
|
||||||
setShowPhaseModal(false);
|
setShowPhaseModal(false);
|
||||||
setPhaseForm({ id: '', name: '' });
|
setPhaseForm({ id: '', name: '' });
|
||||||
await fetchPhases(selectedCategory);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error saving phase:', error);
|
console.error('Error saving phase:', error);
|
||||||
toast.error('Terjadi kesalahan saat menyimpan phase');
|
toast.error('Terjadi kesalahan saat menyimpan phase');
|
||||||
@@ -318,32 +250,16 @@ export function MasterAktivitasContent() {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// First, delete all activities in this phase
|
const deletePhaseResponse = await PhaseApi.delete(Number(phaseToDelete));
|
||||||
const { error: activitiesError } = await supabase
|
|
||||||
.from('phase_activities')
|
|
||||||
.delete()
|
|
||||||
.eq('phase_id', phaseToDelete);
|
|
||||||
|
|
||||||
if (activitiesError) {
|
if (isResponseError(deletePhaseResponse)) {
|
||||||
console.error('Error deleting phase activities:', activitiesError);
|
console.error('Error deleting phase:', deletePhaseResponse.message);
|
||||||
toast.error('Gagal menghapus aktivitas phase');
|
|
||||||
setLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then delete the phase
|
|
||||||
const { error: phaseError } = await supabase
|
|
||||||
.from('phases')
|
|
||||||
.delete()
|
|
||||||
.eq('id', phaseToDelete);
|
|
||||||
|
|
||||||
if (phaseError) {
|
|
||||||
console.error('Error deleting phase:', phaseError);
|
|
||||||
toast.error('Gagal menghapus phase');
|
toast.error('Gagal menghapus phase');
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshPhases();
|
||||||
toast.success('Phase dan semua aktivitasnya berhasil dihapus');
|
toast.success('Phase dan semua aktivitasnya berhasil dihapus');
|
||||||
setShowPhaseDeleteConfirm(false);
|
setShowPhaseDeleteConfirm(false);
|
||||||
setPhaseToDelete(null);
|
setPhaseToDelete(null);
|
||||||
@@ -351,10 +267,7 @@ export function MasterAktivitasContent() {
|
|||||||
// Clear selection if deleted phase was selected
|
// Clear selection if deleted phase was selected
|
||||||
if (selectedPhase?.id === phaseToDelete) {
|
if (selectedPhase?.id === phaseToDelete) {
|
||||||
setSelectedPhase(null);
|
setSelectedPhase(null);
|
||||||
setActivities([]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await fetchPhases(selectedCategory);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error deleting phase:', error);
|
console.error('Error deleting phase:', error);
|
||||||
toast.error('Terjadi kesalahan saat menghapus phase');
|
toast.error('Terjadi kesalahan saat menghapus phase');
|
||||||
@@ -374,10 +287,10 @@ export function MasterAktivitasContent() {
|
|||||||
setShowActivityModal(true);
|
setShowActivityModal(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEditActivity = (activity: Activity) => {
|
const handleEditActivity = (activity: PhaseActivity) => {
|
||||||
setActivityModalMode('edit');
|
setActivityModalMode('edit');
|
||||||
setActivityForm({
|
setActivityForm({
|
||||||
id: activity.id,
|
id: String(activity.id),
|
||||||
name: activity.name,
|
name: activity.name,
|
||||||
description: activity.description || '',
|
description: activity.description || '',
|
||||||
time_type: activity.time_type,
|
time_type: activity.time_type,
|
||||||
@@ -391,15 +304,13 @@ export function MasterAktivitasContent() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!selectedPhase) {
|
if (activityForm.name.trim().length < 3) {
|
||||||
toast.error('Pilih phase terlebih dahulu');
|
toast.error('Nama aktivitas minimal 3 karakter!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSupabaseConfigured()) {
|
if (!selectedPhase) {
|
||||||
toast.error(
|
toast.error('Pilih phase terlebih dahulu');
|
||||||
'Supabase belum dikonfigurasi. Tambahkan environment variables.'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,47 +318,49 @@ export function MasterAktivitasContent() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (activityModalMode === 'create') {
|
if (activityModalMode === 'create') {
|
||||||
const { error } = await supabase.from('phase_activities').insert([
|
const createActivityResponse = await PhaseActivityApi.create({
|
||||||
{
|
phase_id: Number(selectedPhase.id),
|
||||||
phase_id: selectedPhase.id,
|
name: activityForm.name.trim(),
|
||||||
name: activityForm.name.trim(),
|
description: activityForm.description.trim() || '',
|
||||||
description: activityForm.description.trim() || null,
|
time_type: activityForm.time_type,
|
||||||
time_type: activityForm.time_type,
|
});
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (error) {
|
if (isResponseError(createActivityResponse)) {
|
||||||
console.error('Error creating activity:', error);
|
console.error(
|
||||||
|
'Error creating activity:',
|
||||||
|
createActivityResponse.message
|
||||||
|
);
|
||||||
toast.error('Gagal menambahkan aktivitas');
|
toast.error('Gagal menambahkan aktivitas');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshPhaseActivities();
|
||||||
toast.success('Aktivitas berhasil ditambahkan');
|
toast.success('Aktivitas berhasil ditambahkan');
|
||||||
} else {
|
} else {
|
||||||
const { error } = await supabase
|
const updateActivityResponse = await PhaseActivityApi.update(
|
||||||
.from('phase_activities')
|
Number(activityForm.id),
|
||||||
.update({
|
{
|
||||||
name: activityForm.name.trim(),
|
name: activityForm.name.trim(),
|
||||||
description: activityForm.description.trim() || null,
|
description: activityForm.description.trim() || '',
|
||||||
time_type: activityForm.time_type,
|
time_type: activityForm.time_type,
|
||||||
})
|
}
|
||||||
.eq('id', activityForm.id);
|
);
|
||||||
|
|
||||||
if (error) {
|
if (isResponseError(updateActivityResponse)) {
|
||||||
console.error('Error updating activity:', error);
|
console.error(
|
||||||
|
'Error updating activity:',
|
||||||
|
updateActivityResponse.message
|
||||||
|
);
|
||||||
toast.error('Gagal mengubah aktivitas');
|
toast.error('Gagal mengubah aktivitas');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshPhaseActivities();
|
||||||
toast.success('Aktivitas berhasil diubah');
|
toast.success('Aktivitas berhasil diubah');
|
||||||
}
|
}
|
||||||
|
|
||||||
setShowActivityModal(false);
|
setShowActivityModal(false);
|
||||||
setActivityForm({ id: '', name: '', description: '', time_type: 'umum' });
|
setActivityForm({ id: '', name: '', description: '', time_type: 'umum' });
|
||||||
await fetchActivities(selectedPhase.id);
|
|
||||||
if (selectedCategory) {
|
|
||||||
await fetchPhases(selectedCategory, selectedPhase.id); // ✅ Preserve selected phase
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error saving activity:', error);
|
console.error('Error saving activity:', error);
|
||||||
toast.error('Terjadi kesalahan saat menyimpan aktivitas');
|
toast.error('Terjadi kesalahan saat menyimpan aktivitas');
|
||||||
@@ -467,22 +380,23 @@ export function MasterAktivitasContent() {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { error } = await supabase
|
const deleteActivityResponse = await PhaseActivityApi.delete(
|
||||||
.from('phase_activities')
|
Number(activityToDelete)
|
||||||
.delete()
|
);
|
||||||
.eq('id', activityToDelete);
|
|
||||||
|
|
||||||
if (error) {
|
if (isResponseError(deleteActivityResponse)) {
|
||||||
console.error('Error deleting activity:', error);
|
console.error(
|
||||||
|
'Error deleting activity:',
|
||||||
|
deleteActivityResponse.message
|
||||||
|
);
|
||||||
toast.error('Gagal menghapus aktivitas');
|
toast.error('Gagal menghapus aktivitas');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshPhaseActivities();
|
||||||
toast.success('Aktivitas berhasil dihapus');
|
toast.success('Aktivitas berhasil dihapus');
|
||||||
setShowActivityDeleteConfirm(false);
|
setShowActivityDeleteConfirm(false);
|
||||||
setActivityToDelete(null);
|
setActivityToDelete(null);
|
||||||
await fetchActivities(selectedPhase.id);
|
|
||||||
await fetchPhases(selectedCategory, selectedPhase.id); // ✅ Preserve selected phase
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error deleting activity:', error);
|
console.error('Error deleting activity:', error);
|
||||||
toast.error('Terjadi kesalahan saat menghapus aktivitas');
|
toast.error('Terjadi kesalahan saat menghapus aktivitas');
|
||||||
@@ -491,16 +405,12 @@ export function MasterAktivitasContent() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const filteredPhases = phases.filter((phase) =>
|
|
||||||
phase.name.toLowerCase().includes(phaseSearchQuery.toLowerCase())
|
|
||||||
);
|
|
||||||
|
|
||||||
const getTimeTypeLabel = (timeType: string) => {
|
const getTimeTypeLabel = (timeType: string) => {
|
||||||
return TIME_TYPES.find((t) => t.value === timeType)?.label || timeType;
|
return TIME_TYPES.find((t) => t.value === timeType)?.label || timeType;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTimeTypeBadgeClass = (timeType: string) => {
|
const getTimeTypeBadgeClass = (timeType: string) => {
|
||||||
switch (timeType) {
|
switch (timeType.toLowerCase()) {
|
||||||
case 'umum':
|
case 'umum':
|
||||||
return 'bg-gray-50 text-gray-700 border-gray-300';
|
return 'bg-gray-50 text-gray-700 border-gray-300';
|
||||||
case 'pagi':
|
case 'pagi':
|
||||||
@@ -610,7 +520,8 @@ export function MasterAktivitasContent() {
|
|||||||
|
|
||||||
{/* Phase List */}
|
{/* Phase List */}
|
||||||
<div className='divide-y divide-gray-200/60'>
|
<div className='divide-y divide-gray-200/60'>
|
||||||
{filteredPhases.length === 0 ? (
|
{!isResponseSuccess(phases) ||
|
||||||
|
(isResponseSuccess(phases) && phases.data?.length === 0) ? (
|
||||||
<div className='p-8 text-center text-gray-500'>
|
<div className='p-8 text-center text-gray-500'>
|
||||||
{phaseSearchQuery
|
{phaseSearchQuery
|
||||||
? 'Tidak ada phase yang ditemukan'
|
? 'Tidak ada phase yang ditemukan'
|
||||||
@@ -684,9 +595,11 @@ export function MasterAktivitasContent() {
|
|||||||
<h2 className='text-lg font-semibold text-gray-900'>
|
<h2 className='text-lg font-semibold text-gray-900'>
|
||||||
Aktivitas di Phase: {selectedPhase.name}
|
Aktivitas di Phase: {selectedPhase.name}
|
||||||
</h2>
|
</h2>
|
||||||
<p className='text-sm text-gray-600 mt-0.5'>
|
{isResponseSuccess(phaseActivities) && (
|
||||||
{activities.length} aktivitas
|
<p className='text-sm text-gray-600 mt-0.5'>
|
||||||
</p>
|
{phaseActivities.data?.length} aktivitas
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleAddActivity}
|
onClick={handleAddActivity}
|
||||||
@@ -711,7 +624,9 @@ export function MasterAktivitasContent() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className='divide-y divide-gray-200/60'>
|
<tbody className='divide-y divide-gray-200/60'>
|
||||||
{activities.length === 0 ? (
|
{!isResponseSuccess(phaseActivities) ||
|
||||||
|
(isResponseSuccess(phaseActivities) &&
|
||||||
|
phaseActivities.data?.length === 0) ? (
|
||||||
<tr>
|
<tr>
|
||||||
<td
|
<td
|
||||||
colSpan={2}
|
colSpan={2}
|
||||||
@@ -721,7 +636,7 @@ export function MasterAktivitasContent() {
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
activities.map((activity) => (
|
phaseActivities.data?.map((activity) => (
|
||||||
<tr
|
<tr
|
||||||
key={activity.id}
|
key={activity.id}
|
||||||
className='hover:bg-blue-50/30 transition-colors'
|
className='hover:bg-blue-50/30 transition-colors'
|
||||||
@@ -768,7 +683,7 @@ export function MasterAktivitasContent() {
|
|||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleDeleteActivityClick(
|
handleDeleteActivityClick(
|
||||||
activity.id
|
String(activity.id)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className='text-red-600'
|
className='text-red-600'
|
||||||
|
|||||||
Reference in New Issue
Block a user