107 lines
3.1 KiB
TypeScript
107 lines
3.1 KiB
TypeScript
import React from "react";
|
|
import { View, Modal, Pressable, StyleSheet } from "react-native";
|
|
import { Text } from "./ui/text";
|
|
import { Button } from "./ui/button";
|
|
import { LucideIcon } from "lucide-react-native";
|
|
import { X } from "@/lib/icons";
|
|
import { useColorScheme } from "nativewind";
|
|
|
|
interface ActionModalProps {
|
|
visible: boolean;
|
|
onClose: () => void;
|
|
onConfirm: () => void;
|
|
title: string;
|
|
description: string;
|
|
confirmText?: string;
|
|
cancelText?: string;
|
|
confirmVariant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link";
|
|
icon?: LucideIcon;
|
|
iconColor?: string;
|
|
loading?: boolean;
|
|
}
|
|
|
|
export function ActionModal({
|
|
visible,
|
|
onClose,
|
|
onConfirm,
|
|
title,
|
|
description,
|
|
confirmText = "Confirm",
|
|
cancelText = "Cancel",
|
|
confirmVariant = "default",
|
|
icon: Icon,
|
|
iconColor = "#ea580c",
|
|
loading = false,
|
|
}: ActionModalProps) {
|
|
const { colorScheme } = useColorScheme();
|
|
const isDark = colorScheme === "dark";
|
|
|
|
return (
|
|
<Modal
|
|
transparent
|
|
visible={visible}
|
|
animationType="fade"
|
|
onRequestClose={onClose}
|
|
>
|
|
<Pressable
|
|
style={StyleSheet.absoluteFill}
|
|
className="bg-black/60 items-center justify-center p-6"
|
|
onPress={onClose}
|
|
>
|
|
<Pressable
|
|
className="w-full max-w-sm bg-card rounded-[6px] border border-border overflow-hidden"
|
|
onPress={(e) => e.stopPropagation()}
|
|
>
|
|
{/* Header */}
|
|
<View className="flex-row items-center justify-between px-5 pt-5 pb-2">
|
|
<View className="flex-row items-center gap-3">
|
|
{Icon && (
|
|
<View className="p-2 rounded-full bg-primary/10">
|
|
<Icon size={20} color={iconColor} />
|
|
</View>
|
|
)}
|
|
<Text variant="h4" className="font-black uppercase tracking-tight">
|
|
{title}
|
|
</Text>
|
|
</View>
|
|
<Button variant="ghost" size="icon" className="h-8 w-8" onPress={onClose}>
|
|
<X size={18} color={isDark ? "#94a3b8" : "#64748b"} />
|
|
</Button>
|
|
</View>
|
|
|
|
{/* Body */}
|
|
<View className="px-5 pb-6">
|
|
<Text variant="p" className="text-muted-foreground font-medium leading-5">
|
|
{description}
|
|
</Text>
|
|
</View>
|
|
|
|
{/* Footer */}
|
|
<View className="flex-row border-t border-border p-3 gap-3">
|
|
<Button
|
|
variant="outline"
|
|
className="flex-1 h-12 rounded-[6px]"
|
|
onPress={onClose}
|
|
disabled={loading}
|
|
>
|
|
<Text className="font-bold uppercase tracking-widest text-xs">
|
|
{cancelText}
|
|
</Text>
|
|
</Button>
|
|
<Button
|
|
variant={confirmVariant}
|
|
className="flex-1 h-12 rounded-[6px]"
|
|
onPress={onConfirm}
|
|
loading={loading}
|
|
>
|
|
<Text className="font-bold uppercase tracking-widest text-xs">
|
|
{confirmText}
|
|
</Text>
|
|
</Button>
|
|
</View>
|
|
</Pressable>
|
|
</Pressable>
|
|
</Modal>
|
|
);
|
|
}
|