Yaltopia-Tickets-App/app/proforma/[id].tsx
2026-03-11 22:48:53 +03:00

330 lines
12 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect } from "react";
import { View, ScrollView, Pressable, ActivityIndicator } from "react-native";
import { useSirouRouter } from "@sirou/react-native";
import { AppRoutes } from "@/lib/routes";
import { Stack, useLocalSearchParams } from "expo-router";
import { useRouter } from "expo-router";
import { Text } from "@/components/ui/text";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import {
ArrowLeft,
DraftingCompass,
Clock,
Send,
ExternalLink,
ChevronRight,
CheckCircle2,
} from "@/lib/icons";
import { ScreenWrapper } from "@/components/ScreenWrapper";
import { StandardHeader } from "@/components/StandardHeader";
import { api } from "@/lib/api";
import { toast } from "@/lib/toast-store";
const dummyData = {
id: "dummy-1",
proformaNumber: "PF-001",
customerName: "John Doe",
customerEmail: "john@example.com",
customerPhone: "+1234567890",
amount: { value: 1000, currency: "USD" },
currency: "USD",
issueDate: "2026-03-10T11:51:36.134Z",
dueDate: "2026-03-10T11:51:36.134Z",
description: "Dummy proforma",
notes: "Test notes",
taxAmount: { value: 100, currency: "USD" },
discountAmount: { value: 50, currency: "USD" },
pdfPath: "dummy.pdf",
userId: "user-1",
items: [
{
id: "item-1",
description: "Test item",
quantity: 1,
unitPrice: { value: 1000, currency: "USD" },
total: { value: 1000, currency: "USD" }
}
],
createdAt: "2026-03-10T11:51:36.134Z",
updatedAt: "2026-03-10T11:51:36.134Z"
};
export default function ProformaDetailScreen() {
const nav = useSirouRouter<AppRoutes>();
const router = useRouter();
const { id } = useLocalSearchParams();
const [loading, setLoading] = useState(true);
const [proforma, setProforma] = useState<any>(null);
useEffect(() => {
fetchProforma();
}, [id]);
const fetchProforma = async () => {
try {
setLoading(true);
const data = await api.proforma.getById({ params: { id: id as string } });
setProforma(data);
} catch (error: any) {
console.error("[ProformaDetail] Error:", error);
toast.error("Error", "Failed to load proforma details");
setProforma(dummyData); // Use dummy data for testing
} finally {
setLoading(false);
}
};
if (loading) {
return (
<ScreenWrapper className="bg-background">
<Stack.Screen options={{ headerShown: false }} />
<StandardHeader title="Proforma" showBack />
<View className="flex-1 justify-center items-center">
<ActivityIndicator color="#ea580c" size="large" />
</View>
</ScreenWrapper>
);
}
if (!proforma) {
return (
<ScreenWrapper className="bg-background">
<Stack.Screen options={{ headerShown: false }} />
<StandardHeader title="Proforma" showBack />
<View className="flex-1 justify-center items-center">
<Text variant="muted">Proforma not found</Text>
</View>
</ScreenWrapper>
);
}
const subtotal =
proforma.items?.reduce(
(acc: number, item: any) => acc + (Number(item.total) || 0),
0,
) || 0;
return (
<ScreenWrapper className="bg-background">
<Stack.Screen options={{ headerShown: false }} />
{/* Header */}
<StandardHeader title="Proforma" showBack />
<ScrollView
className="flex-1"
contentContainerStyle={{ padding: 16, paddingBottom: 120 }}
showsVerticalScrollIndicator={false}
>
{/* Proforma Info Card */}
<Card className="bg-card rounded-[12px] mb-4 border border-border">
<View className="p-4">
<View className="flex-row items-center gap-3 mb-3">
<View className="bg-primary/10 p-2 rounded-[8px]">
<DraftingCompass color="#ea580c" size={16} strokeWidth={2.5} />
</View>
<Text className="text-foreground font-bold text-sm uppercase tracking-widest">
Proforma Details
</Text>
</View>
<View className="gap-2">
<View className="flex-row justify-between">
<Text variant="muted" className="text-xs font-medium">Proforma Number</Text>
<Text className="text-foreground font-semibold text-sm">{proforma.proformaNumber}</Text>
</View>
<View className="flex-row justify-between">
<Text variant="muted" className="text-xs font-medium">Issued Date</Text>
<Text className="text-foreground font-semibold text-sm">{new Date(proforma.issueDate).toLocaleDateString()}</Text>
</View>
<View className="flex-row justify-between">
<Text variant="muted" className="text-xs font-medium">Due Date</Text>
<Text className="text-foreground font-semibold text-sm">{new Date(proforma.dueDate).toLocaleDateString()}</Text>
</View>
<View className="flex-row justify-between">
<Text variant="muted" className="text-xs font-medium">Currency</Text>
<Text className="text-foreground font-semibold text-sm">{proforma.currency}</Text>
</View>
{proforma.description && (
<View className="mt-2">
<Text variant="muted" className="text-xs font-medium mb-1">Description</Text>
<Text className="text-foreground text-sm">{proforma.description}</Text>
</View>
)}
</View>
</View>
</Card>
{/* Customer Info Card */}
<Card className="bg-card rounded-[12px] mb-4 border border-border">
<View className="p-4">
<View className="flex-row items-center gap-3 mb-3">
<View className="bg-primary/10 p-2 rounded-[8px]">
<CheckCircle2 color="#ea580c" size={16} strokeWidth={2.5} />
</View>
<Text className="text-foreground font-bold text-sm uppercase tracking-widest">
Customer Information
</Text>
</View>
<View className="gap-2">
<View className="flex-row justify-between">
<Text variant="muted" className="text-xs font-medium">Name</Text>
<Text className="text-foreground font-semibold text-sm">{proforma.customerName}</Text>
</View>
<View className="flex-row justify-between">
<Text variant="muted" className="text-xs font-medium">Email</Text>
<Text className="text-foreground font-semibold text-sm">{proforma.customerEmail || "N/A"}</Text>
</View>
<View className="flex-row justify-between">
<Text variant="muted" className="text-xs font-medium">Phone</Text>
<Text className="text-foreground font-semibold text-sm">{proforma.customerPhone || "N/A"}</Text>
</View>
</View>
</View>
</Card>
{/* Line Items Card */}
<Card className="bg-card rounded-[6px] mb-4">
<View className="p-4">
<View className="flex-row items-center gap-2 mb-2">
<Text
variant="small"
className="font-bold uppercase tracking-widest text-[10px] opacity-60"
>
Line Items
</Text>
</View>
{proforma.items?.map((item: any, i: number) => (
<View
key={item.id || i}
className={`flex-row justify-between py-3 ${i < proforma.items.length - 1 ? "border-b border-border/40" : ""}`}
>
<View className="flex-1 pr-4">
<Text
variant="p"
className="text-foreground font-semibold text-sm"
>
{item.description}
</Text>
<Text variant="muted" className="text-[10px] mt-0.5">
{item.quantity} × {proforma.currency}{" "}
{Number(item.unitPrice).toLocaleString()}
</Text>
</View>
<Text variant="p" className="text-foreground font-bold text-sm">
{proforma.currency} {Number(item.total).toLocaleString()}
</Text>
</View>
))}
<View className="mt-3 pt-3 border-t border-border/40 gap-2">
<View className="flex-row justify-between">
<Text
variant="p"
className="text-foreground font-semibold text-sm"
>
Subtotal
</Text>
<Text variant="p" className="text-foreground font-bold text-sm">
{proforma.currency} {subtotal.toLocaleString()}
</Text>
</View>
{Number(proforma.taxAmount) > 0 && (
<View className="flex-row justify-between">
<Text
variant="p"
className="text-foreground font-semibold text-sm"
>
Tax
</Text>
<Text
variant="p"
className="text-foreground font-bold text-sm"
>
{proforma.currency}{" "}
{Number(proforma.taxAmount).toLocaleString()}
</Text>
</View>
)}
{Number(proforma.discountAmount) > 0 && (
<View className="flex-row justify-between">
<Text
variant="p"
className="text-red-500 font-semibold text-sm"
>
Discount
</Text>
<Text variant="p" className="text-red-500 font-bold text-sm">
-{proforma.currency}{" "}
{Number(proforma.discountAmount).toLocaleString()}
</Text>
</View>
)}
<View className="flex-row justify-between items-center mt-1">
<Text variant="p" className="text-foreground font-bold">
Total Amount
</Text>
<Text
variant="h4"
className="text-foreground font-bold tracking-tight"
>
{proforma.currency} {Number(proforma.amount).toLocaleString()}
</Text>
</View>
</View>
</View>
</Card>
{/* Notes Section (New) */}
{proforma.notes && (
<Card className="bg-card rounded-[6px] mb-4">
<View className="p-4">
<Text
variant="small"
className="font-bold uppercase tracking-widest text-[10px] opacity-60 mb-2"
>
Additional Notes
</Text>
<Text
variant="p"
className="text-foreground font-medium text-xs leading-5"
>
{proforma.notes}
</Text>
</View>
</Card>
)}
{/* Actions */}
<View className="gap-3">
<Button
className="h-12 rounded-[10px] bg-transparent border border-border"
onPress={() => router.push("/proforma/edit?id=" + proforma.id)}
>
<DraftingCompass color="#fff" size={16} strokeWidth={2.5} />
<Text className="ml-2 text-foreground font-black text-[12px] uppercase tracking-widest">
Edit
</Text>
</Button>
<Button
className="h-12 rounded-[10px] bg-primary shadow-lg shadow-primary/20"
onPress={() => {}}
>
<Send color="#ffffff" size={16} strokeWidth={2.5} />
<Text className="ml-2 text-white font-black text-[12px] uppercase tracking-widest">
Share SMS
</Text>
</Button>
</View>
</ScrollView>
</ScreenWrapper>
);
}