Yaltopia-Tickets-App/app/(tabs)/index.tsx
“kirukib” 3b471df8d5 feat: finalize app with swagger-based pages, Lucide icons, mobile UI
- Add Lucide React Native icon library and use across tabs and screens
- Mobile-like design: rounded cards (xl/2xl), section dividers, icon chips, chevrons
- New pages from swagger: register, invoices/[id], reports, documents, settings
- Invoice detail: amount, bill to, items, Share/PDF actions (GET /invoices/{id})
- Register screen with link to login (POST /auth/register)
- Reports list with mock data and download (GET /reports)
- Documents list with upload CTA (GET /documents)
- Settings: notifications link, language, about
- Profile: links to Notifications, Reports, Documents, Settings
- Home: invoice rows navigate to /invoices/[id]
- Login ↔ Register navigation
- Keep orange (#ea580c) and dark navbar (#2d2d2d) theme throughout
- README: update screens table with new routes

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-22 23:04:04 +03:00

148 lines
7.0 KiB
TypeScript

import { View, ScrollView, Pressable } from 'react-native';
import { Text } from '@/components/ui/text';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { EARNINGS_SUMMARY, MOCK_INVOICES, MOCK_USER } from '@/lib/mock-data';
import { router } from 'expo-router';
import { Camera, Send, ChevronRight, Wallet, DollarSign, Clock } from '@/lib/icons';
const PRIMARY = '#ea580c';
const statusColor: Record<string, string> = {
Waiting: 'bg-amber-500/20 text-amber-700',
Paid: 'bg-emerald-500/20 text-emerald-700',
Draft: 'bg-gray-200 text-gray-700',
Unpaid: 'bg-red-500/20 text-red-700',
};
export default function HomeScreen() {
return (
<ScrollView
className="flex-1 bg-[#f5f5f5]"
contentContainerStyle={{ padding: 20, paddingBottom: 40 }}
showsVerticalScrollIndicator={false}
>
<View className="mb-5">
<Text className="text-2xl font-bold text-gray-900">Hi {MOCK_USER.name},</Text>
<Text className="text-muted-foreground mt-1 text-base">Take a look at your last activity.</Text>
</View>
<Card className="mb-5 overflow-hidden rounded-2xl border-0 shadow-sm">
<View className="bg-primary/10 px-5 py-5">
<Text className="text-muted-foreground text-sm">Earnings balance</Text>
<Text className="mt-1 text-3xl font-bold text-gray-900">${EARNINGS_SUMMARY.balance.toLocaleString()}</Text>
</View>
<View className="flex-row border-t border-border">
<Pressable
className="flex-1 flex-row items-center gap-3 px-5 py-4"
onPress={() => router.push('/(tabs)/payments')}
>
<View className="rounded-xl bg-primary/15 p-2">
<Clock color={PRIMARY} size={20} strokeWidth={2} />
</View>
<View>
<Text className="text-muted-foreground text-xs">Waiting for pay</Text>
<Text className="font-semibold text-gray-900">${EARNINGS_SUMMARY.waitingAmount.toLocaleString()}</Text>
<Text className="text-muted-foreground text-xs">{EARNINGS_SUMMARY.waitingCount} Waiting invoice</Text>
</View>
</Pressable>
<View className="w-px bg-border" />
<Pressable className="flex-1 flex-row items-center gap-3 px-5 py-4">
<View className="rounded-xl bg-emerald-500/15 p-2">
<DollarSign color="#059669" size={20} strokeWidth={2} />
</View>
<View>
<Text className="text-muted-foreground text-xs">Paid this month</Text>
<Text className="font-semibold text-gray-900">${EARNINGS_SUMMARY.paidThisMonth.toLocaleString()}</Text>
<Text className="text-muted-foreground text-xs">{EARNINGS_SUMMARY.paidCount} Paid invoice</Text>
</View>
</Pressable>
</View>
</Card>
<View className="mb-5 flex-row gap-3">
<Button className="min-h-12 flex-1 rounded-xl bg-primary" onPress={() => router.push('/(tabs)/scan')}>
<Camera color="#ffffff" size={20} strokeWidth={2} />
<Text className="ml-2 text-primary-foreground font-medium">Scan invoice</Text>
</Button>
<Button
variant="outline"
className="min-h-12 flex-1 rounded-xl border-border"
onPress={() => router.push('/(tabs)/proforma')}
>
<Send color={PRIMARY} size={20} strokeWidth={2} />
<Text className="ml-2 font-medium text-gray-700">Send proforma</Text>
</Button>
</View>
<ScrollView horizontal showsHorizontalScrollIndicator={false} className="-mx-1 mb-4">
<View className="flex-row gap-2 px-1">
{['All', 'Draft', 'Waiting', 'Paid', 'Unpaid'].map((filter) => (
<Pressable
key={filter}
className={`rounded-full px-4 py-2.5 ${filter === 'Waiting' ? 'bg-primary' : 'bg-white'} border border-border`}
>
<Text
className={
filter === 'Waiting' ? 'text-primary-foreground text-sm font-medium' : 'text-muted-foreground text-sm'
}
>
{filter}
</Text>
</Pressable>
))}
</View>
</ScrollView>
<View className="mb-2 flex-row items-center gap-2">
<View className="h-px flex-1 bg-border" />
<Text className="text-muted-foreground text-xs font-medium">Today</Text>
<View className="h-px flex-1 bg-border" />
</View>
{MOCK_INVOICES.filter((i) => i.status === 'Waiting').map((inv) => (
<Pressable key={inv.id} onPress={() => router.push(`/invoices/${inv.id}`)}>
<Card className="mb-2.5 overflow-hidden rounded-xl border border-border bg-white">
<CardContent className="flex-row items-center justify-between py-4 pl-4 pr-3">
<View className="flex-1">
<Text className="font-semibold text-gray-900">{inv.recipient}</Text>
<Text className="text-muted-foreground mt-0.5 text-sm">Invoice #{inv.invoiceNumber} · Due {inv.dueDate}</Text>
</View>
<View className="items-end gap-1">
<Text className="font-semibold text-gray-900">${inv.amount.toLocaleString()}</Text>
<View className={`rounded-full px-2.5 py-1 ${statusColor[inv.status]}`}>
<Text className="text-xs font-medium">{inv.status}</Text>
</View>
</View>
<ChevronRight className="ml-2 text-muted-foreground" color="#71717a" size={20} strokeWidth={2} />
</CardContent>
</Card>
</Pressable>
))}
<View className="mb-2 mt-6 flex-row items-center gap-2">
<View className="h-px flex-1 bg-border" />
<Text className="text-muted-foreground text-xs font-medium">Yesterday</Text>
<View className="h-px flex-1 bg-border" />
</View>
{MOCK_INVOICES.filter((i) => i.status === 'Paid').map((inv) => (
<Pressable key={inv.id} onPress={() => router.push(`/invoices/${inv.id}`)}>
<Card className="mb-2.5 overflow-hidden rounded-xl border border-border bg-white">
<CardContent className="flex-row items-center justify-between py-4 pl-4 pr-3">
<View className="flex-1">
<Text className="font-semibold text-gray-900">{inv.recipient}</Text>
<Text className="text-muted-foreground mt-0.5 text-sm">Invoice #{inv.invoiceNumber} · {inv.dueDate}</Text>
</View>
<View className="items-end gap-1">
<Text className="font-semibold text-gray-900">${inv.amount.toLocaleString()}</Text>
<View className={`rounded-full px-2.5 py-1 ${statusColor[inv.status]}`}>
<Text className="text-xs font-medium">{inv.status}</Text>
</View>
</View>
<ChevronRight className="ml-2 text-muted-foreground" color="#71717a" size={20} strokeWidth={2} />
</CardContent>
</Card>
</Pressable>
))}
</ScrollView>
);
}