Yaltopia-Tickets-App/app/team/[id]/details.tsx
2026-06-05 13:39:37 +03:00

266 lines
9.9 KiB
TypeScript

import React, { useEffect, useState } from "react";
import {
View,
ScrollView,
Pressable,
ActivityIndicator,
Image,
} from "react-native";
import { useSirouRouter } from "@sirou/react-native";
import { useLocalSearchParams } from "expo-router";
import { AppRoutes } from "@/lib/routes";
import { ScreenWrapper } from "@/components/ScreenWrapper";
import { StandardHeader } from "@/components/StandardHeader";
import { Text } from "@/components/ui/text";
import { Card, CardContent } from "@/components/ui/card";
import { api } from "@/lib/api";
import { useColorScheme } from "nativewind";
import {
Mail,
Phone,
ShieldCheck,
Calendar,
ChevronRight,
} from "@/lib/icons";
export default function TeamMemberDetailsScreen() {
const nav = useSirouRouter<AppRoutes>();
const { id } = useLocalSearchParams<{ id: string }>();
const { colorScheme } = useColorScheme();
const isDark = colorScheme === "dark";
const [member, setMember] = useState<any>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const load = async () => {
try {
setLoading(true);
const res = await api.team.getById({ params: { id } });
setMember(res?.data ?? res);
} catch (err) {
console.error("[TeamMemberDetails] Error:", err);
} finally {
setLoading(false);
}
};
load();
}, [id]);
const iconCol = isDark ? "#94a3b8" : "#64748b";
if (loading) {
return (
<ScreenWrapper className="bg-background">
<StandardHeader title="Worker Details" showBack />
<View className="flex-1 items-center justify-center">
<ActivityIndicator size="large" color="#E46212" />
</View>
</ScreenWrapper>
);
}
if (!member) {
return (
<ScreenWrapper className="bg-background">
<StandardHeader title="Worker Details" showBack />
<View className="flex-1 items-center justify-center px-5">
<Text className="text-muted-foreground">Worker not found</Text>
</View>
</ScreenWrapper>
);
}
return (
<ScreenWrapper className="bg-background">
<StandardHeader title="Worker Details" showBack />
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{ padding: 16, paddingBottom: 40 }}
>
{/* Avatar + Name */}
<View className="items-center mb-8">
{member.avatar ? (
<View className="h-20 w-20 rounded-full overflow-hidden bg-muted mb-3">
<Image
source={{ uri: member.avatar }}
className="h-full w-full"
resizeMode="cover"
/>
</View>
) : (
<View className="h-20 w-20 rounded-full bg-secondary items-center justify-center mb-3">
<Text className="text-primary font-sans-bold text-3xl">
{member.firstName?.[0]}
{member.lastName?.[0]}
</Text>
</View>
)}
<Text className="text-foreground text-xl font-sans-bold text-center">
{member.firstName} {member.lastName}
</Text>
<View className="mt-2 flex-row items-center">
<View className="px-3 py-1 rounded-[4px] bg-slate-500/10">
<Text className="text-slate-600 text-[9px] font-sans-bold uppercase tracking-widest">
{member.role?.replace("_", " ") || "MEMBER"}
</Text>
</View>
{member.status && (
<View className={`ml-2 px-3 py-1 rounded-[4px] ${
member.status === "ACTIVE" ? "bg-emerald-500/10" : "bg-slate-500/10"
}`}>
<Text className={`text-[9px] font-sans-bold uppercase tracking-widest ${
member.status === "ACTIVE" ? "text-emerald-600" : "text-slate-600"
}`}>
{member.status}
</Text>
</View>
)}
</View>
</View>
{/* Contact Info */}
<Card className="mb-4">
<CardContent className="py-4">
<Text className="text-[11px] font-sans-bold uppercase tracking-widest text-muted-foreground mb-4">
Contact Information
</Text>
<View className="gap-4">
<View className="flex-row items-center">
<View className="h-8 w-8 rounded-lg bg-muted items-center justify-center mr-3">
<Mail size={15} color={iconCol} />
</View>
<View className="flex-1">
<Text className="text-[10px] font-sans-medium text-muted-foreground">
Email
</Text>
<Text className="text-foreground text-sm font-sans-medium mt-0.5">
{member.email || "—"}
</Text>
</View>
</View>
<View className="flex-row items-center">
<View className="h-8 w-8 rounded-lg bg-muted items-center justify-center mr-3">
<Phone size={15} color={iconCol} />
</View>
<View className="flex-1">
<Text className="text-[10px] font-sans-medium text-muted-foreground">
Phone
</Text>
<Text className="text-foreground text-sm font-sans-medium mt-0.5">
{member.phone || "—"}
</Text>
</View>
</View>
<View className="flex-row items-center">
<View className="h-8 w-8 rounded-lg bg-muted items-center justify-center mr-3">
<ShieldCheck size={15} color={iconCol} />
</View>
<View className="flex-1">
<Text className="text-[10px] font-sans-medium text-muted-foreground">
Role
</Text>
<Text className="text-foreground text-sm font-sans-medium mt-0.5">
{member.role?.replace("_", " ") || "MEMBER"}
</Text>
</View>
</View>
</View>
</CardContent>
</Card>
{/* Activity */}
<Card className="mb-4">
<CardContent className="py-4">
<Text className="text-[11px] font-sans-bold uppercase tracking-widest text-muted-foreground mb-4">
Recent Activity
</Text>
{member.activities && member.activities.length > 0 ? (
<View className="gap-3">
{member.activities.map((act: any, i: number) => (
<View
key={act.id || i}
className="flex-row items-start"
>
<View className="h-2 w-2 rounded-full bg-primary mt-1.5 mr-3" />
<View className="flex-1">
<Text className="text-foreground text-sm font-sans-medium">
{act.description || act.action}
</Text>
<Text className="text-muted-foreground text-[10px] font-sans-medium mt-0.5">
{act.createdAt
? new Date(act.createdAt).toLocaleDateString("en-GB", {
day: "numeric",
month: "short",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
})
: ""}
</Text>
</View>
</View>
))}
</View>
) : (
<Text className="text-muted-foreground text-sm font-sans-medium">
No recent activity
</Text>
)}
</CardContent>
</Card>
{/* Account Info */}
<Card>
<CardContent className="py-4">
<Text className="text-[11px] font-sans-bold uppercase tracking-widest text-muted-foreground mb-4">
Account Information
</Text>
<View className="gap-3">
<View className="flex-row items-center">
<View className="h-8 w-8 rounded-lg bg-muted items-center justify-center mr-3">
<Calendar size={15} color={iconCol} />
</View>
<View className="flex-1">
<Text className="text-[10px] font-sans-medium text-muted-foreground">
Created
</Text>
<Text className="text-foreground text-sm font-sans-medium mt-0.5">
{member.createdAt
? new Date(member.createdAt).toLocaleDateString("en-GB", {
day: "numeric",
month: "short",
year: "numeric",
})
: "—"}
</Text>
</View>
</View>
<View className="flex-row items-center">
<View className="h-8 w-8 rounded-lg bg-muted items-center justify-center mr-3">
<Calendar size={15} color={iconCol} />
</View>
<View className="flex-1">
<Text className="text-[10px] font-sans-medium text-muted-foreground">
Last Updated
</Text>
<Text className="text-foreground text-sm font-sans-medium mt-0.5">
{member.updatedAt
? new Date(member.updatedAt).toLocaleDateString("en-GB", {
day: "numeric",
month: "short",
year: "numeric",
})
: "—"}
</Text>
</View>
</View>
</View>
</CardContent>
</Card>
</ScrollView>
</ScreenWrapper>
);
}