@lonelyplanet/dotcom-core
Version:
This package is meant to house some of our more common UI and shared libs across dotcom applications.
247 lines (208 loc) • 6.7 kB
text/typescript
import { IBookmark } from "@lonelyplanet/open-planet-node/dist/resources/bookmark";
import { IBookmarkList } from "@lonelyplanet/open-planet-node/dist/resources/bookmarkList";
import "isomorphic-fetch";
import { ThunkAction } from "redux-thunk";
import { ADD_BOOKMARK_DONE, ADD_BOOKMARK_START, LIST_CREATE_DONE, LIST_CREATE_START, LIST_DELETE_DONE, LIST_DELETE_START, LIST_UPDATE_DONE, LIST_UPDATE_START, UPDATE_BOOKMARK_DONE, UPDATE_BOOKMARK_START } from "../constants/bookmark";
import { showToastMessage } from "./toast";
const messages = {
addBookmarkToListError: "There was an error updating your list",
addBookmarkToListSuccess: "Your item has been added.",
createListSuccess: "Your list has been successfully created.",
createListError: "There was an error creating your list",
updateListError: "There was an error updating your list",
updateListSuccess: "Your list has been updated",
deleteListError: "There was an error deleting your list",
deleteListSuccess: "Your list has been deleted",
updateBookmarkSuccess: "Your bookmark has been updated",
updateBookmarkError: "There was an error updating your bookmark",
}
export type CreateListParams = {
userId: string;
data: IBookmarkList,
onDone: Function,
};
export const createList = ({ userId, data, onDone }: CreateListParams): ThunkAction<void, {}, {}, {
type: string,
}> =>
async (dispatch) => {
dispatch({
type: LIST_CREATE_START,
});
let payload;
try {
const response = await fetch(`${window.lp.hosts.profile}/profile/api/${userId}/lists`, {
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
method: "POST",
credentials: "include",
body: JSON.stringify(data),
});
if (response.status !== 200) {
const errorBody = await response.text();
const errorObj = await JSON.parse(errorBody);
return dispatch(showToastMessage(errorObj.message, "error"));
}
payload = await response.json();
} catch (e) {
return dispatch(showToastMessage(messages.createListError, "error"));
}
dispatch({
type: LIST_CREATE_DONE,
payload,
});
dispatch(showToastMessage(messages.createListSuccess));
if (onDone) {
onDone(payload.id);
}
};
export const updateList = ({ userId, listId, data }: {
userId: string;
listId: string;
entryId: string;
data: IBookmarkList,
}): ThunkAction<void, {}, {}, { type: string }> => async (dispatch) => {
dispatch({
type: LIST_UPDATE_START,
});
let payload;
try {
const response = await fetch(`${window.lp.hosts.profile}/profile/api/${userId}/lists/${listId}.json`, {
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
method: "PATCH",
credentials: "include",
body: JSON.stringify(data),
});
if (response.status !== 200) {
const errorBody = await response.text();
const errorObj = await JSON.parse(errorBody);
return dispatch(showToastMessage(errorObj.message, "error"));
}
payload = await response.json();
} catch (e) {
return dispatch(showToastMessage(messages.updateListError, "error"));
}
dispatch({
type: LIST_UPDATE_DONE,
payload,
});
dispatch(showToastMessage(messages.updateListSuccess));
};
export const deleteList = ({ userId, listId }: {
userId: string;
listId: string;
}): ThunkAction<Promise<void>, {}, {}, { type: string }> => async (dispatch) => {
dispatch({
type: LIST_DELETE_START,
});
try {
const response = await fetch(`${window.lp.hosts.profile}/profile/api/${userId}/lists/${listId}`, {
headers: {
Accept: "application/json",
},
method: "DELETE",
credentials: "include",
});
if (response.status !== 204) {
const errorBody = await response.text();
const errorObj = await JSON.parse(errorBody);
return dispatch(showToastMessage(errorObj.message, "error"));
}
} catch (e) {
return dispatch(showToastMessage(messages.deleteListError, "error"));
}
dispatch({
type: LIST_DELETE_DONE,
});
dispatch(showToastMessage(messages.deleteListSuccess));
};
export const addBookmarkToList = ({ userId, listId, data }: {
userId: string;
listId: string;
data: IBookmark,
}): ThunkAction<Promise<void>, {}, {}, { type: string }> => async (dispatch) => {
dispatch({
type: ADD_BOOKMARK_START,
payload: data,
});
let payload;
try {
const response = await fetch(`${window.lp.hosts.profile}/profile/api/${userId}/lists/${listId}/entries.json`, {
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
method: "POST",
credentials: "include",
body: JSON.stringify(data),
});
if (response.status !== 200) {
const errorBody = await response.text();
const errorObj = await JSON.parse(errorBody);
return dispatch(showToastMessage(errorObj.message, "error"));
}
payload = await response.json();
} catch (e) {
return dispatch(showToastMessage(messages.addBookmarkToListError, "error"));
}
dispatch({
type: ADD_BOOKMARK_DONE,
payload: {
listId,
bookmark: payload,
},
});
dispatch(showToastMessage(messages.addBookmarkToListSuccess));
};
export interface IUpdateBookmarkDoneAction {
type: typeof UPDATE_BOOKMARK_DONE;
payload: {
listId: string,
bookmark: IBookmark,
};
}
export const updateBookmark = ({ userId, listId, entryId, data }: {
userId: string;
listId: string;
entryId: string;
data: IBookmark,
}): ThunkAction<Promise<void>, {}, {}, { type: string }> => async (dispatch) => {
dispatch({
type: UPDATE_BOOKMARK_START,
});
let payload;
try {
const response = await fetch(
`${window.lp.hosts.profile}/profile/api/${userId}/lists/${listId}/entries/${entryId}.json`,
{
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
method: "PATCH",
credentials: "include",
body: JSON.stringify(data),
});
if (response.status !== 200) {
const errorBody = await response.text();
const errorObj = await JSON.parse(errorBody);
return dispatch(showToastMessage(errorObj.message, "error"));
}
payload = await response.json();
} catch (e) {
return dispatch(showToastMessage(messages.updateBookmarkError, "error"));
}
const action: IUpdateBookmarkDoneAction = {
type: UPDATE_BOOKMARK_DONE,
payload: {
listId,
bookmark: payload,
}
};
dispatch(action);
dispatch(showToastMessage(messages.updateBookmarkSuccess));
};