dm: 로그인 변경
This commit is contained in:
@@ -11,6 +11,7 @@ import PostcodeModal from "@/components/PostcodeModal";
|
||||
import type { AddrItem } from "@/app/store/sdmMng/postcode-service";
|
||||
import { useDmStore } from "@/app/store";
|
||||
import { fetchType, getFetch, postFetch, putFetch } from "@/components/ui/api";
|
||||
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
|
||||
import { getCookie } from "@common/components/lib";
|
||||
|
||||
type Option = { value: string; label: string };
|
||||
@@ -166,7 +167,7 @@ function Hr({ className = "" }: { className?: string }) {
|
||||
|
||||
export default function DemandPlaceRegisterPage() {
|
||||
const router = useRouter();
|
||||
const { Common, initializeCommonData } = useDmStore((state) => state);
|
||||
const { Common, initializeCommonData, actionLogin } = useDmStore((state) => state);
|
||||
const { selectSidoData, selectSigunData } = Common;
|
||||
|
||||
const [editMode, setEditMode] = useState(false);
|
||||
@@ -444,21 +445,20 @@ export default function DemandPlaceRegisterPage() {
|
||||
|
||||
alert("수요처 수정 완료!");
|
||||
} else {
|
||||
const response = await postFetch("/reuseFc/request", payload);
|
||||
const responseJson = await response.json().catch(() => null);
|
||||
const savedUser = responseJson?.data ?? payload;
|
||||
await postFetch("/reuseFc/request", payload);
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
const nextSessionUser = {
|
||||
...(sessionUser ?? {}),
|
||||
...savedUser,
|
||||
};
|
||||
delete nextSessionUser.dmdAplyPswd;
|
||||
sessionStorage.setItem("user", JSON.stringify(nextSessionUser));
|
||||
const loginSuccess = await actionLogin({
|
||||
dmdInfoId: fullDmdInfoId,
|
||||
dmdAplyPswd: sha512.hex(password),
|
||||
} as DemandCompType);
|
||||
|
||||
if (!loginSuccess) {
|
||||
alert("수요처 등록은 완료되었지만 자동 로그인에 실패하였습니다. 다시 로그인해 주세요.");
|
||||
return;
|
||||
}
|
||||
|
||||
alert("수요처 등록 완료!");
|
||||
router.push("/apply/dmdinfo"); // 수요정보등록
|
||||
router.push("/apply/dmdinfo");
|
||||
}
|
||||
|
||||
setPw("");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { type ReactNode, createContext, useContext, useRef } from 'react'
|
||||
import { type ReactNode, createContext, useContext, useEffect, useRef } from 'react'
|
||||
import { useStore } from 'zustand'
|
||||
import { type DmStore, StoreZus } from './store'
|
||||
|
||||
@@ -23,6 +23,11 @@ export const StoreProvider = ({
|
||||
// Create store instance if not initialized
|
||||
storeRef.current = StoreZus() as StoreApi
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
storeRef.current?.getState().hydrateLoginUser();
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<StoreContext.Provider value={storeRef.current}>
|
||||
{children}
|
||||
@@ -39,4 +44,4 @@ export const useDmStore = <T,>(
|
||||
}
|
||||
|
||||
return useStore(storeContext, selector)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,20 @@ export const sdmInfoFormSchema = z.object({
|
||||
|
||||
export type SdmInfoFormData = z.infer<typeof sdmInfoFormSchema>;
|
||||
|
||||
export type LoginUser = {
|
||||
dmdCoNm?: string;
|
||||
dmdInfoId?: string;
|
||||
dmdCoSn?: number;
|
||||
zip?: string;
|
||||
daddr?: string;
|
||||
daddr2?: string;
|
||||
telno?: string;
|
||||
ctpvCd?: string;
|
||||
sggCd?: string;
|
||||
rgtr?: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
const formatTelno = (telno?: string | null) => {
|
||||
const digits = (telno ?? '').replace(/\D/g, '');
|
||||
|
||||
@@ -512,7 +526,7 @@ const fetchUpdateSdmInfoData = async (data: SdmInfoFormData): Promise<boolean> =
|
||||
}
|
||||
}
|
||||
|
||||
const postSdmLoginData = async (data: DemandCompType) => {
|
||||
const postSdmLoginData = async (data: DemandCompType): Promise<boolean> => {
|
||||
try {
|
||||
const res = await postFetch("/reuseFc/request/login", data);
|
||||
const jsonData = await res.json();
|
||||
@@ -539,9 +553,23 @@ const postSdmLoginData = async (data: DemandCompType) => {
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
alert("수요처 로그인에 실패하였습니다.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const getStoredLoginUser = (): LoginUser | null => {
|
||||
if (typeof window === "undefined") return null;
|
||||
|
||||
const sessionUser = sessionStorage.getItem("user");
|
||||
if (!sessionUser) return null;
|
||||
|
||||
try {
|
||||
return JSON.parse(sessionUser) as LoginUser;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const getDemandCompList = async (searchText: string, pageCnt: number) => {
|
||||
try {
|
||||
const url = '/reuseFc/request/' + (searchText ? searchText : '') + '/' + pageCnt;
|
||||
@@ -586,11 +614,12 @@ const fetchGetSimilarCaseList = async (part: string, value: number | string) =>
|
||||
====================================*/
|
||||
export type SdmActions = {
|
||||
initializeSdmData: () => void;
|
||||
hydrateLoginUser: () => void;
|
||||
insertSdmData: (data: DemandCompType) => Promise<void>;
|
||||
insertSdmInfoData: (data: SdmInfoFormData) => Promise<boolean>;
|
||||
updateSdmInfoData: (data: SdmInfoFormData) => Promise<boolean>;
|
||||
getDemandCompList: (searchText: string, pageCnt: number) => Promise<void>;
|
||||
actionLogin: (data: DemandCompType) => Promise<void>;
|
||||
actionLogin: (data: DemandCompType) => Promise<boolean>;
|
||||
getSdmInfoStatusList: (dmdInfoId: string) => Promise<void>;
|
||||
getSimilarCaseList: (part: string, value: number | string) => Promise<void>;
|
||||
actionLogout: () => Promise<void>;
|
||||
@@ -616,6 +645,7 @@ export type SdmType = {
|
||||
// 로그인관련
|
||||
successNextPage: boolean;
|
||||
successLogin: boolean;
|
||||
loginUser: LoginUser | null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,6 +667,7 @@ export const SdmState: SdmType = {
|
||||
// 로그인관련
|
||||
successNextPage: false,
|
||||
successLogin: false,
|
||||
loginUser: null,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,6 +675,15 @@ export const SdmReducer = (set: any): SdmActions => {
|
||||
return {
|
||||
initializeSdmData: async () => {
|
||||
},
|
||||
hydrateLoginUser: () => {
|
||||
const loginUser = getStoredLoginUser();
|
||||
set((state: SdmType) => ({
|
||||
Sdm: {
|
||||
...state.Sdm,
|
||||
loginUser,
|
||||
}
|
||||
}))
|
||||
},
|
||||
|
||||
insertSdmData: async (data: DemandCompType) => {
|
||||
const preRes = await getSdmInfoStatusList(data.dmdInfoId);
|
||||
@@ -743,14 +783,20 @@ export const SdmReducer = (set: any): SdmActions => {
|
||||
}))
|
||||
},
|
||||
|
||||
actionLogin: async (data: DemandCompType) => {
|
||||
actionLogin: async (data: DemandCompType): Promise<boolean> => {
|
||||
const loginSuccess = await postSdmLoginData(data);
|
||||
const loginUser = loginSuccess ? getStoredLoginUser() : undefined;
|
||||
set((state: SdmType) => ({
|
||||
Sdm: {
|
||||
...state.Sdm,
|
||||
successLogin: loginSuccess,
|
||||
loginUser:
|
||||
loginSuccess
|
||||
? loginUser
|
||||
: state.Sdm.loginUser,
|
||||
}
|
||||
}))
|
||||
return loginSuccess;
|
||||
},
|
||||
|
||||
// 유사사례 조회
|
||||
@@ -792,6 +838,7 @@ export const SdmReducer = (set: any): SdmActions => {
|
||||
Sdm: {
|
||||
...state.Sdm,
|
||||
successLogin: false,
|
||||
loginUser: null,
|
||||
}
|
||||
}))
|
||||
},
|
||||
|
||||
@@ -8,9 +8,6 @@ import LoginModal from "@/components/LoginModal";
|
||||
import { fetchAnonymousMenu, isMenuActive, type MenuItem } from "@/app/store/common";
|
||||
import { useDmStore } from "@/app/store";
|
||||
|
||||
// const LS_TOKEN_KEY = "reuse_accessToken";
|
||||
const LS_USER_KEY = "user";
|
||||
|
||||
const DEFAULT_NAV_ITEMS: Pick<MenuItem, "menuCd" | "menuKornNm" | "urlPath" | "newWndwYn">[] = [
|
||||
{ menuCd: 1, menuKornNm: "물 재이용 소개", urlPath: "/intro", newWndwYn: "N" },
|
||||
{ menuCd: 2, menuKornNm: "물 재이용 현황", urlPath: "/status", newWndwYn: "N" },
|
||||
@@ -22,21 +19,11 @@ export default function TopNav() {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
const { actionLogout } = useDmStore((state) => state);
|
||||
const { actionLogout, Sdm } = useDmStore((state) => state);
|
||||
const { loginUser } = Sdm;
|
||||
const [loginOpen, setLoginOpen] = useState(false);
|
||||
const [userName, setUserName] = useState<string | null>(null);
|
||||
const [topMenus, setTopMenus] = useState<MenuItem[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const sessionUser = sessionStorage.getItem(LS_USER_KEY);
|
||||
if (sessionUser) {
|
||||
const parsed = JSON.parse(sessionUser) as { dmdCoNm?: string };
|
||||
setUserName(parsed.dmdCoNm ?? "수요처");
|
||||
} else {
|
||||
setUserName(null);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
@@ -72,13 +59,13 @@ export default function TopNav() {
|
||||
otptYn: "Y",
|
||||
}));
|
||||
}, [topMenus]);
|
||||
|
||||
const userName = loginUser?.dmdCoNm ?? null;
|
||||
const isLoggedIn = Boolean(loginUser);
|
||||
|
||||
const openLogin = () => setLoginOpen(true);
|
||||
|
||||
const logout = async () => {
|
||||
// localStorage.removeItem(LS_TOKEN_KEY);
|
||||
// localStorage.removeItem(LS_USER_KEY);
|
||||
setUserName(null);
|
||||
await actionLogout();
|
||||
router.push("/main");
|
||||
};
|
||||
@@ -113,7 +100,7 @@ export default function TopNav() {
|
||||
active ? "text-sky-700" : "text-gray-800 hover:text-sky-700",
|
||||
].join(" ");
|
||||
|
||||
if (requiresLogin && !userName) {
|
||||
if (requiresLogin && !isLoggedIn) {
|
||||
return (
|
||||
<button
|
||||
key={item.menuCd}
|
||||
@@ -149,7 +136,7 @@ export default function TopNav() {
|
||||
|
||||
{/* ✅ 우측: 로그인 버튼 / 로그인 정보 + 로그아웃 */}
|
||||
<div className="flex items-center gap-3">
|
||||
{!userName ? (
|
||||
{!isLoggedIn ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={openLogin}
|
||||
@@ -197,10 +184,7 @@ export default function TopNav() {
|
||||
<LoginModal
|
||||
open={loginOpen}
|
||||
onClose={() => setLoginOpen(false)}
|
||||
onSuccess={({ userName: nextUserName }) => {
|
||||
// localStorage.setItem(LS_USER_KEY, nextUserName);
|
||||
// if (accessToken) localStorage.setItem(LS_TOKEN_KEY, accessToken);
|
||||
setUserName(nextUserName);
|
||||
onSuccess={() => {
|
||||
setLoginOpen(false);
|
||||
router.refresh();
|
||||
}}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"build": "next build",
|
||||
"start:dm": "next start -p 3015",
|
||||
"lint": "next lint",
|
||||
"dev:e2e": "next dev --port 3016",
|
||||
"test:e2e": "playwright test",
|
||||
"test:e2e:headed": "playwright test --headed"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user