From 9a88c03db1081dcb6b5347548b073442e02d90e0 Mon Sep 17 00:00:00 2001 From: ruby10127130 Date: Thu, 5 Dec 2024 23:12:35 +0800 Subject: [PATCH] feat: set up marathon-related actions, saga, and store --- redux/actions/marathon.js | 48 ++++++++++++++ redux/reducers/index.js | 2 + redux/reducers/marathon.js | 89 ++++++++++++++++++++++++++ redux/sagas/index.js | 2 + redux/sagas/marathon/index.js | 115 ++++++++++++++++++++++++++++++++++ redux/store/index.js | 2 +- 6 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 redux/actions/marathon.js create mode 100644 redux/reducers/marathon.js create mode 100644 redux/sagas/marathon/index.js diff --git a/redux/actions/marathon.js b/redux/actions/marathon.js new file mode 100644 index 00000000..ae449ec2 --- /dev/null +++ b/redux/actions/marathon.js @@ -0,0 +1,48 @@ +export function fetchMarathonProfileById(id) { + return { + type: 'FETCH_MARATHON_PROFILE_BY_ID', + payload: { + id, + }, + }; +} + +export function createMarathonProfileByToken(token, marathon) { + return { + type: 'CREATE_MARATHON_PROFILE_BY_TOKEN', + payload: { + token, + marathon + } + }; +} + +export function updateMarathonProfile(token, id, marathon) { + return { + type: 'UPDATE_MARATHON_PROFILE', + payload: { + token, + id, + marathon + } + }; +} + +export function deleteMarathonProfile(token, id) { + return { + type: 'DELETE_MARATHON_PROFILE', + payload: { + token, + id + } + }; +} + +export function fetchMarathonProfileByUserId(userId) { + return { + type: 'FETCH_MARATHON_PROFILE_BY_USER_ID', + payload: { + userId + } + }; +} diff --git a/redux/reducers/index.js b/redux/reducers/index.js index e5c924c4..06c6b716 100644 --- a/redux/reducers/index.js +++ b/redux/reducers/index.js @@ -6,6 +6,7 @@ import shared from './shared'; import resource from './resource'; import group from './group'; import partners from './partners'; +import marathon from './marathon'; const allReducers = combineReducers({ search, @@ -15,6 +16,7 @@ const allReducers = combineReducers({ resource, group, partners, + marathon, }); export default allReducers; diff --git a/redux/reducers/marathon.js b/redux/reducers/marathon.js new file mode 100644 index 00000000..7bcc83e6 --- /dev/null +++ b/redux/reducers/marathon.js @@ -0,0 +1,89 @@ +// import toast from 'react-hot-toast'; + +const initialState = { + title: '', + eventId: '', + userId: '', + description: '', + motivation: { tags: [], description: '' }, + content: "", + goals: "", + strategies: { tags: [], description: '' }, + resources: [], + milestones: [], + outcomes: { tags: [], description: '' }, + status: "Ongoing", + pricing: { option: "", pricing: 0, email: [], file: "" }, + isPublic: false, + startDate: '', + endDate: '', + userMarathon: [] +}; + +const reducer = (state = initialState, action) => { + switch (action.type) { + case 'FETCH_MARATHON_PROFILE_BY_USER_ID': { + return { + ...state, + apiState: 'pending' + }; + } + case 'FETCH_MARATHON_PROFILE_BY_USER_ID_SUCCESS': { + return { + ...state, + userMarathon: action.payload, + apiState: 'success' + }; + } + case 'FETCH_MARATHON_PROFILE_BY_USER_ID_FAILURE': { + return { + ...state, + apiState: 'reject' + }; + } + case 'CREATE_MARATHON_PROFILE': { + return { + ...state, + apiState: 'pending' + }; + } + case 'CREATE_MARATHON_PROFILE_BY_TOKEN_SUCCESS': { + return { + ...state, + ...action.payload, + apiState: 'success' + }; + } + case 'FETCH_MARATHON_PROFILE_BY_ID': { + return { + ...state, + apiState: 'pending' + }; + } + case 'FETCH_MARATHON_PROFILE_BY_ID_SUCCESS': { + return { + ...state, + ...action.payload, + apiState: 'success' + }; + } + case 'FETCH_MARATHON_PROFILE_BY_ID_FAILURE': { + return { + ...state, + apiState: 'reject' + }; + } + case 'UPDATE_MARATHON_PROFILE_SUCCESS': { + return { + ...state, + ...action.payload, + apiState: 'success', + }; + } + default: { + return state; + } + } +}; + +export default reducer; diff --git a/redux/sagas/index.js b/redux/sagas/index.js index ef30f8ad..2d908d84 100644 --- a/redux/sagas/index.js +++ b/redux/sagas/index.js @@ -1,6 +1,7 @@ import { all } from 'redux-saga/effects'; import searchSaga from './searchSaga'; import userSaga from './user'; +import marathonSaga from './marathon'; import partnerSaga from './partnersSaga'; import sharedSaga from './sharedSaga'; import resourceSaga from './resourceSaga'; @@ -16,5 +17,6 @@ export default function* rootSaga() { resourceSaga(), groupSaga(), partnerSaga(), + marathonSaga() ]); } diff --git a/redux/sagas/marathon/index.js b/redux/sagas/marathon/index.js new file mode 100644 index 00000000..59e7539a --- /dev/null +++ b/redux/sagas/marathon/index.js @@ -0,0 +1,115 @@ +import { put, takeEvery, call } from "redux-saga/effects"; +import { BASE_URL } from "@/constants/common"; +import req from "@/utils/request"; + +function* fetchMarathonProfileByUserId(action) { + const { userId } = action.payload; + try { + const URL = `${BASE_URL}/marathon?userId=${userId}`; + + const result = yield req(URL); + yield put({ + type: "FETCH_MARATHON_PROFILE_BY_USER_ID_SUCCESS", + payload: result.data, + }); + } catch (error) { + console.log(error); + yield put({ type: "FETCH_MARATHON_PROFILE_BY_USER_ID_FAILURE" }); + } +} + +function* fetchMarathonProfileById(action) { + const { id } = action.payload; // marathon._id + try { + const URL = `${BASE_URL}/marathon/${id}`; + + const result = yield req(URL); + yield put({ + type: "FETCH_MARATHON_PROFILE_BY_ID_SUCCESS", + payload: result.data, + }); + } catch (error) { + console.log(error); + yield put({ type: "FETCH_MARATHON_PROFILE_BY_ID_FAILURE" }); + } +} +function* createMarathonProfileByToken(action) { + const { token, marathon } = action.payload; + try { + const URL = `${BASE_URL}/marathon`; + + const result = yield req(URL, { + method: "POST", + body: JSON.stringify({ + ...marathon, + }), + }); + + yield put({ + type: "CREATE_MARATHON_PROFILE_BY_TOKEN_SUCCESS", + payload: { token, ...result.data }, + }); + } catch (error) { + console.log(error); + yield put({ type: "CREATE_MARATHON_PROFILE_BY_TOKEN_FAILURE" }); + } +} + +function* updateMarathonProfile(action) { + const { id, marathon } = action.payload; + + try { + const URL = `${BASE_URL}/marathon/${id}`; + + const result = yield req(URL, { + method: "PUT", + body: JSON.stringify({ + ...marathon, + }), + }); + + yield put({ + type: "UPDATE_MARATHON_PROFILE_SUCCESS", + payload: result.data, + }); + } catch (error) { + yield put({ type: "UPDATE_MARATHON_PROFILE_FAILURE" }); + } finally { + yield new Promise((res) => setTimeout(res, 300)); + yield put({ type: "UPDATE_MARATHON_PROFILE_API_STATE_RESET" }); + } +} + +function* deleteMarathonProfile(action) { + const { id } = action.payload; + + try { + const URL = `${BASE_URL}/marathon/${id}`; + + const result = yield req(URL, { + method: "DELETE", + body: JSON.stringify({ + id, + }), + }); + yield put({ + type: "DELETE_MARATHON_PROFILE_SUCCESS", + payload: result.data, + }); + } catch (error) { + yield put({ type: "DELETE_MARATHON_PROFILE_FAILURE" }); + } finally { + yield new Promise((res) => setTimeout(res, 300)); + yield put({ type: "DELETE_MARATHON_PROFILE_API_STATE_RESET" }); + } +} + +function* marathonSaga() { + yield takeEvery("FETCH_MARATHON_PROFILE_BY_ID", fetchMarathonProfileById); + yield takeEvery("CREATE_MARATHON_PROFILE_BY_TOKEN", createMarathonProfileByToken); + yield takeEvery("UPDATE_MARATHON_PROFILE", updateMarathonProfile); + yield takeEvery("DELETE_MARATHON_PROFILE", deleteMarathonProfile); + yield takeEvery("FETCH_MARATHON_PROFILE_BY_USER_ID", fetchMarathonProfileByUserId); +} + +export default marathonSaga; diff --git a/redux/store/index.js b/redux/store/index.js index 4b792586..b817b365 100644 --- a/redux/store/index.js +++ b/redux/store/index.js @@ -16,7 +16,7 @@ import { const persistConfig = { key: 'root', storage, - whitelist: ['user', 'partners'], + whitelist: ['user', 'partners', 'marathon'], }; import rootReducer from '../reducers';