import React, { useState } from "react"; import { View, Text, TouchableOpacity, StyleSheet, Platform, TextInput, Modal, ScrollView, } from "react-native"; import { Ionicons } from "@expo/vector-icons"; import { useI18n } from "@/hooks/use-i18n"; import { useThemeContext } from "@/hooks/use-theme-context"; interface TripCost { id: string; type: string; amount: number; unit: string; cost_per_unit: number; total_cost: number; } interface MaterialCostListProps { items: TripCost[]; onChange: (items: TripCost[]) => void; } // Predefined cost types const COST_TYPES = [ { value: "fuel", label: "Nhiên liệu" }, { value: "food", label: "Thực phẩm" }, { value: "crew_salary", label: "Lương thuyền viên" }, { value: "ice_salt_cost", label: "Muối đá" }, { value: "other", label: "Khác" }, ]; export default function MaterialCostList({ items, onChange, }: MaterialCostListProps) { const { t } = useI18n(); const { colors } = useThemeContext(); const [typeDropdownVisible, setTypeDropdownVisible] = useState(null); const handleAddMaterial = () => { const newMaterial: TripCost = { id: Date.now().toString(), type: "", amount: 0, unit: "", cost_per_unit: 0, total_cost: 0, }; onChange([...items, newMaterial]); }; const handleRemoveMaterial = (id: string) => { onChange(items.filter((item) => item.id !== id)); }; const handleDuplicateMaterial = (material: TripCost) => { const duplicatedMaterial: TripCost = { id: Date.now().toString(), type: material.type, amount: material.amount, unit: material.unit, cost_per_unit: material.cost_per_unit, total_cost: material.total_cost, }; onChange([...items, duplicatedMaterial]); }; const handleUpdateMaterial = (id: string, field: keyof TripCost, value: string | number) => { onChange( items.map((item) => { if (item.id === id) { const updatedItem = { ...item, [field]: value }; // Auto-calculate total_cost when amount or cost_per_unit changes if (field === "amount" || field === "cost_per_unit") { const amount = field === "amount" ? Number(value) : item.amount; const costPerUnit = field === "cost_per_unit" ? Number(value) : item.cost_per_unit; updatedItem.total_cost = amount * costPerUnit; } return updatedItem; } return item; }) ); }; const getTypeLabel = (value: string) => { const type = COST_TYPES.find((t) => t.value === value); return type ? type.label : value || t("diary.selectType"); }; const formatCurrency = (amount: number) => { return new Intl.NumberFormat("vi-VN").format(amount); }; const themedStyles = { sectionTitle: { color: colors.text }, fieldLabel: { color: colors.text }, input: { backgroundColor: colors.card, borderColor: colors.border, color: colors.text, }, dropdown: { backgroundColor: colors.card, borderColor: colors.border, }, dropdownText: { color: colors.text }, placeholder: { color: colors.textSecondary }, addButton: { borderColor: colors.primary, }, addButtonText: { color: colors.primary }, modalOverlay: { backgroundColor: "rgba(0, 0, 0, 0.5)", }, modalContent: { backgroundColor: colors.card, }, option: { borderBottomColor: colors.separator, }, optionText: { color: colors.text }, }; return ( {t("diary.materialCostList")} {/* Cost Items List */} {items.map((cost) => ( {/* Type Dropdown */} {t("diary.costType")} setTypeDropdownVisible(cost.id)} activeOpacity={0.7} > {getTypeLabel(cost.type)} {/* Type Dropdown Modal */} setTypeDropdownVisible(null)} > setTypeDropdownVisible(null)} > {COST_TYPES.map((type) => ( { handleUpdateMaterial(cost.id, "type", type.value); setTypeDropdownVisible(null); }} > {type.label} {cost.type === type.value && ( )} ))} {/* Amount Input */} {t("diary.amount")} handleUpdateMaterial(cost.id, "amount", Number(value) || 0) } placeholder="0" placeholderTextColor={colors.textSecondary} keyboardType="numeric" /> {/* Unit Input */} {t("diary.unit")} handleUpdateMaterial(cost.id, "unit", value) } placeholder={t("diary.unitPlaceholder")} placeholderTextColor={colors.textSecondary} /> {/* Cost Per Unit Input */} {t("diary.costPerUnit")} handleUpdateMaterial( cost.id, "cost_per_unit", Number(value) || 0 ) } placeholder="0" placeholderTextColor={colors.textSecondary} keyboardType="numeric" /> {/* Total Cost (Read-only, auto-calculated) */} {t("diary.totalCost")} {formatCurrency(cost.total_cost)} {/* Action Buttons */} handleDuplicateMaterial(cost)} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} > handleRemoveMaterial(cost.id)} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} > ))} {/* Add Button */} {t("diary.addMaterialCost")} ); } const styles = StyleSheet.create({ container: { marginBottom: 20, }, sectionTitle: { fontSize: 16, fontWeight: "700", marginBottom: 16, fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System", }), }, costRow: { marginBottom: 20, paddingBottom: 16, borderBottomWidth: 1, borderBottomColor: "#E5E5E5", }, formRow: { flexDirection: "row", alignItems: "flex-end", gap: 12, marginBottom: 12, }, inputGroup: { flex: 1, }, typeGroup: { flex: 1.5, }, smallGroup: { flex: 0.8, }, mediumGroup: { flex: 1, }, fieldLabel: { fontSize: 14, fontWeight: "500", marginBottom: 6, fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System", }), }, input: { borderWidth: 1, borderRadius: 8, paddingHorizontal: 12, paddingVertical: 10, fontSize: 15, fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System", }), }, smallInput: {}, mediumInput: {}, dropdown: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", borderWidth: 1, borderRadius: 8, paddingHorizontal: 12, paddingVertical: 10, }, dropdownText: { fontSize: 15, flex: 1, fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System", }), }, readOnlyInput: { justifyContent: "center", opacity: 0.7, }, readOnlyText: { fontSize: 15, fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System", }), }, actionButtons: { flexDirection: "row", gap: 12, alignItems: "center", paddingBottom: 10, }, addButton: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 8, paddingVertical: 12, paddingHorizontal: 16, borderWidth: 1.5, borderRadius: 8, borderStyle: "dashed", marginTop: 4, }, addButtonText: { fontSize: 14, fontWeight: "600", fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System", }), }, // Modal styles modalOverlay: { flex: 1, justifyContent: "center", alignItems: "center", }, modalContent: { borderRadius: 12, width: "80%", maxHeight: "50%", overflow: "hidden", shadowColor: "#000", shadowOffset: { width: 0, height: 4, }, shadowOpacity: 0.3, shadowRadius: 8, elevation: 8, }, option: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", paddingHorizontal: 20, paddingVertical: 16, borderBottomWidth: 1, }, optionText: { fontSize: 16, fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System", }), }, });