diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index 6ec4965..09bb3c5 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -29,12 +29,25 @@ export default function TabLayout() { ( ), }} /> + ( + + ), + }} + /> + diff --git a/app/(tabs)/warning.tsx b/app/(tabs)/warning.tsx new file mode 100644 index 0000000..11c5d91 --- /dev/null +++ b/app/(tabs)/warning.tsx @@ -0,0 +1,35 @@ +import { Platform, ScrollView, StyleSheet, Text, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; + +export default function Warning() { + return ( + + + + Danh sách cảnh báo + + + + ); +} + +const styles = StyleSheet.create({ + scrollContent: { + flexGrow: 1, + }, + container: { + alignItems: "center", + padding: 15, + }, + titleText: { + fontSize: 32, + fontWeight: "700", + lineHeight: 40, + marginBottom: 10, + fontFamily: Platform.select({ + ios: "System", + android: "Roboto", + default: "System", + }), + }, +}); diff --git a/components/tripInfo/NetListTable.tsx b/components/tripInfo/NetListTable.tsx new file mode 100644 index 0000000..90d6b24 --- /dev/null +++ b/components/tripInfo/NetListTable.tsx @@ -0,0 +1,157 @@ +import { IconSymbol } from "@/components/ui/icon-symbol"; +import React, { useRef, useState } from "react"; +import { + Animated, + Platform, + Text, + TouchableOpacity, + UIManager, + View, +} from "react-native"; +import styles from "./style/NetListTable.styles"; + +// --------------------------- +// 🧩 Interface +// --------------------------- +interface NetItem { + id: string; + stt: string; + trangThai: string; +} + +// --------------------------- +// 🧵 Dữ liệu mẫu +// --------------------------- +const data: NetItem[] = [ + { id: "1", stt: "Mẻ 3", trangThai: "Đã hoàn thành" }, + { id: "2", stt: "Mẻ 2", trangThai: "Đã hoàn thành" }, + { id: "3", stt: "Mẻ 1", trangThai: "Đã hoàn thành" }, +]; + +const NetListTable: React.FC = () => { + // Bật animation cho Android + if ( + Platform.OS === "android" && + UIManager.setLayoutAnimationEnabledExperimental + ) { + UIManager.setLayoutAnimationEnabledExperimental(true); + } + + const [collapsed, setCollapsed] = useState(true); + const [contentHeight, setContentHeight] = useState(0); + const animatedHeight = useRef(new Animated.Value(0)).current; + const tongSoMe = data.length; + + const handleToggle = () => { + const toValue = collapsed ? contentHeight : 0; + Animated.timing(animatedHeight, { + toValue, + duration: 300, + useNativeDriver: false, + }).start(); + setCollapsed((prev) => !prev); + }; + + return ( + + {/* Header toggle */} + + Danh sách mẻ lưới + {collapsed && {tongSoMe}} + + + + {/* Nội dung ẩn để đo chiều cao */} + { + const height = event.nativeEvent.layout.height; + if (height > 0 && contentHeight === 0) { + setContentHeight(height); + } + }} + > + {/* Header */} + + STT + Trạng thái + + Thao tác + + + + {/* Body */} + {data.map((item) => ( + + {/* Cột STT */} + {item.stt} + + {/* Cột Trạng thái */} + + + {item.trangThai} + + + {/* Cột Thao tác */} + + + + + + ))} + + + {/* Bảng hiển thị với animation */} + + {/* Header */} + + STT + Trạng thái + + Thao tác + + + + {/* Body */} + {data.map((item) => ( + + {/* Cột STT */} + {item.stt} + + {/* Cột Trạng thái */} + + + {item.trangThai} + + + {/* Cột Thao tác */} + + + + + + ))} + + + ); +}; + +export default NetListTable; diff --git a/components/tripInfo/style/CrewListTable.styles.ts b/components/tripInfo/style/CrewListTable.styles.ts index 907334a..bdb971d 100644 --- a/components/tripInfo/style/CrewListTable.styles.ts +++ b/components/tripInfo/style/CrewListTable.styles.ts @@ -21,7 +21,7 @@ export default StyleSheet.create({ }, title: { fontSize: 18, - fontWeight: "600", + fontWeight: "700", }, totalCollapsed: { color: "#ff6600", diff --git a/components/tripInfo/style/NetListTable.styles.ts b/components/tripInfo/style/NetListTable.styles.ts new file mode 100644 index 0000000..67adf6c --- /dev/null +++ b/components/tripInfo/style/NetListTable.styles.ts @@ -0,0 +1,80 @@ +import { StyleSheet } from "react-native"; + +export default StyleSheet.create({ + container: { + width: "100%", + backgroundColor: "#fff", + borderRadius: 10, + padding: 12, + marginVertical: 10, + borderWidth: 1, + borderColor: "#eee", + shadowColor: "#000", + shadowOpacity: 0.05, + shadowRadius: 4, + elevation: 1, + }, + headerRow: { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + }, + title: { + fontSize: 18, + fontWeight: "700", + }, + totalCollapsed: { + color: "#ff6600", + fontSize: 18, + fontWeight: "700", + textAlign: "center", + }, + row: { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + paddingVertical: 8, + borderBottomWidth: 0.6, + borderBottomColor: "#eee", + }, + tableHeader: { + backgroundColor: "#fafafa", + borderRadius: 6, + marginTop: 10, + }, + cell: { + flex: 1, + fontSize: 15, + color: "#111", + textAlign: "center", + }, + left: { + textAlign: "left", + }, + right: { + textAlign: "right", + }, + headerText: { + fontWeight: "600", + }, + statusContainer: { + flexDirection: "row", + alignItems: "center", + justifyContent: "center", + }, + statusDot: { + width: 8, + height: 8, + borderRadius: 4, + backgroundColor: "#2ecc71", + marginRight: 6, + }, + statusText: { + fontSize: 15, + color: "#111", + }, + actions: { + flexDirection: "row", + justifyContent: "flex-end", + }, +}); diff --git a/components/ui/icon-symbol.tsx b/components/ui/icon-symbol.tsx index 6557c59..b14bac8 100644 --- a/components/ui/icon-symbol.tsx +++ b/components/ui/icon-symbol.tsx @@ -25,6 +25,7 @@ const MAPPING = { "map.fill": "map", "arrowshape.down.fill": "arrow-drop-down", "arrowshape.up.fill": "arrow-drop-up", + "exclamationmark.triangle.fill": "warning", } as IconMapping; /**