feat(FE): Add constants transformation utilities and API service

This commit is contained in:
rstubryan
2026-03-02 09:57:21 +07:00
parent 04b5a7bd4d
commit aa1ef7a559
3 changed files with 237 additions and 0 deletions
+126
View File
@@ -3,6 +3,12 @@ import 'moment/locale/id';
import { twMerge } from 'tailwind-merge';
import clsx, { ClassValue } from 'clsx';
import { SidebarMenuItem } from '@/components/molecules/SidebarMenu';
import { OptionType } from '@/components/input/SelectInput';
import {
ConstantsApiResponse,
ProductFlagMappingUI,
TransformedConstants,
} from '@/types/api/constants/constants';
// set locale globally
moment.locale('id');
@@ -179,3 +185,123 @@ export function findMenuPath(
return null;
}
/**
* Transform a string value to OptionType with formatted label
* Example: "AYAM-AFKIR" -> { label: "Ayam Afkir", value: "AYAM-AFKIR" }
*/
export function toOption(value: string): OptionType {
return {
value,
label: formatConstantLabel(value),
};
}
/**
* Format constant label by:
* 1. Replacing underscores/hyphens with spaces
* 2. Converting to title case
* 3. Handling special cases
*/
export function formatConstantLabel(value: string): string {
const specialCases: Record<string, string> = {
'PRE-STARTER': 'Pre Starter',
BOP: 'BOP',
SAPRONAK: 'SAPRONAK',
OVK: 'OVK',
DOC: 'DOC',
};
if (specialCases[value]) {
return specialCases[value];
}
const withSpaces = value.replace(/[-_]/g, ' ');
return formatTitleCase(withSpaces);
}
/**
* Transform product_flag_mapping from API format to UI format
*/
export function transformProductFlagMapping(
mapping: ConstantsApiResponse['product_flag_mapping']
): ProductFlagMappingUI {
return {
flags: mapping.flags.map(toOption),
options: mapping.options.map((opt) => ({
flag: toOption(opt.flag),
sub_flags: opt.sub_flags.map(toOption),
allow_without_sub_flag: opt.allow_without_sub_flag,
})),
sub_flag_to_flag: mapping.sub_flag_to_flag,
};
}
/**
* Transform approval workflows from API format to UI format
*/
export function transformApprovalWorkflows(
workflows: ConstantsApiResponse['approval_workflows']
) {
return workflows.map((workflow) => ({
key: workflow.key,
steps: workflow.steps.map((step) => ({
value: String(step.step_number),
label: step.step_name,
})),
}));
}
/**
* Transform adjustment transaction subtypes from API format to UI format
*/
export function transformAdjustmentSubtypes(
subtypes: ConstantsApiResponse['adjustment']['transaction_subtypes']
) {
return {
RECORDING: subtypes.RECORDING.map(toOption),
PENJUALAN: subtypes.PENJUALAN.map(toOption),
PEMBELIAN: subtypes.PEMBELIAN.map(toOption),
};
}
/**
* Transform legacy flag aliases from API format to UI format
*/
export function transformLegacyFlagAliases(
aliases: ConstantsApiResponse['legacy_flag_aliases']
): OptionType[] {
return Object.entries(aliases).map(([key, value]) => ({
value: key,
label: formatConstantLabel(key),
}));
}
/**
* Transform the entire constants API response to UI format
*/
export function transformConstants(
data: ConstantsApiResponse
): TransformedConstants {
return {
warehouse_types: data.warehouse_types.map(toOption),
supplier_categories: data.supplier_categories.map(toOption),
customer_supplier_types: data.customer_supplier_types.map(toOption),
adjustment: {
transaction_subtypes: transformAdjustmentSubtypes(
data.adjustment.transaction_subtypes
),
},
approval_workflows: transformApprovalWorkflows(data.approval_workflows),
flags: data.flags.map(toOption),
product_flag_mapping: transformProductFlagMapping(
data.product_flag_mapping
),
legacy_flag_aliases: transformLegacyFlagAliases(data.legacy_flag_aliases),
stock_log: {
log_types: data.stock_log.log_types.map(toOption),
transaction_types: data.stock_log.transaction_types.map(toOption),
},
};
}