223 lines
7.2 KiB
TypeScript
223 lines
7.2 KiB
TypeScript
import { IconSymbol } from "@/components/ui/icon-symbol";
|
|
import React, { useState } from "react";
|
|
import {
|
|
KeyboardAvoidingView,
|
|
Modal,
|
|
Platform,
|
|
ScrollView,
|
|
Text,
|
|
TextInput,
|
|
TouchableOpacity,
|
|
View,
|
|
} from "react-native";
|
|
import styles from "./style/TripCostDetailModal.styles";
|
|
|
|
// ---------------------------
|
|
// 🧩 Interface
|
|
// ---------------------------
|
|
interface CostItem {
|
|
id: string;
|
|
loai: string;
|
|
soLuong: number;
|
|
donVi: string;
|
|
chiPhi: number;
|
|
tongChiPhi: number;
|
|
}
|
|
|
|
interface TripCostDetailModalProps {
|
|
visible: boolean;
|
|
onClose: () => void;
|
|
data: CostItem[];
|
|
}
|
|
|
|
// ---------------------------
|
|
// 💰 Component Modal
|
|
// ---------------------------
|
|
const TripCostDetailModal: React.FC<TripCostDetailModalProps> = ({
|
|
visible,
|
|
onClose,
|
|
data,
|
|
}) => {
|
|
const [isEditing, setIsEditing] = useState(false);
|
|
const [editableData, setEditableData] = useState<CostItem[]>(data);
|
|
|
|
const tongCong = editableData.reduce((sum, item) => sum + item.tongChiPhi, 0);
|
|
|
|
const handleEdit = () => {
|
|
setIsEditing(!isEditing);
|
|
};
|
|
|
|
const handleSave = () => {
|
|
setIsEditing(false);
|
|
// TODO: Save data to backend
|
|
// console.log("Saved data:", editableData);
|
|
};
|
|
|
|
const handleCancel = () => {
|
|
setIsEditing(false);
|
|
setEditableData(data); // Reset to original data
|
|
};
|
|
|
|
const updateItem = (id: string, field: keyof CostItem, value: string) => {
|
|
setEditableData((prev) =>
|
|
prev.map((item) => {
|
|
if (item.id === id) {
|
|
const numValue =
|
|
field === "loai" || field === "donVi" ? value : Number(value) || 0;
|
|
const updated = { ...item, [field]: numValue };
|
|
// Recalculate tongChiPhi
|
|
if (field === "soLuong" || field === "chiPhi") {
|
|
updated.tongChiPhi = updated.soLuong * updated.chiPhi;
|
|
}
|
|
return updated;
|
|
}
|
|
return item;
|
|
})
|
|
);
|
|
};
|
|
|
|
return (
|
|
<Modal
|
|
visible={visible}
|
|
animationType="slide"
|
|
presentationStyle="pageSheet"
|
|
onRequestClose={onClose}
|
|
>
|
|
<KeyboardAvoidingView
|
|
style={{ flex: 1 }}
|
|
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
|
keyboardVerticalOffset={60}
|
|
>
|
|
<View style={styles.container}>
|
|
{/* Header */}
|
|
<View style={styles.header}>
|
|
<Text style={styles.title}>Chi tiết chi phí chuyến đi</Text>
|
|
<View style={styles.headerButtons}>
|
|
{isEditing ? (
|
|
<>
|
|
<TouchableOpacity
|
|
onPress={handleCancel}
|
|
style={styles.cancelButton}
|
|
>
|
|
<Text style={styles.cancelButtonText}>Hủy</Text>
|
|
</TouchableOpacity>
|
|
<TouchableOpacity
|
|
onPress={handleSave}
|
|
style={styles.saveButton}
|
|
>
|
|
<Text style={styles.saveButtonText}>Lưu</Text>
|
|
</TouchableOpacity>
|
|
</>
|
|
) : (
|
|
<TouchableOpacity
|
|
onPress={handleEdit}
|
|
style={styles.editButton}
|
|
>
|
|
<View style={styles.editIconButton}>
|
|
<IconSymbol
|
|
name="pencil"
|
|
size={28}
|
|
color="#fff"
|
|
weight="heavy"
|
|
/>
|
|
</View>
|
|
</TouchableOpacity>
|
|
)}
|
|
<TouchableOpacity onPress={onClose} style={styles.closeButton}>
|
|
<View style={styles.closeIconButton}>
|
|
<IconSymbol name="xmark" size={28} color="#fff" />
|
|
</View>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Content */}
|
|
<ScrollView style={styles.content}>
|
|
{editableData.map((item) => (
|
|
<View key={item.id} style={styles.itemCard}>
|
|
{/* Loại */}
|
|
<View style={styles.fieldGroup}>
|
|
<Text style={styles.label}>Loại chi phí</Text>
|
|
<TextInput
|
|
style={[styles.input, !isEditing && styles.inputDisabled]}
|
|
value={item.loai}
|
|
onChangeText={(value) => updateItem(item.id, "loai", value)}
|
|
editable={isEditing}
|
|
placeholder="Nhập loại chi phí"
|
|
/>
|
|
</View>
|
|
|
|
{/* Số lượng & Đơn vị */}
|
|
<View style={styles.rowGroup}>
|
|
<View
|
|
style={[styles.fieldGroup, { flex: 1, marginRight: 8 }]}
|
|
>
|
|
<Text style={styles.label}>Số lượng</Text>
|
|
<TextInput
|
|
style={[styles.input, !isEditing && styles.inputDisabled]}
|
|
value={String(item.soLuong)}
|
|
onChangeText={(value) =>
|
|
updateItem(item.id, "soLuong", value)
|
|
}
|
|
editable={isEditing}
|
|
keyboardType="numeric"
|
|
placeholder="0"
|
|
/>
|
|
</View>
|
|
<View style={[styles.fieldGroup, { flex: 1, marginLeft: 8 }]}>
|
|
<Text style={styles.label}>Đơn vị</Text>
|
|
<TextInput
|
|
style={[styles.input, !isEditing && styles.inputDisabled]}
|
|
value={item.donVi}
|
|
onChangeText={(value) =>
|
|
updateItem(item.id, "donVi", value)
|
|
}
|
|
editable={isEditing}
|
|
placeholder="kg, lít..."
|
|
/>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Chi phí/đơn vị */}
|
|
<View style={styles.fieldGroup}>
|
|
<Text style={styles.label}>Chi phí/đơn vị (VNĐ)</Text>
|
|
<TextInput
|
|
style={[styles.input, !isEditing && styles.inputDisabled]}
|
|
value={String(item.chiPhi)}
|
|
onChangeText={(value) =>
|
|
updateItem(item.id, "chiPhi", value)
|
|
}
|
|
editable={isEditing}
|
|
keyboardType="numeric"
|
|
placeholder="0"
|
|
/>
|
|
</View>
|
|
|
|
{/* Tổng chi phí */}
|
|
<View style={styles.fieldGroup}>
|
|
<Text style={styles.label}>Tổng chi phí</Text>
|
|
<View style={styles.totalContainer}>
|
|
<Text style={styles.totalText}>
|
|
{item.tongChiPhi.toLocaleString()} VNĐ
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
))}
|
|
|
|
{/* Footer Total */}
|
|
<View style={styles.footerTotal}>
|
|
<Text style={styles.footerLabel}>Tổng cộng</Text>
|
|
<Text style={styles.footerAmount}>
|
|
{tongCong.toLocaleString()} VNĐ
|
|
</Text>
|
|
</View>
|
|
</ScrollView>
|
|
</View>
|
|
</KeyboardAvoidingView>
|
|
</Modal>
|
|
);
|
|
};
|
|
|
|
export default TripCostDetailModal;
|