Skip to content

Instantly share code, notes, and snippets.

@lxm7
Created April 7, 2020 18:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lxm7/61aff64c6bd58b0956c8317b220d8f4e to your computer and use it in GitHub Desktop.
Save lxm7/61aff64c6bd58b0956c8317b220d8f4e to your computer and use it in GitHub Desktop.
Re-write of reducers that are using custom redux hooks
import useReduxState from 'utils/hooks/useReduxState';
// Interfaces
import ICreditPack, { emptyCreditPack } from 'utils/interfaces/ICreditPack';
import ICreditPackExecutiveSummary from 'utils/interfaces/ICreditPackExecutiveSummary';
import ICreditPackApplicationFace from 'utils/interfaces/ICreditPackApplicationFace';
import ICreditPackAppraisal, {
ICreditPackAppraisalSubSection,
TSectionKey,
TClippingType,
} from 'utils/interfaces/ICreditPackAppraisal';
import IClient from 'utils/interfaces/IClient';
import IAylienStory from 'utils/interfaces/IAylienStory';
// Mocks
import creditPacks from 'utils/mocks/creditPacks';
import clients from 'utils/mocks/clients';
// Utils
import randomString from 'utils/helperFunctions/randomString';
const initialState: State = {
activeCreditPack: { ...emptyCreditPack },
creditPackList: creditPacks,
};
const getClientProfile = (slug: string): IClient => clients.find((client: IClient) => {
return client.slug === slug
});
const useCreditPacksState = () =>
useReduxState<State, Actions>({
key: 'creditPacks',
initialState,
actions: {
initNewCreditPack: (state, { clientSlug, newCreditPackId }) => {
const newCreditPack = {
id: newCreditPackId,
client: getClientProfile(clientSlug),
status: 20,
data: {...emptyCreditPack.data},
};
return {
...state,
activeCreditPack: {
...newCreditPack,
},
creditPackList: [
...state.creditPackList,
{...newCreditPack},
]
};
},
initExistingCreditPack: (state, { creditPackId }) => {
const existingCreditPack = state.creditPackList.find(creditPack => {
return creditPack.id === creditPackId;
});
return {
...state,
activeCreditPack: {
...(existingCreditPack ? {...existingCreditPack} : {...emptyCreditPack})
},
};
},
resetActiveCreditPack: state => {
return {
...state,
activeCreditPack: {
...emptyCreditPack,
},
};
},
saveActiveCreditPack: state => {
return {
...state,
creditPackList: [{
...state.creditPackList,
...state.activeCreditPack,
}]
};
},
submitExecutiveSummary: (state, { executiveSummary }) => {
console.log('<SUBMIT> submitExecutiveSummary', state);
const newState = { ...state };
const { section1, section2, section3 } = executiveSummary;
const { data } = newState.activeCreditPack;
if (section1) data.executiveSummary.section1 = section1;
if (section2) data.executiveSummary.section2 = section2;
if (section3) data.executiveSummary.section3 = section3;
return newState;
},
submitApplicationFace: (state, { applicationFace }) => {
const newState = { ...state };
const { section1, section2 } = applicationFace;
const { data } = newState.activeCreditPack;
if (section1) data.applicationFace.section1 = section1;
if (section2) data.applicationFace.section2 = section2;
return newState;
},
initNewAppraisalSubSection: (state, { sectionKey, newSubSectionId }) => {
const newSubSection: ICreditPackAppraisalSubSection = {
id: newSubSectionId,
title: 'New Section',
relevance: 'low',
synopsis: 'New Synopsis',
attachments: [],
};
return {
...state,
activeCreditPack: {
...state.activeCreditPack,
data: {
...state.activeCreditPack.data,
appraisalMemorandum: {
...state.activeCreditPack.data.appraisalMemorandum,
[sectionKey]: [
...state.activeCreditPack.data.appraisalMemorandum[sectionKey as TSectionKey],
{...newSubSection},
]
}
}
},
};
},
editAppraisalSubSection: (state, { section, sectionKey }) => {
const index = state.activeCreditPack.data.appraisalMemorandum[sectionKey as TSectionKey]
const newCreditPack = {
...state.activeCreditPack,
data: {
...state.activeCreditPack.data,
appraisalMemorandum: {
...state.activeCreditPack.data.appraisalMemorandum,
[sectionKey]: [
...index.slice(0, index.length -1),
{...section},
...index.slice(index.length),
]
}
}
};
const creditPackList = [...state.creditPackList]
.reduce((acc: ICreditPack[], creditPack: ICreditPack) => {
if (creditPack.id === newCreditPack.id) {
acc.push(newCreditPack);
} else {
acc.push(creditPack);
}
return acc;
}, []);
return {
...state,
activeCreditPack: {
...newCreditPack,
},
creditPackList,
}
},
addClipping: (
state,
{
creditPackId,
sectionKey,
subSectionId,
analysis,
clippingType,
story,
addedSubSectionTitle,
}: PayloadAddClipping,
) => {
const subSectionAttachment = {
// TODO - generate only on new, not every action fired.
id: randomString(),
analysis,
clippingType,
clipping: {
title: story.title,
source: story.source.title,
sourceUrl: story.source.homePageUrl,
storyUrl: story.links.permalink,
sentiment: story.sentiment.total,
body: story.body,
},
};
const subSection: ICreditPackAppraisalSubSection = {
id: subSectionId,
attachments: [subSectionAttachment],
relevance: "low",
synopsis: "Example synopsis",
title: addedSubSectionTitle || `New ${clippingType} clipping`,
}
const getCreditPackAppraisalMemorandum = (creditPack: ICreditPack) =>
Object.entries(creditPack.data.appraisalMemorandum)
.reduce((acc: ICreditPackAppraisal, pair) => {
const [key, itemsInSection] = pair;
if (key === sectionKey) {
acc[sectionKey as TSectionKey] = [
...itemsInSection,
{...subSection},
];
} else {
acc[key as TSectionKey] = itemsInSection;
}
return acc;
}, {});
const creditPackList = [...state.creditPackList]
.reduce((acc: ICreditPack[], creditPack: ICreditPack) => {
if (creditPack.id === creditPackId) {
const appraisalMemorandum = getCreditPackAppraisalMemorandum(creditPack);
const updateCreditPack = {
...creditPack,
data: {
...creditPack.data,
appraisalMemorandum,
}
}
acc.push(updateCreditPack);
} else {
acc.push(creditPack);
}
return acc;
}, []);
return {...state, creditPackList};
},
},
sagas: {},
});
interface State {
activeCreditPack: ICreditPack;
creditPackList: ICreditPack[];
}
interface Actions {
initNewCreditPack: (payload: { clientSlug: string, newCreditPackId: string }) => void;
initExistingCreditPack: (payload: { creditPackId: string }) => void;
saveActiveCreditPack: () => void;
resetActiveCreditPack: () => void;
editAppraisalSubSection: (payload: {
section: ICreditPackAppraisalSubSection,
sectionKey: string,
}) => void;
initNewAppraisalSubSection: (payload: { sectionKey: string, newSubSectionId: string }) => void;
submitExecutiveSummary: (payload: {
executiveSummary: ICreditPackExecutiveSummary;
}) => void;
submitApplicationFace: (payload: {
applicationFace: ICreditPackApplicationFace;
}) => void;
addClipping: (payload: PayloadAddClipping) => void;
}
interface PayloadAddClipping {
creditPackId: string;
sectionKey: string;
subSectionId: string;
analysis: string;
clippingType: TClippingType;
story: IAylienStory;
addedSubSectionTitle?: string;
}
export default useCreditPacksState;
import useReduxState from 'utils/hooks/useReduxState';
// Interfaces
import ICreditPack, { emptyCreditPack } from 'utils/interfaces/ICreditPack';
import ICreditPackExecutiveSummary from 'utils/interfaces/ICreditPackExecutiveSummary';
import ICreditPackApplicationFace from 'utils/interfaces/ICreditPackApplicationFace';
import {
ICreditPackAppraisalSubSection,
TSectionKey,
TClippingType,
} from 'utils/interfaces/ICreditPackAppraisal';
import IAylienStory from 'utils/interfaces/IAylienStory';
// Mocks
import creditPacks from 'utils/mocks/creditPacks';
import clients from 'utils/mocks/clients';
// Utils
import randomString from 'utils/helperFunctions/randomString';
const initialState: State = {
activeCreditPack: { ...emptyCreditPack },
creditPackList: creditPacks,
};
const useCreditPacksState = () =>
useReduxState<State, Actions>({
key: 'creditPacks',
initialState,
actions: {
initNewCreditPack: (state, { clientSlug }) => {
const newState = { ...state };
if (newState.activeCreditPack.client.slug !== clientSlug) {
console.log('<NEW> CreditPack', { clientSlug });
clients.forEach(client => {
if (client.slug === clientSlug) {
const creditPackId = randomString();
const activeCreditPack = {
id: creditPackId,
client,
data: { ...emptyCreditPack.data },
};
newState.activeCreditPack = activeCreditPack;
newState.creditPackList.push(activeCreditPack);
}
});
}
return newState;
},
initExistingCreditPack: (state, { creditPackId }) => {
const newState = { ...state };
if (newState.activeCreditPack.id !== creditPackId) {
console.log('<EXISTING> CreditPack', { creditPackId });
newState.creditPackList.forEach(creditPack => {
if (creditPack.id === creditPackId) {
newState.activeCreditPack = creditPack;
}
});
}
return newState;
},
saveActiveCreditPack: state => {
const newState = { ...state };
newState.creditPackList.push(newState.activeCreditPack);
return newState;
},
resetActiveCreditPack: state => {
const newState = { ...state };
newState.activeCreditPack = { ...emptyCreditPack };
return newState;
},
submitExecutiveSummary: (state, { executiveSummary }) => {
const newState = { ...state };
const { section1, section2, section3 } = executiveSummary;
const { data } = newState.activeCreditPack;
if (section1) data.executiveSummary.section1 = section1;
if (section2) data.executiveSummary.section2 = section2;
if (section3) data.executiveSummary.section3 = section3;
return newState;
},
submitApplicationFace: (state, { applicationFace }) => {
const newState = { ...state };
const { section1, section2 } = applicationFace;
const { data } = newState.activeCreditPack;
if (section1) data.applicationFace.section1 = section1;
if (section2) data.applicationFace.section2 = section2;
return newState;
},
initNewAppraisalSubSection: (state, { sectionKey }) => {
const newState = { ...state };
const { appraisalMemorandum } = newState.activeCreditPack.data;
const newSubSection: ICreditPackAppraisalSubSection = {
title: 'New Section',
relevance: 'low',
attachments: [],
};
appraisalMemorandum[sectionKey as TSectionKey].push(newSubSection);
return newState;
},
editAppraisalSubSection: (state, { section, sectionKey }) => {
const newState = { ...state };
const { appraisalMemorandum } = newState.activeCreditPack.data;
console.log('editAppraisalSubSection', { section });
appraisalMemorandum[sectionKey as TSectionKey].forEach((sect, i) => {
if (section.id === sect.id) {
appraisalMemorandum[sectionKey as TSectionKey][i] = section;
return newState;
}
});
return newState;
},
addClipping: (
state,
{
creditPackId,
sectionKey,
subSectionId,
analysis,
clippingType,
story,
}: PayloadAddClipping,
) => {
const newState = { ...state };
const { creditPackList } = newState;
creditPackList.forEach(creditPack => {
if (creditPack.id === creditPackId) {
const { appraisalMemorandum } = creditPack.data;
const section = appraisalMemorandum[sectionKey as TSectionKey];
section.forEach(subSection => {
if (subSection.id === subSectionId) {
subSection.attachments.push({
id: randomString(),
analysis,
clippingType,
clipping: {
title: story.title,
source: story.source.title,
sourceUrl: story.source.homePageUrl,
storyUrl: story.links.permalink,
sentiment: story.sentiment.total,
body: story.body,
},
});
}
});
}
});
return newState;
},
},
sagas: {},
});
interface State {
activeCreditPack: ICreditPack;
creditPackList: ICreditPack[];
}
interface Actions {
initNewCreditPack: (payload: { clientSlug: string }) => void;
initExistingCreditPack: (payload: { creditPackId: string }) => void;
saveActiveCreditPack: () => void;
resetActiveCreditPack: () => void;
editAppraisalSubSection: (payload: {
section: ICreditPackAppraisalSubSection;
sectionKey: string;
}) => void;
initNewAppraisalSubSection: (payload: { sectionKey: string }) => void;
submitExecutiveSummary: (payload: {
executiveSummary: ICreditPackExecutiveSummary;
}) => void;
submitApplicationFace: (payload: {
applicationFace: ICreditPackApplicationFace;
}) => void;
addClipping: (payload: PayloadAddClipping) => void;
}
interface PayloadAddClipping {
creditPackId: string;
sectionKey: string;
subSectionId: string;
analysis: string;
clippingType: TClippingType;
story: IAylienStory;
}
export default useCreditPacksState;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment