update login, modal detail in tripInfo

This commit is contained in:
2025-11-01 19:47:45 +07:00
parent eea1482a88
commit 52d2f0f78b
11 changed files with 674 additions and 22 deletions

View File

@@ -0,0 +1,222 @@
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;