diff --git a/__tests__/elements/calendar.tsx b/__tests__/elements/calendar.tsx
index d27e2ef..1b733c8 100644
--- a/__tests__/elements/calendar.tsx
+++ b/__tests__/elements/calendar.tsx
@@ -1,32 +1,31 @@
-import React from 'react';
-import { render, screen, fireEvent } from '@testing-library/react';
-import '@testing-library/jest-dom';
-import { useGetTimelinesByEventQuery } from '@/redux/api/timelineApi';
-import Calendar from '@/components/elements/Timeline/Calendar';
+import React from 'react'
+import { render, screen, fireEvent } from '@testing-library/react'
+import '@testing-library/jest-dom'
+import { useGetTimelinesByEventQuery } from '@/redux/api/timelineApi'
+import Calendar from '@/components/elements/Timeline/Calendar'
// Mock the useGetTimelinesByEventQuery hook
jest.mock('@/redux/api/timelineApi', () => ({
useGetTimelinesByEventQuery: jest.fn(),
-}));
+}))
jest.mock('@/components/elements/Timeline/Calendar', () => {
- return {
- __esModule: true,
- default: jest.fn(() => (
-
-
Calendar Component
-
Task 1
-
Task 2
-
- )),
- }
-});
-
+ return {
+ __esModule: true,
+ default: jest.fn(() => (
+
+
Calendar Component
+
Task 1
+
Task 2
+
+ )),
+ }
+})
describe('Calendar', () => {
beforeEach(() => {
// Mock the return value of useGetTimelinesByEventQuery
- (useGetTimelinesByEventQuery as jest.Mock).mockReturnValue({
+ ;(useGetTimelinesByEventQuery as jest.Mock).mockReturnValue({
data: [
{
id: '1',
@@ -42,26 +41,26 @@ describe('Calendar', () => {
},
],
isLoading: false,
- });
- });
+ })
+ })
afterEach(() => {
- jest.clearAllMocks();
- });
+ jest.clearAllMocks()
+ })
test('renders the calendar component', () => {
- render();
- expect(screen.getByTestId('calendar')).toBeInTheDocument();
- });
+ render()
+ expect(screen.getByTestId('calendar')).toBeInTheDocument()
+ })
test('displays calendar events correctly', () => {
- render();
- expect(screen.getByText('Task 1')).toBeInTheDocument();
- expect(screen.getByText('Task 2')).toBeInTheDocument();
- });
+ render()
+ expect(screen.getByText('Task 1')).toBeInTheDocument()
+ expect(screen.getByText('Task 2')).toBeInTheDocument()
+ })
test('handles event clicks to show details in a modal', async () => {
- render();
- fireEvent.click(screen.getByText('Task 1'));
- });
-});
+ render()
+ fireEvent.click(screen.getByText('Task 1'))
+ })
+})
diff --git a/__tests__/timeline/timeline-delete.test.tsx b/__tests__/timeline/timeline-delete.test.tsx
new file mode 100644
index 0000000..1f9cce2
--- /dev/null
+++ b/__tests__/timeline/timeline-delete.test.tsx
@@ -0,0 +1,66 @@
+import React from 'react'
+import { render, fireEvent, waitFor } from '@testing-library/react'
+import '@testing-library/jest-dom'
+import { Provider } from 'react-redux'
+import { store } from '@/redux/store'
+import TimelineDetailsModal from '@/components/elements/Timeline/TimelineDetailsModal'
+
+jest.mock('@/redux/api/timelineApi', () => ({
+ useDeleteTimelineMutation: jest.fn(() => [
+ jest.fn().mockResolvedValue({}),
+ { isLoading: false, isSuccess: false },
+ ]),
+}))
+
+describe('TimelineDetailsModal', () => {
+ const mockOnClose = jest.fn()
+
+ it('deletes the timeline and closes the modal on successful delete', async () => {
+ const { getByText } = render(
+
+
+
+ )
+
+ global.confirm = jest.fn().mockReturnValue(true)
+
+ fireEvent.click(getByText('Delete Timeline'))
+
+ await waitFor(() => {
+ expect(mockOnClose).toHaveBeenCalled()
+ })
+ })
+
+ it('does not delete the timeline if user cancels', async () => {
+ const { getByText } = render(
+
+
+
+ )
+
+ global.confirm = jest.fn().mockReturnValue(false)
+
+ fireEvent.click(getByText('Delete Timeline'))
+ await waitFor(() => {
+ expect(mockOnClose).not.toHaveBeenCalled()
+ })
+ })
+})
diff --git a/__tests__/timeline/timeline.test.tsx b/__tests__/timeline/timeline.test.tsx
index 27a7097..017f312 100644
--- a/__tests__/timeline/timeline.test.tsx
+++ b/__tests__/timeline/timeline.test.tsx
@@ -17,6 +17,13 @@ jest.mock('@/components/elements/Timeline/Calendar', () => {
}
})
+jest.mock('@/components/elements/Timeline/TimelineDetailsModal', () => {
+ return {
+ __esModule: true,
+ default: jest.fn(() => Mocked DemoApp
),
+ }
+})
+
describe('EventTimeline', () => {
beforeEach(() => {
;(useGetTimelinesByEventQuery as jest.Mock).mockReturnValue({
diff --git a/src/components/elements/Timeline/Calendar.tsx b/src/components/elements/Timeline/Calendar.tsx
index af85967..4e96c86 100644
--- a/src/components/elements/Timeline/Calendar.tsx
+++ b/src/components/elements/Timeline/Calendar.tsx
@@ -2,12 +2,10 @@ import React from 'react'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
-import Modal from '@mui/material/Modal'
-import Box from '@mui/material/Box'
-import Typography from '@mui/material/Typography'
import { useGetTimelinesByEventQuery } from '@/redux/api/timelineApi'
import { EventApi } from '@fullcalendar/core/index.js'
import FullCalendar from '@fullcalendar/react'
+import TimelineDetailsModal from './TimelineDetailsModal'
interface DemoAppProps {
eventId: string
@@ -51,14 +49,12 @@ const DemoApp: React.FC = ({ eventId }) => {
p: 4,
}
-
-
if (isLoading) {
return (
- );
+ )
}
return (
@@ -77,27 +73,18 @@ const DemoApp: React.FC = ({ eventId }) => {
eventColor="#14b8a6"
displayEventTime={false}
/>
-
-
-
- Task Details
-
-
- Task title: {clickedEvent?.title}
-
-
- Start date: {clickedEvent?.start?.toLocaleTimeString()}
-
-
- End date: {clickedEvent?.end?.toLocaleTimeString()}
-
-
-
+ {clickedEvent && (
+
+ )}
)
diff --git a/src/components/elements/Timeline/TimelineDetailsModal.tsx b/src/components/elements/Timeline/TimelineDetailsModal.tsx
new file mode 100644
index 0000000..9a361cf
--- /dev/null
+++ b/src/components/elements/Timeline/TimelineDetailsModal.tsx
@@ -0,0 +1,86 @@
+import React from 'react';
+import { useDeleteTimelineMutation } from '@/redux/api/timelineApi';
+import Modal from '@mui/material/Modal';
+import Box from '@mui/material/Box';
+import Typography from '@mui/material/Typography';
+import Button from '@mui/material/Button';
+
+interface TimelineDetailsModalProps {
+ timelineId: string;
+ onClose: () => void;
+ showModal: boolean;
+ clickedEvent: {
+ title: string;
+ start: Date;
+ end: Date;
+ };
+}
+
+const style = {
+ position: 'absolute' as 'absolute',
+ top: '50%',
+ left: '50%',
+ transform: 'translate(-50%, -50%)',
+ width: 400,
+ bgcolor: 'background.paper',
+ border: '2px solid #000',
+ boxShadow: 24,
+ p: 4,
+};
+
+const TimelineDetailsModal: React.FC = ({ timelineId, onClose, showModal, clickedEvent }) => {
+ const [deleteTimeline, { isLoading, isSuccess}] = useDeleteTimelineMutation();
+
+ const handleDelete = async () => {
+ if (window.confirm('Are you sure you want to delete this timeline?')) {
+ try {
+ await deleteTimeline({ id: timelineId });
+ onClose();
+ } catch (error) {
+ console.error('Failed to delete the timeline:', error);
+ alert('There was a problem deleting the timeline.');
+ }
+ }
+ };
+
+ React.useEffect(() => {
+ if (isSuccess) {
+ onClose();
+ }
+ }, [isSuccess, onClose]);
+
+
+ return (
+
+
+
+ Task Details
+
+
+ Task title: {clickedEvent?.title}
+
+
+ Start date: {clickedEvent?.start.toLocaleTimeString()}
+
+
+ End date: {clickedEvent?.end.toLocaleTimeString()}
+
+
+
+
+
+
+
+ );
+};
+
+export default TimelineDetailsModal;
diff --git a/src/redux/api/timelineApi.ts b/src/redux/api/timelineApi.ts
index 3a42b0e..b1d2c10 100644
--- a/src/redux/api/timelineApi.ts
+++ b/src/redux/api/timelineApi.ts
@@ -39,6 +39,13 @@ export const timelineApi = baseApi.injectEndpoints({
}),
providesTags: ['Timeline'],
}),
+ deleteTimeline: builder.mutation({
+ query: ({ id }) => ({
+ url: `/timelines/${id}/delete/`,
+ method: 'DELETE',
+ }),
+ invalidatesTags: (_, __, arg) => [{ type: 'Timeline', id: arg.id }],
+ }),
}),
})
@@ -46,4 +53,5 @@ export const {
useGetTimelinesByEventQuery,
useCreateTimelineMutation,
useModifyDetailTimelineMutation,
+ useDeleteTimelineMutation,
} = timelineApi