feat(FE-136): add flock and recording management with validation in forms

This commit is contained in:
rstubryan
2025-10-14 22:03:09 +07:00
parent 4b4b74d07c
commit 1869fa8dc5
5 changed files with 241 additions and 0 deletions
@@ -0,0 +1,121 @@
import * as Yup from 'yup';
import { RECORDING_FLAG_OPTIONS } from '@/config/constant';
export const RecordingFormSchema = Yup.object({
flock_id: Yup.number().required('Flock wajib diisi!'),
tanggal: Yup.string().required('Tanggal wajib diisi!'),
data_pakan: Yup.array()
.of(
Yup.object({
nama_pakan: Yup.string().required('Nama pakan wajib diisi!'),
qty_pakan: Yup.number()
.required('Qty pakan wajib diisi!')
.min(1, 'Qty minimal 1!'),
stock_pakan: Yup.number()
.required('Stock pakan wajib diisi!')
.min(0, 'Stock minimal 0!'),
})
)
.min(1, 'Minimal harus ada 1 data pakan!')
.required('Data pakan wajib diisi!'),
bobot_badan: Yup.array()
.of(
Yup.object({
berat_ayam: Yup.number()
.required('Berat ayam wajib diisi!')
.min(1, 'Berat minimal 1!'),
jumlah_ayam: Yup.number()
.required('Jumlah ayam wajib diisi!')
.min(1, 'Jumlah minimal 1!'),
rata_rata_berat_ayam: Yup.number()
.required('Rata-rata berat ayam wajib diisi!')
.min(1, 'Rata-rata minimal 1!'),
})
)
.min(1, 'Minimal harus ada 1 data bobot badan!')
.required('Data bobot badan wajib diisi!'),
vaksinasi: Yup.array()
.of(
Yup.object({
nama_vaksin: Yup.string().required('Nama vaksin wajib diisi!'),
total_stock: Yup.number()
.required('Total stock wajib diisi!')
.min(0, 'Total stock minimal 0!'),
jumlah_stock: Yup.number()
.required('Jumlah stock wajib diisi!')
.min(0, 'Jumlah stock minimal 0!'),
})
)
.min(1, 'Minimal harus ada 1 data vaksinasi!')
.required('Data vaksinasi wajib diisi!'),
mortalitas: Yup.array()
.of(
Yup.object({
kondisi: Yup.mixed<string>()
.oneOf(
RECORDING_FLAG_OPTIONS.map((opt) => opt.value),
'Kondisi tidak valid!'
)
.required('Kondisi wajib diisi!'),
jumlah: Yup.number()
.required('Jumlah wajib diisi!')
.min(1, 'Jumlah minimal 1!'),
})
)
.min(1, 'Minimal harus ada 1 data mortalitas!')
.required('Data mortalitas wajib diisi!'),
});
export const UpdateRecordingFormSchema = RecordingFormSchema;
export type RecordingFormValues = Yup.InferType<typeof RecordingFormSchema>;
export const getRecordingFormInitialValues = (
initialValues?: Partial<RecordingFormValues>
): RecordingFormValues => ({
flock_id: initialValues?.flock_id ?? 0,
tanggal: initialValues?.tanggal ?? '',
data_pakan:
Array.isArray(initialValues?.data_pakan) &&
initialValues.data_pakan.length > 0
? initialValues.data_pakan
: [
{
nama_pakan: '',
qty_pakan: 0,
stock_pakan: 0,
},
],
bobot_badan:
Array.isArray(initialValues?.bobot_badan) &&
initialValues.bobot_badan.length > 0
? initialValues.bobot_badan
: [
{
berat_ayam: 0,
jumlah_ayam: 0,
rata_rata_berat_ayam: 0,
},
],
vaksinasi:
Array.isArray(initialValues?.vaksinasi) &&
initialValues.vaksinasi.length > 0
? initialValues.vaksinasi
: [
{
nama_vaksin: '',
total_stock: 0,
jumlah_stock: 0,
},
],
mortalitas:
Array.isArray(initialValues?.mortalitas) &&
initialValues.mortalitas.length > 0
? initialValues.mortalitas
: [
{
kondisi: '',
jumlah: 0,
},
],
});
+30
View File
@@ -12,6 +12,29 @@ export const MAIN_DRAWER_LINKS: MAIN_DRAWER_MENU[] = [
icon: 'gg:chart',
},
{
title: 'Flock',
link: '/flock',
icon: 'mdi:chicken',
submenu: [
{
title: 'List Flock',
link: '/flock/list',
icon: 'mdi:chicken',
},
{
title: 'Chick In',
link: '/flock/chick-in',
icon: 'mdi:home-import-outline',
},
{
title: 'Recording',
link: '/flock/recording',
icon: 'mdi:clipboard-text',
},
],
},
{
title: 'Persediaan',
link: '/inventory',
@@ -175,3 +198,10 @@ export const PRODUCT_FLAG_OPTIONS = [
export const SUPPLIER_FLAG_OPTIONS = [
{ label: 'EKSPEDISI', value: 'EKSPEDISI' },
];
export const RECORDING_FLAG_OPTIONS = [
{ label: 'Ayam Afkir', value: 'Ayam Afkir' },
{ label: 'Ayam Culling', value: 'Ayam Culling' },
{ label: 'Ayam Mati', value: 'Ayam Mati' },
{ label: 'DOC', value: 'DOC' },
];
+22
View File
@@ -0,0 +1,22 @@
import {
CreateFlockPayload,
Flock,
UpdateFlockPayload,
} from '@/types/api/flock/flock';
import {
CreateRecordingPayload,
Recording,
UpdateRecordingPayload,
} from '@/types/api/flock/recording';
import { BaseApiService } from '@/services/api/base';
export const FlockApi = new BaseApiService<
Flock,
CreateFlockPayload,
UpdateFlockPayload
>('/flock/flocks');
export const RecordingApi = new BaseApiService<
Recording,
CreateRecordingPayload,
UpdateRecordingPayload
>('/flock/recordings');
+14
View File
@@ -0,0 +1,14 @@
import { BaseMetadata } from '@/types/api/api-general';
export type BaseFlock = {
id: number;
name: string;
};
export type Flock = BaseMetadata & BaseFlock;
export type CreateFlockPayload = {
name: string;
};
export type UpdateFlockPayload = CreateFlockPayload;
+54
View File
@@ -0,0 +1,54 @@
import { BaseMetadata } from '@/types/api/api-general';
import { Flock } from '@/types/api/flock/flock';
export type BaseRecording = {
id: number;
flock: Flock;
data_pakan: {
nama_pakan: string;
qty_pakan: number;
stock_pakan;
}[];
bobot_badan: {
berat_ayam: number;
jumlah_ayam: number;
rata_rata_berat_ayam: number;
}[];
vaksinasi: {
nama_vaksin: string;
total_stock: number;
jumlah_stock: number;
}[];
mortalitas: {
kondisi: string;
jumlah: number;
}[];
};
export type Recording = BaseMetadata & BaseRecording;
export type CreateRecordingPayload = {
flock_id: number;
tanggal: string;
data_pakan: {
nama_pakan: string;
qty_pakan: number;
stock_pakan: number;
}[];
bobot_badan: {
berat_ayam: number;
jumlah_ayam: number;
rata_rata_berat_ayam: number;
}[];
vaksinasi: {
nama_vaksin: string;
total_stock: number;
jumlah_stock: number;
}[];
mortalitas: {
kondisi: string;
jumlah: number;
}[];
};
export type UpdateRecordingPayload = CreateRecordingPayload;