diff --git a/apps/cs/app/(with-base-layout)/users/[userUnqId]/modify/page.tsx b/apps/cs/app/(with-base-layout)/users/[userUnqId]/modify/page.tsx
new file mode 100644
index 000000000..a01387c44
--- /dev/null
+++ b/apps/cs/app/(with-base-layout)/users/[userUnqId]/modify/page.tsx
@@ -0,0 +1,10 @@
+import { ModifyPage } from "@/pages/users/ui/modify-page";
+
+export default async function UserModifyPage({
+ params,
+}: {
+ params: Promise<{ userUnqId: string }>;
+}) {
+ const { userUnqId } = await params;
+ return ;
+}
diff --git a/apps/cs/app/(with-base-layout)/users/[userUnqId]/page.tsx b/apps/cs/app/(with-base-layout)/users/[userUnqId]/page.tsx
index d4e0445ec..da4e79b00 100644
--- a/apps/cs/app/(with-base-layout)/users/[userUnqId]/page.tsx
+++ b/apps/cs/app/(with-base-layout)/users/[userUnqId]/page.tsx
@@ -1,6 +1,6 @@
import { UserDetail as VUserDetail } from "@/pages/users";
-export default async function UserDetail({
+export default async function UserDetailPage({
params,
}: {
params: Promise<{ userUnqId: string }>;
diff --git a/apps/cs/src/entities/user/index.ts b/apps/cs/src/entities/user/index.ts
index bd3627f71..7240c1424 100644
--- a/apps/cs/src/entities/user/index.ts
+++ b/apps/cs/src/entities/user/index.ts
@@ -3,9 +3,11 @@ export {
USER_STATE_CODE,
userSaveSchema,
userPasswordUpdateSchema,
+ userUpdateSchema,
type UserSearchParams,
type UserListResponse,
type UserSaveData,
type UserDetailResponse,
type UserPasswordUpdateData,
+ type UserUpdateData,
} from "./model/user-interface";
diff --git a/apps/cs/src/pages/users/ui/create-page.tsx b/apps/cs/src/pages/users/ui/create-page.tsx
index c91fe115d..84cc23b06 100644
--- a/apps/cs/src/pages/users/ui/create-page.tsx
+++ b/apps/cs/src/pages/users/ui/create-page.tsx
@@ -42,21 +42,12 @@ function CreatePage() {
},
});
- // 저장 처리 함수
- const handleSave = async (data: UserSaveData) => {
- try {
- await saveUser(data);
- } catch (error) {
- console.error("회원 등록 실패:", error);
- }
- };
-
return (
);
}
diff --git a/apps/cs/src/pages/users/ui/modify-page.tsx b/apps/cs/src/pages/users/ui/modify-page.tsx
new file mode 100644
index 000000000..fc93e4b05
--- /dev/null
+++ b/apps/cs/src/pages/users/ui/modify-page.tsx
@@ -0,0 +1,75 @@
+"use client";
+
+import React from "react";
+import { useRouter } from "next/navigation";
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { useQuery } from "@tanstack/react-query";
+import {
+ UserApi,
+ userUpdateSchema,
+ type UserUpdateData,
+} from "@/entities/user";
+import { ENDPOINT } from "@/shared/config";
+import { useMutationWrapper, useAlertStore } from "@/shared/lib";
+import { UsersForm } from "./users-form";
+
+interface ModifyPageProps {
+ userUnqId: string;
+}
+
+export function ModifyPage({ userUnqId }: ModifyPageProps) {
+ const router = useRouter();
+ const alert = useAlertStore((state) => state.setMessage);
+
+ const { data: userData } = useQuery({
+ queryKey: [ENDPOINT.USER_SERVICE.USERS, userUnqId],
+ queryFn: () => UserApi.findByUserUnqId(userUnqId),
+ enabled: !!userUnqId,
+ });
+
+ const form = useForm({
+ resolver: zodResolver(userUpdateSchema),
+ defaultValues: {
+ userId: userData?.userId ?? "",
+ userName: userData?.userName ?? "",
+ email: userData?.email ?? "",
+ userStateCode: userData?.userStateCode ?? "",
+ pswdHnt: userData?.pswdHnt ?? "",
+ pswdAns: userData?.pswdAns ?? "",
+ mphn: userData?.mphn ?? "",
+ telno: userData?.telno ?? "",
+ zip: userData?.zip ?? "",
+ addr: userData?.addr ?? "",
+ daddr: userData?.daddr ?? "",
+ laeSeCd: userData?.laeSeCd ?? "",
+ ogdpSeCd: userData?.ogdpSeCd ?? "",
+ aprvYn: userData?.aprvYn ?? "",
+ expryYmd: userData?.expryYmd ?? "",
+ instSeCd: userData?.instSeCd ?? "",
+ dtlInstCd: userData?.dtlInstCd ?? "",
+ aprvYmd: userData?.aprvYmd ?? "",
+ enoCd: userData?.enoCd ?? "",
+ },
+ });
+
+ const { mutateAsync: updateUser } = useMutationWrapper({
+ mutationFn: (data: UserUpdateData) => UserApi.updateUser(userUnqId, data),
+ onSuccess: () => {
+ alert("회원 정보가 수정되었습니다.", router.back);
+ },
+ });
+
+ return (
+
+ );
+}
diff --git a/apps/cs/src/pages/users/ui/user-detail.tsx b/apps/cs/src/pages/users/ui/user-detail.tsx
index 4513555c2..9673f5c02 100644
--- a/apps/cs/src/pages/users/ui/user-detail.tsx
+++ b/apps/cs/src/pages/users/ui/user-detail.tsx
@@ -1,7 +1,7 @@
"use client";
import dayjs from "dayjs";
-import { useRouter } from "next/navigation";
+import { usePathname, useRouter } from "next/navigation";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import {
Button,
@@ -18,6 +18,7 @@ import { PasswordResetDialog } from "./password-reset-dialog";
function UserDetail({ userUnqId }: { userUnqId: string }) {
const router = useRouter();
+ const pathname = usePathname();
const queryClient = useQueryClient();
const alert = useAlertStore((state) => state.setMessage);
@@ -157,7 +158,9 @@ function UserDetail({ userUnqId }: { userUnqId: string }) {
-
+
diff --git a/apps/cs/src/pages/users/ui/users-form.tsx b/apps/cs/src/pages/users/ui/users-form.tsx
index ae575f317..d69e918b0 100644
--- a/apps/cs/src/pages/users/ui/users-form.tsx
+++ b/apps/cs/src/pages/users/ui/users-form.tsx
@@ -1,5 +1,10 @@
import { useState, useMemo, useCallback } from "react";
-import { useWatch, type UseFormReturn } from "react-hook-form";
+import {
+ useWatch,
+ type Path,
+ type PathValue,
+ type UseFormReturn,
+} from "react-hook-form";
import { useQuery } from "@tanstack/react-query";
import {
Button,
@@ -17,7 +22,11 @@ import {
} from "@common/components";
import { FormWrapper } from "@/widgets/form-wrapper";
import { CodeApi, CodeSelect } from "@/entities/code";
-import { UserApi, type UserSaveData } from "@/entities/user";
+import {
+ UserApi,
+ type UserSaveData,
+ type UserUpdateData,
+} from "@/entities/user";
import {
FormField,
FormItem,
@@ -29,19 +38,23 @@ import { useAlertStore, useMutationWrapper } from "@/shared/lib";
import { ZipSearchDialog } from "./zip-search-dialog";
import { AgencySearchDialog } from "./agency-search-dialog";
-type UsersFormProps = {
+type UsersFormProps = {
userId?: string;
- form: UseFormReturn;
- handleSave: (data: UserSaveData) => Promise;
+ form: UseFormReturn;
+ handleSave: (data: T) => Promise;
handleDelete?: () => Promise;
};
-function UsersForm({ userId, form, ...props }: UsersFormProps) {
+function UsersForm({
+ userId,
+ form,
+ ...props
+}: UsersFormProps) {
const isModifyMode = !!userId;
const [watchOgdpSeCd, watchDtlInstCd] = useWatch({
control: form.control,
- name: ["ogdpSeCd", "dtlInstCd"],
+ name: ["ogdpSeCd" as Path, "dtlInstCd" as Path],
});
const alert = useAlertStore((state) => state.setMessage);
@@ -132,21 +145,24 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
);
const handlePasswordConfirmChange = useCallback((value: string) => {
- const password = form.getValues("password");
+ const password = form.getValues("password" as Path);
setPasswordMatch(!password || value === password);
}, []);
const handleAddressSelect = useCallback(
(data: { zip: string; addr: string }) => {
- form.setValue("zip", data.zip);
- form.setValue("addr", data.addr);
+ form.setValue("zip" as Path, data.zip as PathValue>);
+ form.setValue("addr" as Path, data.addr as PathValue>);
},
[form],
);
const handleAgencySelect = useCallback(
(data: { lwpoCd: string; lwpoCdNm: string }) => {
- form.setValue("instSeCd", data.lwpoCd);
+ form.setValue(
+ "instSeCd" as Path,
+ data.lwpoCd as PathValue>,
+ );
setInstSeCdNm(data.lwpoCdNm);
},
[form],
@@ -167,7 +183,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -191,7 +207,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
className="px-6"
onClick={(e) => {
e.preventDefault();
- checkDuplicateUserId(field.value);
+ checkDuplicateUserId(field.value as string);
}}
disabled={!field.value || isValidUserId}
>
@@ -211,7 +227,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -258,7 +274,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -281,7 +297,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -304,7 +320,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -327,7 +343,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -347,7 +363,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -370,7 +386,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -393,7 +409,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
onClick={(e) => {
e.preventDefault();
if (field.value) {
- checkDuplicateEmail(field.value);
+ checkDuplicateEmail(field.value as string);
}
}}
disabled={!field.value || isValidEmail}
@@ -415,7 +431,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -433,7 +449,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -454,7 +470,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -477,7 +493,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -487,9 +503,18 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
value={field.value ?? ""}
onValueChange={(value) => {
field.onChange(value);
- form.setValue("dtlInstCd", "");
- form.setValue("laeSeCd", "");
- form.setValue("enoCd", "");
+ form.setValue(
+ "dtlInstCd" as Path,
+ "" as PathValue>,
+ );
+ form.setValue(
+ "laeSeCd" as Path,
+ "" as PathValue>,
+ );
+ form.setValue(
+ "enoCd" as Path,
+ "" as PathValue>,
+ );
}}
className="w-[16rem]"
placeholder="기관 선택"
@@ -508,7 +533,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -516,8 +541,14 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
value={field.value ?? ""}
onValueChange={(value) => {
field.onChange(value);
- form.setValue("laeSeCd", "");
- form.setValue("enoCd", "");
+ form.setValue(
+ "laeSeCd" as Path,
+ "" as PathValue>,
+ );
+ form.setValue(
+ "enoCd" as Path,
+ "" as PathValue>,
+ );
}}
>
@@ -544,7 +575,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
@@ -552,7 +583,10 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
value={field.value ?? ""}
onValueChange={(value) => {
field.onChange(value);
- form.setValue("enoCd", "");
+ form.setValue(
+ "enoCd" as Path,
+ "" as PathValue>,
+ );
}}
>
@@ -579,7 +613,7 @@ function UsersForm({ userId, form, ...props }: UsersFormProps) {
}
render={({ field }) => (
diff --git a/apps/cs/src/widgets/post/ui/post-form.tsx b/apps/cs/src/widgets/post/ui/post-form.tsx
index dc38f327d..55cd85657 100644
--- a/apps/cs/src/widgets/post/ui/post-form.tsx
+++ b/apps/cs/src/widgets/post/ui/post-form.tsx
@@ -1,7 +1,7 @@
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { useQuery } from "@tanstack/react-query";
-import type { UseFormReturn, FieldPath } from "react-hook-form";
+import type { UseFormReturn, Path } from "react-hook-form";
import { useConfirm } from "@frontend-opensource/use-react-hooks";
import {
Input,
@@ -35,7 +35,7 @@ function PostForm({
form,
handleSave,
}: PostFormProps) {
- const atflCd = form.getValues("atflCd" as FieldPath);
+ const atflCd = form.getValues("atflCd" as Path);
const router = useRouter();
const { confirm } = useConfirm();
@@ -81,7 +81,7 @@ function PostForm({
}
+ name={"pstTtl" as Path}
render={({ field }) => (
@@ -102,7 +102,7 @@ function PostForm({
}
+ name={"wrtrNm" as Path}
render={({ field }) => (
@@ -124,7 +124,7 @@ function PostForm({
}
+ name={"pstPswd" as Path}
render={({ field }) => (
@@ -147,7 +147,7 @@ function PostForm({
}
+ name={"pstCn" as Path}
render={({ field }) => (
@@ -170,7 +170,7 @@ function PostForm({
}
+ name={"rfrncUrl" as Path}
render={({ field }) => (
@@ -194,7 +194,7 @@ function PostForm({
}
+ name={"popupYn" as Path}
render={({ field }) => (
@@ -218,7 +218,7 @@ function PostForm({
/>
}
+ name={"popupYnEtc" as Path}
render={({ field }) => {
const fieldValues = form.getValues().popupYnEtc?.[0];
return (
@@ -227,9 +227,7 @@ function PostForm({
,
- ) === "N"
+ form.getValues("popupYn" as Path) === "N"
}
handlePeriodValueChange={(
periodCode,
@@ -267,7 +265,7 @@ function PostForm({
}
+ name={"upndFixYn" as Path}
render={({ field }) => (
@@ -291,7 +289,7 @@ function PostForm({
/>
}
+ name={"upndFixYnEtc" as Path}
render={({ field }) => {
const fieldValues =
form.getValues().upndFixYnEtc?.[0];
@@ -301,9 +299,8 @@ function PostForm({
,
- ) === "N"
+ form.getValues("upndFixYn" as Path) ===
+ "N"
}
handlePeriodValueChange={(
periodCode,
@@ -341,7 +338,7 @@ function PostForm({
}
+ name={"prdPstgYn" as Path}
render={({ field }) => (
@@ -365,7 +362,7 @@ function PostForm({
/>
}
+ name={"prdPstgYnEtc" as Path}
render={({ field }) => {
const fieldValues =
form.getValues().prdPstgYnEtc?.[0];
@@ -375,9 +372,8 @@ function PostForm({
,
- ) === "N"
+ form.getValues("prdPstgYn" as Path) ===
+ "N"
}
handlePeriodValueChange={(
periodCode,