feat: Expo scaffold + auth screens + core screens (#39-#46, #48)

This commit is contained in:
Nemo
2026-03-23 18:40:04 +08:00
commit 745321e5bd
45 changed files with 10557 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
import React from 'react';
import { View, Text } from 'react-native';
type Status =
| 'active' | 'inactive' | 'suspended'
| 'open' | 'in_progress' | 'resolved' | 'closed'
| 'paid' | 'unpaid' | 'partial' | 'overdue'
| 'pending' | 'approved' | 'rejected'
| string;
interface StatusBadgeProps {
status: Status;
label?: string;
}
const statusConfig: Record<string, { bg: string; text: string; label: string }> = {
active: { bg: 'bg-green-100', text: 'text-green-700', label: 'Active' },
inactive: { bg: 'bg-gray-100', text: 'text-gray-600', label: 'Inactive' },
suspended: { bg: 'bg-red-100', text: 'text-red-700', label: 'Suspended' },
open: { bg: 'bg-blue-100', text: 'text-blue-700', label: 'Open' },
in_progress: { bg: 'bg-yellow-100',text: 'text-yellow-700',label: 'In Progress' },
resolved: { bg: 'bg-green-100', text: 'text-green-700', label: 'Resolved' },
closed: { bg: 'bg-gray-100', text: 'text-gray-600', label: 'Closed' },
paid: { bg: 'bg-green-100', text: 'text-green-700', label: 'Paid' },
unpaid: { bg: 'bg-red-100', text: 'text-red-700', label: 'Unpaid' },
partial: { bg: 'bg-orange-100',text: 'text-orange-700',label: 'Partial' },
overdue: { bg: 'bg-red-100', text: 'text-red-700', label: 'Overdue' },
pending: { bg: 'bg-yellow-100',text: 'text-yellow-700',label: 'Pending' },
approved: { bg: 'bg-green-100', text: 'text-green-700', label: 'Approved' },
rejected: { bg: 'bg-red-100', text: 'text-red-700', label: 'Rejected' },
};
export const StatusBadge: React.FC<StatusBadgeProps> = ({ status, label }) => {
const config = statusConfig[status] ?? {
bg: 'bg-gray-100',
text: 'text-gray-600',
label: status.replace(/_/g, ' '),
};
return (
<View className={`px-2.5 py-1 rounded-full self-start ${config.bg}`}>
<Text className={`text-xs font-medium capitalize ${config.text}`}>
{label ?? config.label}
</Text>
</View>
);
};