Skip to content

Commit

Permalink
feat: add subscription/ plans hooks and mutations
Browse files Browse the repository at this point in the history
  • Loading branch information
abdallah75 authored and Julien-Torrent committed Jun 9, 2022
1 parent 2e9ec85 commit 9f1c594
Show file tree
Hide file tree
Showing 11 changed files with 1,486 additions and 970 deletions.
1 change: 1 addition & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from './itemLike';
export * from './itemValidation';
export * from './action';
export * from './invitation';
export * from './plan';
75 changes: 75 additions & 0 deletions src/api/plan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { QueryClientConfig } from '../types';
import {
buildChangePlanRoute,
buildSetDefaultCardRoute,
CREATE_SETUP_INTENT_ROUTE,
GET_CARDS_ROUTE,
GET_CURRENT_CUSTOMER,
GET_OWN_PLAN_ROUTE,
GET_PLANS_ROUTE,
} from './routes';
import { DEFAULT_GET, DEFAULT_PATCH, DEFAULT_POST, failOnError } from './utils';

export const getPlans = async ({ API_HOST }: QueryClientConfig) => {
const res = await fetch(`${API_HOST}/${GET_PLANS_ROUTE}`, DEFAULT_GET).then(
failOnError,
);

return res.json();
};

export const getOwnPlan = async ({ API_HOST }: QueryClientConfig) => {
const res = await fetch(
`${API_HOST}/${GET_OWN_PLAN_ROUTE}`,
DEFAULT_GET,
).then(failOnError);
return res.json();
};

// payload: planId
export const changePlan = async (
{ planId }: { planId: string },
{ API_HOST }: QueryClientConfig,
) => {
const res = await fetch(`${API_HOST}/${buildChangePlanRoute(planId)}`, {
...DEFAULT_PATCH,
headers: {},
}).then(failOnError);

return res.json();
};

export const getCards = async ({ API_HOST }: QueryClientConfig) => {
const res = await fetch(`${API_HOST}/${GET_CARDS_ROUTE}`, DEFAULT_GET).then(
failOnError,
);
return res.json();
};

export const setDefaultCard = async (
{ cardId }: { cardId: string },
{ API_HOST }: QueryClientConfig,
) => {
const res = await fetch(`${API_HOST}/${buildSetDefaultCardRoute(cardId)}`, {
...DEFAULT_PATCH,
headers: {},
}).then(failOnError);

return res.json();
};

export const createSetupIntent = async ({ API_HOST }: QueryClientConfig) => {
const res = await fetch(`${API_HOST}/${CREATE_SETUP_INTENT_ROUTE}`, {
...DEFAULT_POST,
headers: {},
}).then(failOnError);
return res.json();
};

export const getCurrentCustomer = async ({ API_HOST }: QueryClientConfig) => {
const res = await fetch(
`${API_HOST}/${GET_CURRENT_CUSTOMER}`,
DEFAULT_GET,
).then(failOnError);
return res.json();
};
10 changes: 10 additions & 0 deletions src/api/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,16 @@ export const buildPostInvitationsRoute = (itemId: UUID) =>
export const buildResendInvitationRoute = (args: { itemId: UUID; id: UUID }) =>
`${ITEMS_ROUTE}/${args.itemId}/${INVITATIONS_ROUTE}/${args.id}/send`;

export const GET_PLANS_ROUTE = `${MEMBERS_ROUTE}/plans`;
export const GET_OWN_PLAN_ROUTE = `${MEMBERS_ROUTE}/plans/own`;
export const buildChangePlanRoute = (planId: string) =>
`${MEMBERS_ROUTE}/plans/${planId}`;
export const GET_CARDS_ROUTE = `${MEMBERS_ROUTE}/cards`;
export const buildSetDefaultCardRoute = (cardId: string) =>
`${MEMBERS_ROUTE}/cards/${cardId}/default`;
export const CREATE_SETUP_INTENT_ROUTE = `${MEMBERS_ROUTE}/setup-intent`;
export const GET_CURRENT_CUSTOMER = `${MEMBERS_ROUTE}/customer/current`;

export const API_ROUTES = {
APPS_ROUTE,
ITEMS_ROUTE,
Expand Down
8 changes: 8 additions & 0 deletions src/config/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ export const DATA_KEYS = {
buildInvitationKey,
buildItemInvitationsKey,
};
export const PLANS_KEY = 'plans';
export const OWN_PLAN_KEY = 'ownPlan';
export const buildPlansKey = (id: string) => [MEMBERS_KEY, id, 'plans'];
export const CARDS_KEY = 'cards';
export const CURRENT_CUSTOMER_KEY = 'currentCustomer';

export const MUTATION_KEYS = {
POST_ITEM: 'postItem',
Expand Down Expand Up @@ -232,4 +237,7 @@ export const MUTATION_KEYS = {
PATCH_INVITATION: 'patchInvitation',
DELETE_INVITATION: 'deleteInvitation',
RESEND_INVITATION: 'resendInvitation',
CHANGE_PLAN: 'changePlan',
CREATE_SETUP_INTENT: 'createSetupIntent',
SET_DEFAULT_CARD: 'setDefaultCard',
};
2 changes: 2 additions & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import configureItemValidationHooks from './itemValidation';
import configureActionHooks from './action';
import configureInvitationHooks from './invitation';
import configureMembershipHooks from './membership';
import configurePlanHooks from './plan';

export default (
queryClient: QueryClient,
Expand Down Expand Up @@ -41,5 +42,6 @@ export default (
...configureActionHooks(queryConfig),
...configureInvitationHooks(queryConfig),
...memberHooks,
...configurePlanHooks(queryConfig),
};
};
50 changes: 50 additions & 0 deletions src/hooks/plan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useQuery } from 'react-query';
import { Map, List } from 'immutable';
import { QueryClientConfig } from '../types';
import * as Api from '../api';
import {
CARDS_KEY,
CURRENT_CUSTOMER_KEY,
OWN_PLAN_KEY,
PLANS_KEY,
} from '../config/keys';

export default (queryConfig: QueryClientConfig) => {
const { retry, cacheTime, staleTime } = queryConfig;
const defaultOptions = {
retry,
cacheTime,
staleTime,
};

const usePlans = () =>
useQuery({
queryKey: PLANS_KEY,
queryFn: () => Api.getPlans(queryConfig).then((data) => List(data)),
...defaultOptions,
});

const useOwnPlan = () =>
useQuery({
queryKey: OWN_PLAN_KEY,
queryFn: () => Api.getOwnPlan(queryConfig).then((data) => Map(data)),
...defaultOptions,
});

const useCards = () =>
useQuery({
queryKey: CARDS_KEY,
queryFn: () => Api.getCards(queryConfig).then((data) => List(data)),
...defaultOptions,
});

const useCurrentCustomer = () =>
useQuery({
queryKey: CURRENT_CUSTOMER_KEY,
queryFn: () =>
Api.getCurrentCustomer(queryConfig).then((data) => Map(data)),
...defaultOptions,
});

return { usePlans, useOwnPlan, useCards, useCurrentCustomer };
};
2 changes: 2 additions & 0 deletions src/mutations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import itemLoginMutations from './itemLogin';
import itemMembershipMutations from './membership';
import chatMutations from './chat';
import itemCategoryMutations from './itemCategory';
import planMutations from './plan';
import { QueryClientConfig } from '../types';
import itemExportMutations from './itemExport';
import itemLikeMutations from './itemLike';
Expand All @@ -33,6 +34,7 @@ const configureMutations = (
actionMutations(queryClient, queryConfig);
invitationMutations(queryClient, queryConfig);
authenticationMutations(queryClient, queryConfig);
planMutations(queryClient, queryConfig);
};

export default configureMutations;
58 changes: 58 additions & 0 deletions src/mutations/plan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { QueryClient } from 'react-query';
import {
CURRENT_CUSTOMER_KEY,
MUTATION_KEYS,
OWN_PLAN_KEY,
} from '../config/keys';
import {
changePlanRoutine,
createSetupIntentRoutine,
setDefaultCardRoutine,
} from '../routines';
import * as Api from '../api';
import { QueryClientConfig } from '../types';

export default (queryClient: QueryClient, queryConfig: QueryClientConfig) => {
const { notifier } = queryConfig;

queryClient.setMutationDefaults(MUTATION_KEYS.CHANGE_PLAN, {
mutationFn: (payload) =>
Api.changePlan(payload, queryConfig).then(() => payload),
onSuccess: () => {
notifier?.({ type: changePlanRoutine.SUCCESS });
},
onError: (error) => {
notifier?.({ type: changePlanRoutine.FAILURE, payload: { error } });
},
onSettled: () => {
queryClient.invalidateQueries(OWN_PLAN_KEY);
},
});

queryClient.setMutationDefaults(MUTATION_KEYS.CREATE_SETUP_INTENT, {
mutationFn: () => Api.createSetupIntent(queryConfig),
onSuccess: () => {
notifier?.({ type: createSetupIntentRoutine.SUCCESS });
},
onError: (error) => {
notifier?.({
type: createSetupIntentRoutine.FAILURE,
payload: { error },
});
},
});

queryClient.setMutationDefaults(MUTATION_KEYS.SET_DEFAULT_CARD, {
mutationFn: (payload) =>
Api.setDefaultCard(payload, queryConfig).then(() => payload),
onSuccess: () => {
notifier?.({ type: setDefaultCardRoutine.SUCCESS });
},
onError: (error) => {
notifier?.({ type: setDefaultCardRoutine.FAILURE, payload: { error } });
},
onSettled: () => {
queryClient.invalidateQueries(CURRENT_CUSTOMER_KEY);
},
});
};
1 change: 1 addition & 0 deletions src/routines/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export * from './itemValidation';
export * from './action';
export * from './invitation';
export * from './authentication';
export * from './plan';
5 changes: 5 additions & 0 deletions src/routines/plan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import createRoutine from './utils';

export const changePlanRoutine = createRoutine('CHANGE_PLAN');
export const createSetupIntentRoutine = createRoutine('CREATE_SETUP_INTENT');
export const setDefaultCardRoutine = createRoutine('SET_DEFAULT_CARD');
Loading

0 comments on commit 9f1c594

Please sign in to comment.