Yaltopia-Tickets-App/app/company-details.tsx
2026-06-05 13:39:37 +03:00

255 lines
8.2 KiB
TypeScript

import React, { useEffect, useState } from "react";
import {
View,
ActivityIndicator,
ScrollView,
Image,
Pressable,
useColorScheme,
} from "react-native";
import { ScreenWrapper } from "@/components/ScreenWrapper";
import { Text } from "@/components/ui/text";
import { Card, CardContent } from "@/components/ui/card";
import {
ArrowLeft,
Edit,
Building2,
Hash,
Mail,
Phone,
Globe,
MapPin,
Calendar,
} from "@/lib/icons";
import { useSirouRouter } from "@sirou/react-native";
import { AppRoutes } from "@/lib/routes";
import { api } from "@/lib/api";
export default function CompanyDetailsScreen() {
const nav = useSirouRouter<AppRoutes>();
const isDark = useColorScheme() === "dark";
const iconCol = isDark ? "#94a3b8" : "#64748b";
const [loading, setLoading] = useState(true);
const [company, setCompany] = useState<any>(null);
useEffect(() => {
const load = async () => {
try {
setLoading(true);
const res = await api.company.get();
setCompany(res?.data ?? res);
} finally {
setLoading(false);
}
};
load();
}, []);
const fmtDate = (d: string) =>
d
? new Date(d).toLocaleDateString("en-GB", {
day: "numeric",
month: "short",
year: "numeric",
})
: "—";
if (loading) {
return (
<ScreenWrapper className="bg-background">
<View className="flex-1 items-center justify-center">
<ActivityIndicator size="large" color="#E46212" />
</View>
</ScreenWrapper>
);
}
return (
<ScreenWrapper className="bg-background">
<View className="px-5 pt-4 flex-row justify-between items-center">
<Pressable
onPress={() => nav.back()}
className="h-9 w-9 rounded-[10px] bg-card items-center justify-center border border-border"
>
<ArrowLeft
color={isDark ? "#f8fafc" : "#0f172a"}
size={18}
/>
</Pressable>
<Text className="text-foreground text-[16px] font-sans-bold">
Company Details
</Text>
<Pressable
onPress={() => nav.go("company/edit")}
className="h-9 w-9 rounded-[10px] bg-card items-center justify-center border border-border"
>
<Edit color="#E46212" size={16} strokeWidth={2} />
</Pressable>
</View>
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{ padding: 16, paddingBottom: 40 }}
>
{/* Hero */}
<View className="items-center mb-6">
{company?.logoPath ? (
<View className="h-20 w-20 rounded-full overflow-hidden bg-muted mb-3 border-2 border-border/30">
<Image
source={{ uri: company.logoPath }}
className="h-full w-full"
resizeMode="cover"
/>
</View>
) : (
<View className="h-20 w-20 rounded-full bg-primary/10 items-center justify-center mb-3 border-2 border-primary/20">
<Building2 size={32} color="#E46212" strokeWidth={1.5} />
</View>
)}
<Text className="text-foreground text-xl font-sans-black tracking-tight text-center">
{company?.name || "Company"}
</Text>
{company?.tin && (
<View className="flex-row items-center mt-1.5">
<Hash size={12} color={iconCol} strokeWidth={2} />
<Text className="text-muted-foreground text-sm font-sans-medium ml-1.5">
TIN: {company.tin}
</Text>
</View>
)}
</View>
{/* Contact */}
<Text className="text-[10px] font-sans-bold uppercase tracking-widest text-muted-foreground mb-2 ml-1">
Contact
</Text>
<Card className="rounded-[6px] border-border bg-card overflow-hidden mb-5">
<CardContent className="p-0">
{company?.phone && (
<InfoRow
icon={<Phone size={15} color={iconCol} strokeWidth={2} />}
label="Phone"
value={company.phone}
isLast={!company?.email && !company?.website}
/>
)}
{company?.email && (
<InfoRow
icon={<Mail size={15} color={iconCol} strokeWidth={2} />}
label="Email"
value={company.email}
isLast={!company?.website}
/>
)}
{company?.website && (
<InfoRow
icon={<Globe size={15} color={iconCol} strokeWidth={2} />}
label="Website"
value={company.website}
isLast
/>
)}
{!company?.phone && !company?.email && !company?.website && (
<View className="px-4 py-3">
<Text className="text-muted-foreground text-sm font-sans-medium">
No contact information
</Text>
</View>
)}
</CardContent>
</Card>
{/* Address */}
<Text className="text-[10px] font-sans-bold uppercase tracking-widest text-muted-foreground mb-2 ml-1">
Address
</Text>
<Card className="rounded-[6px] border-border bg-card overflow-hidden mb-5">
<CardContent className="p-0">
{company?.address && (
<InfoRow
icon={<MapPin size={15} color={iconCol} strokeWidth={2} />}
label="Street"
value={company.address}
isLast={!company?.city && !company?.state && !company?.zipCode && !company?.country}
/>
)}
{(company?.city || company?.state) && (
<InfoRow
icon={<MapPin size={15} color={iconCol} strokeWidth={2} />}
label="City / State"
value={[company?.city, company?.state].filter(Boolean).join(", ")}
isLast={!company?.zipCode && !company?.country}
/>
)}
{(company?.zipCode || company?.country) && (
<InfoRow
icon={<MapPin size={15} color={iconCol} strokeWidth={2} />}
label="Zip / Country"
value={[company?.zipCode, company?.country].filter(Boolean).join(", ")}
isLast
/>
)}
{!company?.address && !company?.city && !company?.state && (
<View className="px-4 py-3">
<Text className="text-muted-foreground text-sm font-sans-medium">
No address information
</Text>
</View>
)}
</CardContent>
</Card>
{/* Info */}
<Text className="text-[10px] font-sans-bold uppercase tracking-widest text-muted-foreground mb-2 ml-1">
Account
</Text>
<Card className="rounded-[6px] border-border bg-card overflow-hidden mb-5">
<CardContent className="p-0">
<InfoRow
icon={<Calendar size={15} color={iconCol} strokeWidth={2} />}
label="Created"
value={fmtDate(company?.createdAt)}
isLast={!company?.updatedAt}
/>
{company?.updatedAt && (
<InfoRow
icon={<Calendar size={15} color={iconCol} strokeWidth={2} />}
label="Last Updated"
value={fmtDate(company?.updatedAt)}
isLast
/>
)}
</CardContent>
</Card>
</ScrollView>
</ScreenWrapper>
);
}
function InfoRow({
icon,
label,
value,
isLast,
}: {
icon: React.ReactNode;
label: string;
value: string;
isLast?: boolean;
}) {
return (
<View
className={`flex-row items-center px-4 py-3.5 ${!isLast ? "border-b border-border/40" : ""}`}
>
<View className="h-8 w-8 rounded-[6px] bg-secondary/60 items-center justify-center mr-3">
{icon}
</View>
<View className="flex-1">
<Text className="text-muted-foreground text-[10px] font-sans-medium">{label}</Text>
<Text className="text-foreground text-sm font-sans-bold mt-0.5">{value}</Text>
</View>
</View>
);
}