feat: add EditEventScreen with calendar and chat mode support
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
This commit is contained in:
@@ -1,25 +1,31 @@
|
||||
import { View, Text, Pressable } from "react-native";
|
||||
import { Feather } from "@expo/vector-icons";
|
||||
import { ProposedEventChange, parseRRule, formatDate } from "@calchat/shared";
|
||||
import { ProposedEventChange, formatDate } from "@calchat/shared";
|
||||
import { rrulestr } from "rrule";
|
||||
import { useThemeStore } from "../stores/ThemeStore";
|
||||
import { EventCardBase } from "./EventCardBase";
|
||||
|
||||
type ProposedEventCardProps = {
|
||||
proposedChange: ProposedEventChange;
|
||||
onConfirm: () => void;
|
||||
onConfirm: (proposal: ProposedEventChange) => void;
|
||||
onReject: () => void;
|
||||
onEdit?: (proposal: ProposedEventChange) => void;
|
||||
};
|
||||
|
||||
const ConfirmRejectButtons = ({
|
||||
const ActionButtons = ({
|
||||
isDisabled,
|
||||
respondedAction,
|
||||
showEdit,
|
||||
onConfirm,
|
||||
onReject,
|
||||
onEdit,
|
||||
}: {
|
||||
isDisabled: boolean;
|
||||
respondedAction?: "confirm" | "reject";
|
||||
showEdit: boolean;
|
||||
onConfirm: () => void;
|
||||
onReject: () => void;
|
||||
onEdit?: () => void;
|
||||
}) => {
|
||||
const { theme } = useThemeStore();
|
||||
return (
|
||||
@@ -56,6 +62,19 @@ const ConfirmRejectButtons = ({
|
||||
Ablehnen
|
||||
</Text>
|
||||
</Pressable>
|
||||
{showEdit && onEdit && (
|
||||
<Pressable
|
||||
onPress={onEdit}
|
||||
className="py-2 px-3 rounded-lg items-center"
|
||||
style={{
|
||||
backgroundColor: theme.secondaryBg,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.borderPrimary,
|
||||
}}
|
||||
>
|
||||
<Feather name="edit-2" size={18} color={theme.textPrimary} />
|
||||
</Pressable>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@@ -64,6 +83,7 @@ export const ProposedEventCard = ({
|
||||
proposedChange,
|
||||
onConfirm,
|
||||
onReject,
|
||||
onEdit,
|
||||
}: ProposedEventCardProps) => {
|
||||
const { theme } = useThemeStore();
|
||||
const event = proposedChange.event;
|
||||
@@ -79,7 +99,7 @@ export const ProposedEventCard = ({
|
||||
const newUntilDate =
|
||||
proposedChange.action === "update" &&
|
||||
event?.recurrenceRule &&
|
||||
parseRRule(event.recurrenceRule)?.until;
|
||||
rrulestr(event.recurrenceRule).options.until;
|
||||
|
||||
if (!event) {
|
||||
return null;
|
||||
@@ -93,7 +113,7 @@ export const ProposedEventCard = ({
|
||||
startTime={event.startTime}
|
||||
endTime={event.endTime}
|
||||
description={event.description}
|
||||
isRecurring={event.isRecurring}
|
||||
isRecurring={!!event.recurrenceRule}
|
||||
>
|
||||
{/* Show new exception date for delete/single actions */}
|
||||
{newExceptionDate && (
|
||||
@@ -123,11 +143,13 @@ export const ProposedEventCard = ({
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<ConfirmRejectButtons
|
||||
<ActionButtons
|
||||
isDisabled={isDisabled}
|
||||
respondedAction={proposedChange.respondedAction}
|
||||
onConfirm={onConfirm}
|
||||
showEdit={proposedChange.action !== "delete" && !isDisabled}
|
||||
onConfirm={() => onConfirm(proposedChange)}
|
||||
onReject={onReject}
|
||||
onEdit={onEdit ? () => onEdit(proposedChange) : undefined}
|
||||
/>
|
||||
</EventCardBase>
|
||||
</View>
|
||||
|
||||
Reference in New Issue
Block a user