Yaltopia-Tickets-App/components/FormFlow.tsx
2026-06-05 13:39:37 +03:00

117 lines
3.3 KiB
TypeScript

import React from "react";
import { View, Pressable, ScrollView, ActivityIndicator } from "react-native";
import { Text } from "@/components/ui/text";
import { cn } from "@/lib/utils";
import { ArrowLeft, ArrowRight } from "@/lib/icons";
import { useSirouRouter } from "@sirou/react-native";
import { AppRoutes } from "@/lib/routes";
interface Step {
key: string;
label: string;
}
interface FormFlowProps {
steps: Step[];
currentStep: number;
onNext: () => void;
onBack: () => void;
onComplete: () => void;
children: React.ReactNode;
loading?: boolean;
nextLabel?: string;
completeLabel?: string;
hideFooter?: boolean;
hideHeader?: boolean;
}
export function FormFlow({
steps,
currentStep,
onNext,
onBack,
onComplete,
children,
loading = false,
nextLabel = "Continue",
completeLabel = "Submit",
hideFooter = false,
hideHeader = false,
}: FormFlowProps) {
const nav = useSirouRouter<AppRoutes>();
const isFirst = currentStep === 0;
const isLast = currentStep === steps.length - 1;
return (
<View className="flex-1 bg-background">
{!hideHeader && (
<View className="px-5 pt-4 pb-3 flex-row items-center justify-between">
<Pressable
onPress={isFirst ? () => nav.back() : onBack}
className="h-9 w-9 rounded-[8px] border border-border items-center justify-center"
>
<ArrowLeft size={18} color="#64748b" />
</Pressable>
<View className="flex-row items-center gap-1">
<Text className="text-muted-foreground text-[11px] font-sans-bold">
{currentStep + 1}
</Text>
<Text className="text-muted-foreground text-[11px] font-sans-medium">
/
</Text>
<Text className="text-muted-foreground text-[11px] font-sans-medium">
{steps.length}
</Text>
</View>
</View>
)}
<View className="px-5 pb-5">
<View className="flex-row gap-1">
{steps.map((step, idx) => (
<View
key={step.key}
className={cn(
"h-1.5 rounded-full flex-1",
idx <= currentStep ? "bg-primary" : "bg-border",
)}
/>
))}
</View>
</View>
<ScrollView
className="flex-1 px-5"
showsVerticalScrollIndicator={false}
contentContainerStyle={{ paddingBottom: 20 }}
>
{children}
</ScrollView>
{!hideFooter && (
<View className="px-5 pt-3 border-t border-border">
<Pressable
onPress={isLast ? onComplete : onNext}
className={cn(
"h-12 rounded-[8px] items-center justify-center flex-row gap-2",
loading ? "bg-primary/60" : "bg-primary",
)}
disabled={loading}
>
{loading ? (
<ActivityIndicator color="white" size="small" />
) : (
<>
<Text className="text-white font-sans-bold text-xs">
{isLast ? completeLabel : nextLabel}
</Text>
{!isLast && <ArrowRight size={16} color="white" />}
</>
)}
</Pressable>
</View>
)}
</View>
);
}