diff --git a/web/src/api/index.jsx b/web/src/api/index.jsx
index c433c147e..919ecd60f 100644
--- a/web/src/api/index.jsx
+++ b/web/src/api/index.jsx
@@ -34,7 +34,27 @@ function reducer(state, { type, payload, meta }) {
draftState.queries[url] = { status: ok ? FetchStatus.LOADED : FetchStatus.ERROR, data, fetchId };
});
}
+ case 'DELETE': {
+ const { eventId } = payload;
+ return produce(state, (draftState) => {
+ Object.keys(draftState.queries).map(function (url, index) {
+ // If no url or data has no array length then just return state.
+ if (!(url in draftState.queries) || !draftState.queries[url].data.length) return state;
+
+ //Find the index to remove
+ const removeIndex = draftState.queries[url].data.map((event) => event.id).indexOf(eventId);
+ if (removeIndex === -1) return;
+
+ // We need to keep track of deleted items, This will be used to calculate "ReachEnd" for auto load new events. Events.jsx
+ const totDeleted = state.queries[url].deleted || 0;
+
+ // Splice the deleted index.
+ draftState.queries[url].data.splice(removeIndex, 1);
+ draftState.queries[url].deleted = totDeleted + 1;
+ });
+ });
+ }
default:
return state;
}
@@ -91,8 +111,23 @@ export function useFetch(url, fetchId) {
const data = state.queries[url].data || null;
const status = state.queries[url].status;
+ const deleted = state.queries[url].deleted || 0;
- return { data, status };
+ return { data, status, deleted };
+}
+
+export function useDelete() {
+ const { dispatch, state } = useContext(Api);
+
+ async function deleteEvent(eventId) {
+ if (!eventId) return { success: false };
+
+ const response = await fetch(`${state.host}/api/events/${eventId}`, { method: 'DELETE' });
+ await dispatch({ type: 'DELETE', payload: { eventId } });
+ return await (response.status < 300 ? response.json() : { success: true });
+ }
+
+ return deleteEvent;
}
export function useApiHost() {
diff --git a/web/src/routes/Event.jsx b/web/src/routes/Event.jsx
index bf778ec18..7d3ccaa78 100644
--- a/web/src/routes/Event.jsx
+++ b/web/src/routes/Event.jsx
@@ -10,7 +10,7 @@ import Dialog from '../components/Dialog';
import Heading from '../components/Heading';
import Link from '../components/Link';
import VideoPlayer from '../components/VideoPlayer';
-import { FetchStatus, useApiHost, useEvent } from '../api';
+import { FetchStatus, useApiHost, useEvent, useDelete } from '../api';
import { Table, Thead, Tbody, Th, Tr, Td } from '../components/Table';
export default function Event({ eventId }) {
@@ -18,6 +18,7 @@ export default function Event({ eventId }) {
const { data, status } = useEvent(eventId);
const [showDialog, setShowDialog] = useState(false);
const [deleteStatus, setDeleteStatus] = useState(FetchStatus.NONE);
+ const setDeleteEvent = useDelete();
const handleClickDelete = () => {
setShowDialog(true);
@@ -30,8 +31,7 @@ export default function Event({ eventId }) {
const handleClickDeleteDialog = useCallback(async () => {
let success;
try {
- const response = await fetch(`${apiHost}/api/events/${eventId}`, { method: 'DELETE' });
- success = await (response.status < 300 ? response.json() : { success: true });
+ success = await setDeleteEvent(eventId);
setDeleteStatus(success ? FetchStatus.LOADED : FetchStatus.ERROR);
} catch (e) {
setDeleteStatus(FetchStatus.ERROR);
@@ -42,7 +42,7 @@ export default function Event({ eventId }) {
setShowDialog(false);
route('/events', true);
}
- }, [apiHost, eventId, setShowDialog]);
+ }, [eventId, setShowDialog]);
if (status !== FetchStatus.LOADED) {
return ;
@@ -64,7 +64,11 @@ export default function Event({ eventId }) {