cập nhật modal CRUD thuyền viên trong trip
This commit is contained in:
@@ -12,7 +12,7 @@ import { Ionicons } from "@expo/vector-icons";
|
||||
import { useThemeContext } from "@/hooks/use-theme-context";
|
||||
import { useI18n } from "@/hooks/use-i18n";
|
||||
import dayjs from "dayjs";
|
||||
import { queryCrewImage } from "@/controller/TripCrewController";
|
||||
import { queryCrewImage } from "@/controller/CrewController";
|
||||
import { Buffer } from "buffer";
|
||||
|
||||
interface CrewCardProps {
|
||||
@@ -26,8 +26,12 @@ export default function CrewCard({ crew, onEdit, onDelete }: CrewCardProps) {
|
||||
const { t } = useI18n();
|
||||
|
||||
const person = crew.Person;
|
||||
const joinedDate = crew.joined_at ? dayjs(crew.joined_at).format("DD/MM/YYYY") : "-";
|
||||
const leftDate = crew.left_at ? dayjs(crew.left_at).format("DD/MM/YYYY") : null;
|
||||
const joinedDate = crew.joined_at
|
||||
? dayjs(crew.joined_at).format("DD/MM/YYYY")
|
||||
: "-";
|
||||
const leftDate = crew.left_at
|
||||
? dayjs(crew.left_at).format("DD/MM/YYYY")
|
||||
: null;
|
||||
|
||||
// State for image
|
||||
const [imageUri, setImageUri] = useState<string | null>(null);
|
||||
@@ -47,7 +51,9 @@ export default function CrewCard({ crew, onEdit, onDelete }: CrewCardProps) {
|
||||
const response = await queryCrewImage(person.personal_id);
|
||||
if (response.data) {
|
||||
// Convert arraybuffer to base64
|
||||
const base64 = Buffer.from(response.data as ArrayBuffer).toString("base64");
|
||||
const base64 = Buffer.from(response.data as ArrayBuffer).toString(
|
||||
"base64"
|
||||
);
|
||||
setImageUri(`data:image/jpeg;base64,${base64}`);
|
||||
} else {
|
||||
setImageError(true);
|
||||
@@ -112,7 +118,12 @@ export default function CrewCard({ crew, onEdit, onDelete }: CrewCardProps) {
|
||||
<Text style={[styles.name, themedStyles.name]} numberOfLines={1}>
|
||||
{person?.name || "-"}
|
||||
</Text>
|
||||
<View style={[styles.roleBadge, { backgroundColor: themedStyles.role.backgroundColor }]}>
|
||||
<View
|
||||
style={[
|
||||
styles.roleBadge,
|
||||
{ backgroundColor: themedStyles.role.backgroundColor },
|
||||
]}
|
||||
>
|
||||
<Text style={[styles.roleText, { color: themedStyles.role.color }]}>
|
||||
{crew.role || t("diary.crew.member")}
|
||||
</Text>
|
||||
@@ -123,7 +134,11 @@ export default function CrewCard({ crew, onEdit, onDelete }: CrewCardProps) {
|
||||
<View style={styles.infoGrid}>
|
||||
{/* Phone */}
|
||||
<View style={styles.infoRow}>
|
||||
<Ionicons name="call-outline" size={14} color={themedStyles.iconColor} />
|
||||
<Ionicons
|
||||
name="call-outline"
|
||||
size={14}
|
||||
color={themedStyles.iconColor}
|
||||
/>
|
||||
<Text style={[styles.value, themedStyles.value]} numberOfLines={1}>
|
||||
{person?.phone || "-"}
|
||||
</Text>
|
||||
@@ -131,7 +146,11 @@ export default function CrewCard({ crew, onEdit, onDelete }: CrewCardProps) {
|
||||
|
||||
{/* Personal ID */}
|
||||
<View style={styles.infoRow}>
|
||||
<Ionicons name="card-outline" size={14} color={themedStyles.iconColor} />
|
||||
<Ionicons
|
||||
name="card-outline"
|
||||
size={14}
|
||||
color={themedStyles.iconColor}
|
||||
/>
|
||||
<Text style={[styles.value, themedStyles.value]} numberOfLines={1}>
|
||||
{person?.personal_id || "-"}
|
||||
</Text>
|
||||
@@ -139,14 +158,22 @@ export default function CrewCard({ crew, onEdit, onDelete }: CrewCardProps) {
|
||||
|
||||
{/* Joined Date */}
|
||||
<View style={styles.infoRow}>
|
||||
<Ionicons name="calendar-outline" size={14} color={themedStyles.iconColor} />
|
||||
<Ionicons
|
||||
name="calendar-outline"
|
||||
size={14}
|
||||
color={themedStyles.iconColor}
|
||||
/>
|
||||
<Text style={[styles.value, themedStyles.value]}>{joinedDate}</Text>
|
||||
</View>
|
||||
|
||||
{/* Left Date (only show if exists) */}
|
||||
{leftDate && (
|
||||
<View style={styles.infoRow}>
|
||||
<Ionicons name="exit-outline" size={14} color={themedStyles.iconColor} />
|
||||
<Ionicons
|
||||
name="exit-outline"
|
||||
size={14}
|
||||
color={themedStyles.iconColor}
|
||||
/>
|
||||
<Text style={[styles.value, themedStyles.value]}>{leftDate}</Text>
|
||||
</View>
|
||||
)}
|
||||
@@ -157,10 +184,17 @@ export default function CrewCard({ crew, onEdit, onDelete }: CrewCardProps) {
|
||||
<View style={styles.actionRow}>
|
||||
{onEdit && (
|
||||
<TouchableOpacity
|
||||
style={[styles.actionButton, { backgroundColor: colors.primary + "15" }]}
|
||||
style={[
|
||||
styles.actionButton,
|
||||
{ backgroundColor: colors.primary + "15" },
|
||||
]}
|
||||
onPress={() => onEdit(crew)}
|
||||
>
|
||||
<Ionicons name="pencil-outline" size={14} color={colors.primary} />
|
||||
<Ionicons
|
||||
name="pencil-outline"
|
||||
size={14}
|
||||
color={colors.primary}
|
||||
/>
|
||||
<Text style={[styles.actionText, { color: colors.primary }]}>
|
||||
{t("common.edit")}
|
||||
</Text>
|
||||
@@ -168,11 +202,23 @@ export default function CrewCard({ crew, onEdit, onDelete }: CrewCardProps) {
|
||||
)}
|
||||
{onDelete && (
|
||||
<TouchableOpacity
|
||||
style={[styles.actionButton, { backgroundColor: (colors.error || "#FF3B30") + "15" }]}
|
||||
style={[
|
||||
styles.actionButton,
|
||||
{ backgroundColor: (colors.error || "#FF3B30") + "15" },
|
||||
]}
|
||||
onPress={() => onDelete(crew)}
|
||||
>
|
||||
<Ionicons name="trash-outline" size={14} color={colors.error || "#FF3B30"} />
|
||||
<Text style={[styles.actionText, { color: colors.error || "#FF3B30" }]}>
|
||||
<Ionicons
|
||||
name="trash-outline"
|
||||
size={14}
|
||||
color={colors.error || "#FF3B30"}
|
||||
/>
|
||||
<Text
|
||||
style={[
|
||||
styles.actionText,
|
||||
{ color: colors.error || "#FF3B30" },
|
||||
]}
|
||||
>
|
||||
{t("common.delete")}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
@@ -191,7 +237,7 @@ const styles = StyleSheet.create({
|
||||
borderWidth: 1,
|
||||
marginBottom: 12,
|
||||
overflow: "hidden",
|
||||
maxHeight: 150,
|
||||
maxHeight: 160,
|
||||
},
|
||||
imageSection: {
|
||||
width: 130,
|
||||
|
||||
Reference in New Issue
Block a user