-
diff --git a/src/components/settings/CompanyInfoManagement/index.tsx b/src/components/settings/CompanyInfoManagement/index.tsx
index 48cc400a..fa6953ca 100644
--- a/src/components/settings/CompanyInfoManagement/index.tsx
+++ b/src/components/settings/CompanyInfoManagement/index.tsx
@@ -1,6 +1,7 @@
'use client';
import { useState, useRef, useCallback } from 'react';
+import { useDaumPostcode } from '@/hooks/useDaumPostcode';
import { Building2, Plus, Save, Upload, X, Search } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
@@ -113,9 +114,19 @@ export function CompanyInfoManagement() {
}
};
+ // Daum 우편번호 서비스
+ const { openPostcode } = useDaumPostcode({
+ onComplete: (result) => {
+ setFormData(prev => ({
+ ...prev,
+ zipCode: result.zonecode,
+ address: result.address,
+ }));
+ },
+ });
+
const handleAddressSearch = () => {
- // TODO: 다음 주소 API 연동
- console.log('주소 검색');
+ openPostcode();
};
const handleSave = async () => {
diff --git a/src/hooks/useAuthGuard.ts b/src/hooks/useAuthGuard.ts
index 1ed859a6..55159316 100644
--- a/src/hooks/useAuthGuard.ts
+++ b/src/hooks/useAuthGuard.ts
@@ -1,5 +1,5 @@
import { useEffect } from 'react';
-import { useRouter } from 'next/navigation';
+import { callLogoutAPI } from '@/lib/auth/logout';
/**
* Auth Guard Hook
@@ -18,8 +18,6 @@ import { useRouter } from 'next/navigation';
* ```
*/
export function useAuthGuard() {
- const router = useRouter();
-
useEffect(() => {
console.log('🔄 useAuthGuard: Starting auth check...');
@@ -36,15 +34,20 @@ export function useAuthGuard() {
console.log('📥 Response status:', response.status);
if (!response.ok) {
- // 인증 실패 시 로그인 페이지로 이동
- console.log('⚠️ 인증 실패: 로그인 페이지로 이동');
- router.replace('/login');
+ // 인증 실패 시:
+ // 1. 서버 로그아웃 API 호출하여 HttpOnly 쿠키 삭제
+ // 2. 쿠키 삭제 후 로그인 페이지로 이동
+ // (쿠키가 남아있으면 미들웨어가 대시보드로 리다이렉트하는 버그 방지)
+ console.log('⚠️ 인증 실패: 쿠키 삭제 후 로그인 페이지로 이동');
+ await callLogoutAPI();
+ window.location.href = '/login';
} else {
console.log('✅ 인증 성공');
}
} catch (error) {
console.error('❌ 인증 확인 오류:', error);
- router.replace('/login');
+ await callLogoutAPI();
+ window.location.href = '/login';
}
};
diff --git a/src/hooks/useDaumPostcode.ts b/src/hooks/useDaumPostcode.ts
new file mode 100644
index 00000000..9428ec15
--- /dev/null
+++ b/src/hooks/useDaumPostcode.ts
@@ -0,0 +1,129 @@
+'use client';
+
+import { useCallback, useEffect, useState } from 'react';
+
+// Daum Postcode 타입 정의
+interface DaumPostcodeData {
+ zonecode: string; // 우편번호
+ address: string; // 기본 주소
+ addressEnglish: string; // 영문 주소
+ addressType: 'R' | 'J'; // R: 도로명, J: 지번
+ userSelectedType: 'R' | 'J';
+ roadAddress: string; // 도로명 주소
+ roadAddressEnglish: string;
+ jibunAddress: string; // 지번 주소
+ jibunAddressEnglish: string;
+ buildingCode: string;
+ buildingName: string; // 건물명
+ apartment: 'Y' | 'N'; // 아파트 여부
+ sido: string; // 시/도
+ sigungu: string; // 시/군/구
+ sigunguCode: string;
+ bname: string; // 법정동/법정리
+ bname1: string;
+ bname2: string;
+ hname: string; // 행정동
+ query: string; // 검색어
+}
+
+interface DaumPostcode {
+ open: () => void;
+}
+
+interface DaumPostcodeConstructor {
+ new (options: {
+ oncomplete: (data: DaumPostcodeData) => void;
+ onclose?: () => void;
+ width?: string | number;
+ height?: string | number;
+ }): DaumPostcode;
+}
+
+interface DaumNamespace {
+ Postcode: DaumPostcodeConstructor;
+}
+
+declare global {
+ interface Window {
+ daum?: DaumNamespace;
+ }
+}
+
+export interface PostcodeResult {
+ zonecode: string; // 우편번호
+ address: string; // 기본 주소 (도로명)
+ buildingName: string; // 건물명
+ jibunAddress: string; // 지번 주소
+}
+
+interface UseDaumPostcodeOptions {
+ onComplete?: (result: PostcodeResult) => void;
+}
+
+export function useDaumPostcode(options?: UseDaumPostcodeOptions) {
+ const [isScriptLoaded, setIsScriptLoaded] = useState(false);
+ const [isLoading, setIsLoading] = useState(false);
+
+ // 스크립트 로드
+ useEffect(() => {
+ // 이미 로드된 경우
+ if (window.daum?.Postcode) {
+ setIsScriptLoaded(true);
+ return;
+ }
+
+ // 이미 스크립트가 추가된 경우
+ const existingScript = document.querySelector(
+ 'script[src*="postcode.v2.js"]'
+ );
+ if (existingScript) {
+ existingScript.addEventListener('load', () => setIsScriptLoaded(true));
+ return;
+ }
+
+ // 스크립트 추가
+ const script = document.createElement('script');
+ script.src =
+ '//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js';
+ script.async = true;
+ script.onload = () => setIsScriptLoaded(true);
+ document.head.appendChild(script);
+
+ return () => {
+ // cleanup: 스크립트는 유지 (다른 컴포넌트에서 사용할 수 있음)
+ };
+ }, []);
+
+ // 우편번호 검색 팝업 열기
+ const openPostcode = useCallback(() => {
+ if (!isScriptLoaded || !window.daum?.Postcode) {
+ console.warn('Daum Postcode script not loaded yet');
+ return;
+ }
+
+ setIsLoading(true);
+
+ new window.daum.Postcode({
+ oncomplete: (data: DaumPostcodeData) => {
+ const result: PostcodeResult = {
+ zonecode: data.zonecode,
+ address: data.roadAddress || data.jibunAddress,
+ buildingName: data.buildingName,
+ jibunAddress: data.jibunAddress,
+ };
+
+ options?.onComplete?.(result);
+ setIsLoading(false);
+ },
+ onclose: () => {
+ setIsLoading(false);
+ },
+ }).open();
+ }, [isScriptLoaded, options]);
+
+ return {
+ openPostcode,
+ isScriptLoaded,
+ isLoading,
+ };
+}
\ No newline at end of file