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
1 change: 1 addition & 0 deletions src/components/mypage/edit/EditProfileContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ function EditProfileContent({ className, schools, majors, ...props }: EditProfil
const onSubmit = (data: EditProfileFormData) => {
updateProfile(
{
clubId,
user: {
name: data.name,
email: data.email,
Expand Down
5 changes: 3 additions & 2 deletions src/hooks/home/useProfileStatusQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { useQuery } from '@tanstack/react-query';
import { homeApi } from '@/lib/apis/home';
import { useClubId } from '@/stores/useClubStore';

export function useProfileStatusQuery() {
const clubId = useClubId();
export function useProfileStatusQuery(clubIdOverride?: string) {
const storedClubId = useClubId();
const clubId = clubIdOverride ?? storedClubId;

return useQuery({
queryKey: ['home', 'profile-status', clubId],
Expand Down
10 changes: 7 additions & 3 deletions src/hooks/home/useWritePost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useSetActiveBoardId } from '@/stores/useBoardNavStore';
export function useWritePost() {
const router = useRouter();
const { clubId } = useParams<{ clubId: string }>();
const { data: profileStatus, isLoading, isFetching, refetch } = useProfileStatusQuery();
const { data: profileStatus, isLoading, isFetching, refetch } = useProfileStatusQuery(clubId);
const setActiveBoardId = useSetActiveBoardId();

const [cardinalModalOpen, setCardinalModalOpen] = useState(false);
Expand All @@ -17,8 +17,12 @@ export function useWritePost() {
const handleWriteClick = async () => {
if (isLoading || isFetching) return;

const { data: latestProfileStatus } = await refetch();
const currentProfileStatus = latestProfileStatus ?? profileStatus;
let currentProfileStatus = profileStatus;

if (!currentProfileStatus?.cardinalAssigned || !currentProfileStatus?.profileCompleted) {
const { data: latestProfileStatus } = await refetch();
currentProfileStatus = latestProfileStatus ?? currentProfileStatus;
}

if (!currentProfileStatus?.cardinalAssigned) {
setCardinalModalOpen(true);
Expand Down
52 changes: 41 additions & 11 deletions src/hooks/mutations/useUpdateProfileMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,23 @@ import { useClubId } from '@/stores/useClubStore';
import { useUserStore } from '@/stores/useUserStore';

interface UpdateProfileParams {
clubId?: string;
user: UpdateUserBody;
clubProfile: Omit<UpdateClubProfileBody, 'profileImage'>;
profileImageFile?: File | null;
resetImage?: boolean;
}

const isCompleteProfile = (user: UpdateUserBody) =>
Boolean(
user.name.trim() &&
user.email.trim() &&
user.tel.trim() &&
user.school.trim() &&
user.department.trim() &&
user.studentId.trim(),
);

export function useUpdateProfileMutation() {
const queryClient = useQueryClient();
const clubId = useClubId();
Expand All @@ -38,11 +49,12 @@ export function useUpdateProfileMutation() {

return { isReset: !!resetImage };
},
onSuccess: async ({ isReset }, { user, clubProfile }) => {
if (!clubId) return;
onSuccess: async ({ isReset }, { clubId: mutationClubId, user, clubProfile }) => {
const targetClubId = mutationClubId ?? clubId;
if (!targetClubId) return;

queryClient.setQueryData(
['mypage', 'me', clubId],
['mypage', 'me', targetClubId],
(old: Record<string, unknown> | undefined) => {
if (!old) return old;
return {
Expand All @@ -65,20 +77,38 @@ export function useUpdateProfileMutation() {
'syncProfile',
);

void queryClient.invalidateQueries({ queryKey: ['home', clubId] });
void queryClient.invalidateQueries({ queryKey: ['home', 'profile-status', clubId] });
void queryClient.invalidateQueries({ queryKey: ['home', 'recent-posts', clubId] });
void queryClient.invalidateQueries({ queryKey: ['posts', clubId] });
queryClient.setQueryData(
['home', 'profile-status', targetClubId],
(
old:
| { cardinalAssigned: boolean; profileCompleted: boolean; missingFields: string[] }
| undefined,
) => {
if (!old) return old;

const profileCompleted = isCompleteProfile(user);
return {
...old,
profileCompleted,
missingFields: profileCompleted ? [] : old.missingFields,
};
},
Comment on lines +80 to +95
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

missingFields도 현재 값 기준으로 갱신해 주세요.

지금은 profileCompleted만 다시 계산하고 missingFields는 이전 캐시를 그대로 유지합니다. 그래서 일부 필드를 수정한 뒤에도 모달이 오래된 누락 목록을 보여줄 수 있습니다. 이 구간은 현재 입력값으로 다시 계산하거나 서버 응답으로 덮어쓰는 쪽이 안전합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/hooks/mutations/useUpdateProfileMutation.ts` around lines 80 - 95, The
cache update in queryClient.setQueryData (key ['home','profile-status',
targetClubId]) only recomputes profileCompleted via isCompleteProfile(user) but
leaves missingFields as old.missingFields; change it to recompute missingFields
from the current user input (or replace with the server response) so the modal
shows up-to-date missing fields. Concretely, inside the updater for
queryClient.setQueryData (the function that currently returns { ...old,
profileCompleted, missingFields: profileCompleted ? [] : old.missingFields }),
replace the missingFields assignment with a recomputation e.g. missingFields:
profileCompleted ? [] : computeMissingFields(user) (or use the server response
payload if available) so missingFields is derived from the current user object
rather than preserved from old.

);

await queryClient.invalidateQueries({ queryKey: ['home', targetClubId] });
await queryClient.invalidateQueries({ queryKey: ['home', 'profile-status', targetClubId] });
void queryClient.invalidateQueries({ queryKey: ['home', 'recent-posts', targetClubId] });
void queryClient.invalidateQueries({ queryKey: ['posts', targetClubId] });

if (isReset) {
void queryClient.invalidateQueries({ queryKey: ['mypage', 'me', clubId] });
void queryClient.invalidateQueries({ queryKey: ['mypage', 'me', targetClubId] });
return;
}

try {
const res = await queryClient.fetchQuery({
queryKey: ['mypage', 'me', clubId],
queryFn: () => mypageApi.getMe(clubId).then((r) => r.data.data),
queryKey: ['mypage', 'me', targetClubId],
queryFn: () => mypageApi.getMe(targetClubId).then((r) => r.data.data),
staleTime: 0,
});
useUserStore.setState(
Expand All @@ -87,7 +117,7 @@ export function useUpdateProfileMutation() {
'syncProfile',
);
} catch {
void queryClient.invalidateQueries({ queryKey: ['mypage', 'me', clubId] });
void queryClient.invalidateQueries({ queryKey: ['mypage', 'me', targetClubId] });
}
},
});
Expand Down
Loading