Add a unified event editor that works in two modes: - Calendar mode: Create/edit events directly via EventService API - Chat mode: Edit AI-proposed events before confirming them The chat mode allows users to modify proposed events (title, time, recurrence) and persists changes both locally and to the server. New components: DateTimePicker, ScrollableDropdown, useDropdownPosition New API: PUT /api/chat/messages/:messageId/proposal
80 lines
1.9 KiB
TypeScript
80 lines
1.9 KiB
TypeScript
import { Modal, Pressable, View } from "react-native";
|
|
import { ReactNode } from "react";
|
|
import { useThemeStore } from "../stores/ThemeStore";
|
|
import { CardBase } from "./CardBase";
|
|
|
|
type ModalBaseProps = {
|
|
visible: boolean;
|
|
onClose: () => void;
|
|
title: string;
|
|
subtitle?: string;
|
|
children: ReactNode;
|
|
attachment?: ReactNode;
|
|
footer?: {
|
|
label: string;
|
|
onPress: () => void;
|
|
};
|
|
scrollable?: boolean;
|
|
maxContentHeight?: number;
|
|
};
|
|
|
|
export const ModalBase = ({
|
|
visible,
|
|
onClose,
|
|
title,
|
|
subtitle,
|
|
children,
|
|
attachment,
|
|
footer,
|
|
scrollable,
|
|
maxContentHeight,
|
|
}: ModalBaseProps) => {
|
|
const { theme } = useThemeStore();
|
|
|
|
return (
|
|
<Modal
|
|
visible={visible}
|
|
transparent={true}
|
|
animationType="fade"
|
|
onRequestClose={onClose}
|
|
>
|
|
<View className="flex-1 justify-center items-center">
|
|
{/* Backdrop - absolute positioned behind the card */}
|
|
<Pressable
|
|
className="absolute inset-0"
|
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
|
onPress={onClose}
|
|
/>
|
|
{/* Card content - on top, naturally blocks touches to backdrop */}
|
|
<View
|
|
className="w-11/12 rounded-2xl overflow-hidden"
|
|
style={{
|
|
backgroundColor: theme.primeBg,
|
|
borderWidth: 4,
|
|
borderColor: theme.borderPrimary,
|
|
}}
|
|
>
|
|
<CardBase
|
|
title={title}
|
|
subtitle={subtitle}
|
|
attachment={attachment}
|
|
footer={footer}
|
|
scrollable={scrollable}
|
|
maxContentHeight={maxContentHeight}
|
|
borderWidth={0}
|
|
headerBorderWidth={3}
|
|
headerPadding={4}
|
|
contentPadding={4}
|
|
headerTextSize="text-lg"
|
|
contentBg={theme.primeBg}
|
|
>
|
|
{children}
|
|
</CardBase>
|
|
</View>
|
|
</View>
|
|
</Modal>
|
|
);
|
|
};
|
|
|
|
export default ModalBase;
|