Skip to content

Commit

Permalink
feat: Create a req.js utils - add token when fetch Api
Browse files Browse the repository at this point in the history
  • Loading branch information
whalekiller03 committed Apr 29, 2024
1 parent dcb0e12 commit 53c8684
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 56 deletions.
46 changes: 24 additions & 22 deletions components/Partner/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,29 +111,31 @@ function Partner() {
/>
<PartnerList />
</StyledContent>
{partners.items.length > 0 && current < totalPages && (
<Box
sx={
mobileScreen
? { textAlign: 'center', padding: '32px 0' }
: { textAlign: 'center', padding: '72px 0' }
}
>
<Button
onClick={() => handleFetchData(current + 1)}
variant="outlined"
sx={{
fontSize: '16px',
color: '#536166',
borderColor: '#16B9B3',
borderRadius: '20px',
padding: '6px 48px',
}}
{partners.items &&
partners.items.length > 0 &&
current < totalPages && (
<Box
sx={
mobileScreen
? { textAlign: 'center', padding: '32px 0' }
: { textAlign: 'center', padding: '72px 0' }
}
>
顯示更多
</Button>
</Box>
)}
<Button
onClick={() => handleFetchData(current + 1)}
variant="outlined"
sx={{
fontSize: '16px',
color: '#536166',
borderColor: '#16B9B3',
borderRadius: '20px',
padding: '6px 48px',
}}
>
顯示更多
</Button>
</Box>
)}
</StyledWrapper>
</>
);
Expand Down
16 changes: 13 additions & 3 deletions components/Profile/MyGroup/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,21 @@ const MyGroup = ({ hasTitle = true, sx, userId }) => {
if (!userId) {
return <Typography py={7.5}>趕快發起屬於你的揪團吧~</Typography>;
}
// TODO: 待優化
const me = useSelector((state) => state.user);

const [response, setResponse] = useState(null);
const { isFetching } = useFetch(`${GROUP_API_URL}/user/${userId}`, {
onSuccess: setResponse,
});
const { isFetching } = useFetch(
`${GROUP_API_URL}/${userId}`,
{
headers: {
Authorization: `Bearer ${me.token}`,
},
},
{
onSuccess: setResponse,
},
);

const getTargetIndexById = (data, id) => {
if (!Array.isArray(data)) return -1;
Expand Down
4 changes: 2 additions & 2 deletions hooks/useFetch.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useReducer, useState } from 'react';

const useFetch = (url, { initialValue, onSuccess } = {}) => {
const useFetch = (url, options = {}, { initialValue, onSuccess } = {}) => {
const [render, refetch] = useReducer((pre) => !pre, true);
const [data, setData] = useState(initialValue);
const [isFetching, setIsFetching] = useState(true);
Expand All @@ -14,7 +14,7 @@ const useFetch = (url, { initialValue, onSuccess } = {}) => {
setIsFetching(true);
setIsError(false);

fetch(url)
fetch(url, options)
.then((res) => res.json())
.then((json) => pass && setData(json))
.catch(() => setIsError(true))
Expand Down
11 changes: 8 additions & 3 deletions pages/group/detail/index.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import React, { useMemo } from 'react';
import { useRouter } from 'next/router';
import { useSelector } from 'react-redux';
import SEOConfig from '@/shared/components/SEO';
import GroupDetail from '@/components/Group/detail';
import GroupEmpty from '@/components/Group/detail/Empty';
import Navigation from '@/shared/components/Navigation_v2';
import Footer from '@/shared/components/Footer_v2';
import useFetch from '@/hooks/useFetch';
import { BASE_URL } from '@/constants/common';

function GroupPage() {
const router = useRouter();
const { id } = router.query;
const { data, isFetching, isError } = useFetch(
`https://daodao-server.vercel.app/activity/${id}`,
);
const me = useSelector((state) => state.user);
const { data, isFetching, isError } = useFetch(`${BASE_URL}/activity/${id}`, {
headers: {
Authorization: `Bearer ${me.token}`,
},
});
const source = data?.data?.[0];

const SEOData = useMemo(
Expand Down
9 changes: 6 additions & 3 deletions pages/group/edit/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ import SEOConfig from '@/shared/components/SEO';
import Navigation from '@/shared/components/Navigation_v2';
import Footer from '@/shared/components/Footer_v2';
import { GROUP_API_URL } from '@/redux/actions/group';
import { BASE_URL } from '@/constants/common';

function EditGroupPage() {
const { pushSnackbar } = useSnackbar();
const router = useRouter();
const me = useSelector((state) => state.user);
const { id } = router.query;
const { data, isFetching } = useFetch(
`https://daodao-server.vercel.app/activity/${id}`,
);
const { data, isFetching } = useFetch(`${BASE_URL}/activity/${id}`, {
headers: {
Authorization: `Bearer ${me.token}`,
},
});
const source = data?.data?.[0];

const SEOData = useMemo(
Expand Down
15 changes: 14 additions & 1 deletion pages/index.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { useMemo } from 'react';
import React, { useMemo, useEffect } from 'react';
import styled from '@emotion/styled';
import { useRouter } from 'next/router';
import { useDispatch, useSelector } from 'react-redux';
import { fetchUserById } from '@/redux/actions/user';
import SEOConfig from '../shared/components/SEO';
import Home from '../components/Home';
import Navigation from '../shared/components/Navigation_v2';
Expand Down Expand Up @@ -45,6 +47,17 @@ const HomePage = () => {
[router?.asPath],
);

// fetch signin userData with token and id from query String

const dispatch = useDispatch();
const { token, id } = router.query;
useEffect(() => {
if (token) {
dispatch(fetchUserById(id, token));
router.push('/');
}
}, [id, token]);

return (
<HomePageWrapper>
<SEOConfig data={SEOData} />
Expand Down
4 changes: 4 additions & 0 deletions pages/partner/detail/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const Detail = () => {

// fetch login user info
const {
_id,
email,
name,
roleList,
photoURL,
Expand All @@ -56,6 +58,8 @@ const Detail = () => {
const handleOnOk = ({ message, contact }) => {
dispatch(
sendEmailToPartner({
userId: _id,
from: email,
to: partner.email,
name,
roleList:
Expand Down
8 changes: 7 additions & 1 deletion redux/actions/partners.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { BASE_URL } from '@/constants/common';

export function fetchPartners({ pageSize = 10, page = 1, ...rest } = {}) {
return {
type: 'FETCH_PARTNERS',
Expand All @@ -19,10 +21,14 @@ export function fetchPartnerById({ id } = {}) {
}

export function sendEmailToPartner(payload) {
const { to, name, roleList, photoURL, text, information } = payload;
const { userId, from, to, name, roleList, photoURL, text, information } =
payload;
return {
type: 'SEND_EMAIL_TO_PARTNER',
payload: {
from,
userId, //寄件者id
url: BASE_URL,
to, // 收件者信箱
subject: '【島島阿學】點開 Email,認識新夥伴',
title: '有新夥伴想認識你!',
Expand Down
8 changes: 7 additions & 1 deletion redux/actions/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@ export function fetchAllUsers() {
};
}

export function fetchUserById(id) {
/**
* @param {string} id
* @param {string} token
* @returns
*/
export function fetchUserById(id, token) {
return {
type: 'FETCH_USER_BY_ID',
payload: {
id,
token,
},
};
}
Expand Down
4 changes: 3 additions & 1 deletion redux/sagas/groupSaga.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { put, takeEvery, select } from 'redux-saga/effects';
import req from '@/utils/request';

import {
GROUP_API_URL,
SET_PAGE_SIZE,
Expand All @@ -14,7 +16,7 @@ function* getGroupItems() {
const queryString = new URLSearchParams({ ...query, pageSize }).toString();
const URL = `${GROUP_API_URL}?${queryString}`;
try {
const response = yield fetch(URL).then((res) => res.json());
const response = yield req(URL);
yield put(getGroupItemsSuccess(response));
} catch (error) {
yield put(getGroupItemsError(error));
Expand Down
19 changes: 8 additions & 11 deletions redux/sagas/partnersSaga.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { put, takeEvery } from 'redux-saga/effects';
import { BASE_URL } from '@/constants/common';
import req from '@/utils/request';

function* fetchPartnersResource(action) {
const { pageSize = 10, page = 1, ...rest } = action.payload;
Expand All @@ -12,9 +13,8 @@ function* fetchPartnersResource(action) {
}, startParams);

try {
const baseUrl = process.env.NEXT_PUBLIC_API_URL || BASE_URL;
const URL = `${baseUrl}/user?${queryStr}`;
const result = yield fetch(URL).then((res) => res.json());
const URL = `${BASE_URL}/user?${queryStr}`;
const result = yield req(URL);
yield put({
type:
page !== 1 ? 'FETCH_PARTNERS_MORE_SUCCESS' : 'FETCH_PARTNERS_SUCCESS',
Expand All @@ -36,9 +36,8 @@ function* fetchPartnersResource(action) {
function* fetchPartnerById(action) {
const { id } = action.payload;
try {
const baseUrl = process.env.NEXT_PUBLIC_API_URL || BASE_URL;
const URL = `${baseUrl}/user/${id}`;
const result = yield fetch(URL).then((res) => res.json());
const URL = `${BASE_URL}/user/${id}`;
const result = yield req(URL);
yield put({
type: 'FETCH_PARTNER_BY_ID_SUCCESS',
payload: result.data && result.data[0],
Expand All @@ -51,19 +50,17 @@ function* fetchPartnerById(action) {
function* sendEmailToPartner(action) {
try {
const URL = `${BASE_URL}/email`;
yield fetch(URL, {
yield req(URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
...action.payload,
}),
}).then((res) => res.json());
});
yield put({
type: 'SEND_EMAIL_TO_PARTNER_SUCCESS',
});
} catch (error) {
console.log(error);
yield put({ type: 'SEND_EMAIL_TO_PARTNER_FAILURE' });
}
}
Expand Down
19 changes: 11 additions & 8 deletions redux/sagas/user/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { put, all, take, takeEvery, select, call } from 'redux-saga/effects';
import * as localforage from 'localforage';
import firebase from '../../../utils/firebase';
import { BASE_URL } from '@/constants/common';
import req from '@/utils/request';

function* checkUserStatus() {
try {
Expand Down Expand Up @@ -52,30 +53,32 @@ function* updateUserProfile(action) {
try {
const URL = `${BASE_URL}/user/${user.id}`;

const result = yield fetch(URL, {
const result = yield req(URL, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
...user,
}),
}).then((res) => res.json());
});

yield put({ type: 'UPDATE_USER_PROFILE_SUCCESS', payload: result.data });
} catch (error) {
yield put({ type: 'UPDATE_USER_PROFILE_FAILURE' });
}
}

// fetch user data by id with header auth token
function* fetchUserById(action) {
const { id } = action.payload;
const { id, token } = action.payload;
try {
const URL = `${BASE_URL}/user/${id}`;
const result = yield fetch(URL).then((res) => res.json());
const result = yield req(URL, {
headers: {
Authorization: `Bearer ${token}`,
},
});
yield put({
type: 'FETCH_USER_BY_ID_SUCCESS',
payload: result.data && result.data[0],
payload: result.data && { ...result.data[0], token },
});
} catch (error) {
console.log(error);
Expand Down
30 changes: 30 additions & 0 deletions utils/request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { select } from 'redux-saga/effects';

const request = function* (url, options = {}) {
// retrieve the token from the user persist
const { token } = yield select((state) => state.user);

// default headers for JSON content type
const defaultHeaders = {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
};

// merge default headers with options.headers
const headers = { ...defaultHeaders, ...options.headers };

// create a new options object with the merged headers
const fetchOptions = { ...options, headers };

const response = yield fetch(url, fetchOptions);
const data = yield response.json();

// Check for non-200 status and throw an error
if (response.status !== 200) {
throw new Error(data);
}

return data;
};

export default request;

0 comments on commit 53c8684

Please sign in to comment.