update tab warning, update CrewListTable, NetListTable
This commit is contained in:
@@ -29,12 +29,25 @@ export default function TabLayout() {
|
|||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="tripInfo"
|
name="tripInfo"
|
||||||
options={{
|
options={{
|
||||||
title: "Thông Tin Chuyến Đi",
|
title: "Chuyến Đi",
|
||||||
tabBarIcon: ({ color }) => (
|
tabBarIcon: ({ color }) => (
|
||||||
<IconSymbol size={28} name="ferry.fill" color={color} />
|
<IconSymbol size={28} name="ferry.fill" color={color} />
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="warning"
|
||||||
|
options={{
|
||||||
|
title: "Cảnh báo",
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<IconSymbol
|
||||||
|
size={28}
|
||||||
|
name="exclamationmark.triangle.fill"
|
||||||
|
color={color}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="setting"
|
name="setting"
|
||||||
options={{
|
options={{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import CrewListTable from "@/components/tripInfo/CrewListTable";
|
import CrewListTable from "@/components/tripInfo/CrewListTable";
|
||||||
import FishingToolsTable from "@/components/tripInfo/FishingToolsList";
|
import FishingToolsTable from "@/components/tripInfo/FishingToolsList";
|
||||||
|
import NetListTable from "@/components/tripInfo/NetListTable";
|
||||||
import TripCostTable from "@/components/tripInfo/TripCostTable";
|
import TripCostTable from "@/components/tripInfo/TripCostTable";
|
||||||
import { Platform, ScrollView, StyleSheet, Text, View } from "react-native";
|
import { Platform, ScrollView, StyleSheet, Text, View } from "react-native";
|
||||||
import { SafeAreaView } from "react-native-safe-area-context";
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
@@ -13,6 +14,7 @@ export default function TripInfoScreen() {
|
|||||||
<TripCostTable />
|
<TripCostTable />
|
||||||
<FishingToolsTable />
|
<FishingToolsTable />
|
||||||
<CrewListTable />
|
<CrewListTable />
|
||||||
|
<NetListTable />
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
|
|||||||
35
app/(tabs)/warning.tsx
Normal file
35
app/(tabs)/warning.tsx
Normal file
@@ -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 (
|
||||||
|
<SafeAreaView style={{ flex: 1 }}>
|
||||||
|
<ScrollView contentContainerStyle={styles.scrollContent}>
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.titleText}>Danh sách cảnh báo</Text>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
157
components/tripInfo/NetListTable.tsx
Normal file
157
components/tripInfo/NetListTable.tsx
Normal file
@@ -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<number>(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 (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header toggle */}
|
||||||
|
<TouchableOpacity
|
||||||
|
activeOpacity={0.7}
|
||||||
|
onPress={handleToggle}
|
||||||
|
style={styles.headerRow}
|
||||||
|
>
|
||||||
|
<Text style={styles.title}>Danh sách mẻ lưới</Text>
|
||||||
|
{collapsed && <Text style={styles.totalCollapsed}>{tongSoMe}</Text>}
|
||||||
|
<IconSymbol
|
||||||
|
name={collapsed ? "arrowshape.down.fill" : "arrowshape.up.fill"}
|
||||||
|
size={16}
|
||||||
|
color="#000"
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* Nội dung ẩn để đo chiều cao */}
|
||||||
|
<View
|
||||||
|
style={{ position: "absolute", opacity: 0, zIndex: -1000 }}
|
||||||
|
onLayout={(event) => {
|
||||||
|
const height = event.nativeEvent.layout.height;
|
||||||
|
if (height > 0 && contentHeight === 0) {
|
||||||
|
setContentHeight(height);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={[styles.row, styles.tableHeader]}>
|
||||||
|
<Text style={[styles.cell, styles.left, styles.headerText]}>STT</Text>
|
||||||
|
<Text style={[styles.cell, styles.headerText]}>Trạng thái</Text>
|
||||||
|
<Text style={[styles.cell, styles.right, styles.headerText]}>
|
||||||
|
Thao tác
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Body */}
|
||||||
|
{data.map((item) => (
|
||||||
|
<View key={item.id} style={styles.row}>
|
||||||
|
{/* Cột STT */}
|
||||||
|
<Text style={[styles.cell, styles.left]}>{item.stt}</Text>
|
||||||
|
|
||||||
|
{/* Cột Trạng thái */}
|
||||||
|
<View style={[styles.cell, styles.statusContainer]}>
|
||||||
|
<View style={styles.statusDot} />
|
||||||
|
<Text style={styles.statusText}>{item.trangThai}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Cột Thao tác */}
|
||||||
|
<View style={[styles.cell, styles.actions]}>
|
||||||
|
<IconSymbol name="eye" size={16} color="#333" />
|
||||||
|
<IconSymbol
|
||||||
|
name="square.and.pencil"
|
||||||
|
size={16}
|
||||||
|
color="#333"
|
||||||
|
style={{ marginLeft: 10 }}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Bảng hiển thị với animation */}
|
||||||
|
<Animated.View style={{ height: animatedHeight, overflow: "hidden" }}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={[styles.row, styles.tableHeader]}>
|
||||||
|
<Text style={[styles.cell, styles.left, styles.headerText]}>STT</Text>
|
||||||
|
<Text style={[styles.cell, styles.headerText]}>Trạng thái</Text>
|
||||||
|
<Text style={[styles.cell, styles.right, styles.headerText]}>
|
||||||
|
Thao tác
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Body */}
|
||||||
|
{data.map((item) => (
|
||||||
|
<View key={item.id} style={styles.row}>
|
||||||
|
{/* Cột STT */}
|
||||||
|
<Text style={[styles.cell, styles.left]}>{item.stt}</Text>
|
||||||
|
|
||||||
|
{/* Cột Trạng thái */}
|
||||||
|
<View style={[styles.cell, styles.statusContainer]}>
|
||||||
|
<View style={styles.statusDot} />
|
||||||
|
<Text style={styles.statusText}>{item.trangThai}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Cột Thao tác */}
|
||||||
|
<View style={[styles.cell, styles.actions]}>
|
||||||
|
<IconSymbol name="eye" size={16} color="#333" />
|
||||||
|
<IconSymbol
|
||||||
|
name="square.and.pencil"
|
||||||
|
size={16}
|
||||||
|
color="#333"
|
||||||
|
style={{ marginLeft: 10 }}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</Animated.View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NetListTable;
|
||||||
@@ -21,7 +21,7 @@ export default StyleSheet.create({
|
|||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: "600",
|
fontWeight: "700",
|
||||||
},
|
},
|
||||||
totalCollapsed: {
|
totalCollapsed: {
|
||||||
color: "#ff6600",
|
color: "#ff6600",
|
||||||
|
|||||||
80
components/tripInfo/style/NetListTable.styles.ts
Normal file
80
components/tripInfo/style/NetListTable.styles.ts
Normal file
@@ -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",
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -25,6 +25,7 @@ const MAPPING = {
|
|||||||
"map.fill": "map",
|
"map.fill": "map",
|
||||||
"arrowshape.down.fill": "arrow-drop-down",
|
"arrowshape.down.fill": "arrow-drop-down",
|
||||||
"arrowshape.up.fill": "arrow-drop-up",
|
"arrowshape.up.fill": "arrow-drop-up",
|
||||||
|
"exclamationmark.triangle.fill": "warning",
|
||||||
} as IconMapping;
|
} as IconMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user