- Dockerfile + deploy.sh for Hetzner server - Email verification via Better Auth + Resend - Invite code flow (6-digit OTP, generate/join) - Settlement share percent fix (payer vs debtor) - OCR scanner fixes (date display, retry, viewfinder) - app.json icon/splash/adaptive-icon configured - iOS deployment target 15.5 (ML Kit requirement) - DB migration 0014: household_invitations table Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
import { ActivityIndicator, Pressable, Text, View } from "react-native";
|
|
import { TAB_COLORS } from "@/src/constants/colors";
|
|
|
|
type Props = {
|
|
title: string;
|
|
onClose: () => void;
|
|
closeLabel: string;
|
|
onSave?: () => void;
|
|
saveLabel?: string;
|
|
saveDisabled?: boolean;
|
|
saveLoading?: boolean;
|
|
saveColor?: string;
|
|
};
|
|
|
|
export function ModalHeader({
|
|
title,
|
|
onClose,
|
|
closeLabel,
|
|
onSave,
|
|
saveLabel,
|
|
saveDisabled = false,
|
|
saveLoading = false,
|
|
saveColor = TAB_COLORS.household,
|
|
}: Props) {
|
|
return (
|
|
<View className="flex-row items-center justify-between px-4 py-4 border-b border-gray-100">
|
|
<Pressable onPress={onClose}>
|
|
<Text className="text-base text-gray-500">{closeLabel}</Text>
|
|
</Pressable>
|
|
<Text className="text-base font-semibold text-gray-900">{title}</Text>
|
|
{onSave ? (
|
|
<Pressable onPress={onSave} disabled={saveLoading || saveDisabled}>
|
|
{saveLoading ? (
|
|
<ActivityIndicator size="small" color={saveColor} />
|
|
) : (
|
|
<Text
|
|
className="text-base font-semibold"
|
|
style={{ color: saveDisabled ? "#9ca3af" : saveColor }}
|
|
>
|
|
{saveLabel}
|
|
</Text>
|
|
)}
|
|
</Pressable>
|
|
) : (
|
|
<View style={{ width: 40 }} />
|
|
)}
|
|
</View>
|
|
);
|
|
}
|