-
κ΄λ¦¬μ μμ
-
ν΄λΉ κ΄λ¦¬μλ₯Ό μμ νμκ² μ΅λκΉ?
+
+
+
μ λ§ μμ νμκ² μ΅λκΉ?
-
+
diff --git a/src/components/ClientManagement.js b/src/components/ClientManagement.js
index 5faf989..9fc7d1e 100644
--- a/src/components/ClientManagement.js
+++ b/src/components/ClientManagement.js
@@ -1,8 +1,10 @@
import "../styles/ClientManagement.css";
-import DummyData from "../data/DummyData";
import React, { useState, useEffect } from "react";
import KakaoMap from "./KakaoMap";
+const API_BASE_URL = process.env.REACT_APP_API_URL;
+const REST_API_KEY = process.env.REACT_APP_KAKAO_REST_API_KEY;
+
const ClientManagement = () => {
const [selectedClient, setSelectedClient] = useState(null);
const [searchTerm, setSearchTerm] = useState("");
@@ -13,8 +15,15 @@ const ClientManagement = () => {
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [isHistoryModalOpen, setIsHistoryModalOpen] = useState(false);
const [editedClient, setEditedClient] = useState(null);
- const [clients, setClients] = useState(DummyData);
- const [isKakaoLoaded, setIsKakaoLoaded] = useState(!!window.kakao?.maps);
+ const [clients, setClients] = useState([]);
+ const [isKakaoLoaded] = useState(!!window.kakao?.maps);
+ const [totalPages, setTotalPages] = useState(1);
+ const [currentPage, setCurrentPage] = useState([]);
+ const [pageGroup, setPageGroup] = useState(0);
+ const [setAddresses] = useState([]);
+ const [addressHistory, setAddressHistory] = useState([]);
+ const itemsPerPage = 10;
+ const pagesPerGroup = 10;
const [newClient, setNewClient] = useState({
name: "",
@@ -22,91 +31,459 @@ const ClientManagement = () => {
phone: "",
gender: "",
age: "",
- region_Address: "",
- road_Address: "",
- lat: null,
- lng: null,
+ regionAddress: "",
+ roadAddress: "",
addressHistory: [],
});
+ const fetchClients = async () => {
+ try {
+ let token = localStorage.getItem("token")?.trim();
+ if (!token) throw new Error("λ‘κ·ΈμΈμ΄ νμν©λλ€.");
+
+ if (!token.startsWith("Bearer ")) {
+ token = `Bearer ${token}`;
+ }
+
+ const response = await fetch(
+ `${API_BASE_URL}/api/users?page=1&size=${itemsPerPage}`,
+ {
+ method: "GET",
+ headers: { Authorization: token },
+ }
+ );
+
+ if (!response.ok) throw new Error("λ°μ΄ν° λΆλ¬μ€κΈ° μ€ν¨");
+
+ const data = await response.json();
+
+ console.log("π μλ² μλ΅ λ°μ΄ν°:", data);
+
+ setClients(data.content || data.contents || []);
+ setTotalPages(data.totalPages || data.pageable?.totalPages || 1);
+ setCurrentPage(1);
+ } catch (error) {
+ console.error("π¨ κ³ κ° λ°μ΄ν° κ°μ Έμ€κΈ° μ€λ₯:", error);
+ alert(error.message);
+ }
+ };
+
+ const searchClients = async () => {
+ if (!searchTerm.trim()) {
+ fetchClients();
+ return;
+ }
+
+ try {
+ const token = localStorage.getItem("token");
+ if (!token) throw new Error("λ‘κ·ΈμΈμ΄ νμν©λλ€.");
+
+ let endpoint = "";
+ let queryParam = "";
+
+ if (searchCategory === "name") {
+ endpoint = `/api/users/search/name`;
+ queryParam = `name=${searchTerm}`;
+ } else if (searchCategory === "newAddress") {
+ endpoint = `/api/users/search/road`;
+ queryParam = `keyword=${searchTerm}`;
+ } else if (searchCategory === "oldAddress") {
+ endpoint = `/api/users/search/region`;
+ queryParam = `keyword=${searchTerm}`;
+ }
+
+ const response = await fetch(
+ `${API_BASE_URL}${endpoint}?${queryParam}&page=1&size=${itemsPerPage}`,
+ {
+ method: "GET",
+ headers: { Authorization: token },
+ }
+ );
+
+ if (!response.ok) throw new Error("κ²μ μ€ν¨");
+
+ const data = await response.json();
+
+ console.log("π κ²μ κ²°κ³Ό μλ΅ λ°μ΄ν°:", data);
+
+ const updatedClients = (data.content || data.contents || []).map(
+ (client) => ({
+ ...client,
+ regionAddress: client.regionAddress || "μ£Όμ μμ",
+ roadAddress: client.roadAddress || "μ£Όμ μμ",
+ })
+ );
+
+ setClients(updatedClients);
+ setTotalPages(data.totalPages || data.pageable?.totalPages || 1);
+ setCurrentPage(1);
+ } catch (error) {
+ console.error("π¨ κ²μ μ€ μ€λ₯ λ°μ:", error);
+ alert(error.message);
+ }
+ };
+
+ const filteredClients = searchTerm.trim() ? clients : clients;
+
useEffect(() => {
- if (window.kakao && window.kakao.maps) {
- console.log("β
Kakao μ§λ APIκ° μ΄λ―Έ λ‘λλ¨");
- setIsKakaoLoaded(true);
+ console.log("π’ ν΄λΌμ΄μΈνΈ 리μ€νΈ μ
λ°μ΄νΈ:", clients);
+ }, [clients]);
+
+ useEffect(() => {
+ console.log("π νν°λ§λ κ³ κ° λ¦¬μ€νΈ:", filteredClients);
+ }, [filteredClients]);
+
+ const handleSearchInputChange = (e) => {
+ setSearchTerm(e.target.value);
+ };
+
+ const handleSearchKeyPress = (e) => {
+ if (e.key === "Enter") {
+ e.preventDefault();
+ searchClients();
+ }
+ };
+
+ const handleShowAllClients = () => {
+ fetchClients();
+ setSearchTerm("");
+ };
+
+ const handleClientSelect = async (client) => {
+ console.log("π μ νλ κ³ κ°:", client);
+
+ let updatedClient = {
+ id: client.id,
+ name: client.name,
+ email: client.email,
+ phoneNumber: client.phoneNumber || client.phone || "",
+ regionAddress:
+ client.latestRegionAddress || client.regionAddress || "μ£Όμ μμ",
+ roadAddress:
+ client.latestRoadAddress || client.roadAddress || "μ£Όμ μμ",
+ gender: client.gender,
+ age: client.age,
+ lat: client.x || client.lat || null,
+ lng: client.y || client.lng || null,
+ };
+
+ let addressToSearch =
+ updatedClient.roadAddress !== "μ£Όμ μμ"
+ ? updatedClient.roadAddress
+ : updatedClient.regionAddress;
+
+ if (!updatedClient.lat || !updatedClient.lng) {
+ console.log("π μ§λ μ’ν μμ, Kakao APIλ‘ λ³ν μλ...");
+
+ try {
+ let coords = await fetchCoordinates(addressToSearch);
+ console.log("π λ³νλ Kakao μ’ν:", coords);
+
+ if (coords.lat && coords.lng) {
+ updatedClient.lat = coords.lat;
+ updatedClient.lng = coords.lng;
+ } else {
+ console.warn("β οΈ Kakao API μ’ν λ³ν μ€ν¨. κΈ°λ³Έκ° μ μ§");
+ }
+
+ console.log("π’ μ΅μ’
μ
λ°μ΄νΈλ μ’ν:", updatedClient);
+ } catch (error) {
+ console.error("π¨ Kakao API μ’ν λ³ν μ€ μ€λ₯ λ°μ:", error);
+ }
}
+
+ setSelectedClient(updatedClient);
+ };
+
+ useEffect(() => {
+ fetchClients();
}, []);
- const filteredClients = clients.filter((client) =>
- client[searchCategory].toLowerCase().includes(searchTerm.toLowerCase())
- );
+ const fetchClientsAndAddresses = async () => {
+ try {
+ const token = localStorage.getItem("token");
+ if (!token) {
+ throw new Error("λ‘κ·ΈμΈμ΄ νμν©λλ€.");
+ }
+
+ const userResponse = await fetch(
+ `${API_BASE_URL}/api/users?page=1&size=${itemsPerPage}`,
+ {
+ method: "GET",
+ headers: { Authorization: token },
+ }
+ );
- const handleSearchAddress = (setClientState) => {
+ if (!userResponse.ok) {
+ throw new Error("κ³ κ° λ°μ΄ν° λΆλ¬μ€κΈ° μ€ν¨");
+ }
+
+ const userData = await userResponse.json();
+ setClients(userData.contents || []);
+
+ const newAddress = {
+ regionAddress: newClient.regionAddress || "",
+ roadAddress: newClient.roadAddress || "",
+ x: newClient.lng ? Number(newClient.lng) : null,
+ y: newClient.lat ? Number(newClient.lat) : null,
+ region: newClient.region || "μμΈ",
+ };
+
+ console.log("π POST /api/addresses μμ² λ°μ΄ν°:", newAddress);
+
+ if (!newAddress.roadAddress || !newAddress.regionAddress) {
+ console.warn("β οΈ μ£Όμ μ λ³΄κ° λΆμμ νμ¬ μμ²μ 보λ΄μ§ μμ.");
+ return;
+ }
+
+ const addressResponse = await fetch(`${API_BASE_URL}/api/addresses`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: token,
+ },
+ body: JSON.stringify(newAddress),
+ });
+
+ const responseText = await addressResponse.text();
+ console.log("π΄ μ£Όμ API μλ΅:", responseText);
+
+ if (!addressResponse.ok) {
+ console.error(`π¨ μ£Όμ μ μ₯ μ€ν¨ (HTTP ${addressResponse.status})`);
+ throw new Error(responseText);
+ }
+
+ const addressData = JSON.parse(responseText);
+ setAddresses(addressData.contents || []);
+
+ console.log("π κ°μ Έμ¨ μ£Όμ λ°μ΄ν°:", addressData.contents);
+ } catch (error) {
+ console.error("π¨ λ°μ΄ν° κ°μ Έμ€λ μ€ μ€λ₯ λ°μ:", error);
+ alert(error.message);
+ }
+ };
+
+ useEffect(() => {
+ fetchClientsAndAddresses();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ const handlePageChange = async (pageNumber) => {
+ setCurrentPage(pageNumber);
+
+ try {
+ const token = localStorage.getItem("token");
+ if (!token) throw new Error("λ‘κ·ΈμΈμ΄ νμν©λλ€.");
+
+ const response = await fetch(
+ `${API_BASE_URL}/api/users?page=${pageNumber}&size=${itemsPerPage}`,
+ {
+ method: "GET",
+ headers: { Authorization: token },
+ }
+ );
+
+ if (!response.ok) throw new Error("λ°μ΄ν° λΆλ¬μ€κΈ° μ€ν¨");
+
+ const data = await response.json();
+ setClients(data.contents);
+ setTotalPages(data.pageable?.totalPages || 1);
+ } catch (error) {
+ console.error("π¨ νμ΄μ§ λ³κ²½ μ€λ₯:", error);
+ }
+ };
+
+ const handlePrevPageGroup = () => {
+ if (pageGroup > 0) {
+ setPageGroup(pageGroup - 1);
+ }
+ };
+
+ const handleNextPageGroup = () => {
+ if ((pageGroup + 1) * pagesPerGroup < totalPages) {
+ setPageGroup(pageGroup + 1);
+ }
+ };
+
+ const pageNumbers = Array.from(
+ { length: pagesPerGroup },
+ (_, i) => pageGroup * pagesPerGroup + i + 1
+ ).filter((page) => page <= totalPages);
+
+ const handleSearchAddressForNewClient = () => {
new window.daum.Postcode({
oncomplete: function (data) {
const { roadAddress, jibunAddress, autoJibunAddress } = data;
+ console.log("π [μΆκ°] μ νλ μ£Όμ:", roadAddress, jibunAddress);
+
+ setNewClient((prev) => {
+ const updatedClient = {
+ ...prev,
+ roadAddress: roadAddress || "",
+ regionAddress: jibunAddress || autoJibunAddress || "",
+ };
+ console.log("π’ [μΆκ°] μ
λ°μ΄νΈλ newClient μν:", updatedClient);
+ return updatedClient;
+ });
+ },
+ }).open();
+ };
- setClientState((prev) => ({
- ...prev,
- road_Address: roadAddress || prev.road_Address,
- region_Address:
- jibunAddress || autoJibunAddress || prev.region_Address,
- }));
-
- const addressForGeocode =
- roadAddress || jibunAddress || autoJibunAddress;
- if (addressForGeocode) {
- fetchCoordinates(addressForGeocode, setClientState);
- }
+ const handleSearchAddressForEditClient = () => {
+ new window.daum.Postcode({
+ oncomplete: function (data) {
+ const { roadAddress, jibunAddress, autoJibunAddress } = data;
+ console.log("π [μμ ] μ νλ μ£Όμ:", roadAddress, jibunAddress);
+
+ setEditedClient((prev) => {
+ const updatedClient = {
+ ...prev,
+ roadAddress: roadAddress || "",
+ regionAddress: jibunAddress || autoJibunAddress || "",
+ };
+ console.log("π’ [μμ ] μ
λ°μ΄νΈλ editedClient μν:", updatedClient);
+ return updatedClient;
+ });
},
}).open();
};
- const fetchCoordinates = (address, updateClientState) => {
- const geocoder = new window.kakao.maps.services.Geocoder();
- geocoder.addressSearch(address, (result, status) => {
- if (status === window.kakao.maps.services.Status.OK) {
- updateClientState((prev) => ({
- ...prev,
- lat: parseFloat(result[0].y),
- lng: parseFloat(result[0].x),
- }));
+ const fetchCoordinates = async (address) => {
+ return new Promise(async (resolve, reject) => {
+ if (!REST_API_KEY) {
+ console.error("π¨ Kakao REST API ν€κ° μ€μ λμ§ μμμ΅λλ€!");
+ reject("Kakao API ν€ μ€λ₯");
+ return;
+ }
+
+ console.log(`π‘ Kakao API μ£Όμ κ²μ μμ²: ${address}`);
+
+ const fetchFromKakaoAPI = async (query) => {
+ const response = await fetch(
+ `https://dapi.kakao.com/v2/local/search/address.json?query=${encodeURIComponent(
+ query.trim()
+ )}`,
+ {
+ method: "GET",
+ headers: {
+ Authorization: `KakaoAK ${REST_API_KEY}`,
+ "Content-Type": "application/json",
+ },
+ }
+ );
+ return response.json();
+ };
+
+ try {
+ let data = await fetchFromKakaoAPI(address);
+
+ if (!data.documents || data.documents.length === 0) {
+ console.warn("β οΈ λλ‘λͺ
μ£Όμ λ³ν μ€ν¨. μ§λ² μ£Όμλ‘ μ¬μλ...");
+ data = await fetchFromKakaoAPI(address);
+ }
+
+ if (data.documents && data.documents.length > 0) {
+ const coords = {
+ lat: parseFloat(data.documents[0].y),
+ lng: parseFloat(data.documents[0].x),
+ };
+ console.log(
+ `π λ³νλ Kakao μ’ν: lat=${coords.lat}, lng=${coords.lng}`
+ );
+ resolve(coords);
+ } else {
+ console.warn("β οΈ Kakao API μλ΅ μμ. κΈ°λ³Έ μ’ν λ°ν");
+ resolve({ lat: 37.5665, lng: 126.978 });
+ }
+ } catch (error) {
+ console.error("π¨ Kakao API μμ² μ€ν¨", error);
+ resolve({ lat: 37.5665, lng: 126.978 });
}
});
};
- const handleAddClient = (e) => {
+ const handleAddClient = async (e) => {
e.preventDefault();
- if (Object.values(newClient).some((field) => field === "")) {
- alert("λͺ¨λ νλλ₯Ό μ
λ ₯νμΈμ!");
+
+ if (!newClient.name || !newClient.email || !newClient.phone) {
+ alert("μ΄λ¦, μ΄λ©μΌ, μ νλ²νΈλ νμ μ
λ ₯ νλͺ©μ
λλ€.");
return;
}
- setClients([...clients, { id: clients.length + 1, ...newClient }]);
- setNewClient({
- name: "",
- email: "",
- phone: "",
- gender: "",
- age: "",
- region_Address: "",
- road_Address: "",
- lat: null,
- lng: null,
- });
- setIsModalOpen(false);
+
+ console.log("π μΆκ°ν κ³ κ° μ 보 (μ μ‘ μ ):", newClient);
+
+ const userData = {
+ name: newClient.name,
+ email: newClient.email,
+ phoneNumber: newClient.phone.replace(/-/g, ""),
+ regionAddress: newClient.regionAddress || null,
+ roadAddress: newClient.roadAddress || null,
+ gender: newClient.gender,
+ age: parseInt(newClient.age, 10),
+ };
+
+ try {
+ const token = localStorage.getItem("token")?.trim();
+ if (!token) throw new Error("λ‘κ·ΈμΈμ΄ νμν©λλ€.");
+
+ const response = await fetch(`${API_BASE_URL}/api/users`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: token.startsWith("Bearer ")
+ ? token
+ : `Bearer ${token}`,
+ },
+ body: JSON.stringify(userData),
+ });
+
+ if (!response.ok) {
+ const errorText = await response.text();
+ console.error("π¨ μ¬μ©μ μΆκ° μ€λ₯ μλ΅:", errorText);
+
+ if (response.status === 409) {
+ alert("β μ΄λ―Έ μ‘΄μ¬νλ μ΄λ©μΌμ
λλ€.");
+ } else {
+ alert(`β μ¬μ©μ μΆκ° μ€ν¨ (HTTP ${response.status})`);
+ }
+
+ throw new Error(`β μ¬μ©μ μΆκ° μ€ν¨ (HTTP ${response.status})`);
+ }
+
+ console.log("β
μ¬μ©μ μΆκ° μ±κ³΅");
+ alert("κ³ κ°μ΄ μ±κ³΅μ μΌλ‘ μΆκ°λμμ΅λλ€.");
+ fetchClients();
+ } catch (error) {
+ console.error("π¨ μ¬μ©μ μΆκ° μ€ μ€λ₯ λ°μ:", error);
+ }
};
useEffect(() => {
if (selectedClient) {
- console.log("π μ νλ κ³ κ°:", selectedClient);
- console.log("π κ³ κ° μ’ν:", selectedClient.lat, selectedClient.lng);
console.log(
- `π lat νμ
: ${typeof selectedClient.lat}, lng νμ
: ${typeof selectedClient.lng}`
+ "π κ³ κ° μ’ν μ
λ°μ΄νΈλ¨:",
+ selectedClient.lat,
+ selectedClient.lng
+ );
+
+ console.log(
+ "π μ£Όμ μ 보:",
+ selectedClient.road_Address,
+ selectedClient.region_Address
);
- if (typeof selectedClient.lat !== "number") {
- console.warn("β οΈ lat λλ lngμ΄ μ«μκ° μλλλ€. λ³ν μλ...");
- selectedClient.lat = parseFloat(selectedClient.lat);
- selectedClient.lng = parseFloat(selectedClient.lng);
+ if (
+ !selectedClient.lat ||
+ !selectedClient.lng ||
+ isNaN(selectedClient.lat) ||
+ isNaN(selectedClient.lng)
+ ) {
+ console.warn("β οΈ κ³ κ° μ’ν μμ. κΈ°λ³Έκ°(μμΈ μμ²) μ μ©.");
+ setSelectedClient((prev) => ({
+ ...prev,
+ lat: 37.5665,
+ lng: 126.978,
+ }));
}
}
}, [selectedClient]);
@@ -142,8 +519,25 @@ const ClientManagement = () => {
}
};
+ const handleOpenAddModal = () => {
+ setNewClient({
+ name: "",
+ email: "",
+ phone: "",
+ gender: "",
+ age: "",
+ regionAddress: "",
+ roadAddress: "",
+ addressHistory: [],
+ });
+ setIsModalOpen(true);
+ };
+
const handleOpenEditModal = () => {
- setEditedClient({ ...selectedClient });
+ setEditedClient({
+ ...selectedClient,
+ gender: selectedClient.gender === "λ¨μ" ? "MALE" : "FEMALE",
+ });
setIsEditModalOpen(true);
};
@@ -156,18 +550,98 @@ const ClientManagement = () => {
setEditedClient((prev) => ({ ...prev, [name]: value }));
};
- const handleSaveEdit = () => {
- setClients((prevClients) =>
- prevClients.map((client) =>
- client.id === editedClient.id ? editedClient : client
- )
- );
- setSelectedClient(editedClient);
- setIsEditModalOpen(false);
- };
+ const handleSaveEdit = async () => {
+ try {
+ let token = localStorage.getItem("token")?.trim();
- const handleOpenHistoryModal = () => {
- setIsHistoryModalOpen(true);
+ if (!token) {
+ alert("λ‘κ·ΈμΈμ΄ νμν©λλ€.");
+ return;
+ }
+
+ if (!token.startsWith("Bearer ")) {
+ token = `Bearer ${token}`;
+ }
+
+ console.log("π μ΅μ’
JWT Token:", `"${token}"`);
+
+ let transformedGender = editedClient.gender;
+ if (transformedGender === "MALE") {
+ transformedGender = "λ¨μ";
+ } else if (transformedGender === "FEMALE") {
+ transformedGender = "μ¬μ";
+ }
+
+ const requestBody = {
+ name: editedClient.name,
+ email: editedClient.email,
+ phoneNumber: editedClient.phoneNumber,
+ regionAddress:
+ editedClient.regionAddress || selectedClient?.regionAddress,
+ roadAddress: editedClient.roadAddress || selectedClient?.roadAddress,
+ gender: transformedGender,
+ age: editedClient.age,
+ };
+
+ console.log(
+ "π€ κ³ κ° μμ μμ² λ°μ΄ν°:",
+ JSON.stringify(requestBody, null, 2)
+ );
+
+ const response = await fetch(
+ `${API_BASE_URL}/api/users/${editedClient.id}`,
+ {
+ method: "PATCH",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: token,
+ },
+ body: JSON.stringify(requestBody),
+ }
+ );
+
+ if (!response.ok) {
+ const errorText = await response.text();
+ console.error("π¨ μλ² μλ΅ μ€λ₯:", errorText);
+ alert(`β μλ² μλ΅ μ€λ₯: ${errorText}`);
+ throw new Error(`β κ³ κ° μ 보 μμ μ€ν¨ (status: ${response.status})`);
+ }
+
+ console.log("β
κ³ κ° μ 보 μμ μ±κ³΅!");
+
+ let updatedLat = selectedClient.lat;
+ let updatedLng = selectedClient.lng;
+
+ if (
+ editedClient.roadAddress !== selectedClient.roadAddress ||
+ editedClient.regionAddress !== selectedClient.regionAddress
+ ) {
+ console.log("π μ£Όμκ° λ³κ²½λ¨! Kakao APIλ‘ μ μ’ν μμ²");
+
+ const newCoords = await fetchCoordinates(
+ editedClient.roadAddress || editedClient.regionAddress
+ );
+ console.log("π μ μ’ν:", newCoords);
+
+ if (newCoords.lat && newCoords.lng) {
+ updatedLat = newCoords.lat;
+ updatedLng = newCoords.lng;
+ }
+ }
+
+ setSelectedClient((prev) => ({
+ ...prev,
+ ...editedClient,
+ lat: updatedLat,
+ lng: updatedLng,
+ regionAddress: editedClient.regionAddress || prev.regionAddress,
+ roadAddress: editedClient.roadAddress || prev.roadAddress,
+ }));
+
+ setIsEditModalOpen(false);
+ } catch (error) {
+ console.error("π¨ κ³ κ° μ 보 μμ μ€ μ€λ₯ λ°μ:", error);
+ }
};
const handleCloseHistoryModal = (e) => {
@@ -176,6 +650,38 @@ const ClientManagement = () => {
}
};
+ const fetchAddressHistory = async (userId) => {
+ try {
+ const token = localStorage.getItem("token")?.trim();
+ if (!token) throw new Error("λ‘κ·ΈμΈμ΄ νμν©λλ€.");
+
+ const response = await fetch(
+ `${API_BASE_URL}/api/users/${userId}/address-histories`,
+ {
+ method: "GET",
+ headers: { Authorization: token },
+ }
+ );
+
+ if (!response.ok) throw new Error("μ£Όμ λ³κ²½ λ΄μ λΆλ¬μ€κΈ° μ€ν¨");
+
+ const data = await response.json();
+ console.log("π μ£Όμ λ³κ²½ λ΄μ:", data);
+
+ setAddressHistory(data.responses || []);
+ } catch (error) {
+ console.error("π¨ μ£Όμ λ³κ²½ λ΄μ κ°μ Έμ€κΈ° μ€λ₯:", error);
+ setAddressHistory([]);
+ }
+ };
+
+ const handleOpenHistoryModal = () => {
+ if (selectedClient) {
+ fetchAddressHistory(selectedClient.id);
+ setIsHistoryModalOpen(true);
+ }
+ };
+
return (
κ³ κ° κ΄λ¦¬
@@ -190,11 +696,15 @@ const ClientManagement = () => {
setSearchTerm(e.target.value)}
+ onChange={handleSearchInputChange}
+ onKeyPress={handleSearchKeyPress}
/>
-
@@ -206,7 +716,7 @@ const ClientManagement = () => {
setSelectedClient(client)}
+ onClick={() => handleClientSelect(client)}
>
{client.name}
@@ -214,6 +724,26 @@ const ClientManagement = () => {