diff --git a/src/features/Calendar/components/EventDetailCard/EventDetailCard.style.ts b/src/features/Calendar/components/EventDetailCard/EventDetailCard.style.ts
index 0112e53..80d45aa 100644
--- a/src/features/Calendar/components/EventDetailCard/EventDetailCard.style.ts
+++ b/src/features/Calendar/components/EventDetailCard/EventDetailCard.style.ts
@@ -43,6 +43,7 @@ export const Content = styled.div`
export const TextWrapper = styled.div`
display: flex;
flex-direction: column;
+ align-items: flex-start;
gap: 8px;
`
diff --git a/src/features/Calendar/hooks/useCalendarDraftEvent.ts b/src/features/Calendar/hooks/useCalendarDraftEvent.ts
index f8d9d50..f794066 100644
--- a/src/features/Calendar/hooks/useCalendarDraftEvent.ts
+++ b/src/features/Calendar/hooks/useCalendarDraftEvent.ts
@@ -32,11 +32,16 @@ export const useCalendarDraftEvent = ({
updateEventTiming,
}: UseCalendarDraftEventArgs) => {
const handleCloseModalWithCleanup = useCallback(() => {
- if (!isModalEditing && modal.eventId != null) {
- removeEvent(modal.eventId)
+ if (modal.eventId != null) {
+ const shouldRemoveDraft =
+ !isModalEditing ||
+ events.some((eventItem) => eventItem.id === modal.eventId && eventItem.isTemporary)
+ if (shouldRemoveDraft) {
+ removeEvent(modal.eventId)
+ }
}
handleCloseModal()
- }, [handleCloseModal, isModalEditing, modal.eventId, removeEvent])
+ }, [events, handleCloseModal, isModalEditing, modal.eventId, removeEvent])
const clearPendingDraftEvent = useCallback(() => {
if (!modal.isOpen || isModalEditing || modal.eventId == null) return
diff --git a/src/features/Calendar/hooks/useCalendarEvents.ts b/src/features/Calendar/hooks/useCalendarEvents.ts
index c7653be..ff780a6 100644
--- a/src/features/Calendar/hooks/useCalendarEvents.ts
+++ b/src/features/Calendar/hooks/useCalendarEvents.ts
@@ -144,7 +144,9 @@ export const useCalendarEvents = (options: UseCalendarEventsOptions = {}) => {
// 서버 응답 후 임시 이벤트 id를 실제 id로 교체
const updateEventId = useCallback((tempId: CalendarEvent['id'], nextId: CalendarEvent['id']) => {
setEvents((prev) =>
- prev.map((event) => (event.id === tempId ? { ...event, id: nextId } : event)),
+ prev.map((event) =>
+ event.id === tempId ? { ...event, id: nextId, isTemporary: false } : event,
+ ),
)
}, [])
diff --git a/src/features/Calendar/utils/helpers/calendarPageHelpers.ts b/src/features/Calendar/utils/helpers/calendarPageHelpers.ts
index 7ca43ed..5dbfc6c 100644
--- a/src/features/Calendar/utils/helpers/calendarPageHelpers.ts
+++ b/src/features/Calendar/utils/helpers/calendarPageHelpers.ts
@@ -34,6 +34,7 @@ export const createEvent = (date: Date, index: number, allDay = false): Calendar
recurrenceGroup: null,
friendIds: [],
type: 'schedule',
+ isTemporary: true,
}
}
diff --git a/src/features/Todo/components/TodoCard/TodoCard.style.ts b/src/features/Todo/components/TodoCard/TodoCard.style.ts
index a37edf2..40a3adb 100644
--- a/src/features/Todo/components/TodoCard/TodoCard.style.ts
+++ b/src/features/Todo/components/TodoCard/TodoCard.style.ts
@@ -45,6 +45,15 @@ export const ButtonWrapper = styled.div`
}
}
`
+export const DeleteButton = styled.button`
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ cursor: pointer;
+`
export const TodoLeftWrapper = styled.div`
display: flex;
gap: 16px;
diff --git a/src/features/Todo/components/TodoCard/TodoCard.tsx b/src/features/Todo/components/TodoCard/TodoCard.tsx
index 832c1ae..5f19aa0 100644
--- a/src/features/Todo/components/TodoCard/TodoCard.tsx
+++ b/src/features/Todo/components/TodoCard/TodoCard.tsx
@@ -86,13 +86,16 @@ const TodoCard = ({
- {
event.stopPropagation()
handleDelete()
}}
- />
+ >
+
+
{openDeleteModal && isRecurringTodo && (
useCallback(
(values: ScheduleEditorFormValues, scope?: RecurrenceEventScope, occurrenceDate?: string) => {
- if (eventId == null || eventId === 0) return Promise.resolve()
+ if (eventId == null || eventId === 0 || initialEvent?.isTemporary) return Promise.resolve()
const startDate = values.eventStartDate ?? new Date(date)
const endDate = values.eventEndDate ?? startDate
const [start, end] = values.isAllday
diff --git a/src/shared/hooks/addSchedule/useScheduleSubmitFlow.ts b/src/shared/hooks/addSchedule/useScheduleSubmitFlow.ts
index ad0771e..cd2de0b 100644
--- a/src/shared/hooks/addSchedule/useScheduleSubmitFlow.ts
+++ b/src/shared/hooks/addSchedule/useScheduleSubmitFlow.ts
@@ -81,6 +81,7 @@ export const useScheduleSubmitFlow = ({
}, [])
const showToast = useToastStore.getState().showToast
+ const isTemporaryEvent = Boolean(initialEvent?.isTemporary)
const confirmTitle = useCallback(
(values: ScheduleEditorFormValues) => {
@@ -163,7 +164,7 @@ export const useScheduleSubmitFlow = ({
return
}
await submitScheduleValues(values, {
- mode: isEditing ? 'patch' : 'create',
+ mode: isEditing && !isTemporaryEvent ? 'patch' : 'create',
})
},
(errors) => {
diff --git a/src/shared/hooks/addTodo/useTodoDetailHydration.ts b/src/shared/hooks/addTodo/useTodoDetailHydration.ts
index 21fb664..3c8a119 100644
--- a/src/shared/hooks/addTodo/useTodoDetailHydration.ts
+++ b/src/shared/hooks/addTodo/useTodoDetailHydration.ts
@@ -12,6 +12,7 @@ type UseTodoDetailHydrationProps = {
date: string
eventId: CalendarEvent['id']
isEditing: boolean
+ initialEvent?: CalendarEvent | null
todoDate: Date | null
setValue: UseFormSetValue
}
@@ -20,11 +21,13 @@ export const useTodoDetailHydration = ({
date,
eventId,
isEditing,
+ initialEvent,
todoDate,
setValue,
}: UseTodoDetailHydrationProps) => {
const hydratedDetailKeyRef = useRef(null)
- const isPersistedTodo = isEditing && eventId != null && eventId !== 0
+ const isPersistedTodo =
+ isEditing && eventId != null && eventId !== 0 && !initialEvent?.isTemporary
const shouldFetchDetail = isPersistedTodo
const detailOccurrenceDate = moment(date).format('YYYY-MM-DD')
const { data: detailData } = useGetDetailTodoQuery(
diff --git a/src/shared/hooks/addTodo/useTodoFooter.tsx b/src/shared/hooks/addTodo/useTodoFooter.tsx
index 6140ff0..2aa6e70 100644
--- a/src/shared/hooks/addTodo/useTodoFooter.tsx
+++ b/src/shared/hooks/addTodo/useTodoFooter.tsx
@@ -99,7 +99,12 @@ export const useTodoFooter = ({
if (eventIdRef.current != null && eventIdRef.current !== 0) {
onEventColorChangeRef.current?.(eventIdRef.current, value)
}
- if (!isEditingRef.current || eventIdRef.current == null || eventIdRef.current === 0) {
+ if (
+ !isEditingRef.current ||
+ eventIdRef.current == null ||
+ eventIdRef.current === 0 ||
+ !isPersistedTodoRef.current
+ ) {
return
}
patchTodoMutateRef.current(
diff --git a/src/shared/hooks/form/useTodoEditorForm.ts b/src/shared/hooks/form/useTodoEditorForm.ts
index 8c7150a..d74e459 100644
--- a/src/shared/hooks/form/useTodoEditorForm.ts
+++ b/src/shared/hooks/form/useTodoEditorForm.ts
@@ -127,7 +127,7 @@ export const useTodoEditorForm = ({
recurrenceGroup,
}
- const isPersistedTodoId = typeof id === 'number' && id > 0
+ const isPersistedTodoId = typeof id === 'number' && id > 0 && !initialEvent?.isTemporary
if (isEditing && isPersistedTodoId) {
const occurrenceDate = options?.occurrenceDate ?? formatIsoDate(date)
return patchTodoMutate({
diff --git a/src/shared/types/calendar/types.ts b/src/shared/types/calendar/types.ts
index 3661414..413e456 100644
--- a/src/shared/types/calendar/types.ts
+++ b/src/shared/types/calendar/types.ts
@@ -31,6 +31,7 @@ export type CalendarEvent = Omit & {
type?: 'todo' | 'schedule'
isDone?: boolean
isRecurring?: boolean
+ isTemporary?: boolean
}
export type GetEventsResponseDTO = {
diff --git a/src/shared/ui/Modals/TodoEditor/TodoEditorContent.tsx b/src/shared/ui/Modals/TodoEditor/TodoEditorContent.tsx
index 81f0c4f..4d7cacc 100644
--- a/src/shared/ui/Modals/TodoEditor/TodoEditorContent.tsx
+++ b/src/shared/ui/Modals/TodoEditor/TodoEditorContent.tsx
@@ -39,6 +39,7 @@ const TodoEditorContent = ({
date,
eventId,
isEditing,
+ initialEvent,
todoDate: todo.todoDate,
setValue,
})