Merge branch 'feat/enable-edit-chick-in-date' into 'development'

[FEAT/FE] Enable Edit Chick-In Date

See merge request mbugroup/lti-web-client!502
This commit is contained in:
Rivaldi A N S
2026-06-03 07:26:17 +00:00
4 changed files with 116 additions and 13 deletions
@@ -847,7 +847,8 @@ const DeliveryOrderFormModal = ({}: { initialValues?: Marketing }) => {
} }
}} }}
className='p-3 shadow-button-soft text-base-100 rounded-lg text-sm font-semibold' className='p-3 shadow-button-soft text-base-100 rounded-lg text-sm font-semibold'
disabled={deliveryRejected} disabled={deliveryRejected || isLoading}
isLoading={isLoading}
> >
{marketing?.data?.latest_approval?.step_number === 1 && {marketing?.data?.latest_approval?.step_number === 1 &&
'Approve'} 'Approve'}
@@ -2,16 +2,17 @@ import Alert from '@/components/Alert';
import Button from '@/components/Button'; import Button from '@/components/Button';
import Card from '@/components/Card'; import Card from '@/components/Card';
import RequirePermission from '@/components/helper/RequirePermission'; import RequirePermission from '@/components/helper/RequirePermission';
import DateInput from '@/components/input/DateInput';
import PillBadge from '@/components/PillBadge'; import PillBadge from '@/components/PillBadge';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { formatDate, formatNumber } from '@/lib/helper'; import { formatDate, formatNumber } from '@/lib/helper';
import { ChickinApi } from '@/services/api/production/chickin'; import { ChickinApi } from '@/services/api/production/chickin';
import { useChickinStore } from '@/stores/production/chickin/chickin.store';
import { BaseApproval } from '@/types/api/api-general'; import { BaseApproval } from '@/types/api/api-general';
import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang'; import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang';
import { Icon } from '@iconify/react'; import { Icon } from '@iconify/react';
import { useState } from 'react'; import { useState } from 'react';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import { useChickinStore } from '@/stores/production/chickin/chickin.store';
const ChickinLogsView = ({ const ChickinLogsView = ({
initialValues, initialValues,
@@ -23,6 +24,9 @@ const ChickinLogsView = ({
rawDataApprovals: BaseApproval[]; rawDataApprovals: BaseApproval[];
}) => { }) => {
const [chickinErrorMessage, setChickinErrorMessage] = useState(''); const [chickinErrorMessage, setChickinErrorMessage] = useState('');
const [editingChickinId, setEditingChickinId] = useState<number | null>(null);
const [editDate, setEditDate] = useState('');
const [isEditLoading, setIsEditLoading] = useState(false);
const { openChickinApproveModal, openChickinDeleteModal } = useChickinStore(); const { openChickinApproveModal, openChickinDeleteModal } = useChickinStore();
const handleClickApprove = () => { const handleClickApprove = () => {
@@ -44,6 +48,23 @@ const ChickinLogsView = ({
}); });
}; };
const handleSaveChickinDate = async () => {
setIsEditLoading(true);
const res = await ChickinApi.updateChickinDate(
initialValues.id as number,
formatDate(editDate, 'YYYY-MM-DD')
);
setIsEditLoading(false);
if (isResponseSuccess(res)) {
toast.success(res?.message as string);
setEditingChickinId(null);
afterSubmit && afterSubmit();
}
if (isResponseError(res)) {
toast.error(res?.message as string);
}
};
const handleDeleteChickin = (chickinId: number) => { const handleDeleteChickin = (chickinId: number) => {
openChickinDeleteModal(chickinId, async () => { openChickinDeleteModal(chickinId, async () => {
const deleteRes = await ChickinApi.delete(chickinId); const deleteRes = await ChickinApi.delete(chickinId);
@@ -133,9 +154,54 @@ const ChickinLogsView = ({
<Icon icon={'mdi:calendar'} width={14} height={14} />{' '} <Icon icon={'mdi:calendar'} width={14} height={14} />{' '}
<span>Tanggal Chick In</span> <span>Tanggal Chick In</span>
</div> </div>
<div className='text-end text-gray-500'> {editingChickinId === chickin.id ? (
{formatDate(chickin.chick_in_date, 'DD MMM YYYY')} <div className='flex flex-col gap-2 items-end w-1/2'>
</div> <DateInput
name='edit_chick_in_date'
value={editDate}
isNestedModal
onChange={(e) => setEditDate(e.target.value)}
/>
<div className='flex flex-row gap-1'>
<Button
color='none'
className='btn-xs btn-ghost text-gray-500'
onClick={() => setEditingChickinId(null)}
disabled={isEditLoading}
>
Batal
</Button>
<Button
color='success'
className='btn-xs text-base-100'
onClick={handleSaveChickinDate}
isLoading={isEditLoading}
disabled={!editDate || isEditLoading}
>
Simpan
</Button>
</div>
</div>
) : (
<div className='flex flex-row gap-2 items-center'>
<span className='text-gray-500'>
{formatDate(chickin.chick_in_date, 'DD MMM YYYY')}
</span>
<button
className='btn btn-ghost btn-xs p-0 text-gray-400 hover:text-primary'
onClick={() => {
setEditingChickinId(chickin.id);
setEditDate(chickin.chick_in_date);
}}
>
<Icon
icon='mdi:pencil-outline'
width={13}
height={13}
/>
</button>
</div>
)}
</div> </div>
{/* Kandang */} {/* Kandang */}
+20 -8
View File
@@ -45,8 +45,11 @@ export class SalesOrderService extends BaseApiService<
notes: notes || `${action} marketing ${id}`, notes: notes || `${action} marketing ${id}`,
}, },
}); });
} catch (error) { } catch (error: unknown) {
throw error; if (axios.isAxiosError<BaseApiResponse<{ message: string }>>(error)) {
return error.response?.data;
}
return undefined;
} }
} }
@@ -68,8 +71,11 @@ export class SalesOrderService extends BaseApiService<
notes: notes || `${action} marketing ${ids.join(', ')}`, notes: notes || `${action} marketing ${ids.join(', ')}`,
}, },
}); });
} catch (error) { } catch (error: unknown) {
throw error; if (axios.isAxiosError<BaseApiResponse<{ message: string }>>(error)) {
return error.response?.data;
}
return undefined;
} }
} }
@@ -110,8 +116,11 @@ export class SalesOrderService extends BaseApiService<
notes: notes || `Delivery marketing ${id}`, notes: notes || `Delivery marketing ${id}`,
}, },
}); });
} catch (error) { } catch (error: unknown) {
throw error; if (axios.isAxiosError<BaseApiResponse<{ message: string }>>(error)) {
return error.response?.data;
}
return undefined;
} }
} }
} }
@@ -142,8 +151,11 @@ class MarketingExportService extends BaseApiService<
notes: notes, notes: notes,
}, },
}); });
} catch (error) { } catch (error: unknown) {
throw error; if (axios.isAxiosError<BaseApiResponse<Marketing[] | Marketing>>(error)) {
return error.response?.data;
}
return undefined;
} }
} }
+24
View File
@@ -6,6 +6,7 @@ import {
import { BaseApiService } from '@/services/api/base'; import { BaseApiService } from '@/services/api/base';
import { BaseApiResponse } from '@/types/api/api-general'; import { BaseApiResponse } from '@/types/api/api-general';
import { httpClient } from '@/services/http/client'; import { httpClient } from '@/services/http/client';
import axios from 'axios';
export class ChickinService extends BaseApiService< export class ChickinService extends BaseApiService<
Chickin, Chickin,
@@ -16,6 +17,29 @@ export class ChickinService extends BaseApiService<
super(basePath); super(basePath);
} }
async updateChickinDate(
projectFlockKandangId: number,
chickInDate: string
): Promise<BaseApiResponse<{ message: string }> | undefined> {
try {
return await httpClient<BaseApiResponse<{ message: string }>>(
`${this.basePath}/chick-in-date`,
{
method: 'PATCH',
body: {
project_flock_kandang_id: projectFlockKandangId,
chick_in_date: chickInDate,
},
}
);
} catch (error: unknown) {
if (axios.isAxiosError<BaseApiResponse<{ message: string }>>(error)) {
return error.response?.data;
}
return undefined;
}
}
/** /**
* Approve single marketing data * Approve single marketing data
*/ */