mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
Merge branch 'fix/adjustment-uniformity-ui' into 'development'
[FIX/FE] Adjusment Pixel Perfect Uniformity UI See merge request mbugroup/lti-web-client!289
This commit is contained in:
@@ -16,7 +16,6 @@ interface DrawerProps {
|
|||||||
onBackdropClick?: () => void;
|
onBackdropClick?: () => void;
|
||||||
closeOnBackdropClick?: boolean;
|
closeOnBackdropClick?: boolean;
|
||||||
expandedContent?: ReactNode;
|
expandedContent?: ReactNode;
|
||||||
expandedWidth?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type DrawerClassName = {
|
type DrawerClassName = {
|
||||||
@@ -25,6 +24,7 @@ type DrawerClassName = {
|
|||||||
drawerSide?: string;
|
drawerSide?: string;
|
||||||
drawerOverlay?: string;
|
drawerOverlay?: string;
|
||||||
drawerSidebarContent?: string;
|
drawerSidebarContent?: string;
|
||||||
|
drawerExpandedContent?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Drawer = ({
|
const Drawer = ({
|
||||||
@@ -39,7 +39,6 @@ const Drawer = ({
|
|||||||
onBackdropClick,
|
onBackdropClick,
|
||||||
closeOnBackdropClick = true,
|
closeOnBackdropClick = true,
|
||||||
expandedContent,
|
expandedContent,
|
||||||
expandedWidth = 'w-[400px]',
|
|
||||||
}: DrawerProps) => {
|
}: DrawerProps) => {
|
||||||
const getDrawerClassNames = (): DrawerClassName => {
|
const getDrawerClassNames = (): DrawerClassName => {
|
||||||
const baseClassNames = {
|
const baseClassNames = {
|
||||||
@@ -56,6 +55,9 @@ const Drawer = ({
|
|||||||
? 'w-full lg:min-w-[600px] lg:max-w-[600px]'
|
? 'w-full lg:min-w-[600px] lg:max-w-[600px]'
|
||||||
: 'w-full max-w-[300px] lg:w-[300px]';
|
: 'w-full max-w-[300px] lg:w-[300px]';
|
||||||
}
|
}
|
||||||
|
if (className?.drawerSidebarContent) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
return 'w-full sm:min-w-120 sm:w-fit';
|
return 'w-full sm:min-w-120 sm:w-fit';
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,7 +176,7 @@ const Drawer = ({
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
'border-l border-gray-200 bg-white flex flex-col h-full',
|
'border-l border-gray-200 bg-white flex flex-col h-full',
|
||||||
expandedWidth
|
className?.drawerExpandedContent
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className='overflow-y-auto flex-1 h-full'>
|
<div className='overflow-y-auto flex-1 h-full'>
|
||||||
|
|||||||
@@ -58,7 +58,10 @@ export default function UniformityPageWrapper({
|
|||||||
zIndex='99999'
|
zIndex='99999'
|
||||||
sidebarContent={isOpen ? <div className=''>{children}</div> : null}
|
sidebarContent={isOpen ? <div className=''>{children}</div> : null}
|
||||||
expandedContent={expandedDrawerOpen ? expandedDrawerContent : null}
|
expandedContent={expandedDrawerOpen ? expandedDrawerContent : null}
|
||||||
expandedWidth='w-[500px]'
|
className={{
|
||||||
|
drawerSidebarContent: 'w-[446px]',
|
||||||
|
drawerExpandedContent: 'w-[446px]',
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -42,8 +42,6 @@ import {
|
|||||||
ProjectFlock,
|
ProjectFlock,
|
||||||
} from '@/types/api/production/project-flock';
|
} from '@/types/api/production/project-flock';
|
||||||
import {
|
import {
|
||||||
getStatusColor,
|
|
||||||
getStatusIndicatorColor,
|
|
||||||
getStatusText,
|
getStatusText,
|
||||||
getStatusBadgeColor,
|
getStatusBadgeColor,
|
||||||
} from '@/components/pages/production/uniformity/uniformity-utils';
|
} from '@/components/pages/production/uniformity/uniformity-utils';
|
||||||
@@ -112,11 +110,19 @@ const UniformityConfirmationPreview = ({
|
|||||||
|
|
||||||
const columns: ColumnDef<DetailOptionType>[] = [
|
const columns: ColumnDef<DetailOptionType>[] = [
|
||||||
{
|
{
|
||||||
header: 'Label',
|
accessorKey: 'label',
|
||||||
|
enableSorting: false,
|
||||||
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Label</span>
|
||||||
|
),
|
||||||
cell: (props) => props.row.original.label,
|
cell: (props) => props.row.original.label,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Value',
|
accessorKey: 'value',
|
||||||
|
enableSorting: false,
|
||||||
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Value</span>
|
||||||
|
),
|
||||||
cell: (props) => {
|
cell: (props) => {
|
||||||
const id = props.row.original.id;
|
const id = props.row.original.id;
|
||||||
const value = props.row.original.value;
|
const value = props.row.original.value;
|
||||||
@@ -124,16 +130,10 @@ const UniformityConfirmationPreview = ({
|
|||||||
if (id === 'status') {
|
if (id === 'status') {
|
||||||
return (
|
return (
|
||||||
<div className='w-full'>
|
<div className='w-full'>
|
||||||
<Badge
|
<StatusBadge
|
||||||
statusIndicator={true}
|
color={getStatusBadgeColor(value)}
|
||||||
variant='soft'
|
text={getStatusText(value)}
|
||||||
className={{
|
/>
|
||||||
badge: `rounded-xl w-full justify-start border border-gray-200 text-black ${getStatusColor(value)}`,
|
|
||||||
status: getStatusIndicatorColor(value),
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{getStatusText(value)}
|
|
||||||
</Badge>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,6 @@ const UniformityTable = () => {
|
|||||||
const [isBulkActionLoading, setIsBulkActionLoading] = useState(false);
|
const [isBulkActionLoading, setIsBulkActionLoading] = useState(false);
|
||||||
const [isPdfExportLoading, setIsPdfExportLoading] = useState(false);
|
const [isPdfExportLoading, setIsPdfExportLoading] = useState(false);
|
||||||
const [isExcelExportLoading, setIsExcelExportLoading] = useState(false);
|
const [isExcelExportLoading, setIsExcelExportLoading] = useState(false);
|
||||||
const isAnyExportLoading = isPdfExportLoading || isExcelExportLoading;
|
|
||||||
|
|
||||||
const singleDeleteModal = useModal();
|
const singleDeleteModal = useModal();
|
||||||
const successModal = useModal();
|
const successModal = useModal();
|
||||||
@@ -238,7 +237,7 @@ const UniformityTable = () => {
|
|||||||
const [filterEndDate, setFilterEndDate] = useState('');
|
const [filterEndDate, setFilterEndDate] = useState('');
|
||||||
const [filterProjectFlockLocationId, setFilterProjectFlockLocationId] =
|
const [filterProjectFlockLocationId, setFilterProjectFlockLocationId] =
|
||||||
useState<string>('');
|
useState<string>('');
|
||||||
const [filterErrors, setFilterErrors] = useState<Record<string, string>>({});
|
const [, setFilterErrors] = useState<Record<string, string>>({});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
setInputValue: setFilterLocationInputValue,
|
setInputValue: setFilterLocationInputValue,
|
||||||
@@ -309,7 +308,6 @@ const UniformityTable = () => {
|
|||||||
? projectFlockKandangLookupData.data
|
? projectFlockKandangLookupData.data
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
// Update filterProjectFlockKandangId when lookup changes
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (projectFlockKandangLookup?.id) {
|
if (projectFlockKandangLookup?.id) {
|
||||||
setFilterProjectFlockKandangId(projectFlockKandangLookup.id);
|
setFilterProjectFlockKandangId(projectFlockKandangLookup.id);
|
||||||
@@ -483,12 +481,6 @@ const UniformityTable = () => {
|
|||||||
[filterFormik]
|
[filterFormik]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleApplyFilters = useCallback(() => {
|
|
||||||
handleFormSubmit(
|
|
||||||
new Event('submit') as unknown as React.FormEvent<HTMLFormElement>
|
|
||||||
);
|
|
||||||
}, [handleFormSubmit]);
|
|
||||||
|
|
||||||
const selectedRowIds = useMemo(() => {
|
const selectedRowIds = useMemo(() => {
|
||||||
return Object.keys(rowSelection)
|
return Object.keys(rowSelection)
|
||||||
.filter((key) => rowSelection[key])
|
.filter((key) => rowSelection[key])
|
||||||
@@ -1076,7 +1068,7 @@ const UniformityTable = () => {
|
|||||||
modalBox: 'rounded-2xl',
|
modalBox: 'rounded-2xl',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='flex flex-col gap-4 mt-4'>
|
<div className='flex flex-col gap-4'>
|
||||||
{createdUniformity ? (
|
{createdUniformity ? (
|
||||||
<UniformityConfirmationPreview
|
<UniformityConfirmationPreview
|
||||||
uniformityDetail={createdUniformity}
|
uniformityDetail={createdUniformity}
|
||||||
@@ -1112,7 +1104,7 @@ const UniformityTable = () => {
|
|||||||
modalBox: 'rounded-2xl',
|
modalBox: 'rounded-2xl',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='flex flex-col gap-4 mt-4'>
|
<div className='flex flex-col gap-4'>
|
||||||
<UniformityConfirmationPreview uniformity={selectedUniformity} />
|
<UniformityConfirmationPreview uniformity={selectedUniformity} />
|
||||||
</div>
|
</div>
|
||||||
</ConfirmationModal>
|
</ConfirmationModal>
|
||||||
@@ -1136,7 +1128,7 @@ const UniformityTable = () => {
|
|||||||
modalBox: 'rounded-2xl',
|
modalBox: 'rounded-2xl',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='flex flex-col gap-4 mt-4'>
|
<div className='flex flex-col gap-4'>
|
||||||
{selectedRowIds.length === 1 ? (
|
{selectedRowIds.length === 1 ? (
|
||||||
<UniformityConfirmationPreview
|
<UniformityConfirmationPreview
|
||||||
uniformity={selectedUniformities[0]}
|
uniformity={selectedUniformities[0]}
|
||||||
@@ -1168,7 +1160,7 @@ const UniformityTable = () => {
|
|||||||
modalBox: 'rounded-2xl',
|
modalBox: 'rounded-2xl',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='flex flex-col gap-4 mt-4'>
|
<div className='flex flex-col gap-4'>
|
||||||
<UniformityConfirmationPreview uniformity={selectedUniformity} />
|
<UniformityConfirmationPreview uniformity={selectedUniformity} />
|
||||||
</div>
|
</div>
|
||||||
</ConfirmationModal>
|
</ConfirmationModal>
|
||||||
@@ -1192,7 +1184,7 @@ const UniformityTable = () => {
|
|||||||
modalBox: 'rounded-2xl',
|
modalBox: 'rounded-2xl',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='flex flex-col gap-4 mt-4'>
|
<div className='flex flex-col gap-4'>
|
||||||
{selectedRowIds.length === 1 ? (
|
{selectedRowIds.length === 1 ? (
|
||||||
<UniformityConfirmationPreview
|
<UniformityConfirmationPreview
|
||||||
uniformity={selectedUniformities[0]}
|
uniformity={selectedUniformities[0]}
|
||||||
@@ -1224,7 +1216,7 @@ const UniformityTable = () => {
|
|||||||
modalBox: 'rounded-2xl',
|
modalBox: 'rounded-2xl',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='flex flex-col gap-4 mt-4'>
|
<div className='flex flex-col gap-4'>
|
||||||
{selectedRowIds.length === 1 ? (
|
{selectedRowIds.length === 1 ? (
|
||||||
<UniformityConfirmationPreview
|
<UniformityConfirmationPreview
|
||||||
uniformity={selectedUniformities[0]}
|
uniformity={selectedUniformities[0]}
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ const UniformityBarChart: React.FC<UniformityBarChartProps> = ({ data }) => {
|
|||||||
const margin = {
|
const margin = {
|
||||||
top: 20,
|
top: 20,
|
||||||
right: 30,
|
right: 30,
|
||||||
left: 20,
|
left: 0,
|
||||||
bottom: 5,
|
bottom: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ const UniformityBarChart: React.FC<UniformityBarChartProps> = ({ data }) => {
|
|||||||
<ResponsiveContainer
|
<ResponsiveContainer
|
||||||
width='100%'
|
width='100%'
|
||||||
height='100%'
|
height='100%'
|
||||||
className='min-h-[300px] xl:min-h-[350px]'
|
className='min-h-[270px] xl:min-h-72'
|
||||||
>
|
>
|
||||||
<BarChart data={data} margin={margin} barGap={20}>
|
<BarChart data={data} margin={margin} barGap={20}>
|
||||||
<defs>
|
<defs>
|
||||||
|
|||||||
@@ -65,12 +65,12 @@ const UniformityGaugeChart: React.FC<UniformityGaugeChartProps> = ({
|
|||||||
</Pie>
|
</Pie>
|
||||||
</PieChart>
|
</PieChart>
|
||||||
</ResponsiveContainer>
|
</ResponsiveContainer>
|
||||||
<div className='absolute inset-x-0 bottom-8 flex flex-col items-center justify-center'>
|
<div className='absolute inset-x-0 bottom-10 flex flex-col items-center justify-center'>
|
||||||
<span className='2xl:text-3xl text-2xl font-bold text-gray-800 mb-4'>
|
<span className='text-2xl font-medium text-base-content mb-4 leading-8'>
|
||||||
{value}%
|
{value}%
|
||||||
</span>
|
</span>
|
||||||
<div className='mt-2 px-4 py-1 bg-base-100 rounded-full shadow-sm border border-gray-200'>
|
<div className='px-3.5 py-1 bg-base-100 rounded-full shadow-sm border border-base-content/10'>
|
||||||
<span className='text-sm font-medium text-gray-700 mb-32'>
|
<span className='text-lg font-medium text-base-content leading-6'>
|
||||||
{label}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -81,7 +81,7 @@ const UniformityGaugeChart: React.FC<UniformityGaugeChartProps> = ({
|
|||||||
<button
|
<button
|
||||||
onClick={() => onWeekChange?.('prev')}
|
onClick={() => onWeekChange?.('prev')}
|
||||||
disabled={!hasPrevWeek}
|
disabled={!hasPrevWeek}
|
||||||
className='p-2 rounded-lg border border-gray-200 bg-white hover:bg-gray-50 disabled:opacity-30 disabled:cursor-not-allowed transition-colors shadow-sm'
|
className='p-1 rounded-lg border border-base-content/10 bg-white hover:bg-base-content/5 disabled:opacity-30 disabled:cursor-not-allowed transition-colors shadow-sm cursor-pointer'
|
||||||
aria-label='Previous week'
|
aria-label='Previous week'
|
||||||
>
|
>
|
||||||
<Icon icon='heroicons:chevron-left' width={20} height={20} />
|
<Icon icon='heroicons:chevron-left' width={20} height={20} />
|
||||||
@@ -89,21 +89,24 @@ const UniformityGaugeChart: React.FC<UniformityGaugeChartProps> = ({
|
|||||||
<Card
|
<Card
|
||||||
variant='bordered'
|
variant='bordered'
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'max-w-xs',
|
wrapper: 'max-w-40 rounded-lg',
|
||||||
|
body: 'p-3',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<section className='flex items-center justify-center gap-4'>
|
<section className='flex items-center justify-center gap-4'>
|
||||||
<div className='grid grid-cols-1 min-w-0 text-center'>
|
<div className='grid grid-cols-1 min-w-0 text-center'>
|
||||||
<div className='flex items-center justify-center space-x-2 text-[#18181B80] text-sm mb-1'>
|
<div className='flex items-center justify-center space-x-2 text-base-content/50 text-sm mb-1'>
|
||||||
<span className='text-[#0069E0] font-semibold truncate'>
|
<span className='text-primary font-semibold truncate'>
|
||||||
{week}
|
{week}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='text-xl font-bold text-[#18181B80]'>
|
<div className='text-xl font-bold text-base-content/50'>
|
||||||
<span className='text-[#0069E0] break-all'>
|
<span className='text-primary break-all'>
|
||||||
{formatNumber(currentValue ?? 0)}
|
{formatNumber(currentValue ?? 0)}
|
||||||
</span>
|
</span>
|
||||||
<span className='mx-1 text-gray-400 text-base'>From</span>
|
<span className='mx-1 text-base-content/50 text-sm font-semibold leading-5'>
|
||||||
|
From
|
||||||
|
</span>
|
||||||
<span className='break-all'>
|
<span className='break-all'>
|
||||||
{formatNumber(totalValue ?? 0)}
|
{formatNumber(totalValue ?? 0)}
|
||||||
</span>
|
</span>
|
||||||
@@ -114,7 +117,7 @@ const UniformityGaugeChart: React.FC<UniformityGaugeChartProps> = ({
|
|||||||
<button
|
<button
|
||||||
onClick={() => onWeekChange?.('next')}
|
onClick={() => onWeekChange?.('next')}
|
||||||
disabled={!hasNextWeek}
|
disabled={!hasNextWeek}
|
||||||
className='p-2 rounded-lg border border-gray-200 bg-white hover:bg-gray-50 disabled:opacity-30 disabled:cursor-not-allowed transition-colors shadow-sm'
|
className='p-1 rounded-lg border border-base-content/10 bg-white hover:bg-base-content/5 disabled:opacity-30 disabled:cursor-not-allowed transition-colors shadow-sm cursor-pointer'
|
||||||
aria-label='Next week'
|
aria-label='Next week'
|
||||||
>
|
>
|
||||||
<Icon icon='heroicons:chevron-right' width={20} height={20} />
|
<Icon icon='heroicons:chevron-right' width={20} height={20} />
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { ColumnDef } from '@tanstack/react-table';
|
|||||||
import Button from '@/components/Button';
|
import Button from '@/components/Button';
|
||||||
import DrawerHeader from '@/components/helper/drawer/DrawerHeader';
|
import DrawerHeader from '@/components/helper/drawer/DrawerHeader';
|
||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import Badge from '@/components/Badge';
|
import StatusBadge from '@/components/helper/StatusBadge';
|
||||||
import Tooltip from '@/components/Tooltip';
|
import Tooltip from '@/components/Tooltip';
|
||||||
import RequirePermission from '@/components/helper/RequirePermission';
|
import RequirePermission from '@/components/helper/RequirePermission';
|
||||||
import { UniformityDetail as UniformityDetailType } from '@/types/api/production/uniformity';
|
import { UniformityDetail as UniformityDetailType } from '@/types/api/production/uniformity';
|
||||||
@@ -18,8 +18,7 @@ import { UniformityApi } from '@/services/api/uniformity';
|
|||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
import {
|
import {
|
||||||
getStatusColor,
|
getStatusBadgeColor,
|
||||||
getStatusIndicatorColor,
|
|
||||||
getStatusText,
|
getStatusText,
|
||||||
} from '@/components/pages/production/uniformity/uniformity-utils';
|
} from '@/components/pages/production/uniformity/uniformity-utils';
|
||||||
import { DetailOptionType } from '@/types/api/production/uniformity';
|
import { DetailOptionType } from '@/types/api/production/uniformity';
|
||||||
@@ -150,12 +149,18 @@ const UniformityDetail: React.FC<UniformityDetailProps> = ({
|
|||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
accessorKey: 'label',
|
accessorKey: 'label',
|
||||||
header: 'Label',
|
enableSorting: false,
|
||||||
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Label</span>
|
||||||
|
),
|
||||||
cell: (props) => props.row.original.label,
|
cell: (props) => props.row.original.label,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'value',
|
accessorKey: 'value',
|
||||||
header: 'Value',
|
enableSorting: false,
|
||||||
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Value</span>
|
||||||
|
),
|
||||||
cell: (props) => {
|
cell: (props) => {
|
||||||
const id = props.row.original.id;
|
const id = props.row.original.id;
|
||||||
const { info_umum, latest_approval } = initialValues!;
|
const { info_umum, latest_approval } = initialValues!;
|
||||||
@@ -178,16 +183,10 @@ const UniformityDetail: React.FC<UniformityDetailProps> = ({
|
|||||||
if (status) {
|
if (status) {
|
||||||
return (
|
return (
|
||||||
<div className='w-full'>
|
<div className='w-full'>
|
||||||
<Badge
|
<StatusBadge
|
||||||
statusIndicator={true}
|
color={getStatusBadgeColor(status)}
|
||||||
variant='soft'
|
text={getStatusText(status)}
|
||||||
className={{
|
/>
|
||||||
badge: `rounded-xl w-full justify-start border border-gray-200 text-black ${getStatusColor(status)}`,
|
|
||||||
status: getStatusIndicatorColor(status),
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{getStatusText(status)}
|
|
||||||
</Badge>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -258,12 +257,18 @@ const UniformityDetail: React.FC<UniformityDetailProps> = ({
|
|||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
accessorKey: 'label',
|
accessorKey: 'label',
|
||||||
header: 'Label',
|
enableSorting: false,
|
||||||
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Label</span>
|
||||||
|
),
|
||||||
cell: (props) => props.row.original.label,
|
cell: (props) => props.row.original.label,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'value',
|
accessorKey: 'value',
|
||||||
header: 'Value',
|
enableSorting: false,
|
||||||
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Value</span>
|
||||||
|
),
|
||||||
cell: (props) => <span>{props.row.original.value}</span>,
|
cell: (props) => <span>{props.row.original.value}</span>,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -301,12 +306,18 @@ const UniformityDetail: React.FC<UniformityDetailProps> = ({
|
|||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
accessorKey: 'label',
|
accessorKey: 'label',
|
||||||
header: 'Label',
|
enableSorting: false,
|
||||||
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Label</span>
|
||||||
|
),
|
||||||
cell: (props) => props.row.original.label,
|
cell: (props) => props.row.original.label,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'value',
|
accessorKey: 'value',
|
||||||
header: 'Value',
|
enableSorting: false,
|
||||||
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Value</span>
|
||||||
|
),
|
||||||
cell: (props) => <span>{props.row.original.value}</span>,
|
cell: (props) => <span>{props.row.original.value}</span>,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -326,10 +337,10 @@ const UniformityDetail: React.FC<UniformityDetailProps> = ({
|
|||||||
{/* Form Section */}
|
{/* Form Section */}
|
||||||
<section className='w-full p-4'>
|
<section className='w-full p-4'>
|
||||||
{initialValues ? (
|
{initialValues ? (
|
||||||
<div className='flex flex-col gap-4'>
|
<div className='flex flex-col gap-3'>
|
||||||
{/* Info Umum */}
|
{/* Info Umum */}
|
||||||
<div className=''>
|
<div className=''>
|
||||||
<h2 className='text-base font-medium text-base-content/50 font-roboto mb-5'>
|
<h2 className='text-base font-medium text-base-content/50 font-roboto leading-6 tracking-[0.15px] mb-1.5'>
|
||||||
Informasi Umum
|
Informasi Umum
|
||||||
</h2>
|
</h2>
|
||||||
<Table<DetailOptionType>
|
<Table<DetailOptionType>
|
||||||
@@ -346,7 +357,7 @@ const UniformityDetail: React.FC<UniformityDetailProps> = ({
|
|||||||
{/* Sampling and Range */}
|
{/* Sampling and Range */}
|
||||||
{initialValues.sampling && (
|
{initialValues.sampling && (
|
||||||
<div className=''>
|
<div className=''>
|
||||||
<h2 className='text-base font-medium text-base-content/50 font-roboto mb-5'>
|
<h2 className='text-base font-medium text-base-content/50 font-roboto leading-6 tracking-[0.15px] mb-1.5'>
|
||||||
Sampling and Range
|
Sampling and Range
|
||||||
</h2>
|
</h2>
|
||||||
<Table<DetailOptionType>
|
<Table<DetailOptionType>
|
||||||
@@ -364,7 +375,7 @@ const UniformityDetail: React.FC<UniformityDetailProps> = ({
|
|||||||
{/* Result */}
|
{/* Result */}
|
||||||
{initialValues.result && (
|
{initialValues.result && (
|
||||||
<div className=''>
|
<div className=''>
|
||||||
<h2 className='text-base font-medium text-base-content/50 font-roboto mb-5'>
|
<h2 className='text-base font-medium text-base-content/50 font-roboto leading-6 tracking-[0.15px] mb-1.5'>
|
||||||
Result
|
Result
|
||||||
</h2>
|
</h2>
|
||||||
<Table<DetailOptionType>
|
<Table<DetailOptionType>
|
||||||
|
|||||||
@@ -97,10 +97,10 @@ const UniformityDetailsPreview = ({
|
|||||||
{/* Form Section */}
|
{/* Form Section */}
|
||||||
<section className='w-full p-4'>
|
<section className='w-full p-4'>
|
||||||
{info_umum ? (
|
{info_umum ? (
|
||||||
<div className='flex flex-col gap-4'>
|
<div className='flex flex-col gap-3'>
|
||||||
{/* Body Weight Details */}
|
{/* Body Weight Details */}
|
||||||
{uniformity_details && uniformity_details.length > 0 ? (
|
{uniformity_details && uniformity_details.length > 0 ? (
|
||||||
<div className='mt-4'>
|
<div className=''>
|
||||||
<Table<BodyWeightData>
|
<Table<BodyWeightData>
|
||||||
data={tableData}
|
data={tableData}
|
||||||
columns={columnsUniformity}
|
columns={columnsUniformity}
|
||||||
|
|||||||
@@ -507,11 +507,11 @@ const UniformityForm = ({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<section className='w-full p-4'>
|
<section className='w-full p-4'>
|
||||||
<h2 className='text-base font-medium text-base-content/50 font-roboto'>
|
<h2 className='text-base font-medium text-base-content/50 font-roboto mb-1.5'>
|
||||||
Informasi Umum
|
Informasi Umum
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<form onSubmit={handleFormSubmit} className='flex flex-col gap-1.5'>
|
<form onSubmit={handleFormSubmit} className='flex flex-col'>
|
||||||
<DateInput
|
<DateInput
|
||||||
required
|
required
|
||||||
label='Tanggal'
|
label='Tanggal'
|
||||||
@@ -582,7 +582,7 @@ const UniformityForm = ({
|
|||||||
<label
|
<label
|
||||||
htmlFor='file-upload-input'
|
htmlFor='file-upload-input'
|
||||||
className={cn(
|
className={cn(
|
||||||
"w-full text-sm font-normal leading-5 after:content-['*'] after:ml-0.5 after:text-red-500",
|
"w-full text-xs font-semibold leading-5 after:content-['*'] after:ml-0.5 after:text-red-500 py-2",
|
||||||
formik.touched.document &&
|
formik.touched.document &&
|
||||||
formik.errors.document &&
|
formik.errors.document &&
|
||||||
'text-red-500'
|
'text-red-500'
|
||||||
@@ -598,8 +598,8 @@ const UniformityForm = ({
|
|||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
icon='heroicons-solid:trash'
|
icon='heroicons-solid:trash'
|
||||||
width={20}
|
width={15}
|
||||||
height={20}
|
height={15}
|
||||||
className='text-gray-400 hover:text-gray-600'
|
className='text-gray-400 hover:text-gray-600'
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
@@ -611,8 +611,8 @@ const UniformityForm = ({
|
|||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
icon='heroicons:information-circle'
|
icon='heroicons:information-circle'
|
||||||
width={20}
|
width={15}
|
||||||
height={20}
|
height={15}
|
||||||
className='text-gray-400 hover:text-gray-600'
|
className='text-gray-400 hover:text-gray-600'
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -622,7 +622,7 @@ const UniformityForm = ({
|
|||||||
|
|
||||||
<section
|
<section
|
||||||
className={cn(
|
className={cn(
|
||||||
'h-full w-full border rounded-2xl border-dashed cursor-pointer mt-2',
|
'h-full w-full border rounded-2xl border-dashed cursor-pointer',
|
||||||
formik.touched.document && formik.errors.document
|
formik.touched.document && formik.errors.document
|
||||||
? 'border-red-500'
|
? 'border-red-500'
|
||||||
: 'border-gray-300'
|
: 'border-gray-300'
|
||||||
@@ -758,12 +758,12 @@ const UniformityForm = ({
|
|||||||
|
|
||||||
{!isNextStep && (
|
{!isNextStep && (
|
||||||
<>
|
<>
|
||||||
<div className='border-t border-base-content/20 mt-3' />
|
<div className='border-t border-base-content/10 -mx-4 mt-4' />
|
||||||
<RequirePermission permissions='lti.production.uniformity.create'>
|
<RequirePermission permissions='lti.production.uniformity.create'>
|
||||||
<Button
|
<Button
|
||||||
type='submit'
|
type='submit'
|
||||||
color='primary'
|
color='primary'
|
||||||
className='w-full mt-4'
|
className='w-full mt-4 px-3 py-2.5 text-sm text-base-100 rounded-lg shadow-sm'
|
||||||
disabled={formik.isSubmitting}
|
disabled={formik.isSubmitting}
|
||||||
>
|
>
|
||||||
{formik.isSubmitting ? (
|
{formik.isSubmitting ? (
|
||||||
|
|||||||
@@ -50,12 +50,16 @@ const UniformityPreviewForm = () => {
|
|||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
accessorKey: 'number',
|
accessorKey: 'number',
|
||||||
header: 'Number',
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Number</span>
|
||||||
|
),
|
||||||
cell: (props) => props.row.original.number,
|
cell: (props) => props.row.original.number,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'weight',
|
accessorKey: 'weight',
|
||||||
header: 'Weight (g)',
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Weight (g)</span>
|
||||||
|
),
|
||||||
cell: (props) => <span>{props.row.original.weight}</span>,
|
cell: (props) => <span>{props.row.original.weight}</span>,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -89,7 +93,11 @@ const UniformityPreviewForm = () => {
|
|||||||
className={{ containerClassName: 'mb-5' }}
|
className={{ containerClassName: 'mb-5' }}
|
||||||
/>
|
/>
|
||||||
<RequirePermission permissions='lti.production.uniformity.create'>
|
<RequirePermission permissions='lti.production.uniformity.create'>
|
||||||
<Button color='primary' onClick={handleNext} className='mb-10'>
|
<Button
|
||||||
|
color='primary'
|
||||||
|
onClick={handleNext}
|
||||||
|
className='mb-5 px-3 py-2.5 text-sm text-base-100 rounded-lg shadow-sm'
|
||||||
|
>
|
||||||
Next
|
Next
|
||||||
</Button>
|
</Button>
|
||||||
</RequirePermission>
|
</RequirePermission>
|
||||||
|
|||||||
@@ -120,13 +120,19 @@ const UniformityResultForm = () => {
|
|||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
accessorKey: 'label',
|
accessorKey: 'label',
|
||||||
header: 'Label',
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Label</span>
|
||||||
|
),
|
||||||
cell: (props) => props.row.original.label,
|
cell: (props) => props.row.original.label,
|
||||||
|
enableSorting: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'value',
|
accessorKey: 'value',
|
||||||
header: 'Value',
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Value</span>
|
||||||
|
),
|
||||||
cell: (props) => <span>{props.row.original.value}</span>,
|
cell: (props) => <span>{props.row.original.value}</span>,
|
||||||
|
enableSorting: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[]
|
[]
|
||||||
@@ -160,13 +166,19 @@ const UniformityResultForm = () => {
|
|||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
accessorKey: 'label',
|
accessorKey: 'label',
|
||||||
header: 'Label',
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Label</span>
|
||||||
|
),
|
||||||
cell: (props) => props.row.original.label,
|
cell: (props) => props.row.original.label,
|
||||||
|
enableSorting: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'value',
|
accessorKey: 'value',
|
||||||
header: 'Value',
|
header: () => (
|
||||||
|
<span className='font-medium text-sm leading-[150%]'>Value</span>
|
||||||
|
),
|
||||||
cell: (props) => <span>{props.row.original.value}</span>,
|
cell: (props) => <span>{props.row.original.value}</span>,
|
||||||
|
enableSorting: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[]
|
[]
|
||||||
@@ -227,7 +239,7 @@ const UniformityResultForm = () => {
|
|||||||
>
|
>
|
||||||
<Button variant='link' className='p-0 text-error' onClick={handleClose}>
|
<Button variant='link' className='p-0 text-error' onClick={handleClose}>
|
||||||
<Tooltip content='Hapus' position='left'>
|
<Tooltip content='Hapus' position='left'>
|
||||||
<Icon icon='heroicons-outline:trash' width={20} height={20} />
|
<Icon icon='heroicons-outline:trash' width={18} height={18} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Button>
|
</Button>
|
||||||
</DrawerHeader>
|
</DrawerHeader>
|
||||||
@@ -235,9 +247,9 @@ const UniformityResultForm = () => {
|
|||||||
{/* Form Section */}
|
{/* Form Section */}
|
||||||
<section className='w-full p-4'>
|
<section className='w-full p-4'>
|
||||||
{verifyUniformityResult ? (
|
{verifyUniformityResult ? (
|
||||||
<div className='flex flex-col gap-4'>
|
<div className='flex flex-col gap-3'>
|
||||||
<div className=''>
|
<div className=''>
|
||||||
<h2 className='text-base font-medium text-base-content/50 font-roboto mb-5'>
|
<h2 className='text-base font-medium text-base-content/50 font-roboto leading-6 tracking-[0.15px] mb-1.5'>
|
||||||
Sampling and Range
|
Sampling and Range
|
||||||
</h2>
|
</h2>
|
||||||
<Table<DetailOptionType>
|
<Table<DetailOptionType>
|
||||||
@@ -252,7 +264,7 @@ const UniformityResultForm = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className=''>
|
<div className=''>
|
||||||
<h2 className='text-base font-medium text-base-content/50 font-roboto mb-5'>
|
<h2 className='text-base font-medium text-base-content/50 font-roboto leading-6 tracking-[0.15px] mb-1.5'>
|
||||||
Result
|
Result
|
||||||
</h2>
|
</h2>
|
||||||
<Table<DetailOptionType>
|
<Table<DetailOptionType>
|
||||||
@@ -265,7 +277,7 @@ const UniformityResultForm = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-4'>
|
<div className=''>
|
||||||
<Table<BodyWeightData>
|
<Table<BodyWeightData>
|
||||||
data={tableData}
|
data={tableData}
|
||||||
columns={columnsUniformity}
|
columns={columnsUniformity}
|
||||||
@@ -280,7 +292,7 @@ const UniformityResultForm = () => {
|
|||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
isLoading={isSubmitting}
|
isLoading={isSubmitting}
|
||||||
disabled={!uniformityFormData}
|
disabled={!uniformityFormData}
|
||||||
className='mb-10'
|
className='mb-5 px-3 py-2.5 text-sm text-base-100 rounded-lg shadow-sm'
|
||||||
>
|
>
|
||||||
Submit
|
Submit
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,26 +1,8 @@
|
|||||||
export const weightStatusColorMap: Record<string, string> = {
|
|
||||||
ideal: 'bg-[#00D39033]',
|
|
||||||
outside: 'bg-error/10',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const weightStatusIndicatorColorMap: Record<string, string> = {
|
|
||||||
ideal: 'bg-[#008000]',
|
|
||||||
outside: 'bg-error',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const weightStatusTextMap: Record<string, string> = {
|
export const weightStatusTextMap: Record<string, string> = {
|
||||||
ideal: 'Ideal',
|
ideal: 'Ideal',
|
||||||
outside: 'Outside',
|
outside: 'Outside',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getWeightStatusColor = (status: string): string => {
|
|
||||||
return weightStatusColorMap[status] || 'bg-info';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getWeightStatusIndicatorColor = (status: string): string => {
|
|
||||||
return weightStatusIndicatorColorMap[status] || 'bg-info';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getWeightStatusText = (status: string): string => {
|
export const getWeightStatusText = (status: string): string => {
|
||||||
return weightStatusTextMap[status] || status;
|
return weightStatusTextMap[status] || status;
|
||||||
};
|
};
|
||||||
@@ -39,24 +21,6 @@ export const getWeightStatusBadgeColor = (
|
|||||||
return weightStatusBadgeColorMap[status] || 'neutral';
|
return weightStatusBadgeColorMap[status] || 'neutral';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const statusColorMap: Record<string, string> = {
|
|
||||||
APPROVED: 'bg-[#00D39033]',
|
|
||||||
Disetujui: 'bg-[#00D39033]',
|
|
||||||
REJECTED: 'bg-error/10',
|
|
||||||
Ditolak: 'bg-error/10',
|
|
||||||
CREATED: 'bg-[#f3f3f4]',
|
|
||||||
Pengajuan: 'bg-[#f3f3f4]',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const statusIndicatorColorMap: Record<string, string> = {
|
|
||||||
APPROVED: 'bg-[#008000]',
|
|
||||||
Disetujui: 'bg-[#008000]',
|
|
||||||
REJECTED: 'bg-error',
|
|
||||||
Ditolak: 'bg-error',
|
|
||||||
CREATED: 'bg-[#D9D9D9]',
|
|
||||||
Pengajuan: 'bg-[#D9D9D9]',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const statusTextMap: Record<string, string> = {
|
export const statusTextMap: Record<string, string> = {
|
||||||
APPROVED: 'Disetujui',
|
APPROVED: 'Disetujui',
|
||||||
Disetujui: 'Disetujui',
|
Disetujui: 'Disetujui',
|
||||||
@@ -66,14 +30,6 @@ export const statusTextMap: Record<string, string> = {
|
|||||||
Pengajuan: 'Pengajuan',
|
Pengajuan: 'Pengajuan',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getStatusColor = (status: string): string => {
|
|
||||||
return statusColorMap[status] || 'bg-info';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getStatusIndicatorColor = (status: string): string => {
|
|
||||||
return statusIndicatorColorMap[status] || 'bg-info';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getStatusText = (status: string): string => {
|
export const getStatusText = (status: string): string => {
|
||||||
return statusTextMap[status] || status;
|
return statusTextMap[status] || status;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user