setFormErrorList([])}
+ />
+ )}
+
{openChickin && (
diff --git a/src/components/pages/production/chickin/form/tabs/ChickLogsView.tsx b/src/components/pages/production/chickin/form/tabs/ChickLogsView.tsx
index 80846565..e800ee68 100644
--- a/src/components/pages/production/chickin/form/tabs/ChickLogsView.tsx
+++ b/src/components/pages/production/chickin/form/tabs/ChickLogsView.tsx
@@ -8,6 +8,7 @@ import PillBadge from '@/components/PillBadge';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { formatDate, formatNumber } from '@/lib/helper';
import { ChickinApi } from '@/services/api/production/chickin';
+import { BaseApproval } from '@/types/api/api-general';
import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang';
import { Icon } from '@iconify/react';
import { useState } from 'react';
@@ -16,9 +17,11 @@ import toast from 'react-hot-toast';
const ChickinLogsView = ({
initialValues,
afterSubmit,
+ rawDataApprovals,
}: {
initialValues: ProjectFlockKandang;
afterSubmit?: () => void;
+ rawDataApprovals: BaseApproval[];
}) => {
const confirmModal = useModal();
const [isApproveLoading, setIsApproveLoading] = useState(false);
@@ -60,9 +63,15 @@ const ChickinLogsView = ({
) : (
(initialValues?.chickins || []).map((chickin, index) => {
+ const latestApproval = rawDataApprovals[0];
const isApproved =
- initialValues.chickin_approval?.step_number === 2;
- const isPending = initialValues.chickin_approval?.step_number === 1;
+ index == (initialValues?.chickins || []).length - 1
+ ? latestApproval?.step_number === 2
+ : true;
+ const isPending =
+ index == (initialValues?.chickins || []).length - 1
+ ? latestApproval?.step_number === 1
+ : false;
const quantity = isApproved
? chickin.usage_qty
: isPending
@@ -82,7 +91,7 @@ const ChickinLogsView = ({
{/* Header with Status Badge */}
- Chick In #{index + 1}
+ Chick In #{index + 1} - {latestApproval?.step_number}
=
diff --git a/src/components/pages/production/project-flock/form/ProjectFlockForm.tsx b/src/components/pages/production/project-flock/form/ProjectFlockForm.tsx
index 20a8aff4..7e90c94b 100644
--- a/src/components/pages/production/project-flock/form/ProjectFlockForm.tsx
+++ b/src/components/pages/production/project-flock/form/ProjectFlockForm.tsx
@@ -6,6 +6,8 @@ import SelectInput, {
useSelect,
} from '@/components/input/SelectInput';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
+import { getUniqueFormikErrors } from '@/lib/formik-helper';
+import AlertErrorList from '@/components/helper/form/FormErrors';
import {
AreaApi,
FcrApi,
@@ -64,6 +66,7 @@ const ProjectFlockForm = ({
const [projectFlockFormErrorMessage, setProjectFlockFormErrorMessage] =
useState('');
+ const [formErrorList, setFormErrorList] = useState([]);
const [selectedArea, setSelectedArea] = useState('');
const [selectedLocation, setSelectedLocation] = useState('');
const [selectedCategory, setSelectedCategory] = useState('');
@@ -134,6 +137,7 @@ const ProjectFlockForm = ({
const kandangUrl = `${KandangApi.basePath}?${new URLSearchParams({
search: '',
location_id: selectedLocation == '' ? '0' : selectedLocation,
+ limit: 'limit',
}).toString()}`;
const {
data: kandang,
@@ -638,6 +642,17 @@ const ProjectFlockForm = ({
return !isNonstockAlreadyInBudgets;
});
+ const handleValidateForm = async () => {
+ const errors = await formik.validateForm();
+
+ if (Object.keys(errors).length > 0) {
+ // Parse and display errors
+ const errorMessages = getUniqueFormikErrors(errors);
+ setFormErrorList(errorMessages);
+ return; // Stop submission
+ }
+ };
+
return (
<>
@@ -697,7 +712,11 @@ const ProjectFlockForm = ({
+ {/* Error List Alert */}
+ {formErrorList.length > 0 && (
+ setFormErrorList([])}
+ />
+ )}
+
{formType !== 'detail' && (
(
+ errors: FormikErrors,
+ parentKey: string = ''
+): ErrorMessage[] {
+ const errorList: ErrorMessage[] = [];
+
+ Object.keys(errors).forEach((key) => {
+ const value = errors[key as keyof typeof errors];
+ const fullKey = parentKey ? `${parentKey}.${key}` : key;
+
+ if (typeof value === 'string') {
+ // Direct error message
+ errorList.push({ key: fullKey, message: value });
+ } else if (Array.isArray(value)) {
+ // Array of errors
+ value.forEach((item, index) => {
+ if (typeof item === 'string') {
+ errorList.push({ key: `${fullKey}[${index}]`, message: item });
+ } else if (item && typeof item === 'object') {
+ // Nested object in array
+ const nestedErrors = parseFormikErrors(
+ item as FormikErrors,
+ `${fullKey}[${index}]`
+ );
+ errorList.push(...nestedErrors);
+ }
+ });
+ } else if (value && typeof value === 'object') {
+ // Nested object
+ const nestedErrors = parseFormikErrors(
+ value as FormikErrors,
+ fullKey
+ );
+ errorList.push(...nestedErrors);
+ }
+ });
+
+ return errorList;
+}
+
+/**
+ * Get unique error messages from Formik errors
+ * @param errors - Formik errors object
+ * @returns Array of unique error messages
+ */
+export function getUniqueFormikErrors(errors: FormikErrors): string[] {
+ const errorList = parseFormikErrors(errors);
+ return Array.from(new Set(errorList.map((e) => e.message)));
+}
+
+/**
+ * Get all error messages from Formik errors
+ * @param errors - Formik errors object
+ * @returns Array of error messages
+ */
+export function getAllFormikErrors(errors: FormikErrors): ErrorMessage[] {
+ return parseFormikErrors(errors);
+}