Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 54 additions & 18 deletions src/entities/user/model/use-user-profile-query.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { sendGTMEvent } from '@next/third-parties/google';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
getUserProfile,
patchAutoMatching,
} from '@/entities/user/api/get-user-profile';
import type {
GetUserProfileResponse,
PatchAutoMatchingParams,
} from '@/entities/user/api/types';
import type { GetUserProfileResponse } from '@/entities/user/api/types';
import { hashValue } from '@/shared/lib/hash';

export const useUserProfileQuery = (memberId: number) => {
Expand All @@ -19,23 +16,62 @@ export const useUserProfileQuery = (memberId: number) => {
});
};

export interface PatchAutoMatchingParams {
memberId: number;
autoMatching: boolean;
}

export const usePatchAutoMatchingMutation = () => {
return useMutation<void, unknown, PatchAutoMatchingParams>({
const qc = useQueryClient();

return useMutation<
void,
unknown,
PatchAutoMatchingParams,
{ prev?: unknown }
>({
mutationFn: patchAutoMatching,
onSuccess: (_, variables) => {
if (variables.autoMatching) {
sendGTMEvent({
event: 'custom_member_study_toggle_on',
dl_timestamp: new Date().toISOString(),
dl_member_id: hashValue(String(variables.memberId)),
});
} else {
sendGTMEvent({
event: 'custom_member_study_toggle_off',
dl_timestamp: new Date().toISOString(),
dl_member_id: hashValue(String(variables.memberId)),

onMutate: async ({ memberId, autoMatching }) => {
await qc.cancelQueries({ queryKey: ['userProfile', memberId] });
const prev = qc.getQueryData(['userProfile', memberId]);
if (prev && typeof prev === 'object') {
qc.setQueryData(['userProfile', memberId], {
...(prev as any),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any 대신 GetUserProfileResponse 타입을 이용하는건 어떨까요?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋습니다...이 부분은...나중에 리뷰 확인하면서 고치도록 하겠습니다..ㅜㅜ

autoMatching,
});
}

return { prev };
},
Comment on lines +36 to +46
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기는 낙관적 업데이트 로직인걸까요?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 그렇습니다!!


onError: (_err, { memberId }, ctx) => {
if (ctx?.prev) {
qc.setQueryData(['userProfile', memberId], ctx.prev);
}
},

onSuccess: async (_data, { memberId, autoMatching }) => {
await qc.invalidateQueries({ queryKey: ['userProfile', memberId] });

await qc.invalidateQueries({
predicate: (q) =>
Array.isArray(q.queryKey) && q.queryKey[0] === 'weeklyParticipation',
});

await qc.invalidateQueries({
predicate: (q) =>
Array.isArray(q.queryKey) &&
q.queryKey[0] === 'weeklyReservationMembers',
});

sendGTMEvent({
event: autoMatching
? 'custom_member_study_toggle_on'
: 'custom_member_study_toggle_off',
dl_timestamp: new Date().toISOString(),
dl_member_id: hashValue(String(memberId)),
});
},
});
};
Loading