208 lines
7.3 KiB
TypeScript
208 lines
7.3 KiB
TypeScript
import React from "react";
|
|
import { View, ScrollView, Pressable } from "react-native";
|
|
import { useLocalSearchParams, router, Stack } from "expo-router";
|
|
import { Text } from "@/components/ui/text";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Card } from "@/components/ui/card";
|
|
import {
|
|
FileText,
|
|
Calendar,
|
|
Share2,
|
|
Download,
|
|
ArrowLeft,
|
|
Tag,
|
|
CreditCard,
|
|
Building2,
|
|
ExternalLink,
|
|
} from "@/lib/icons";
|
|
import { MOCK_INVOICES } from "@/lib/mock-data";
|
|
import { ScreenWrapper } from "@/components/ScreenWrapper";
|
|
import { ShadowWrapper } from "@/components/ShadowWrapper";
|
|
|
|
const MOCK_ITEMS = [
|
|
{
|
|
description: "Marketing Landing Page Package",
|
|
qty: 1,
|
|
unitPrice: 1000,
|
|
total: 1000,
|
|
},
|
|
{
|
|
description: "Instagram Post Initial Design",
|
|
qty: 4,
|
|
unitPrice: 100,
|
|
total: 400,
|
|
},
|
|
];
|
|
|
|
export default function InvoiceDetailScreen() {
|
|
const { id } = useLocalSearchParams<{ id: string }>();
|
|
const invoice = MOCK_INVOICES.find((i) => i.id === id);
|
|
|
|
return (
|
|
<ScreenWrapper className="bg-background">
|
|
<Stack.Screen options={{ headerShown: false }} />
|
|
|
|
<View className="px-6 pt-4 flex-row justify-between items-center">
|
|
<Pressable
|
|
onPress={() => router.back()}
|
|
className="h-10 w-10 rounded-[10px] bg-card items-center justify-center border border-border"
|
|
>
|
|
<ArrowLeft color="#0f172a" size={20} />
|
|
</Pressable>
|
|
<Text variant="h4" className="text-foreground font-semibold">
|
|
Invoice Details
|
|
</Text>
|
|
<Pressable className="h-10 w-10 rounded-[10px] bg-card items-center justify-center border border-border">
|
|
<ExternalLink className="text-foreground" color="#000" size={18} />
|
|
</Pressable>
|
|
</View>
|
|
|
|
<ScrollView
|
|
className="flex-1"
|
|
contentContainerStyle={{ padding: 16, paddingBottom: 120 }}
|
|
showsVerticalScrollIndicator={false}
|
|
>
|
|
{/* Status Hero Card */}
|
|
<Card className="mb-4 overflow-hidden rounded-[6px] border-0 bg-primary">
|
|
<View className="p-5">
|
|
<View className="flex-row items-center justify-between mb-3">
|
|
<View className="bg-white/20 p-1.5 rounded-[6px]">
|
|
<FileText color="white" size={16} strokeWidth={2.5} />
|
|
</View>
|
|
<View
|
|
className={`rounded-[6px] px-3 py-1 ${invoice?.status === "Paid" ? "bg-emerald-500/20" : "bg-white/15"}`}
|
|
>
|
|
<Text
|
|
className={`text-[10px] font-bold ${invoice?.status === "Paid" ? "text-emerald-400" : "text-white"}`}
|
|
>
|
|
{invoice?.status || "Pending"}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
|
|
<Text variant="small" className="text-white/70 mb-0.5">
|
|
Total Amount
|
|
</Text>
|
|
<Text variant="h3" className="text-white font-bold mb-3">
|
|
${invoice?.amount.toLocaleString() ?? "—"}
|
|
</Text>
|
|
|
|
<View className="flex-row items-center gap-3 border-t border-white/40 pt-3">
|
|
<View className="flex-row items-center gap-1.5">
|
|
<Calendar color="rgba(255,255,255,0.9)" size={12} />
|
|
<Text className="text-white/90 text-xs font-semibold">
|
|
Due {invoice?.dueDate || "—"}
|
|
</Text>
|
|
</View>
|
|
<View className="h-3 w-[1px] bg-white/60" />
|
|
<Text className="text-white/90 text-xs font-semibold">
|
|
#{invoice?.invoiceNumber || id}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</Card>
|
|
|
|
{/* Recipient & Category — inline info strip */}
|
|
<Card className="bg-card rounded-[6px] mb-4">
|
|
<View className="flex-row px-4 py-2">
|
|
<View className="flex-1 flex-row items-center">
|
|
<View className="flex-col">
|
|
<Text className="text-foreground text-xs">Recipient</Text>
|
|
<Text
|
|
variant="p"
|
|
className="text-foreground font-semibold"
|
|
numberOfLines={1}
|
|
>
|
|
{invoice?.recipient || "—"}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
<View className="w-[1px] bg-border/70 mx-3" />
|
|
<View className="flex-1 flex-row items-center">
|
|
<View className="flex-col">
|
|
<Text className="text-foreground text-xs">Category</Text>
|
|
<Text
|
|
variant="p"
|
|
className="text-foreground font-semibold"
|
|
numberOfLines={1}
|
|
>
|
|
Subscription
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</Card>
|
|
|
|
{/* Items / Billing Summary */}
|
|
<Card className="mb-4 bg-card rounded-[6px]">
|
|
<View className="p-4">
|
|
<View className="flex-row items-center gap-2">
|
|
<Text variant="small" className="">
|
|
Billing Summary
|
|
</Text>
|
|
</View>
|
|
|
|
{MOCK_ITEMS.map((item, i) => (
|
|
<View
|
|
key={i}
|
|
className={`flex-row justify-between py-3 ${i < MOCK_ITEMS.length - 1 ? "border-b border-border/70" : ""}`}
|
|
>
|
|
<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">
|
|
QTY: {item.qty} · ${item.unitPrice}/unit
|
|
</Text>
|
|
</View>
|
|
<Text variant="p" className="text-foreground font-bold text-sm">
|
|
${item.total.toLocaleString()}
|
|
</Text>
|
|
</View>
|
|
))}
|
|
|
|
<View className="mt-3 pt-3 flex-row justify-between items-center border-t border-border/70">
|
|
<Text variant="muted" className="font-semibold text-sm">
|
|
Total Balance
|
|
</Text>
|
|
<Text
|
|
variant="h3"
|
|
className="text-foreground font-semibold text-xl tracking-tight"
|
|
>
|
|
${invoice?.amount.toLocaleString() || "0"}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</Card>
|
|
|
|
{/* Actions */}
|
|
<View className="flex-row gap-3">
|
|
<Button
|
|
className=" flex-1 mb-4 h-10 rounded-[6px] bg-primary shadow-lg shadow-primary/30"
|
|
onPress={() => {}}
|
|
>
|
|
<Share2 color="#ffffff" size={14} strokeWidth={2.5} />
|
|
<Text className=" text-white text-xs font-semibold uppercase tracking-widest">
|
|
Share
|
|
</Text>
|
|
</Button>
|
|
<ShadowWrapper>
|
|
<Button
|
|
className=" flex-1 mb-4 h-10 rounded-[10px] bg-card"
|
|
onPress={() => {}}
|
|
>
|
|
<Download color="#000" size={14} strokeWidth={2.5} />
|
|
<Text className="text-black text-xs font-semibold uppercase tracking-widest">
|
|
Download PDF
|
|
</Text>
|
|
</Button>
|
|
</ShadowWrapper>
|
|
</View>
|
|
</ScrollView>
|
|
</ScreenWrapper>
|
|
);
|
|
}
|