import React, { ReactNode, useState } from 'react'; import { Modal, View, TouchableOpacity, StyleSheet, Animated, Easing, Dimensions, TextInput, KeyboardAvoidingView, Platform, ScrollView } from 'react-native'; import MyText from './text'; import MyButton from './button'; import tw from "../lib/tailwind"; interface DialogProps { open: boolean; onClose: () => void; children: ReactNode; enableDismiss?: boolean; } const SCREEN_HEIGHT = Dimensions.get('window').height; export const BottomDialog: React.FC = ({ open, onClose, children, enableDismiss = true }) => { const [slideAnim] = useState(new Animated.Value(SCREEN_HEIGHT)); React.useEffect(() => { if (open) { Animated.timing(slideAnim, { toValue: 0, duration: 300, easing: Easing.out(Easing.cubic), useNativeDriver: true, }).start(); } else { Animated.timing(slideAnim, { toValue: SCREEN_HEIGHT, duration: 200, useNativeDriver: true, }).start(); } }, [open]); return ( {enableDismiss ? ( ) : ( )} {children} ); }; export const RawBottomDialog: React.FC = ({ open, onClose, children, enableDismiss = true }) => { const [slideAnim] = useState(new Animated.Value(SCREEN_HEIGHT)); React.useEffect(() => { if (open) { Animated.timing(slideAnim, { toValue: 0, duration: 300, easing: Easing.out(Easing.cubic), useNativeDriver: true, }).start(); } else { Animated.timing(slideAnim, { toValue: SCREEN_HEIGHT, duration: 200, useNativeDriver: true, }).start(); } }, [open]); return ( {enableDismiss ? ( ) : ( )} {children} {/* {children} */} ); }; const styles = StyleSheet.create({ backdrop: { flex: 1, backgroundColor: 'rgba(0,0,0,0.3)', }, disabledBackdrop: { pointerEvents: 'none', }, dialog: { position: 'absolute', left: 0, right: 0, bottom: 0, backgroundColor: '#fff', borderTopLeftRadius: 18, borderTopRightRadius: 18, paddingHorizontal: 20, paddingBottom: 0, elevation: 8, shadowColor: '#000', shadowOffset: { width: 0, height: -2 }, shadowOpacity: 0.2, shadowRadius: 8, maxHeight: SCREEN_HEIGHT * 0.85, // Limit max height so it doesn't cover entire screen }, handle: { width: 40, height: 5, borderRadius: 3, backgroundColor: '#ccc', alignSelf: 'center', marginTop: 12, marginBottom: 8, }, keyboardAvoidingContainer: { flex: 1, width: '100%', }, scrollContainer: { flex: 1, width: '100%', }, scrollContent: { flexGrow: 1, paddingBottom: Platform.OS === 'ios' ? 40 : 20, // Extra padding for iOS keyboard }, }); const commentStyles = StyleSheet.create({ container: { marginBottom: 16, }, input: { borderWidth: 1, borderColor: '#ccc', borderRadius: 8, padding: 10, minHeight: 80, fontSize: 16, }, }); export default BottomDialog; interface ConfirmationDialogProps { open: boolean; positiveAction: (comment?: string) => void; commentNeeded?: boolean; negativeAction?: () => void; title?: string; message?: string; confirmText?: string; cancelText?: string; isLoading?: boolean; } export const ConfirmationDialog: React.FC = (props) => { const { open, positiveAction, commentNeeded = false, negativeAction, title = "Are you sure?", message = "Do you really want to proceed with this action?", confirmText = "Confirm", cancelText = "Cancel", isLoading = false, } = props; const [comment, setComment] = useState(''); const handleConfirm = () => { positiveAction(commentNeeded ? comment : undefined); setComment(''); // Reset comment after action }; const handleCancel = () => { if (negativeAction) { negativeAction(); } setComment(''); // Reset comment on cancel }; return ( {title} {message} {commentNeeded && ( )} ); }