@25sprout/react-starter
Version:
25sprout web starter with React
89 lines (72 loc) • 2.07 kB
text/typescript
import { createAction, handleActions } from 'redux-actions';
import { useRedux } from 'util/hook/redux';
import { customApi } from 'util/api';
import { BannerResource } from 'util/api/swaggerApi/data-contracts';
import { State as GlobalState } from './reducers';
export const getBanners = createAction('GET_BANNERS', async () => {
try {
const FEATURE_STORAGE_DOMAIN =
'https://25sprout-backstagefeatures-sit.25demo.com/backstage/storage';
const { bsxfeatureV1BannerList } = customApi;
const { data } = await bsxfeatureV1BannerList({ secure: true });
const result = data?.data?.map(list => {
if (list.youtubeLink?.length === 0) {
return {
...list,
youtubeLink: null,
imageMobile: `${FEATURE_STORAGE_DOMAIN}/${list.imageMobile}`,
};
}
return {
...list,
imageMobile: `${FEATURE_STORAGE_DOMAIN}/${list.imageMobile}`,
};
});
return result;
} catch (e) {
console.log('error!', e);
return { list: [] };
}
});
type Concrete<Type> = {
[Property in keyof Type]-?: Type[Property];
};
export interface Banners extends Concrete<BannerResource> {
subTitle: string;
}
// For Global State usage
export interface State {
loading: boolean;
banners: Banners[];
}
export const defaultState: State = {
loading: false,
banners: [],
};
export const reducer = {
// Workaround: HandleActions 目前定義無法支援多種 action 形式
banners: handleActions<State, any>( // eslint-disable-line @typescript-eslint/no-explicit-any
{
GET_BANNERS_PENDING: state => ({
...state,
loading: true,
}),
GET_BANNERS_FULFILLED: (state, action) => ({
...state,
banners: action.payload,
loading: false,
}),
},
defaultState,
),
};
const bannerActionsMap = {
getBanners,
};
const mapHooksToState = (state: GlobalState) => ({
banners: state.banners.banners,
});
type BannerSelector = ReturnType<typeof mapHooksToState>;
type BannerctionsMap = typeof bannerActionsMap;
export const useBanner = () =>
useRedux<BannerSelector, BannerctionsMap>(mapHooksToState, bannerActionsMap);