Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/GAMZA-BAT/algohub-client in…
Browse files Browse the repository at this point in the history
…to fix#308/reduce-api-call
  • Loading branch information
ptyoiy committed Feb 2, 2025
2 parents e6bbd80 + 91e32d4 commit 6f8d95b
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 30 deletions.
2 changes: 2 additions & 0 deletions src/app/[user]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getGroupsByUsers } from "@/app/api/users";
import { auth } from "@/auth";
import Sidebar from "@/common/component/Sidebar";
import { sidebarWrapper } from "@/styles/shared.css";
import LoginAlertModalController from "@/view/user/index/GroupCard/LoginAlertModalController";
import ListSection from "@/view/user/index/ListSection";
import UserCard from "@/view/user/index/UserCard";
import { userCardWrapper } from "@/view/user/index/UserCard/index.css";
Expand Down Expand Up @@ -48,6 +49,7 @@ const UserDashboardPage = async ({
/>
))}
</div>
<LoginAlertModalController />
</main>
);
};
Expand Down
12 changes: 9 additions & 3 deletions src/app/[user]/setting/action.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use server";
import { patchMyInfo, patchPassword } from "@/app/api/users";
import type { PasswordRequest } from "@/app/api/users/type";
import { isHTTPError } from "@/shared/util/error";

export const patchMyInfoAction = async (formData: FormData) => {
try {
Expand All @@ -15,8 +16,13 @@ export const patchPasswordAction = async ({
newPassword,
}: PasswordRequest) => {
try {
await patchPassword({ currentPassword, newPassword });
} catch {
throw new Error("fail to patch password");
const response = await patchPassword({ currentPassword, newPassword });
return response;
} catch (error) {
if (isHTTPError(error)) {
const customError = { status: error?.response?.status };
throw new Error(JSON.stringify(customError));
}
throw error;
}
};
6 changes: 2 additions & 4 deletions src/app/[user]/setting/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,10 @@ export const usePatchPasswordMutation = () => {
showToast("비밀번호가 변경되었습니다.", "success");
},
onError: (error: HTTPError) => {
if (!error.response) return;

const { status } = error.response;
const { status } = JSON.parse(error.message);

switch (status) {
case HTTP_ERROR_STATUS.FORBIDDEN: {
case HTTP_ERROR_STATUS.BAD_REQUEST: {
showToast("비밀번호가 일치하지 않습니다.", "error");
break;
}
Expand Down
21 changes: 14 additions & 7 deletions src/app/api/users/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,19 @@ export const patchPassword = async ({
currentPassword,
newPassword,
}: PasswordRequest) => {
const response = await kyInstance.patch("api/users/me/password", {
json: {
currentPassword,
newPassword,
},
});
try {
const response = await kyInstance
.patch("api/users/me/password", {
json: {
currentPassword,
newPassword,
},
})
.json();

return response;
return response;
} catch (err) {
console.log({ err });
throw err;
}
};
5 changes: 4 additions & 1 deletion src/shared/component/LoginAlertModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ const LoginAlertModal = ({
}: LoginAlertModalProps) => {
const router = useRouter();

const handleRedirectToLogin = () => router.push("/login");
const handleRedirectToLogin = () => {
onClose();
router.push("/login");
};

return (
<Modal isOpen={isOpen} onClose={onClose} hasCloseBtn>
Expand Down
19 changes: 19 additions & 0 deletions src/shared/component/ProtectedLink/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { loginAlertModalAtom } from "@/shared/store/alertModal";
import { useSetAtom } from "jotai";
import { useSession } from "next-auth/react";
import Link from "next/link";
import type { ComponentProps, MouseEvent } from "react";

const ProtectedLink = (props: ComponentProps<typeof Link>) => {
const handleShowModal = useSetAtom(loginAlertModalAtom);
const { status: authStatus } = useSession();
const handleClick = (e: MouseEvent) => {
if (authStatus === "unauthenticated") {
e.preventDefault();
handleShowModal(true);
}
};
return <Link {...props} onClick={handleClick} />;
};

export default ProtectedLink;
3 changes: 3 additions & 0 deletions src/shared/store/alertModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { atom } from "jotai";

export const loginAlertModalAtom = atom(false);
12 changes: 12 additions & 0 deletions src/shared/util/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const isHTTPError = (
error: unknown,
): error is { response: { status: number } } => {
return (
typeof error === "object" &&
error !== null &&
"response" in error &&
error.response !== null &&
typeof error.response === "object" &&
"status" in error.response
);
};
2 changes: 1 addition & 1 deletion src/shared/util/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export const createFormDataFromDirtyFields = <T extends z.ZodRawShape>(

return acc;
},
{} as Record<string, ValueType>,
{ isDefaultImage: true } as Record<string, ValueType>,
);
data.append("request", JSON.stringify(requestData));
return data;
Expand Down
25 changes: 14 additions & 11 deletions src/view/group/problem-list/SolvedList/ProblemInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ProblemContent } from "@/app/api/problems/type";
import ProblemList from "@/shared/component/ProblemList";
import Link from "next/link";

type ProblemInfoProps = {
problemInfo: ProblemContent;
Expand All @@ -9,17 +10,19 @@ const ProblemInfo = ({ problemInfo }: ProblemInfoProps) => {
return (
<ProblemList>
<ProblemList.Header />
<ProblemList.Item
problemId={problemInfo.problemId}
title={problemInfo.title}
endDate={problemInfo.endDate}
level={problemInfo.level}
solved={problemInfo.solved}
memberCount={problemInfo.memberCount}
submitMemberCount={problemInfo.submitMemberCount}
accuracy={problemInfo.accuracy}
link={problemInfo.link}
/>
<Link href={problemInfo.link} target="_blank" rel="noopener noreferrer">
<ProblemList.Item
problemId={problemInfo.problemId}
title={problemInfo.title}
endDate={problemInfo.endDate}
level={problemInfo.level}
solved={problemInfo.solved}
memberCount={problemInfo.memberCount}
submitMemberCount={problemInfo.submitMemberCount}
accuracy={problemInfo.accuracy}
link={problemInfo.link}
/>
</Link>
</ProblemList>
);
};
Expand Down
12 changes: 12 additions & 0 deletions src/view/user/index/GroupCard/LoginAlertModalController.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"use client";

import LoginAlertModal from "@/shared/component/LoginAlertModal";
import { loginAlertModalAtom } from "@/shared/store/alertModal";
import { useAtom } from "jotai";

const LoginAlertModalController = () => {
const [isOpen, setIsOpen] = useAtom(loginAlertModalAtom);
return <LoginAlertModal isOpen={isOpen} onClose={() => setIsOpen(false)} />;
};

export default LoginAlertModalController;
6 changes: 3 additions & 3 deletions src/view/user/index/GroupCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { GroupResponse, GroupStatus } from "@/app/api/groups/type";
import defaultImg from "@/asset/img/img_card_profile.png";
import { IcnCalenderCard, IcnUser, IcnUser2 } from "@/asset/svg";
import ProtectedLink from "@/shared/component/ProtectedLink";
import StatusDot from "@/view/user/index/GroupCard/StatusDot";
import {
dateStyle,
Expand All @@ -12,7 +13,6 @@ import {
ownerStyle,
} from "@/view/user/index/GroupCard/index.css";
import Image from "next/image";
import Link from "next/link";

interface GroupCardProps {
item: GroupResponse;
Expand All @@ -23,7 +23,7 @@ const GroupCard = ({ item, status }: GroupCardProps) => {
const isDone = status === "done";

return (
<Link href={`/group/${id}`}>
<ProtectedLink href={`/group/${id}`}>
<article className={groupCardWrapper}>
<Image
src={groupImage || defaultImg}
Expand Down Expand Up @@ -52,7 +52,7 @@ const GroupCard = ({ item, status }: GroupCardProps) => {
<p className={descStyle({ isDone })}>{ownerNickname}</p>
</div>
</article>
</Link>
</ProtectedLink>
);
};

Expand Down

0 comments on commit 6f8d95b

Please sign in to comment.