update login, detail table in tripInfo
This commit is contained in:
@@ -10,9 +10,10 @@ import {
|
|||||||
} from "@/utils/storage";
|
} from "@/utils/storage";
|
||||||
import { parseJwtToken } from "@/utils/token";
|
import { parseJwtToken } from "@/utils/token";
|
||||||
import { useRouter } from "expo-router";
|
import { useRouter } from "expo-router";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
|
Image,
|
||||||
KeyboardAvoidingView,
|
KeyboardAvoidingView,
|
||||||
Platform,
|
Platform,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
@@ -98,9 +99,23 @@ export default function LoginScreen() {
|
|||||||
<ThemedView style={styles.container}>
|
<ThemedView style={styles.container}>
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<View style={styles.headerContainer}>
|
<View style={styles.headerContainer}>
|
||||||
|
{/* Logo */}
|
||||||
|
<Image
|
||||||
|
source={require("@/assets/images/logo.png")}
|
||||||
|
style={styles.logo}
|
||||||
|
resizeMode="contain"
|
||||||
|
/>
|
||||||
<ThemedText type="title" style={styles.title}>
|
<ThemedText type="title" style={styles.title}>
|
||||||
SGW App
|
Hệ thống giám sát tàu cá
|
||||||
</ThemedText>
|
</ThemedText>
|
||||||
|
{/* Owner Logo */}
|
||||||
|
<View style={styles.ownerContainer}>
|
||||||
|
<Image
|
||||||
|
source={require("@/assets/images/owner.png")}
|
||||||
|
style={styles.ownerLogo}
|
||||||
|
resizeMode="contain"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
<ThemedText style={styles.subtitle}>
|
<ThemedText style={styles.subtitle}>
|
||||||
Đăng nhập để tiếp tục
|
Đăng nhập để tiếp tục
|
||||||
</ThemedText>
|
</ThemedText>
|
||||||
@@ -160,6 +175,13 @@ export default function LoginScreen() {
|
|||||||
<Text style={styles.linkText}>Đăng ký ngay</Text>
|
<Text style={styles.linkText}>Đăng ký ngay</Text>
|
||||||
</ThemedText>
|
</ThemedText>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{/* Copyright */}
|
||||||
|
<View style={styles.copyrightContainer}>
|
||||||
|
<ThemedText style={styles.copyrightText}>
|
||||||
|
© {new Date().getFullYear()} - Sản phẩm của Mobifone
|
||||||
|
</ThemedText>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
@@ -181,8 +203,13 @@ const styles = StyleSheet.create({
|
|||||||
marginBottom: 40,
|
marginBottom: 40,
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
},
|
},
|
||||||
|
logo: {
|
||||||
|
width: 120,
|
||||||
|
height: 120,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
title: {
|
title: {
|
||||||
fontSize: 32,
|
fontSize: 28,
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
marginBottom: 8,
|
marginBottom: 8,
|
||||||
},
|
},
|
||||||
@@ -236,4 +263,20 @@ const styles = StyleSheet.create({
|
|||||||
color: "#007AFF",
|
color: "#007AFF",
|
||||||
fontWeight: "600",
|
fontWeight: "600",
|
||||||
},
|
},
|
||||||
|
ownerContainer: {
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
ownerLogo: {
|
||||||
|
width: 150,
|
||||||
|
height: 50,
|
||||||
|
},
|
||||||
|
copyrightContainer: {
|
||||||
|
marginTop: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
copyrightText: {
|
||||||
|
fontSize: 12,
|
||||||
|
opacity: 0.6,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
BIN
assets/images/logo.png
Normal file
BIN
assets/images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
assets/images/owner.png
Normal file
BIN
assets/images/owner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
@@ -17,6 +17,12 @@ interface CrewMember {
|
|||||||
// ⚓ Dữ liệu mẫu
|
// ⚓ Dữ liệu mẫu
|
||||||
// ---------------------------
|
// ---------------------------
|
||||||
const data: CrewMember[] = [
|
const data: CrewMember[] = [
|
||||||
|
{
|
||||||
|
id: "10",
|
||||||
|
maDinhDanh: "ChuTau",
|
||||||
|
ten: "Nguyễn Nhật Minh",
|
||||||
|
chucVu: "Chủ tàu",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "1",
|
id: "1",
|
||||||
maDinhDanh: "TV001",
|
maDinhDanh: "TV001",
|
||||||
@@ -43,6 +49,10 @@ const CrewListTable: React.FC = () => {
|
|||||||
setCollapsed((prev) => !prev);
|
setCollapsed((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCrewPress = (crewId: string) => {
|
||||||
|
console.log("Crew ID:", crewId);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
{/* Header toggle */}
|
{/* Header toggle */}
|
||||||
@@ -77,7 +87,9 @@ const CrewListTable: React.FC = () => {
|
|||||||
<Text style={[styles.cell, styles.left, styles.headerText]}>
|
<Text style={[styles.cell, styles.left, styles.headerText]}>
|
||||||
Mã định danh
|
Mã định danh
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={[styles.cell, styles.headerText]}>Tên</Text>
|
<View style={styles.cellWrapper}>
|
||||||
|
<Text style={[styles.cell, styles.headerText]}>Tên</Text>
|
||||||
|
</View>
|
||||||
<Text style={[styles.cell, styles.right, styles.headerText]}>
|
<Text style={[styles.cell, styles.right, styles.headerText]}>
|
||||||
Chức vụ
|
Chức vụ
|
||||||
</Text>
|
</Text>
|
||||||
@@ -87,7 +99,12 @@ const CrewListTable: React.FC = () => {
|
|||||||
{data.map((item) => (
|
{data.map((item) => (
|
||||||
<View key={item.id} style={styles.row}>
|
<View key={item.id} style={styles.row}>
|
||||||
<Text style={[styles.cell, styles.left]}>{item.maDinhDanh}</Text>
|
<Text style={[styles.cell, styles.left]}>{item.maDinhDanh}</Text>
|
||||||
<Text style={[styles.cell]}>{item.ten}</Text>
|
<TouchableOpacity
|
||||||
|
style={styles.cellWrapper}
|
||||||
|
onPress={() => handleCrewPress(item.id)}
|
||||||
|
>
|
||||||
|
<Text style={[styles.cell, styles.linkText]}>{item.ten}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
<Text style={[styles.cell, styles.right]}>{item.chucVu}</Text>
|
<Text style={[styles.cell, styles.right]}>{item.chucVu}</Text>
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
@@ -109,7 +126,9 @@ const CrewListTable: React.FC = () => {
|
|||||||
<Text style={[styles.cell, styles.left, styles.headerText]}>
|
<Text style={[styles.cell, styles.left, styles.headerText]}>
|
||||||
Mã định danh
|
Mã định danh
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={[styles.cell, styles.headerText]}>Tên</Text>
|
<View style={styles.cellWrapper}>
|
||||||
|
<Text style={[styles.cell, styles.headerText]}>Tên</Text>
|
||||||
|
</View>
|
||||||
<Text style={[styles.cell, styles.right, styles.headerText]}>
|
<Text style={[styles.cell, styles.right, styles.headerText]}>
|
||||||
Chức vụ
|
Chức vụ
|
||||||
</Text>
|
</Text>
|
||||||
@@ -119,7 +138,12 @@ const CrewListTable: React.FC = () => {
|
|||||||
{data.map((item) => (
|
{data.map((item) => (
|
||||||
<View key={item.id} style={styles.row}>
|
<View key={item.id} style={styles.row}>
|
||||||
<Text style={[styles.cell, styles.left]}>{item.maDinhDanh}</Text>
|
<Text style={[styles.cell, styles.left]}>{item.maDinhDanh}</Text>
|
||||||
<Text style={[styles.cell]}>{item.ten}</Text>
|
<TouchableOpacity
|
||||||
|
style={styles.cellWrapper}
|
||||||
|
onPress={() => handleCrewPress(item.id)}
|
||||||
|
>
|
||||||
|
<Text style={[styles.cell, styles.linkText]}>{item.ten}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
<Text style={[styles.cell, styles.right]}>{item.chucVu}</Text>
|
<Text style={[styles.cell, styles.right]}>{item.chucVu}</Text>
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ const NetListTable: React.FC = () => {
|
|||||||
setCollapsed((prev) => !prev);
|
setCollapsed((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleStatusPress = (id: string) => {
|
||||||
|
console.log(`ID mẻ lưới: ${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
{/* Header toggle */}
|
{/* Header toggle */}
|
||||||
@@ -79,7 +83,9 @@ const NetListTable: React.FC = () => {
|
|||||||
{/* Cột Trạng thái */}
|
{/* Cột Trạng thái */}
|
||||||
<View style={[styles.cell, styles.statusContainer]}>
|
<View style={[styles.cell, styles.statusContainer]}>
|
||||||
<View style={styles.statusDot} />
|
<View style={styles.statusDot} />
|
||||||
<Text style={styles.statusText}>{item.trangThai}</Text>
|
<TouchableOpacity onPress={() => handleStatusPress(item.id)}>
|
||||||
|
<Text style={styles.statusText}>{item.trangThai}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
@@ -102,7 +108,9 @@ const NetListTable: React.FC = () => {
|
|||||||
{/* Cột Trạng thái */}
|
{/* Cột Trạng thái */}
|
||||||
<View style={[styles.cell, styles.statusContainer]}>
|
<View style={[styles.cell, styles.statusContainer]}>
|
||||||
<View style={styles.statusDot} />
|
<View style={styles.statusDot} />
|
||||||
<Text style={styles.statusText}>{item.trangThai}</Text>
|
<TouchableOpacity onPress={() => handleStatusPress(item.id)}>
|
||||||
|
<Text style={styles.statusText}>{item.trangThai}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ const TripCostTable: React.FC = () => {
|
|||||||
setCollapsed((prev) => !prev);
|
setCollapsed((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleViewDetail = () => {
|
||||||
|
console.log("View trip cost details");
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
@@ -140,6 +144,14 @@ const TripCostTable: React.FC = () => {
|
|||||||
{tongCong.toLocaleString()}
|
{tongCong.toLocaleString()}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{/* View Detail Button */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.viewDetailButton}
|
||||||
|
onPress={handleViewDetail}
|
||||||
|
>
|
||||||
|
<Text style={styles.viewDetailText}>Xem chi tiết</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Animated.View style={{ height: animatedHeight, overflow: "hidden" }}>
|
<Animated.View style={{ height: animatedHeight, overflow: "hidden" }}>
|
||||||
@@ -170,6 +182,14 @@ const TripCostTable: React.FC = () => {
|
|||||||
{tongCong.toLocaleString()}
|
{tongCong.toLocaleString()}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{/* View Detail Button */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.viewDetailButton}
|
||||||
|
onPress={handleViewDetail}
|
||||||
|
>
|
||||||
|
<Text style={styles.viewDetailText}>Xem chi tiết</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ export default StyleSheet.create({
|
|||||||
color: "#111",
|
color: "#111",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
},
|
},
|
||||||
|
cellWrapper: {
|
||||||
|
flex: 1.5,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
left: {
|
left: {
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
},
|
},
|
||||||
@@ -64,4 +69,8 @@ export default StyleSheet.create({
|
|||||||
color: "#ff6600",
|
color: "#ff6600",
|
||||||
fontWeight: "800",
|
fontWeight: "800",
|
||||||
},
|
},
|
||||||
|
linkText: {
|
||||||
|
color: "#007AFF",
|
||||||
|
textDecorationLine: "underline",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ export default StyleSheet.create({
|
|||||||
container: {
|
container: {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
backgroundColor: "#fff",
|
backgroundColor: "#fff",
|
||||||
borderRadius: 10,
|
borderRadius: 12,
|
||||||
padding: 12,
|
padding: 16,
|
||||||
marginVertical: 10,
|
marginVertical: 10,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderColor: "#eee",
|
borderColor: "#eee",
|
||||||
shadowColor: "#000",
|
shadowColor: "#000",
|
||||||
shadowOpacity: 0.05,
|
shadowOpacity: 0.1,
|
||||||
shadowRadius: 4,
|
shadowRadius: 4,
|
||||||
elevation: 1,
|
elevation: 1,
|
||||||
},
|
},
|
||||||
@@ -34,7 +34,7 @@ export default StyleSheet.create({
|
|||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
paddingVertical: 8,
|
paddingVertical: 8,
|
||||||
borderBottomWidth: 0.6,
|
borderBottomWidth: 0.5,
|
||||||
borderBottomColor: "#eee",
|
borderBottomColor: "#eee",
|
||||||
},
|
},
|
||||||
tableHeader: {
|
tableHeader: {
|
||||||
@@ -52,7 +52,7 @@ export default StyleSheet.create({
|
|||||||
flex: 0.3,
|
flex: 0.3,
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
color: "#111",
|
color: "#111",
|
||||||
textAlign: "left",
|
textAlign: "center",
|
||||||
paddingLeft: 10,
|
paddingLeft: 10,
|
||||||
},
|
},
|
||||||
headerText: {
|
headerText: {
|
||||||
@@ -72,6 +72,7 @@ export default StyleSheet.create({
|
|||||||
},
|
},
|
||||||
statusText: {
|
statusText: {
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
color: "#111",
|
color: "#4a90e2",
|
||||||
|
textDecorationLine: "underline",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,6 +56,17 @@ const styles = StyleSheet.create({
|
|||||||
color: "#ff6600",
|
color: "#ff6600",
|
||||||
fontWeight: "700",
|
fontWeight: "700",
|
||||||
},
|
},
|
||||||
|
viewDetailButton: {
|
||||||
|
marginTop: 12,
|
||||||
|
paddingVertical: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
viewDetailText: {
|
||||||
|
color: "#007AFF",
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: "600",
|
||||||
|
textDecorationLine: "underline",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default styles;
|
export default styles;
|
||||||
|
|||||||
Reference in New Issue
Block a user