From 4b5d528706bc43e20043b5eb3e096f7b07292cf2 Mon Sep 17 00:00:00 2001 From: sangminee Date: Mon, 4 Mar 2024 20:04:03 +0900 Subject: [PATCH 01/10] =?UTF-8?q?[FEAT]=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EB=B3=B4=EC=97=AC=EC=A3=BC?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Chat/ChatList.jsx | 71 +++++++++++++++++++++++++ src/pages/administrator/adminChat.jsx | 12 +++-- src/pages/business/chat.jsx | 11 ++-- 3 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 src/components/common/Chat/ChatList.jsx diff --git a/src/components/common/Chat/ChatList.jsx b/src/components/common/Chat/ChatList.jsx new file mode 100644 index 0000000..815f305 --- /dev/null +++ b/src/components/common/Chat/ChatList.jsx @@ -0,0 +1,71 @@ +import React, {useEffect, useState} from 'react'; +import {Link, useNavigate} from 'react-router-dom'; +import './ChatApp.css'; +import ChatApi from "../../../api/chatApi"; + +/** + * 채팅 리스트 컴포넌트 + * + * @since 2024.03.02 + * @author 이상민 + */ +const ChatList = ({api, url, role}) => { + + const [data, setData] = useState([]); + const [limit, setLimit] = useState(10); + const [page, setPage] = useState(1); + + const navigate = useNavigate(); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await api.getChatRooms(page - 1, limit); + const mappedData = response.data.data.list.map((chatRoom, index) => { + const sequenceNumber = index + 1 + (page - 1) * limit; + return { + pkId: chatRoom.chatRoomId || "-", + sequenceNumber, + title: chatRoom.name ? chatRoom.name : "-", + createdDate: chatRoom.createdDate ? chatRoom.createdDate : "-", + modifiedDate: chatRoom.modifiedDate ? chatRoom.modifiedDate : "-", + }; + }); + setData( mappedData.map((chatRoom) => [...Object.values(chatRoom)])); + } catch (error) { + console.error("사용자 데이터를 가져오는 중 오류 발생:", error); + } + }; + fetchData(); + }, [page, limit]); + + const handleRowClick = (roomId) => { + navigate(`${url}/${roomId}`); + }; + + return ( +
+
+

대화

+ {data && data.map((chatRoom, index) => ( +
handleRowClick(chatRoom[0])}> +

{chatRoom[0]} {chatRoom[2]} {chatRoom[3]}{' '}

+
+
+ ))} +
+
+ +
+ +
+ ); +}; + +export default ChatList; diff --git a/src/pages/administrator/adminChat.jsx b/src/pages/administrator/adminChat.jsx index 405e121..5708a1e 100644 --- a/src/pages/administrator/adminChat.jsx +++ b/src/pages/administrator/adminChat.jsx @@ -1,6 +1,8 @@ import React from "react"; import AdminChatApi from "../../api/administrator/adminChatApi"; import ChatPage from "../../components/common/Chat/ChatPage"; +import ChatApi from "../../api/chatApi"; +import ChatList from "../../components/common/Chat/ChatList"; /** * 채팅 페이지 제작 @@ -10,10 +12,12 @@ import ChatPage from "../../components/common/Chat/ChatPage"; */ const AdminChat = () => { return ( - + + + // ); }; diff --git a/src/pages/business/chat.jsx b/src/pages/business/chat.jsx index e6b872f..591c26d 100644 --- a/src/pages/business/chat.jsx +++ b/src/pages/business/chat.jsx @@ -1,6 +1,6 @@ import React from "react"; import ChatApi from "../../api/chatApi"; -import ChatPage from "../../components/common/Chat/ChatPage"; +import ChatList from "../../components/common/Chat/ChatList"; /** * 채팅 페이지 제작 @@ -10,10 +10,11 @@ import ChatPage from "../../components/common/Chat/ChatPage"; */ const Chat = () => { return ( - + + // ); }; From 7b972e0bd25763967b546248b84ef3565a6004e4 Mon Sep 17 00:00:00 2001 From: sangminee Date: Mon, 4 Mar 2024 20:14:35 +0900 Subject: [PATCH 02/10] =?UTF-8?q?[FEAT]=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EB=94=94=ED=85=8C=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 85 ++++++++++++++++++ package.json | 4 + src/App.js | 20 +++-- src/components/common/Chat/ChatApp.css | 48 ++++++++++ src/components/common/Chat/ChatList.jsx | 7 +- src/components/common/Chat/ChatPage.jsx | 66 -------------- src/components/common/Chat/ChatRoomDetail.jsx | 27 ++++++ src/components/common/Chat/FormattedTime.jsx | 19 ++++ src/components/common/Chat/MeChatMessage.jsx | 11 +-- .../common/Chat/OtherChatMessage.jsx | 8 +- .../{ChatRoom.jsx => WebSocketConnect.jsx} | 13 +-- .../common/FloatingButton/FloatingButton.css | 36 ++++++++ .../common/FloatingButton/FloatingButton.jsx | 87 +++++++++++++++++++ src/components/common/Table/ChatTable.jsx | 42 --------- src/pages/administrator/adminChat.jsx | 7 -- src/pages/administrator/adminChatRoom.jsx | 16 ---- src/pages/business/businessChatRoom.jsx | 16 ---- src/pages/business/chat.jsx | 4 - 18 files changed, 339 insertions(+), 177 deletions(-) create mode 100644 src/components/common/Chat/ChatApp.css delete mode 100644 src/components/common/Chat/ChatPage.jsx create mode 100644 src/components/common/Chat/ChatRoomDetail.jsx create mode 100644 src/components/common/Chat/FormattedTime.jsx rename src/components/common/Chat/{ChatRoom.jsx => WebSocketConnect.jsx} (94%) create mode 100644 src/components/common/FloatingButton/FloatingButton.css create mode 100644 src/components/common/FloatingButton/FloatingButton.jsx delete mode 100644 src/components/common/Table/ChatTable.jsx delete mode 100644 src/pages/administrator/adminChatRoom.jsx delete mode 100644 src/pages/business/businessChatRoom.jsx diff --git a/package-lock.json b/package-lock.json index d368edf..3caa740 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "web-business", "version": "0.1.0", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/react-fontawesome": "^0.2.0", "@heroicons/react": "^2.1.1", "@material-tailwind/react": "^2.1.9", "@stomp/stompjs": "^7.0.0", @@ -26,6 +29,7 @@ "react-dom": "^17.0.2", "react-i18next": "^14.0.5", "react-icons": "^5.0.1", + "react-modal": "^3.16.1", "react-redux": "^7.2.9", "react-router-dom": "^6.22.1", "react-scripts": "5.0.1", @@ -2468,6 +2472,51 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz", + "integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz", + "integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz", + "integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz", + "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/@heroicons/react": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.1.1.tgz", @@ -8548,6 +8597,11 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/exenv": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", + "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" + }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -16804,6 +16858,29 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "node_modules/react-modal": { + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.16.1.tgz", + "integrity": "sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==", + "dependencies": { + "exenv": "^1.2.0", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.0", + "warning": "^4.0.3" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18", + "react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18" + } + }, "node_modules/react-redux": { "version": "7.2.9", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", @@ -19922,6 +19999,14 @@ "makeerror": "1.0.12" } }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", diff --git a/package.json b/package.json index 9a70c2f..590b0ad 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,9 @@ "version": "0.1.0", "private": true, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/react-fontawesome": "^0.2.0", "@heroicons/react": "^2.1.1", "@material-tailwind/react": "^2.1.9", "@stomp/stompjs": "^7.0.0", @@ -21,6 +24,7 @@ "react-dom": "^17.0.2", "react-i18next": "^14.0.5", "react-icons": "^5.0.1", + "react-modal": "^3.16.1", "react-redux": "^7.2.9", "react-router-dom": "^6.22.1", "react-scripts": "5.0.1", diff --git a/src/App.js b/src/App.js index bdfa21a..f9b3c5b 100644 --- a/src/App.js +++ b/src/App.js @@ -21,8 +21,8 @@ import BusinessPlanDetail from "./pages/business/plan"; import AdminPlainDetail from "./pages/administrator/adminPlanDetail"; import AdminChat from "./pages/administrator/adminChat"; import Chat from "./pages/business/chat"; -import BusinessChatRoom from "./pages/business/businessChatRoom"; -import AdminChatRoom from "./pages/administrator/adminChatRoom"; +import FloatingButton from "./components/common/FloatingButton/FloatingButton"; +import ChatRoomDetail from "./components/common/Chat/ChatRoomDetail"; /** * @since 2024.02.25 @@ -30,8 +30,13 @@ import AdminChatRoom from "./pages/administrator/adminChatRoom"; */ function App() { + const handleButtonClick = () => { + // 버튼 클릭 시 실행할 동작을 추가하세요 + console.log('Floating button clicked!'); + }; + const businessColor = "bg-main-color-600 border-r border-gray-200 sm:translate-x-0 dark:bg-gray-800 dark:border-gray-700"; - const businessSideBarColor = "bg-main-color-600 dark:bg-blue-600"; + const businessSideBarColor = "bg-main-color-600 text-white dark:bg-blue-600"; const adminColor = "bg-main-blue-600 border-r border-gray-200 sm:translate-x-0 dark:bg-gray-800 dark:border-gray-700"; const adminSideBarColor = "bg-main-blue-600 dark:bg-blue-600"; @@ -62,7 +67,7 @@ function App() { {generateRoute(businessColor, businessSideBarColor, businessSideBarList, businessHomeUrl, "/plan/create", CreatePlan)} {generateRoute(businessColor, businessSideBarColor, businessSideBarList, businessHomeUrl, "/ad/create", Ad)} {generateRoute(businessColor, businessSideBarColor, businessSideBarList, businessHomeUrl, "/chat", Chat)} - {generateRoute(businessColor, businessSideBarColor, businessSideBarList, businessHomeUrl, "/chat/:roomId", BusinessChatRoom)} + {generateRoute(businessColor, businessSideBarColor, businessSideBarList, businessHomeUrl, "/chat/:roomId", ChatRoomDetail)} {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/users', User)} {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/business', Business)} @@ -70,23 +75,22 @@ function App() { {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/plan/:planId', AdminPlainDetail)} {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/community', Community)} {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/chat', AdminChat)} - {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/chat/:roomId', AdminChatRoom)} + {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/chat/:roomId', ChatRoomDetail)} + + ); } const generateRoute = (color, sideBarColor, sideBarList, homeUrl, path, Component) => ( - } homeUrl={homeUrl} /> - ]} /> ); diff --git a/src/components/common/Chat/ChatApp.css b/src/components/common/Chat/ChatApp.css new file mode 100644 index 0000000..1fd4166 --- /dev/null +++ b/src/components/common/Chat/ChatApp.css @@ -0,0 +1,48 @@ + +.rounded-rectangle { + position: relative; + width: 350px; + height: 600px; + border-radius: 20px; + overflow: hidden; + background-color: #ffffff; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); +} + +.content { + padding: 20px; + overflow-y: auto; +} + +.bottom-nav { + position: absolute; + bottom: 0; + width: 100%; + background-color: #f0f0f0; + padding: 10px; +} + +.bottom-nav ul { + list-style: none; + padding: 0; + margin: 0; + display: flex; + justify-content: space-around; +} + +.close-button { + position: absolute; + top: 10px; + right: 10px; + padding: 8px 12px; + background-color: #3498db; + color: #ffffff; + border: none; + cursor: pointer; + font-size: 10px; +} + +.chat-room:hover { + background-color: #f0f0f0; /* 호버 시 바뀔 배경색을 지정하세요 */ + cursor: pointer; +} diff --git a/src/components/common/Chat/ChatList.jsx b/src/components/common/Chat/ChatList.jsx index 815f305..c014590 100644 --- a/src/components/common/Chat/ChatList.jsx +++ b/src/components/common/Chat/ChatList.jsx @@ -1,7 +1,6 @@ import React, {useEffect, useState} from 'react'; -import {Link, useNavigate} from 'react-router-dom'; +import {useNavigate} from 'react-router-dom'; import './ChatApp.css'; -import ChatApi from "../../../api/chatApi"; /** * 채팅 리스트 컴포넌트 @@ -39,7 +38,7 @@ const ChatList = ({api, url, role}) => { fetchData(); }, [page, limit]); - const handleRowClick = (roomId) => { + const handleRowClick = (roomId, role) => { navigate(`${url}/${roomId}`); }; @@ -48,7 +47,7 @@ const ChatList = ({api, url, role}) => {

대화

{data && data.map((chatRoom, index) => ( -
handleRowClick(chatRoom[0])}> +
handleRowClick(chatRoom[0], role)}>

{chatRoom[0]} {chatRoom[2]} {chatRoom[3]}{' '}


diff --git a/src/components/common/Chat/ChatPage.jsx b/src/components/common/Chat/ChatPage.jsx deleted file mode 100644 index 3c6b62e..0000000 --- a/src/components/common/Chat/ChatPage.jsx +++ /dev/null @@ -1,66 +0,0 @@ -import React, { useEffect, useState } from "react"; -import ContentBox from "../../common/ContentBox/ContentBox"; -import Pagination from "../../common/Pagination/Pagination"; -import Table from "../Table/Table"; -import ChatTable from "../Table/ChatTable"; - -const ChatPage = ({ api, title }) => { - const [data, setData] = useState(null); - const [limit, setLimit] = useState(10); - const [page, setPage] = useState(1); - const [size, setSize] = useState(null); - - const headerTitles = ["순번", "제목", "생성일", "수정일"]; - - useEffect(() => { - const fetchData = async () => { - try { - const response = await api.getChatRooms(page - 1, limit); - const mappedData = response.data.data.list.map((chatRoom, index) => { - const sequenceNumber = index + 1 + (page - 1) * limit; - return { - pkId: chatRoom.chatRoomId || "-", - sequenceNumber, - title: chatRoom.name ? chatRoom.name : "-", - createdDate: chatRoom.createdDate ? chatRoom.createdDate : "-", - modifiedDate: chatRoom.modifiedDate ? chatRoom.modifiedDate : "-", - }; - }); - setData({ - headerTitles, - sampleData: mappedData.map((chatRoom) => [...Object.values(chatRoom)]), - }); - setSize(response.data.data.sum); - } catch (error) { - console.error("사용자 데이터를 가져오는 중 오류 발생:", error); - } - }; - fetchData(); - }, [page, limit, api]); - - return ( -
- - {data && data.headerTitles && data.sampleData ? ( - <> - -
-
- -
- - ) : ( -

Loading...

- )} - - } - > -
-
- ); -}; - -export default ChatPage; diff --git a/src/components/common/Chat/ChatRoomDetail.jsx b/src/components/common/Chat/ChatRoomDetail.jsx new file mode 100644 index 0000000..f889fe3 --- /dev/null +++ b/src/components/common/Chat/ChatRoomDetail.jsx @@ -0,0 +1,27 @@ +import {useParams} from "react-router-dom"; +import WebSocketConnect from "./WebSocketConnect"; + +const ChatRoomDetail = ({role}) => { + + const { chatRoomId } = useParams(); + const longChatRoomId = parseInt(chatRoomId, 10); + + const handleGoBack = () => { + window.history.back(); // Use the window.history object to go back + }; + + return ( +
+
+ + +
+
+ ); +}; + +export default ChatRoomDetail; diff --git a/src/components/common/Chat/FormattedTime.jsx b/src/components/common/Chat/FormattedTime.jsx new file mode 100644 index 0000000..1e9bf1c --- /dev/null +++ b/src/components/common/Chat/FormattedTime.jsx @@ -0,0 +1,19 @@ +import React from 'react'; + +/** + * 시간 + * + * @since 2024.03.04 + * @author 이상민 + */ +const FormattedTime = ({ time }) => { + const dateObject = new Date(time); + const formattedTime = `${(dateObject.getMonth() + 1).toString().padStart(2, '0')}.${dateObject.getDate().toString().padStart(2, '0')} ${dateObject.getHours().toString().padStart(2, '0')}:${dateObject.getMinutes().toString().padStart(2, '0')}`; + + return ( + {formattedTime} + ); +}; + +export default FormattedTime; + diff --git a/src/components/common/Chat/MeChatMessage.jsx b/src/components/common/Chat/MeChatMessage.jsx index 0172786..2958c12 100644 --- a/src/components/common/Chat/MeChatMessage.jsx +++ b/src/components/common/Chat/MeChatMessage.jsx @@ -1,4 +1,5 @@ import React from "react"; +import FormattedTime from "./FormattedTime"; /** * 나의 채팅 메시지 컴포넌트 @@ -7,16 +8,16 @@ import React from "react"; * @author 이상민 */ const MeChatMessage = ({ nickname, time, text }) => { + return (
+ className="flex flex-col w-full max-w-[240px] + leading-1.5 p-4 border-gray-200 rounded-tl-xl rounded-bl-xl rounded-br-xl bg-gray-700" + style={{ height: 'auto' }} >
{nickname} - {time} +

{text}

diff --git a/src/components/common/Chat/OtherChatMessage.jsx b/src/components/common/Chat/OtherChatMessage.jsx index b56b8b2..33dc0e2 100644 --- a/src/components/common/Chat/OtherChatMessage.jsx +++ b/src/components/common/Chat/OtherChatMessage.jsx @@ -1,4 +1,5 @@ import React from "react"; +import FormattedTime from "./FormattedTime"; /** * 나 이외의 채팅 메시지 컴포넌트 @@ -10,13 +11,14 @@ const OtherChatMessage = ({ nickname, time, text }) => { return (
+ className="flex flex-col w-full max-w-[240px] + leading-1.5 p-4 border-gray-200 bg-gray-100 rounded-e-xl rounded-es-xl" + style={{ height: 'auto' }} >
{nickname} - {time} +

{text}

- Delivered
); diff --git a/src/components/common/Chat/ChatRoom.jsx b/src/components/common/Chat/WebSocketConnect.jsx similarity index 94% rename from src/components/common/Chat/ChatRoom.jsx rename to src/components/common/Chat/WebSocketConnect.jsx index bc2c364..ff802d1 100644 --- a/src/components/common/Chat/ChatRoom.jsx +++ b/src/components/common/Chat/WebSocketConnect.jsx @@ -13,7 +13,7 @@ import OtherChatMessage from "./OtherChatMessage"; * @since 2024.03.03 * @author 이상민 */ -const ChatRoom = ({role}) => { +const WebSocketConnect = ({role}) => { const [stompClient, setStompClient] = useState(null); const [messages, setMessages] = useState([]); const [newMessage, setNewMessage] = useState(""); @@ -134,19 +134,20 @@ const ChatRoom = ({role}) => { }; return ( -
+

{chatRoomDetail.name}

Messages:

    {messages.map((message, index) => (
  • {message.checkedMe === true ? ( - + ) : ( {
-
+
{ ); }; -export default ChatRoom; +export default WebSocketConnect; diff --git a/src/components/common/FloatingButton/FloatingButton.css b/src/components/common/FloatingButton/FloatingButton.css new file mode 100644 index 0000000..e15fd7b --- /dev/null +++ b/src/components/common/FloatingButton/FloatingButton.css @@ -0,0 +1,36 @@ +.floating-button { + position: fixed; + bottom: 20px; + right: 20px; + width: 50px; + height: 50px; + border-radius: 50%; + background-color: #007bff; + color: #fff; + font-size: 24px; + border: none; + cursor: pointer; + outline: none; + /* 그림자 효과를 추가하거나 필요에 따라 스타일을 수정하세요 */ + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); + transition: background-color 0.3s ease; +} + +.floating-button:hover { + background-color: #0056b3; +} + +.floating-button-modal { + position: fixed; + top: 50%; + left: auto; + right: 0; + transform: translate(-50%, -50%); + overflow: auto; + outline: none; + background: white; + padding: 20px; + border-radius: 10px; + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); + /* 추가적인 스타일 설정 */ +} diff --git a/src/components/common/FloatingButton/FloatingButton.jsx b/src/components/common/FloatingButton/FloatingButton.jsx new file mode 100644 index 0000000..38b22ea --- /dev/null +++ b/src/components/common/FloatingButton/FloatingButton.jsx @@ -0,0 +1,87 @@ +import React, {useState} from 'react'; +import './FloatingButton.css'; // 스타일 파일을 추가합니다. +import Modal from 'react-modal'; +import ChatList from "../Chat/ChatList"; + +const FloatingButton = () => { + const [modalIsOpen, setModalIsOpen] = useState(false); + const [buttonPosition, setButtonPosition] = useState({ top: 0, left: 0 }); + + const openModal = () => { + const button = document.querySelector('.floating-button'); + if (button) { + const rect = button.getBoundingClientRect(); + setButtonPosition({ top: rect.bottom + window.scrollY, left: rect.left + window.scrollX }); + console.log('Button Position:', buttonPosition); + } + + setModalIsOpen(true); + }; + + /** + * 모달 닫을 때 사용 + * + * @since 2024.03.04 + * @author 이상민 + */ + const closeModal = () => { + setModalIsOpen(false); + }; + + return ( + <> + {/**/} + +
+ +
+ + + +
+ +
+
+ + ); +}; + +export default FloatingButton; diff --git a/src/components/common/Table/ChatTable.jsx b/src/components/common/Table/ChatTable.jsx deleted file mode 100644 index 99ded25..0000000 --- a/src/components/common/Table/ChatTable.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from "react"; -import TableHeader from "./TableHeader"; -import TableRow from "./TableRow"; - -/** - * Table 컴포넌트 생성 - * - * @since 2024.02.25 - * @author 이상민 - */ -const ChatTable = ({ headerTitles, sampleData }) => { - - const handleRowClick = (id) => { - const currentUrl = window.location.pathname; - const newUrl = `${currentUrl}/${id}`; - // 팝업으로 새로운 페이지 열기 - window.open(newUrl, '_blank', 'width=400,height=700,toolbar=no,scrollbars=yes,resizable=yes'); - - // const currentUrl = window.location.pathname; - // window.location.href = `${currentUrl}/${id}`; - }; - - const renderTableBody = (sampleData) => ( - - {sampleData.map((rowData, index) => ( - handleRowClick(rowData[0])} /> - ))} - - ); - - return ( -
- - - {renderTableBody(sampleData)} -
-
- ); - }; - - export default ChatTable; - diff --git a/src/pages/administrator/adminChat.jsx b/src/pages/administrator/adminChat.jsx index 5708a1e..cea885a 100644 --- a/src/pages/administrator/adminChat.jsx +++ b/src/pages/administrator/adminChat.jsx @@ -1,7 +1,5 @@ import React from "react"; import AdminChatApi from "../../api/administrator/adminChatApi"; -import ChatPage from "../../components/common/Chat/ChatPage"; -import ChatApi from "../../api/chatApi"; import ChatList from "../../components/common/Chat/ChatList"; /** @@ -13,11 +11,6 @@ import ChatList from "../../components/common/Chat/ChatList"; const AdminChat = () => { return ( - - // ); }; diff --git a/src/pages/administrator/adminChatRoom.jsx b/src/pages/administrator/adminChatRoom.jsx deleted file mode 100644 index f1c7b87..0000000 --- a/src/pages/administrator/adminChatRoom.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; -import ChatRoom from "../../components/common/Chat/ChatRoom"; - -/** - * 관리자 채팅방 - * - * @since 2024.03.03 - * @author 이상민 - */ -const AdminChatRoom = () => { - return ( - - ); -}; - -export default AdminChatRoom; diff --git a/src/pages/business/businessChatRoom.jsx b/src/pages/business/businessChatRoom.jsx deleted file mode 100644 index 75bf8a7..0000000 --- a/src/pages/business/businessChatRoom.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; -import ChatRoom from "../../components/common/Chat/ChatRoom"; - -/** - * 사업체 채팅방 - * - * @since 2024.03.03 - * @author 이상민 - */ -const BusinessChatRoom = () => { - return ( - - ); -}; - -export default BusinessChatRoom; diff --git a/src/pages/business/chat.jsx b/src/pages/business/chat.jsx index 591c26d..23f9cce 100644 --- a/src/pages/business/chat.jsx +++ b/src/pages/business/chat.jsx @@ -11,10 +11,6 @@ import ChatList from "../../components/common/Chat/ChatList"; const Chat = () => { return ( - // ); }; From 10ac6ca30f1657076c8702c72a4fba8093bf3945 Mon Sep 17 00:00:00 2001 From: sangminee Date: Mon, 4 Mar 2024 20:45:30 +0900 Subject: [PATCH 03/10] =?UTF-8?q?[FEAT]=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=A0=9C=EB=AA=A9=20CSS=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Chat/ChatApp.css | 16 +++++++++++++ src/components/common/Chat/ChatList.jsx | 2 +- src/components/common/Chat/ChatRoomDetail.jsx | 20 +++++----------- .../common/Chat/WebSocketConnect.jsx | 24 +++++++++++++++---- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/components/common/Chat/ChatApp.css b/src/components/common/Chat/ChatApp.css index 1fd4166..3920dbc 100644 --- a/src/components/common/Chat/ChatApp.css +++ b/src/components/common/Chat/ChatApp.css @@ -46,3 +46,19 @@ background-color: #f0f0f0; /* 호버 시 바뀔 배경색을 지정하세요 */ cursor: pointer; } + +/* 스크롤바의 너비를 조절합니다. */ +#messagesContainer::-webkit-scrollbar { + width: 8px; /* 웹킷 브라우저에서 스크롤바의 너비를 설정합니다. */ +} + +/* 스크롤바의 색상을 설정합니다. */ +#messagesContainer::-webkit-scrollbar-thumb { + background-color: #3498db; /* 스크롤바 색상 설정 */ + border-radius: 4px; /* 스크롤바의 둥근 모서리를 설정합니다. */ +} + +/* 스크롤바 트랙의 색상을 설정합니다. */ +#messagesContainer::-webkit-scrollbar-track { + background-color: #f1f1f1; /* 스크롤바 트랙 색상 설정 */ +} diff --git a/src/components/common/Chat/ChatList.jsx b/src/components/common/Chat/ChatList.jsx index c014590..f6fdebd 100644 --- a/src/components/common/Chat/ChatList.jsx +++ b/src/components/common/Chat/ChatList.jsx @@ -45,7 +45,7 @@ const ChatList = ({api, url, role}) => { return (
-

대화

+

대화

{data && data.map((chatRoom, index) => (
handleRowClick(chatRoom[0], role)}>

{chatRoom[0]} {chatRoom[2]} {chatRoom[3]}{' '}

diff --git a/src/components/common/Chat/ChatRoomDetail.jsx b/src/components/common/Chat/ChatRoomDetail.jsx index f889fe3..1c90f34 100644 --- a/src/components/common/Chat/ChatRoomDetail.jsx +++ b/src/components/common/Chat/ChatRoomDetail.jsx @@ -1,23 +1,15 @@ -import {useParams} from "react-router-dom"; import WebSocketConnect from "./WebSocketConnect"; +/** + * 채팅방 컴포넌트 + * + * @since 2024.03.02 + * @author 이상민 + */ const ChatRoomDetail = ({role}) => { - - const { chatRoomId } = useParams(); - const longChatRoomId = parseInt(chatRoomId, 10); - - const handleGoBack = () => { - window.history.back(); // Use the window.history object to go back - }; - return (
-
diff --git a/src/components/common/Chat/WebSocketConnect.jsx b/src/components/common/Chat/WebSocketConnect.jsx index ff802d1..77ff3d9 100644 --- a/src/components/common/Chat/WebSocketConnect.jsx +++ b/src/components/common/Chat/WebSocketConnect.jsx @@ -133,15 +133,31 @@ const WebSocketConnect = ({role}) => { } }; + const handleGoBack = () => { + window.history.back(); // Use the window.history object to go back + }; + return (
-

{chatRoomDetail.name}

+
+ +

+ {chatRoomDetail.name} +

+
+
-

Messages:

    {messages.map((message, index) => (
  • @@ -164,7 +180,7 @@ const WebSocketConnect = ({role}) => {
    setNewMessage(e.target.value)} className="flex-grow border p-2 rounded" From f01ac6b662d1746d80136cc8751aa651cdf02fda Mon Sep 17 00:00:00 2001 From: sangminee Date: Tue, 5 Mar 2024 18:33:41 +0900 Subject: [PATCH 04/10] =?UTF-8?q?[FEAT]=20css=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 16 +- src/api/administrator/adminChatApi.js | 23 +- src/api/chatApi.js | 12 +- src/components/administrator/ChatPage.jsx | 65 ++++++ src/components/administrator/ChatTable.jsx | 73 ++++++ .../{common => business}/Chat/ChatList.jsx | 20 +- .../Chat/ChatRoom.jsx} | 101 +++++--- src/components/common/Chat/ChatApp.css | 6 +- src/components/common/Chat/ChatRoomDetail.jsx | 215 +++++++++++++++++- .../common/FloatingButton/FloatingButton.css | 5 +- .../common/FloatingButton/FloatingButton.jsx | 61 ++--- src/pages/administrator/adminChat.jsx | 7 +- src/pages/business/chat.jsx | 17 -- src/pages/business/dashboard.jsx | 5 + 14 files changed, 481 insertions(+), 145 deletions(-) create mode 100644 src/components/administrator/ChatPage.jsx create mode 100644 src/components/administrator/ChatTable.jsx rename src/components/{common => business}/Chat/ChatList.jsx (84%) rename src/components/{common/Chat/WebSocketConnect.jsx => business/Chat/ChatRoom.jsx} (69%) delete mode 100644 src/pages/business/chat.jsx diff --git a/src/App.js b/src/App.js index f9b3c5b..485e353 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,4 @@ -import {BrowserRouter, Navigate, Route, Routes} from "react-router-dom"; +import {BrowserRouter, Route, Routes} from "react-router-dom"; import React from "react"; @@ -20,9 +20,6 @@ import Plans from "./pages/business/plans"; import BusinessPlanDetail from "./pages/business/plan"; import AdminPlainDetail from "./pages/administrator/adminPlanDetail"; import AdminChat from "./pages/administrator/adminChat"; -import Chat from "./pages/business/chat"; -import FloatingButton from "./components/common/FloatingButton/FloatingButton"; -import ChatRoomDetail from "./components/common/Chat/ChatRoomDetail"; /** * @since 2024.02.25 @@ -30,11 +27,6 @@ import ChatRoomDetail from "./components/common/Chat/ChatRoomDetail"; */ function App() { - const handleButtonClick = () => { - // 버튼 클릭 시 실행할 동작을 추가하세요 - console.log('Floating button clicked!'); - }; - const businessColor = "bg-main-color-600 border-r border-gray-200 sm:translate-x-0 dark:bg-gray-800 dark:border-gray-700"; const businessSideBarColor = "bg-main-color-600 text-white dark:bg-blue-600"; @@ -42,7 +34,7 @@ function App() { const adminSideBarColor = "bg-main-blue-600 dark:bg-blue-600"; const businessSideBarList = [ - ['대시보드', '/dashboard'], ['나의 사업계획서 목록', '/plans'], ['팝업 스토어 제안', '/plan/create'], ['광고 신청', '/ad/create'], ['1:1 채팅상담', '/chat'] + ['대시보드', '/dashboard'], ['나의 사업계획서 목록', '/plans'], ['팝업 스토어 제안', '/plan/create'], ['광고 신청', '/ad/create'] ]; const adminSideBarList = [ ['사용자 관리', [['일반 사용자 관리', '/admin/users'], ['사업체 관리', '/admin/business']]], @@ -66,8 +58,6 @@ function App() { {generateRoute(businessColor, businessSideBarColor, businessSideBarList, businessHomeUrl, "/plans/:planId", BusinessPlanDetail)} {generateRoute(businessColor, businessSideBarColor, businessSideBarList, businessHomeUrl, "/plan/create", CreatePlan)} {generateRoute(businessColor, businessSideBarColor, businessSideBarList, businessHomeUrl, "/ad/create", Ad)} - {generateRoute(businessColor, businessSideBarColor, businessSideBarList, businessHomeUrl, "/chat", Chat)} - {generateRoute(businessColor, businessSideBarColor, businessSideBarList, businessHomeUrl, "/chat/:roomId", ChatRoomDetail)} {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/users', User)} {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/business', Business)} @@ -75,10 +65,8 @@ function App() { {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/plan/:planId', AdminPlainDetail)} {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/community', Community)} {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/chat', AdminChat)} - {generateRoute(adminColor, adminSideBarColor, adminSideBarList, adminHomeUrl, '/admin/chat/:roomId', ChatRoomDetail)} - ); diff --git a/src/api/administrator/adminChatApi.js b/src/api/administrator/adminChatApi.js index b87de87..72ce1fc 100644 --- a/src/api/administrator/adminChatApi.js +++ b/src/api/administrator/adminChatApi.js @@ -1,14 +1,7 @@ -import axios from "axios"; - -import GetTokenFromLocalStorage from "../Common/token"; - -const Token = GetTokenFromLocalStorage('admin') -if (Token) { - axios.defaults.headers.common['Authorization'] = `Bearer ${Token}` -} +import adminInstance from "../adminBaseApi"; /** - * @since 2024.03.52 + * @since 2024.03.02 * @author 이상민 */ const ChatApi = { @@ -19,7 +12,17 @@ const ChatApi = { * @author 이상민 */ getChatRooms: async (pageNo = 0, amount = 10) => { - return await axios.get(`/api/v1/chat/rooms/admin?pageNo=${pageNo}&amount=${amount}`); + return await adminInstance.get(`/chat/rooms/admin?pageNo=${pageNo}&amount=${amount}`); + }, + + /** + * 나의 채팅방 메시지 리스트 조회 + * + * @since 2024.03.02 + * @author 이상민 + */ + getMessages: async (roomId = 0) => { + return await adminInstance.get(`/chat/rooms/${roomId}`); }, } diff --git a/src/api/chatApi.js b/src/api/chatApi.js index 10c7e63..5e40dee 100644 --- a/src/api/chatApi.js +++ b/src/api/chatApi.js @@ -1,10 +1,4 @@ -import GetTokenFromLocalStorage from "./Common/token"; -import axios from "axios"; - -const Token = GetTokenFromLocalStorage('user') -if (Token) { - axios.defaults.headers.common['Authorization'] = `Bearer ${Token}` -} +import userBaseApi from "./userBaseApi"; /** * @since 2024.03.52 @@ -18,7 +12,7 @@ const ChatApi = { * @author 이상민 */ getChatRooms: async (pageNo = 0, amount = 10) => { - return await axios.get(`/api/v1/chat/rooms?pageNo=${pageNo}&amount=${amount}`); + return await userBaseApi.get(`/chat/rooms?pageNo=${pageNo}&amount=${amount}`); }, /** @@ -28,7 +22,7 @@ const ChatApi = { * @author 이상민 */ getMessages: async (roomId = 0) => { - return await axios.get(`/api/v1/chat/rooms/${roomId}`); + return await userBaseApi.get(`/chat/rooms/${roomId}`); }, } diff --git a/src/components/administrator/ChatPage.jsx b/src/components/administrator/ChatPage.jsx new file mode 100644 index 0000000..99e85cc --- /dev/null +++ b/src/components/administrator/ChatPage.jsx @@ -0,0 +1,65 @@ +import React, { useEffect, useState } from "react"; +import ContentBox from "../../components/common/ContentBox/ContentBox"; +import Pagination from "../../components/common/Pagination/Pagination"; +import ChatTable from "./ChatTable"; + +const ChatPage = ({ api, title }) => { + const [data, setData] = useState(null); + const [limit, setLimit] = useState(10); + const [page, setPage] = useState(1); + const [size, setSize] = useState(null); + + const headerTitles = ["순번", "제목", "생성일", "수정일"]; + + useEffect(() => { + const fetchData = async () => { + try { + const response = await api.getChatRooms(page - 1, limit); + const mappedData = response.data.data.list.map((chatRoom, index) => { + const sequenceNumber = index + 1 + (page - 1) * limit; + return { + pkId: chatRoom.chatRoomId || "-", + sequenceNumber, + title: chatRoom.name ? chatRoom.name : "-", + createdDate: chatRoom.createdDate ? chatRoom.createdDate : "-", + modifiedDate: chatRoom.modifiedDate ? chatRoom.modifiedDate : "-", + }; + }); + setData({ + headerTitles, + sampleData: mappedData.map((chatRoom) => [...Object.values(chatRoom)]), + }); + setSize(response.data.data.sum); + } catch (error) { + console.error("사용자 데이터를 가져오는 중 오류 발생:", error); + } + }; + fetchData(); + }, [page, limit, api]); + + return ( +
    + + {data && data.headerTitles && data.sampleData ? ( + <> + +
    +
    + +
    + + ) : ( +

    Loading...

    + )} + + } + > +
    +
    + ); +}; + +export default ChatPage; \ No newline at end of file diff --git a/src/components/administrator/ChatTable.jsx b/src/components/administrator/ChatTable.jsx new file mode 100644 index 0000000..632147d --- /dev/null +++ b/src/components/administrator/ChatTable.jsx @@ -0,0 +1,73 @@ +import React, {useState} from "react"; +import TableHeader from "../common/Table/TableHeader"; +import TableRow from "../common/Table/TableRow"; +import {useNavigate} from "react-router-dom"; +import ChatRoomDetail from "../common/Chat/ChatRoomDetail"; +import Modal from "react-modal"; + +/** + * Table 컴포넌트 생성 + * + * @since 2024.02.25 + * @author 이상민 + */ +const ChatTable = ({ headerTitles, sampleData }) => { + + const navigate = useNavigate(); + const [modalIsOpen, setModalIsOpen] = useState(false); + const [selectedChatRoomId, setSelectedChatRoomId] = useState(null); + + const handleRowClick = (id) => { + console.log("테이블 : " + id) + + setSelectedChatRoomId(id); + setModalIsOpen(true); + + // const role = 'admin'; + // const currentUrl = window.location.pathname; + // navigate(`${currentUrl}/${id}`, { state: { role } }); + }; + + const renderTableBody = (sampleData) => ( + + {sampleData.map((rowData, index) => ( + handleRowClick(rowData[0])} /> + ))} + + ); + + return ( +
    + + + {renderTableBody(sampleData)} +
    + + setModalIsOpen(false)} + contentLabel="ChatRoomDetail Modal" + style={{ + overlay: { + backgroundColor: 'rgba(0, 0, 0, 0.5)', + }, + content: { + top: '50%', + left: '50%', + right: 'auto', + bottom: 'auto', + marginRight: '-50%', + transform: 'translate(-50%, -50%)', + maxWidth: '80%', // 필요에 따라 최대 너비 조정 + }, + }} + > + {selectedChatRoomId && ( + + )} + +
    + ); +}; + +export default ChatTable; diff --git a/src/components/common/Chat/ChatList.jsx b/src/components/business/Chat/ChatList.jsx similarity index 84% rename from src/components/common/Chat/ChatList.jsx rename to src/components/business/Chat/ChatList.jsx index f6fdebd..8eaf5ef 100644 --- a/src/components/common/Chat/ChatList.jsx +++ b/src/components/business/Chat/ChatList.jsx @@ -1,6 +1,6 @@ import React, {useEffect, useState} from 'react'; import {useNavigate} from 'react-router-dom'; -import './ChatApp.css'; +import '../../common/Chat/ChatApp.css'; /** * 채팅 리스트 컴포넌트 @@ -8,13 +8,15 @@ import './ChatApp.css'; * @since 2024.03.02 * @author 이상민 */ -const ChatList = ({api, url, role}) => { +const ChatList = ({api, onChatRoomClick, closeModal}) => { const [data, setData] = useState([]); const [limit, setLimit] = useState(10); const [page, setPage] = useState(1); - const navigate = useNavigate(); + const handleChatRoomClick = (chatRoom) => { + onChatRoomClick(chatRoom[0]); + }; useEffect(() => { const fetchData = async () => { @@ -38,16 +40,12 @@ const ChatList = ({api, url, role}) => { fetchData(); }, [page, limit]); - const handleRowClick = (roomId, role) => { - navigate(`${url}/${roomId}`); - }; - return (
    -

    대화

    +

    대화

    {data && data.map((chatRoom, index) => ( -
    handleRowClick(chatRoom[0], role)}> +
    handleChatRoomClick(chatRoom)}>

    {chatRoom[0]} {chatRoom[2]} {chatRoom[3]}{' '}


    @@ -62,7 +60,9 @@ const ChatList = ({api, url, role}) => {
- +
); }; diff --git a/src/components/common/Chat/WebSocketConnect.jsx b/src/components/business/Chat/ChatRoom.jsx similarity index 69% rename from src/components/common/Chat/WebSocketConnect.jsx rename to src/components/business/Chat/ChatRoom.jsx index 77ff3d9..dfdebb4 100644 --- a/src/components/common/Chat/WebSocketConnect.jsx +++ b/src/components/business/Chat/ChatRoom.jsx @@ -1,26 +1,32 @@ +import ChatApi from "../../../api/chatApi"; import React, {useEffect, useRef, useState} from "react"; -import SockJS from "sockjs-client"; -import { Stomp } from "@stomp/stompjs"; -import { useParams } from "react-router-dom"; import GetTokenFromLocalStorage from "../../../api/Common/token"; -import ChatApi from "../../../api/chatApi"; -import MeChatMessage from "./MeChatMessage"; -import OtherChatMessage from "./OtherChatMessage"; +import SockJS from "sockjs-client"; +import {Stomp} from "@stomp/stompjs"; +import MeChatMessage from "../../common/Chat/MeChatMessage"; +import OtherChatMessage from "../../common/Chat/OtherChatMessage"; +import '../../common/Chat/ChatApp.css'; /** - * 채팅방 + * 채팅방 컴포넌트 * - * @since 2024.03.03 + * @since 2024.03.02 * @author 이상민 */ -const WebSocketConnect = ({role}) => { +const ChatRoom= ({selectedChatRoom, setSelectedChatRoom}) => { + + console.log("선택된 채팅방:", selectedChatRoom); + const [stompClient, setStompClient] = useState(null); const [messages, setMessages] = useState([]); const [newMessage, setNewMessage] = useState(""); - const { roomId } = useParams(); + const roomId = selectedChatRoom; + + + const role = 'user' const messagesContainerRef = useRef(null); - const token = GetTokenFromLocalStorage(role) + const token = GetTokenFromLocalStorage('role') const [chatRoomDetail, setChatRoomDetail] = useState([]); @@ -31,21 +37,28 @@ const WebSocketConnect = ({role}) => { * @author 이상민 */ useEffect(() => { - const socket = new SockJS(`http://15.164.236.13:8080/ws`); + const socket = new SockJS(`http://localhost:8080/ws`); const stomp = Stomp.over(socket); setStompClient(stomp); // 고유한 ID 생성 const uniqueId = `sub-${Math.random().toString(36).substr(2, 9)}`; stomp.connect({ Authorization: `Bearer ${token}` }, (frame) => { console.log("연결 성공!", frame); + console.log("1 : " + role) + // 2. 특정 채팅방에 구독 stomp.subscribe(`/topic/messages`, (message) => { const newMessage = JSON.parse(message.body); - newMessage.checkedMe = true; + if(newMessage.role === role){ + newMessage.checkedMe = true; + }else{ + newMessage.checkedMe = false; + } // 기존 메시지와 새 메시지를 합쳐서 상태 업데이트 - setMessages((prevMessages) => [...prevMessages, newMessage]); + // setMessages((prevMessages) => [...prevMessages, newMessage]); + // 새 메시지가 현재 채팅방에 대한 것인지 확인 if (roomId === newMessage.roomId) { showMessage(newMessage); @@ -68,6 +81,8 @@ const WebSocketConnect = ({role}) => { const loadPreviousMessages = async () => { try { const response = await ChatApi.getMessages(roomId); + console.log(response) + const data = response.data; setMessages(data?.data?.chatMessageDetailResponse || []); setChatRoomDetail(data?.data?.chatRoomDetailResponse || []); @@ -87,6 +102,7 @@ const WebSocketConnect = ({role}) => { const chatMessageRequest = { roomId: roomId, message: newMessage, + role : role, sendingTime: new Date().toISOString(), }; @@ -134,15 +150,20 @@ const WebSocketConnect = ({role}) => { }; const handleGoBack = () => { - window.history.back(); // Use the window.history object to go back + setSelectedChatRoom(null); }; return ( -
-
+
+
+
+
+ setNewMessage(e.target.value)} + className="border p-1 rounded-full w-80 border-gray-" + style={{fontSize: '12px', padding: '6px'}} + /> + +
+
); }; -export default WebSocketConnect; +export default ChatRoom; diff --git a/src/components/common/Chat/ChatApp.css b/src/components/common/Chat/ChatApp.css index 3920dbc..827a4dc 100644 --- a/src/components/common/Chat/ChatApp.css +++ b/src/components/common/Chat/ChatApp.css @@ -32,14 +32,12 @@ .close-button { position: absolute; - top: 10px; + top: 17px; right: 10px; padding: 8px 12px; - background-color: #3498db; - color: #ffffff; border: none; cursor: pointer; - font-size: 10px; + font-size: 15px; } .chat-room:hover { diff --git a/src/components/common/Chat/ChatRoomDetail.jsx b/src/components/common/Chat/ChatRoomDetail.jsx index 1c90f34..7e091d3 100644 --- a/src/components/common/Chat/ChatRoomDetail.jsx +++ b/src/components/common/Chat/ChatRoomDetail.jsx @@ -1,4 +1,10 @@ -import WebSocketConnect from "./WebSocketConnect"; +import React, {useEffect, useRef, useState} from "react"; +import GetTokenFromLocalStorage from "../../../api/Common/token"; +import SockJS from "sockjs-client"; +import {Stomp} from "@stomp/stompjs"; +import MeChatMessage from "./MeChatMessage"; +import OtherChatMessage from "./OtherChatMessage"; +import AdminChatApi from "../../../api/administrator/adminChatApi"; /** * 채팅방 컴포넌트 @@ -6,12 +12,213 @@ import WebSocketConnect from "./WebSocketConnect"; * @since 2024.03.02 * @author 이상민 */ -const ChatRoomDetail = ({role}) => { +const ChatRoomDetail = ({selectedChatRoomId}) => { + + const [stompClient, setStompClient] = useState(null); + const [messages, setMessages] = useState([]); + const [newMessage, setNewMessage] = useState(""); + + const roomId = selectedChatRoomId; + const role = 'admin' + console.log("채팅방 : " + roomId) + + const messagesContainerRef = useRef(null); + const token = GetTokenFromLocalStorage(role) + const [chatRoomDetail, setChatRoomDetail] = useState([]); + + /** + * WebSocket 연결 + * + * @since 2024.03.03 + * @author 이상민 + */ + useEffect(() => { + const socket = new SockJS(`http://localhost:8080/ws`); + const stomp = Stomp.over(socket); + setStompClient(stomp); + // 고유한 ID 생성 + const uniqueId = `sub-${Math.random().toString(36).substr(2, 9)}`; + stomp.connect({ Authorization: `Bearer ${token}` }, (frame) => { + console.log("연결 성공!", frame); + console.log("1 : " + role) + + // 2. 특정 채팅방에 구독 + stomp.subscribe(`/topic/messages`, (message) => { + const newMessage = JSON.parse(message.body); + + if(newMessage.role === role){ + newMessage.checkedMe = true; + }else{ + newMessage.checkedMe = false; + } + + // 기존 메시지와 새 메시지를 합쳐서 상태 업데이트 + // setMessages((prevMessages) => [...prevMessages, newMessage]); + + // 새 메시지가 현재 채팅방에 대한 것인지 확인 + if (roomId === newMessage.roomId) { + showMessage(newMessage); + } + }, { id: uniqueId }); // 고유한 ID로 구독 + }, (error) => { + console.error("연결 실패:", error); + }); + // 3. 이전 메시지 불러오기 + loadPreviousMessages(); + return () => { + stomp.disconnect(); + }; + }, [roomId]); + + useEffect(() => { + scrollToBottom(); // 새로운 메시지가 추가될 때마다 스크롤을 최하단으로 이동 + }, [messages]); + + const loadPreviousMessages = async () => { + try { + const response = await AdminChatApi.getMessages(roomId); + console.log(response) + + const data = response.data; + setMessages(data?.data?.chatMessageDetailResponse || []); + setChatRoomDetail(data?.data?.chatRoomDetailResponse || []); + } catch (error) { + console.error("이전 메시지 불러오기 실패:", error); + } + }; + + /** + * 메시지 전송 + * + * @since 2024.03.03 + * @author 이상민 + */ + const sendMessage = () => { + if (newMessage.trim() !== '' && stompClient) { + const chatMessageRequest = { + roomId: roomId, + message: newMessage, + role : role, + sendingTime: new Date().toISOString(), + }; + + // 'send' 메서드의 옵션으로 'Authorization' 헤더를 설정 + const headers = { Authorization: `Bearer ${token}` }; + + // 헤더를 포함하여 메시지를 전송 + stompClient.send("/app/sendMessage", headers, JSON.stringify(chatMessageRequest)); + + // 메시지 입력을 지웁니다 + setNewMessage(''); + } + }; + + /** + * 메시지 보여주기 + * + * @since 2024.03.03 + * @author 이상민 + */ + const showMessage = (message) => { + const formattedMessage = { + sender: message.senderNickname, + sendingTime: message.sendingTime, + message: message.message, + checkedMe: message.checkedMe, + }; + + console.log("포맷 :: " + formattedMessage); + + setMessages((prevMessages) => [...prevMessages, formattedMessage]); + scrollToBottom(); + }; + + /** + * 최하단으로 스크롤 이동 + * + * @since 2024.03.03 + * @author 이상민 + */ + const scrollToBottom = () => { + if (messagesContainerRef.current) { + messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight; + } + }; + + const handleGoBack = () => { + // setSelectedChatRoom(null); + }; + return (
-
- +
+ +

+ {chatRoomDetail.name} +

+ +
+ +
    + {messages.map((message, index) => ( +
  • + {message.checkedMe === true ? ( + + ) : ( + + )} +
    +
  • + ))} +
+
+ +
+
+ setNewMessage(e.target.value)} + className="border p-1 rounded-full w-80 border-gray-" + style={{fontSize: '12px', padding: '6px'}} + /> + +
+
+
); }; diff --git a/src/components/common/FloatingButton/FloatingButton.css b/src/components/common/FloatingButton/FloatingButton.css index e15fd7b..24fce59 100644 --- a/src/components/common/FloatingButton/FloatingButton.css +++ b/src/components/common/FloatingButton/FloatingButton.css @@ -28,9 +28,8 @@ transform: translate(-50%, -50%); overflow: auto; outline: none; - background: white; - padding: 20px; - border-radius: 10px; + padding: 0px; + border-radius: 25px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); /* 추가적인 스타일 설정 */ } diff --git a/src/components/common/FloatingButton/FloatingButton.jsx b/src/components/common/FloatingButton/FloatingButton.jsx index 38b22ea..4c4f99c 100644 --- a/src/components/common/FloatingButton/FloatingButton.jsx +++ b/src/components/common/FloatingButton/FloatingButton.jsx @@ -1,20 +1,27 @@ import React, {useState} from 'react'; import './FloatingButton.css'; // 스타일 파일을 추가합니다. import Modal from 'react-modal'; -import ChatList from "../Chat/ChatList"; +import ChatApi from "../../../api/chatApi"; +import ChatRoom from "../../business/Chat/ChatRoom"; +import ChatList from "../../business/Chat/ChatList"; +/** + * FloatingButton 컴포넌트 + * + * @since 2024.03.04 + * @author 이상민 + */ const FloatingButton = () => { const [modalIsOpen, setModalIsOpen] = useState(false); const [buttonPosition, setButtonPosition] = useState({ top: 0, left: 0 }); + const [selectedChatRoom, setSelectedChatRoom] = useState(null); const openModal = () => { const button = document.querySelector('.floating-button'); if (button) { const rect = button.getBoundingClientRect(); setButtonPosition({ top: rect.bottom + window.scrollY, left: rect.left + window.scrollX }); - console.log('Button Position:', buttonPosition); } - setModalIsOpen(true); }; @@ -26,39 +33,23 @@ const FloatingButton = () => { */ const closeModal = () => { setModalIsOpen(false); + // 모달이 닫힐 때 선택된 채팅방 정보 초기화 + setSelectedChatRoom(null); + }; + + const handleChatRoomClick = (chatRoom) => { + console.log("chat room id : " + chatRoom) + setSelectedChatRoom(chatRoom); }; return ( <> - {/**/} -
-
- { position: 'absolute', }} > -
- -
+ {/* 선택된 채팅방이 없을 때에만 ChatList를 모달 안에 렌더링 */} + {!selectedChatRoom && } + + {/* 선택된 채팅방이 있을 때 ChatRoomDetail을 표시 */} + {selectedChatRoom && }
); diff --git a/src/pages/administrator/adminChat.jsx b/src/pages/administrator/adminChat.jsx index cea885a..43ec963 100644 --- a/src/pages/administrator/adminChat.jsx +++ b/src/pages/administrator/adminChat.jsx @@ -1,6 +1,6 @@ import React from "react"; import AdminChatApi from "../../api/administrator/adminChatApi"; -import ChatList from "../../components/common/Chat/ChatList"; +import ChatPage from "../../components/administrator/ChatPage"; /** * 채팅 페이지 제작 @@ -10,7 +10,10 @@ import ChatList from "../../components/common/Chat/ChatList"; */ const AdminChat = () => { return ( - + ); }; diff --git a/src/pages/business/chat.jsx b/src/pages/business/chat.jsx deleted file mode 100644 index 23f9cce..0000000 --- a/src/pages/business/chat.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react"; -import ChatApi from "../../api/chatApi"; -import ChatList from "../../components/common/Chat/ChatList"; - -/** - * 채팅 페이지 제작 - * - * @since 2024.03.02 - * @author 이상민 - */ -const Chat = () => { - return ( - - ); -}; - -export default Chat; diff --git a/src/pages/business/dashboard.jsx b/src/pages/business/dashboard.jsx index 5c3cacc..4948ed1 100644 --- a/src/pages/business/dashboard.jsx +++ b/src/pages/business/dashboard.jsx @@ -5,6 +5,7 @@ import PopupCurrent from "../../components/business/DashBoard/PopupCurrent"; import PopupRanking from "../../components/business/DashBoard/PopupRanking"; import PopupStatistics from "../../components/business/DashBoard/PopupStatistics"; import PopupPostList from "../../components/business/DashBoard/PopupPostList"; +import FloatingButton from "../../components/common/FloatingButton/FloatingButton"; /** * DashBoard 페이지 제작 @@ -13,6 +14,9 @@ import PopupPostList from "../../components/business/DashBoard/PopupPostList"; * @author 이승민 */ const DashBoard = () => { + const handleButtonClick = () => { + + }; return (
@@ -32,6 +36,7 @@ const DashBoard = () => { }/>
+
) } From 1b602539cc32e1554498901cf696c4fb38226a10 Mon Sep 17 00:00:00 2001 From: sangminee Date: Tue, 5 Mar 2024 18:52:14 +0900 Subject: [PATCH 05/10] =?UTF-8?q?[CHORE]=20=ED=8C=8C=EC=9D=BC=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EB=B0=8F=20css=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Chat => administrator}/ChatRoomDetail.jsx | 15 ++++++++------- src/components/administrator/ChatTable.jsx | 13 +++++-------- src/components/business/Chat/ChatList.jsx | 1 - src/components/business/Chat/ChatRoom.jsx | 2 +- .../FloatingButton/FloatingButton.css | 0 .../FloatingButton/FloatingButton.jsx | 0 src/pages/business/dashboard.jsx | 2 +- 7 files changed, 15 insertions(+), 18 deletions(-) rename src/components/{common/Chat => administrator}/ChatRoomDetail.jsx (94%) rename src/components/{common => business}/FloatingButton/FloatingButton.css (100%) rename src/components/{common => business}/FloatingButton/FloatingButton.jsx (100%) diff --git a/src/components/common/Chat/ChatRoomDetail.jsx b/src/components/administrator/ChatRoomDetail.jsx similarity index 94% rename from src/components/common/Chat/ChatRoomDetail.jsx rename to src/components/administrator/ChatRoomDetail.jsx index 7e091d3..f1a628e 100644 --- a/src/components/common/Chat/ChatRoomDetail.jsx +++ b/src/components/administrator/ChatRoomDetail.jsx @@ -1,10 +1,10 @@ import React, {useEffect, useRef, useState} from "react"; -import GetTokenFromLocalStorage from "../../../api/Common/token"; import SockJS from "sockjs-client"; import {Stomp} from "@stomp/stompjs"; -import MeChatMessage from "./MeChatMessage"; -import OtherChatMessage from "./OtherChatMessage"; -import AdminChatApi from "../../../api/administrator/adminChatApi"; +import GetTokenFromLocalStorage from "../../api/Common/token"; +import AdminChatApi from "../../api/administrator/adminChatApi"; +import MeChatMessage from "../common/Chat/MeChatMessage"; +import OtherChatMessage from "../common/Chat/OtherChatMessage"; /** * 채팅방 컴포넌트 @@ -12,7 +12,7 @@ import AdminChatApi from "../../../api/administrator/adminChatApi"; * @since 2024.03.02 * @author 이상민 */ -const ChatRoomDetail = ({selectedChatRoomId}) => { +const ChatRoomDetail = ({selectedChatRoomId, setModalIsOpen}) => { const [stompClient, setStompClient] = useState(null); const [messages, setMessages] = useState([]); @@ -24,6 +24,7 @@ const ChatRoomDetail = ({selectedChatRoomId}) => { const messagesContainerRef = useRef(null); const token = GetTokenFromLocalStorage(role) + const [chatRoomDetail, setChatRoomDetail] = useState([]); /** @@ -33,7 +34,7 @@ const ChatRoomDetail = ({selectedChatRoomId}) => { * @author 이상민 */ useEffect(() => { - const socket = new SockJS(`http://localhost:8080/ws`); + const socket = new SockJS(`http://15.164.236.13:8080/ws`); const stomp = Stomp.over(socket); setStompClient(stomp); // 고유한 ID 생성 @@ -146,7 +147,7 @@ const ChatRoomDetail = ({selectedChatRoomId}) => { }; const handleGoBack = () => { - // setSelectedChatRoom(null); + setModalIsOpen(false) }; return ( diff --git a/src/components/administrator/ChatTable.jsx b/src/components/administrator/ChatTable.jsx index 632147d..5f321c4 100644 --- a/src/components/administrator/ChatTable.jsx +++ b/src/components/administrator/ChatTable.jsx @@ -1,9 +1,8 @@ import React, {useState} from "react"; import TableHeader from "../common/Table/TableHeader"; import TableRow from "../common/Table/TableRow"; -import {useNavigate} from "react-router-dom"; -import ChatRoomDetail from "../common/Chat/ChatRoomDetail"; import Modal from "react-modal"; +import ChatRoomDetail from "./ChatRoomDetail"; /** * Table 컴포넌트 생성 @@ -13,7 +12,6 @@ import Modal from "react-modal"; */ const ChatTable = ({ headerTitles, sampleData }) => { - const navigate = useNavigate(); const [modalIsOpen, setModalIsOpen] = useState(false); const [selectedChatRoomId, setSelectedChatRoomId] = useState(null); @@ -22,10 +20,6 @@ const ChatTable = ({ headerTitles, sampleData }) => { setSelectedChatRoomId(id); setModalIsOpen(true); - - // const role = 'admin'; - // const currentUrl = window.location.pathname; - // navigate(`${currentUrl}/${id}`, { state: { role } }); }; const renderTableBody = (sampleData) => ( @@ -59,11 +53,14 @@ const ChatTable = ({ headerTitles, sampleData }) => { marginRight: '-50%', transform: 'translate(-50%, -50%)', maxWidth: '80%', // 필요에 따라 최대 너비 조정 + padding: 0, + borderRadius: 25, + boxShadow: '0px 4px 8px rgba(0, 0, 0, 0.1)', }, }} > {selectedChatRoomId && ( - + )}
diff --git a/src/components/business/Chat/ChatList.jsx b/src/components/business/Chat/ChatList.jsx index 8eaf5ef..f7c66ad 100644 --- a/src/components/business/Chat/ChatList.jsx +++ b/src/components/business/Chat/ChatList.jsx @@ -1,5 +1,4 @@ import React, {useEffect, useState} from 'react'; -import {useNavigate} from 'react-router-dom'; import '../../common/Chat/ChatApp.css'; /** diff --git a/src/components/business/Chat/ChatRoom.jsx b/src/components/business/Chat/ChatRoom.jsx index dfdebb4..bd7c1ea 100644 --- a/src/components/business/Chat/ChatRoom.jsx +++ b/src/components/business/Chat/ChatRoom.jsx @@ -37,7 +37,7 @@ const ChatRoom= ({selectedChatRoom, setSelectedChatRoom}) => { * @author 이상민 */ useEffect(() => { - const socket = new SockJS(`http://localhost:8080/ws`); + const socket = new SockJS(`http://15.164.236.13:8080/ws`); const stomp = Stomp.over(socket); setStompClient(stomp); // 고유한 ID 생성 diff --git a/src/components/common/FloatingButton/FloatingButton.css b/src/components/business/FloatingButton/FloatingButton.css similarity index 100% rename from src/components/common/FloatingButton/FloatingButton.css rename to src/components/business/FloatingButton/FloatingButton.css diff --git a/src/components/common/FloatingButton/FloatingButton.jsx b/src/components/business/FloatingButton/FloatingButton.jsx similarity index 100% rename from src/components/common/FloatingButton/FloatingButton.jsx rename to src/components/business/FloatingButton/FloatingButton.jsx diff --git a/src/pages/business/dashboard.jsx b/src/pages/business/dashboard.jsx index 4948ed1..c66e210 100644 --- a/src/pages/business/dashboard.jsx +++ b/src/pages/business/dashboard.jsx @@ -5,7 +5,7 @@ import PopupCurrent from "../../components/business/DashBoard/PopupCurrent"; import PopupRanking from "../../components/business/DashBoard/PopupRanking"; import PopupStatistics from "../../components/business/DashBoard/PopupStatistics"; import PopupPostList from "../../components/business/DashBoard/PopupPostList"; -import FloatingButton from "../../components/common/FloatingButton/FloatingButton"; +import FloatingButton from "../../components/business/FloatingButton/FloatingButton"; /** * DashBoard 페이지 제작 From a3a99cdc775f9a6d94efc313639f07c4bd811863 Mon Sep 17 00:00:00 2001 From: sangminee Date: Tue, 5 Mar 2024 19:17:46 +0900 Subject: [PATCH 06/10] =?UTF-8?q?[CHORE]=20=EB=A8=B8=EC=A7=80=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/Table/MyPostListTable.js | 21 +++++++++---------- src/components/common/Table/Table.jsx | 19 ++++++++--------- src/components/common/Table/TableRow.jsx | 2 +- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/components/common/Table/MyPostListTable.js b/src/components/common/Table/MyPostListTable.js index 7aae700..0ad9088 100644 --- a/src/components/common/Table/MyPostListTable.js +++ b/src/components/common/Table/MyPostListTable.js @@ -23,17 +23,16 @@ function MyPostListTable({ posts }) { <> - {displayedData.map((post, index) => ( - - - - - - ))} + {displayedData.map((post, index) => ( + + + + + ))}
-
{index + 1}
-
-
{post.title}
-
{post.pulledDate}
+
{index + 1}
+
+
{post.title}
+
diff --git a/src/components/common/Table/Table.jsx b/src/components/common/Table/Table.jsx index 4b320c7..c3b0869 100644 --- a/src/components/common/Table/Table.jsx +++ b/src/components/common/Table/Table.jsx @@ -22,16 +22,15 @@ const Table = ({ headerTitles, sampleData }) => { ))} ); - + return (
- - - {renderTableBody(sampleData)} -
+ + + {renderTableBody(sampleData)} +
- ); - }; - - export default Table; - + ); +}; + +export default Table; diff --git a/src/components/common/Table/TableRow.jsx b/src/components/common/Table/TableRow.jsx index 2064ca0..1546687 100644 --- a/src/components/common/Table/TableRow.jsx +++ b/src/components/common/Table/TableRow.jsx @@ -26,4 +26,4 @@ const TableRow = ({ rowData, onRowClick }) => { } }; -export default TableRow; \ No newline at end of file +export default TableRow; From ff7638b36581993e22be0088baf7748519a48be0 Mon Sep 17 00:00:00 2001 From: LSMJJAng <127660101+LSMJJAng@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:47:07 +0900 Subject: [PATCH 07/10] =?UTF-8?q?[REFACTOR]=20Ranking=20y=EC=B6=95=20?= =?UTF-8?q?=EA=B0=84=EA=B2=A9=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/business/DashBoard/PopupRanking.js | 13 +++++-------- src/components/common/InfoList/RankingList.js | 8 ++++---- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/components/business/DashBoard/PopupRanking.js b/src/components/business/DashBoard/PopupRanking.js index b825555..9c216b0 100644 --- a/src/components/business/DashBoard/PopupRanking.js +++ b/src/components/business/DashBoard/PopupRanking.js @@ -23,23 +23,20 @@ function PopupRanking() { }, []); return ( -
+
{myPopup.length > 0 && ( -
+
MY
-
+
{myPopup[0].popupName}
-
-
- {myPopup[0].popupView} -
+
- 회 + {myPopup[0].popupView} 회
diff --git a/src/components/common/InfoList/RankingList.js b/src/components/common/InfoList/RankingList.js index 025fe64..bd038e8 100644 --- a/src/components/common/InfoList/RankingList.js +++ b/src/components/common/InfoList/RankingList.js @@ -9,16 +9,16 @@ export default RankingList; function RankingList(props) { return (
-
+
-
+
{props.id}위
-
+
{props.title}
-
+
{formatNumberWithCommas(props.content)} 회
From 463a6d654caa89d8d4df0b842bd245479897eeda Mon Sep 17 00:00:00 2001 From: sangminee Date: Tue, 5 Mar 2024 20:18:50 +0900 Subject: [PATCH 08/10] =?UTF-8?q?[FEAT]=20=EC=82=AC=EC=97=85=EC=B2=B4=20?= =?UTF-8?q?=ED=94=8C=EB=A1=9C=ED=8C=85=20=EB=B2=84=ED=8A=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FloatingButton/FloatingButton.css | 14 +++++------ .../FloatingButton/FloatingButton.jsx | 23 +++++++++++-------- src/pages/business/ad.jsx | 2 ++ src/pages/business/createPlan.jsx | 4 +++- src/pages/business/dashboard.jsx | 4 +--- src/pages/business/plan.jsx | 2 ++ src/pages/business/plans.jsx | 4 +++- 7 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/components/business/FloatingButton/FloatingButton.css b/src/components/business/FloatingButton/FloatingButton.css index 24fce59..ed98fe7 100644 --- a/src/components/business/FloatingButton/FloatingButton.css +++ b/src/components/business/FloatingButton/FloatingButton.css @@ -5,31 +5,29 @@ width: 50px; height: 50px; border-radius: 50%; - background-color: #007bff; + background-color: #49675a; color: #fff; font-size: 24px; border: none; cursor: pointer; outline: none; - /* 그림자 효과를 추가하거나 필요에 따라 스타일을 수정하세요 */ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease; } .floating-button:hover { - background-color: #0056b3; + background-color: #96b2a4; } .floating-button-modal { position: fixed; - top: 50%; - left: auto; - right: 0; - transform: translate(-50%, -50%); + top: calc(64%); /* 버튼 바로 위에 위치하도록 수정 */ + right: 20px; /* 화면 오른쪽에 위치하도록 수정 */ + transform: translate(0, -50%); overflow: auto; outline: none; - padding: 0px; border-radius: 25px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); + background-color: #fff; /* 배경 색상 추가 */ /* 추가적인 스타일 설정 */ } diff --git a/src/components/business/FloatingButton/FloatingButton.jsx b/src/components/business/FloatingButton/FloatingButton.jsx index 4c4f99c..89bd0f3 100644 --- a/src/components/business/FloatingButton/FloatingButton.jsx +++ b/src/components/business/FloatingButton/FloatingButton.jsx @@ -13,16 +13,17 @@ import ChatList from "../../business/Chat/ChatList"; */ const FloatingButton = () => { const [modalIsOpen, setModalIsOpen] = useState(false); - const [buttonPosition, setButtonPosition] = useState({ top: 0, left: 0 }); + // const [buttonPosition, setButtonPosition] = useState({ top: 0, left: 0 }); const [selectedChatRoom, setSelectedChatRoom] = useState(null); const openModal = () => { const button = document.querySelector('.floating-button'); if (button) { const rect = button.getBoundingClientRect(); - setButtonPosition({ top: rect.bottom + window.scrollY, left: rect.left + window.scrollX }); + // setButtonPosition({ top: rect.bottom + window.scrollY, left: rect.left + window.scrollX }); } setModalIsOpen(true); + document.body.style.overflow = 'hidden'; }; /** @@ -34,6 +35,7 @@ const FloatingButton = () => { const closeModal = () => { setModalIsOpen(false); // 모달이 닫힐 때 선택된 채팅방 정보 초기화 + document.body.style.overflow = 'auto'; setSelectedChatRoom(null); }; @@ -44,9 +46,13 @@ const FloatingButton = () => { return ( <> -
+
@@ -55,11 +61,10 @@ const FloatingButton = () => { onRequestClose={closeModal} contentLabel="Floating Button Modal" className="floating-button-modal" - style={{ - top: buttonPosition.top, - left: buttonPosition.left, - position: 'absolute', - }} + overlayClassName="custom-overlay-class" + portalClassName="custom-portal-class" + shouldCloseOnOverlayClick={true} // 모달 이외의 영역 클릭시 모달 닫힘 설정 + shouldCloseOnEsc={true} > {/* 선택된 채팅방이 없을 때에만 ChatList를 모달 안에 렌더링 */} {!selectedChatRoom && } diff --git a/src/pages/business/ad.jsx b/src/pages/business/ad.jsx index b96fd39..083acab 100644 --- a/src/pages/business/ad.jsx +++ b/src/pages/business/ad.jsx @@ -13,6 +13,7 @@ import MyCommunityApi from "../../api/business/createAd/myCommunityApi"; import FileUpload from "../../components/common/Input/FileUpload"; import MyPopupApi from "../../api/business/createAd/myPopupApi"; import Button from "../../components/common/Button/Button"; +import FloatingButton from "../../components/business/FloatingButton/FloatingButton"; /** * Ad 페이지 제작 @@ -103,6 +104,7 @@ const Ad = () => {
diff --git a/src/pages/business/createPlan.jsx b/src/pages/business/createPlan.jsx index 4eff523..b6876db 100644 --- a/src/pages/business/createPlan.jsx +++ b/src/pages/business/createPlan.jsx @@ -7,7 +7,8 @@ import DepartmentDropdown from "../../components/business/DepartmentDropdown/Dep import FloorDropdown from "../../components/business/FloorDropdown/FloorDropdown"; import Button from "../../components/common/Button/Button"; import PlanApi from "../../api/business/createPlan/planApi"; -import {useRef, useState} from "react"; +import React, {useRef, useState} from "react"; +import FloatingButton from "../../components/business/FloatingButton/FloatingButton"; /** * CreatePlan 페이지 제작 @@ -86,6 +87,7 @@ const PlanContentBox = ({onOpenDateChange, onCloseDateChange, onPhoneNumberChang secondInput={}/> +
) } diff --git a/src/pages/business/dashboard.jsx b/src/pages/business/dashboard.jsx index c66e210..48c8899 100644 --- a/src/pages/business/dashboard.jsx +++ b/src/pages/business/dashboard.jsx @@ -14,9 +14,7 @@ import FloatingButton from "../../components/business/FloatingButton/FloatingBut * @author 이승민 */ const DashBoard = () => { - const handleButtonClick = () => { - }; return (
@@ -36,7 +34,7 @@ const DashBoard = () => { }/>
- +
) } diff --git a/src/pages/business/plan.jsx b/src/pages/business/plan.jsx index 5b07d5e..e97bcf1 100644 --- a/src/pages/business/plan.jsx +++ b/src/pages/business/plan.jsx @@ -14,6 +14,7 @@ import colorSyntax from '@toast-ui/editor-plugin-color-syntax'; import 'tui-color-picker/dist/tui-color-picker.css'; import '@toast-ui/editor-plugin-color-syntax/dist/toastui-editor-plugin-color-syntax.css'; import './planViewer.css'; +import FloatingButton from "../../components/business/FloatingButton/FloatingButton"; /** * Plan 페이지 제작 @@ -102,6 +103,7 @@ const Plan = () => { }/> }/> +
); }; diff --git a/src/pages/business/plans.jsx b/src/pages/business/plans.jsx index 3aef05d..cd529bf 100644 --- a/src/pages/business/plans.jsx +++ b/src/pages/business/plans.jsx @@ -2,9 +2,10 @@ import ContentBox from "../../components/common/ContentBox/ContentBox"; import CategoryDropdown from "../../components/business/CategoryDropdown/CategoryDropdown"; import EntranceStatusDropdown from "../../components/business/EntranceStatusDropdown/EntranceStatusDropdown"; import MyPlanTable from "../../components/business/MyPlanTable/MyPlanTable"; -import {useEffect, useState} from "react"; +import React, {useEffect, useState} from "react"; import MyPlansApi from "../../api/business/plans/myPlansApi"; import SearchButton from "../../components/common/Button/SearchButton"; +import FloatingButton from "../../components/business/FloatingButton/FloatingButton"; /** * Plans 페이지 제작 @@ -38,6 +39,7 @@ function Plans() { onClick={getPlans(category, entranceStatus, page, limit, setTotal, setPlans)}/>
+ }/>
From 0712a1ed0a49041e8f7a7a05ce1ef2a8e71d146d Mon Sep 17 00:00:00 2001 From: sangminee Date: Thu, 7 Mar 2024 13:30:56 +0900 Subject: [PATCH 09/10] =?UTF-8?q?[FEAT]=20=EC=82=AC=EC=97=85=EC=B2=B4=20?= =?UTF-8?q?=EC=B1=84=ED=8C=85=20ui=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/admin.png | Bin 0 -> 12643 bytes public/logo.png | Bin 0 -> 38617 bytes public/logo_black.png | Bin 0 -> 49599 bytes public/logo_maincolor.png | Bin 0 -> 15191 bytes src/components/business/Chat/ChatList.jsx | 43 +++++++++++++----- .../FloatingButton/FloatingButton.css | 4 +- .../FloatingButton/FloatingButton.jsx | 5 +- src/components/common/Chat/ChatApp.css | 2 +- 8 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 public/admin.png create mode 100644 public/logo.png create mode 100644 public/logo_black.png create mode 100644 public/logo_maincolor.png diff --git a/public/admin.png b/public/admin.png new file mode 100644 index 0000000000000000000000000000000000000000..1b9cc07b5dd0b74ba595c6b633f7146a8668dd72 GIT binary patch literal 12643 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 FzW~D%PMiP$ literal 0 HcmV?d00001 diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0047ca2b6d0d5ed593e3866544021b845190110d GIT binary patch literal 38617 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 L^LeSFiQoSK8L$%b literal 0 HcmV?d00001 diff --git a/public/logo_black.png b/public/logo_black.png new file mode 100644 index 0000000000000000000000000000000000000000..5c25f24ff1e1dfe521dc6e95609276ecbdceb905 GIT binary patch literal 49599 zcmV)xK$E|TP)s>mPBzgblSPn( zgiu5|=PaEr=a+Ws-+8)wdS-fdXZP)UH$Q3b?ap-W>gww1>S}-%En2i_(V|6*7A;z| zXwjlYixw?fv}nVw6*0|{}+C7lA z0?3z_mus4>#@l1?a|y{aM&JD&Y+Q9-{fs_L%*it@}oUnvF-OioS)!?UqhJMSR) zxMX=1ezekyKhA& zNmlN&cI{eLi-nY?V~~sirYTvOCWM$IKnSGDz`rS^;vb?kNm)D|0$DODeriJTWK0>7 zME}G7AgMIbCDK&9Cy`qM-aAn)N{Hplek3|=UP|hUgi=%f#BMjV3Pl7E92kkrFwowt z9z}Nmw_TPEk>+X8SGoCR44WKUu{n3wpbm2u8U3AiQH{5jQ?(Xyxr)RpS@7TV5 z-Q?8NLS8$PHAhY!e5j+QE7`vKlY=02G~=H4N;X+8xADr5-UmbjqFT=g8&Pfn*3pdCVX_?i0I@e5^CP!B(2<{2QgCC z7znD%+;W+5nxc88`XV2=IHRoKJfp0tyq|cM>V~Yo;%SL+Ku5?3B(Lx{YJZgbQMTXPl!&c8AaPgwir`3Z>lh5v_SbsCKQ^~ ztdQ1QFA`RfPjNXyt*?7V_Z}$`NcFmTN9wO#3^BY7Ex2=p{iFzT&b9iJWFcjXC_bS= zu&$g~xM<6D2_iMkl3;IAb6Y%lk7r%JPhOJv)`_Lon zU%GSW?lX4m+O?XJq(g#9qG|wDLBdd17J@g7Lttn%tCBjbZuNS`9vFTX1c=fd7l5I7 zn2~yrK^r2d!&b{d_IktmE9Z>>M^{Dg2axltm$FeYA)`&dP)OT{Ib`0j9^FB)P|_7b0J;On|{a z*nBxnUs2Zn?%PoN+hfBoq$_S?1W{5!5G40~!KeWDZAN_*2$7YS)CB5>&&13S9rIwx zSZDW|RjaOEy<)|ePkh|TKmF<#K6xATh@RNVx?_)BzF=nR@26(EFWs_j*THRsM3xlqPE%A`YXq|VU2c$hQfhlVxu@ae79P}gJ7qxp-npJJuE1i@xXtBXTf&A6i zRE6uMPkDc(MUtHAk87c*G%LFL}0Mw8FU|n+B1Wu;!K;;=?oBY%yBM(A}SD4pI{|} zw&@Pb-a*muw#5suRx1*T+Bc%WyL?jQq*{m(q`^%6!FLvM^1yxf{o0|2AM}xn&OP@k zsDY$T;G>T{?%(%Jci+f%RmY`#!lLsA&uQle#GL0dM!LC1p9z z3VvLL75|<>ar>u*>CEl^%Gv^%`WF_i-?Ztadv;H~{5|h^&#F4=z-KOFd&Y~BiVbn`(eGPiu(Uy??-0vBh3WSguOGC1Jh$MO>yWgh#GFD+ zzDG~B;7PRRqttHM2hGPLY&RSY@tfvm_u~WC!{XX{*cc6 z-BnjzwSR29C#*F0N9 z0{PLoCAZ#s$Nxt}Q4LqAgI=|2)d|<%c;l-lrlyZ2OhS2rqdPSZ_17VG;9Me>matpQ zI?(&HXdLMNNElzmq=g$dYJ7P8`p3q^sASM- zB8(*=t#zcOMT-_KTKLdL$WxQkQ3qBk*=|DI<12UQORd>lixw?f)IsPtBr&PC3uD|} zb5-#i)N~RjS^(XEW8X8*r`4%l& z%mYxt_gJ&>T(@pr zrP$dr=sAOyF}G+jZ$JbOJn%rbDp-t)W29kU(n*ze+94)K5#eV`zk-3^t*)mGvEp+l6jIccf_eZd76 zRECYQg9hW6pDG*%^&?4_DAPm1#I1+?zAvKcbac5(r~*r#v}~|N3y501=|!pjOX$Wm z=QIea#l9k`2=n6^A&{q2s4VPIQEXdBKR^5IN)^ZKZxY%q8#+twTn2#Vrd)k%Ztijb z)X%INjeWn)PBcGVJN;?}Na$1gvXm&jK%|Y@?N`>V>Cx%7m@|l=9qi!~oqjKL>s`T( z>MsStXwvPQPx`|-G*~0XMHYm-v1N_1rXiUG{dGh$G`mSSD4nzcDyFRSD-wyldB+^G z@xmzvSggLVItcTxLeHZJuP7~3rm8?y@TYBpI7%y9jJ6mgOe@DomOUpvAb10a6uF6~ z6b?!Vv$He}wndpJRv4*1ykW@I992=O8FZ3pfwFN3-7j(f)m$qhnX2eFU2a3H>I)Bt zn&qHcCXq8CNS2#8{FBr-t+AGOC+evl)!Qr$vJ(^KlpV;`Ddsr6;iKfWyPA_N>NM}Y ziA$D^%musRN-;G$Wl%lQq$Yn1Fk3=Z`ozgiA%QfV0e%@;*~Ub|TYxV%l2915)IS%w31pV6g!(=BlMO4W}(vN4t}S_nrRaX2hnwoEb!!<11HvDl)N4>NjY&$|3ws``}N zbd3)_NleC5D(R|N>H$R~iNz=k(=_?X@Ik$q${#5)iJ|^Cz{`B*Zx1Y4JX?ZB$S6!z zg2;|;1_3!a*geEu8_vK@H{A+bckX~fq$wPJ$RV)r0sFz&*jT=jly8^pwKcgBMG;7M zW*Y9f?_PLx<7SY|8ulvicH)A`;zf(#v5z?hRqSh>pOb!T4Dqtrn<7bna z`wCR~P=)hy&V(%SSMRf-3A<^_7P$9;2Vu{|)NJr&gK7pX{3KzsD-zXGoumUtA8{Cb z?vtN@0}tFkAB>4~Xl7Ql3dE5(GpB=$HZ9(fSaE$8ru5E~IfWw1*HT?tQm<;Af`mlY$EQWJ1laq(`0q{J7#>{W2-6;~97;tcxTfBeVr zyyrd}7A#m`(vvNd=t>r3p;s7?Ba*zGjjZFwO`G5!{^_6Li(mVCCY9}NU>$to;~x+I z_`bh~6CV3mNK}9Gl}wsiw8Z~lN79p8!uc#W)XJL4*`e|RLTCULBUMtrNmnshmqTM= zst!G9=1x{R9EnNDfy1D^@fVtWq^ytz!)sv+!JWk9wp9Y({r(T&Pu~3(fPXOX^`MKCP#020a7&jg0Vs|x>V3q)2f;ooSHt-Dm^F~Ib%p!aey=4N zbPJQ)xk1n((jvC3U$b(hTIa-?OU^HFb<)23>;s1%bTF)1vQ#})G=yGD+h@)&TUnta zs)CXnZ6;_BSDQZN)3gS?8)S~5b# z!T%u)tX29%CKU@E8s(*d5J3#WBAe8%M!i#spbFT{zH8AM22jXoXr`F8uXx%`E9F$v z#s1*;nQRfz`+}hW@}b3JX1BR!6Qrk8&JxrIL+dQG`ocbyAO#B~vScERXwNLbFr8Em z6GZknD4ASrRfu`SdW5YK{4^>D5QNhYmoJX$W34zyN;%DrB&SjA8IRI%Ap2)f8C=PJ zLMdhMtu&)*nkl&g<-mwMOB0WarH%vWGYQA0oWYV?Z zb+|JKAkVyG#eYXNP*hfvD1^(c$*lviI|wo*%_OvPtD3PF@9#etb< zju`a5incT`?X6XI9xd6(=^UdnR53!#IcAv}M?)o92eYb|hPBEr8D_ZvCR9Nka_y;X zrF0UhEll)}q7fTHG=nahfck;f2*CoNfJ(}C_+*AxxxtgC@a}28-Swg$|UJZ zvf&IGbzIbME84Z>sC-b%q2r)bE0xX1^A>s&nlQZY(RhQ{bY%BwRX#}?T2c}( z5ikbkSd~z(gjQ8JyApm_j7%3GzI;V_P+{oF$!dE}SDE5YZcf?_k%3fi%yA~%EBHYb zw(*xF;&@gy$x|IgZk@1xc<|yP_>?g`)S>f=ab^yol(mOu!kRHtnD^I2xHsbLXDU@3 zd~?|`B5w++y;8oUrp)b8Z)8AyNOJQZylJ{K+#Iln)*YytLrtnNlJY!MQkz3Z1CV{1 z!+aTA6v-1wRad%QXv%WU;cqpT6%hwj5*XY`uLjbj8WO7Zb5Rk@akqtm7^TGyNcf?5 z!D9E?9#oR1Mhd0fsN$kN=R#SUuAMEwPzI~dv}ar0F-QTnf(hhI;c_JA(Ur3q3?*>G zA^7U7*s)b(3^o?FDsB%+IIV_6gG4*xM$FU@tLlu&Uxxfgy|%%>TMOPD2$X~`HA1IAj|dtozrp`2d1 zG+h})g`|Qsp?Y}aQw6k+4>f|^gdI=s@pjPI#9Y#1s89y@**sBAs%L)G~M>CG=Km7Y1uRtEzG?S0ID*4ny7CH!@7V+pFoC)SXn zW3IeHwFO#mO-(;!CQFTFI<;JOR2Vj=Ht1QUYv*6S!)`D2WC!?b{4h$(R=T{cUn$vp z0dzw`!- zt&YHo!U;Mz8xzH8B4KHJWKs2$m2GxV>{#~l=-b0Mjn4ELqvEhfaq+7jQM^l9^gN9W zm&>RodfA{DWT*B)bQrS$QhMqkGfd+*doD2Q0U%0R6YbLvZDB!fSn)14-LxWJowD~@ z&mL#V5l1D1F0N)X*BPeWZmT^R6qF<&O+c#~d8jgj%8W9n*LxjCLq=0u}8%8{EPOaI|+aX-}247pme%54I6Y1O4G>aP%{- zzDb*6&|v4#ECq2@XR3}<3TH{Sk3S3czG~UgYF}?gMR&*Ml)Rp*rN%m6-j;(VjWQK< z&iu(Kt6dLIZ-uL zWeiN7W&LW82l>q(FK#E;?_FBXSBAW;8aaC{S(vh|d7aFJ2uFTP?XCJVJDDeyOI!Qy`>{OEZr*#-pamwjT7mOi91MSel zhP){;$DB25EgrtG?yTVcw$G0UCA?{H2-46%;cRB zUe1ioOR_pGJ5q?wmBV~bRRel8fn{`7Q347C7dkz1;*W|W#lhaFQmVI+99mp052}q! zkie`)>Yt!CLQ8z!jP59*{dW%6a*58N9gj#Xf)axZDZf;sjFhwNC|4m;#DQ8Dr|Vca zU`^C~W~Qv+Nd?6 z*e0{q$kw`Xb*(Q!Q}zX+PdyDQ)OGtmSmMZ@J zYgophjmI{R*es&dxBQ~oi55~1>DOrDp$h9la*dW$TnM~NIk)R=wBV08hNWj9+W8$VPMwq`xG?m0qYpn! zHEjas`Z4D+ia;?6EI@)`OZroHIc1Nmcn}cgdEnGgv!9kXTHV|VEVWR*Bm3fJ%+w8e zwO|<1Vo8lpDwp#8n3{R=G;X}-t0mr_a zqJgH47I&Zl42Y&tHb+IzUnI;-Z@T3c`1^nQ5UgIYLJ1_~2LmWrwriFWj-$&GAw(g% zMfdt3bY~(_zQhHeJx1E^@A5(wdanVJ7M?4WKU^$ z3A#ztOs}RLG+D#cl?HpM2ahw&q`N!rzDK5I6N2T2(XcVccLZn9`u;r2;~HhNE}?B; z=Ee6IINABepiIr;UC3&ZPE&By4U|dm!8G+%J4A6pS^-ltgQk$_q44=^Bo@;)Bg`b{ z3HVJnciefm^~4i4ilF*a^zDErGYrvA*+sWlQEunAon|1oj$<=+MVb_wMWCuA$`)3o1bdJzmdp^O_hJ%X{~xBuG8*D;ML2vhW~ESn$$3^2`{dPVa1`m>w7+& znTSI%$&H1fxS=fSv{hlEHVqem!rUb|A7Du$b%5R%w5mKJBwcfpunz`ZYI0XOB|?6B zb5$<7TtUXD-c=JDdii1Y@oazje`v&XD=d19)7rGu8W;Dpx?L}qIXkuTHWB?0vW#9j z6^zxbQx;!taQf-nKa=8jH6d09F?!MwKp)g!3BwpFxkH#nLP2uRZ21PNrBPj!UVMb) zrV>D*pZAij)CZh8=^X2JNkCmR2+k*_dr4rmAzdD&q#gBJWlp3^6z^R)(OUo|1q zX;`d)vZP3_+wDfRbpTc`7dis~iJQq9KQJV0&&Fq^DkZ*vsK=O05; z5_&oAoAlc4PXUSxm(R+na@1-%1qdzjB#GGED4$s-k!B(_<`WTh>ZI0KQ11x|+#K9* zMGIImex`XIshH#m>^-e~ifFAOb7!LheWz``^&P6VG%WJvMptST>&QEluZQjne}B9# zLUTnO)R3UApJ8glBR{Uq=|DQPN7Ok6!;IguwU?M@;Ks-5QxGbx*mCW)1WN=K9_ zm2uFV4HONK8Y)Y&!!DxkiJU-G+j4WjneI$}FgS##S`Q;n|Mv;3K|6iqB5TF|>2x}* z{S(=qlud2&qSWI349N`iib;i6glqe&7n52d+gA8;VC~)I2Y+nUg*V~LWH`Mh(Bbq! z**M5xvoTaciJUO}DZoq^-hPAPO`=>~H8zq&-Mp9T2}h+VDw9YNEU^hhF*Z9_ZJKJc z18)Fl0;In6hE9T}fCO%uLs8`x# zjxt%mq04w`m8F=Y5DwB5Z0gJ$Fj=Bz7Ts-bvLsJ! zS50O#Si%N?Gk^?B!;)sR-#O9%SllreB*~FulI4kt(lJ{-k{-uuOeB^-mko0%eE2IH zRI670PM45Rn77|^H{5dPov>$esy_}3kT)Kyfe3%lGYO!XJ{A1Nj)dk1s09jy$Di;x z_`)YX1_$i34~UNN8$-?7hD7!FNNs60GfvkgY_=J_&49B=XbX;DTNZ0RV_Qt z_m?q?#;jFj7pN5u8Ic8)%;J^D5^EG=m*ZZx<$r(eEAWSZ^lrwWC$s$B=yB+CJoM&^ zqr_QGRCEzf{$09cDJ)#D5XQ#Fb%Ivf899=dwOp-giGc#e%hE}5nOjl=WURYTh*HwC zSSs?4Pwl`e!9){WNiQZ8&V_PcWH`UzD9ch_S_EHm5vg|5N{PpDOWH%f)`4R(JJ75U z#>W=GvgOOfL{;8)VFdj(>q%4m$R=A<`!pDp2g0I7i(%=~rA+;TkZr!Y{U`sV;OK>v zlu3zX(snGv@Uj}%l>x0-6$~1)Gi~yz{E?zhM?4%^$;EUWW`zwhTc3~UU39-T?lfh; zC2f5q24!N@d`9JGGgkx%yJ5~IKTzt;Wy_X`$-QqB54kABo7p*yrZYC0o5HeHL6R2+ zV(B>)12Uibp4%<4JJOmdDW9h;G-Ajjy+;Y?Ct%y5Iuk-R_q$10M36(!y$#r@nvfXN z+muaiDBXvqrIezG+NuJT9C``nXI{p0T%*GrBvd;%?jxyyd6gv+g3?{1)8~p4Xd0<# z4zaX0yol5$RwfNQ%+_L%T5=c6)z)tt;c6hM@O|cmlF;)V$>M{lqcM>Mjhms0Xx`3@wR-e8WwZSndRS;6~xh>LU!zsAk1f}DN2ri~)cdAfW9 z<<8jzkE$$sGf2M=Gl=4p><8#Pvk1f>zui}sL#Af((;!t=XOx4jb(C~#F>kwAMv_#o zt%=tkCoTiFieilclP*{SNLeL4uaUkG<&wRmL;c6Jdu}|dmUYGxZBjJag#V|n;qvWW_XP-BJ|JaUXW6s9VG z7ZfUz?9o(+$eVck07gFyBf?>Ssy!Zq^xUi%f8RPvHG3MOrkp@x1+@#*42DR!_6Fu~ zk*XzHBA4R@HnK*?t{>nqo5!9$nr|PY0nn?KA$37DZ$vq&ER{ivhCx(w67>6``99Hf zkzyPJjgX*Sse{T29i`F$L6~Iekn-g0+dUUAQJm!)_}P*7&Q8Y-=|;>iyviRGJ=csm zHhctByEzZ2IH;C|%WQo`ikNMLQb;H7{49B&D_=Q`&@=%4gr)^JGqlw%by2i_E`E)M z|9Wjl*5EH$LSV_0XnO1yj#|TBVd}Pxh?jd6Njn%{wA_Q7Kv$>Fbwaj%OYfkf#`X>f78lhC`nAm7)idjtiBqpCrKl`;+I$;2vGVl4MI~f?k2n^r z_ZUj6mWe09?8psQSh4{$9|eD9iq4|dSU#=`%&8JH+M%+|qtGO77sm^l4^#&}jrV~* z`zGSp7~hslC?lrqzn< zY{u1KONOpuDhDY6B|*ET2ixk+V7`t^cfx1{eI`>aL8pmYtL1YQb7=WWFM|_M4}Rx{ zF)xvI6=B$|CeWI?yEl>-E~nK zbwJ)q%!9+z{7xlz!YI3$JjdIeiQG=upM>P#p`5;uz*YZL%{0Bjwz7#&Ta-|(qyQ@h zd<9VblbhDiyOoCW-D4NX{pr(ApEMr;0^~N15kqb18KhC!NO2+B*$UvB&QSzi=MsUE zF-U$~|3PtF(H?089S}I`5G9XTuZ#OG2YsyBL&Ix2t1Oc4V>Ku-5;Q>v9f_p>sYNmh z_XZV<0aeDef2M&n3c}7Qluf$@;!bcN5X9QEX+p=^(nEcgWh{T4ZXZm4$pbNUhn&ZC z8V5pt_t^U_`k_ftu3z+84!iw4Ge`TpLzyI0m|hVuF6lI48g4tl%3%zV>$HIJp z=|!>@#Sw@xvqP8HYr^RtV*62iBM6-c%(Aqm27e%jPCmH_S-{e_Az;Pgq0A($GW|03 zN8yq(kg8Kgz3yvpNp7tItM}Q^n#PC2?QKnxEjMXzcHDj+(Q+tc0-~oLb=3+*Z*nb~ zqk&%QO-`Cr^r|>k9%cI(CAwnr!d_89`tr+$|!;<3V`i=_A)H4k>I4^2h zgd@h8uZ;+AcByg6Cp~i|&4^igoJc>N;IzKI>;W}A%*gZfOJ$N*?g(<>&qC-`W+98T zDJSpttu*1hKGbT1*m_yfbP~DpQSU6nByTNvuqtfTgklvfav@rgUp_rMgtkh_H#)c_ zaAX1s2Qxtnm^sRK^~X1Pf34b31;41s3|-C^j!M3nTYL@5j1J3N0xeP|C_Steh+9Nw z{R;-@P6+)aRq#B{bSZ+Nr;=MZ`eMbX`usp0I0524x_*yb`w2-f>*DgN=@o zu}oK60`!){C6i?C}0UTz+ zm*}<3-rR;oBR<-Hg9QiOdbQ;hy)jS&`htk!0NTAkpftJluB>x*#gs`T3!y#EL3Y<= zsdv9zd5US&SGl;Fynq_VvXG*Jc!mbd1rlz*mJYL$m${~MBW9MM1m)_=8dOqlB3b;- zDwVt1qGl&|L5C?t3CEE~y_rVNoEE9QaIQ+b;I}=# z27%SLSQG=R(+?E|?5m4<$gWP5=t(COhAP4pOm^mX?J1~dh+&Fl<*7`e@F~@d6Nfrw zt<#QJ5C`k0*(`sqg-R|ihn&qU69`^SRU4S8=uqplbsjAmgAz8!I_2(Xhtle{FJir3 zvhU7oK0`1Y+i?O*k4UV1?A!d}>SbNb)MD15xN%b&0&+iMM=x>K4yA~>Q3V2PCg>jo zj%P3XN}pT<6@3q+>HI`5nk^%iEqASGRd!`%!gX0Qp)aGC3{mH-dliZ#hdAg-6APDh z7^pK@-vjC>eOk-AAXMko4>grGxz+_llT2A>mPN$yTl5a&IAIkn3YAjRI`WcMu`W|} z=nCaT5q}n~PFt118>6*0a;sEmy~NQMJPb-;bVc4OR5EDp1P!^9okB^+RymX`QM|#a z|G3L)pGZT5@9U7Pcbe$*yEJj~#~MB^Y_(#}Wn_{5&ntdznB=rMc_y8QYIAGuDoX>3 z23YAB;*l~PHC7&y@Fwh>IivSJVB0FJEkxBiE|c#81-B!qzv|z>MxnbWz-1bnb}G1f z3EwC6l1#grQ~|u}PV$m|%5tD6tAt#w)UP5ci=QN7itPhQV>haBkoQ-k z);c1FJVi;>W?NXFfibh4IHsp-UQM5AR;CYM#Ck5eixnvcQclGI4 zBu|UMqXFt&!JAyJ;P`@8(Y3GiqLq48vg8Lvu&?i)o|ytN;mkTCmvD{}EYEc0h0r5W zx^%VrP}93k!gfJG`E-3MCBGhk&c0CI#L*fh&OmV~QPUMValqWOFu7*}sM@bV50G_8 zP>lFW#4u>fkduP1YeNqxrr^H*hMVE{-}NW3bkRbU1z8Q}fxx=?J4;8?03U>0U4GJI zkAvTQ?Q3A&x^>VL!lWy)ZQFME_WynlF23|q(2EjOyvFxok=>k36?s^>**x9Q8aeSY zt)RugbfmE{xc7kvN>?GW#cgFnL&OV;I^%HA{`=eLQ` zD?)U#p*+vG4_TeXkih8 zQs+SWNkib>^5~|`@SPu>%Q`qQj@3iR#;(hh5z#s@K(K)Q-tv^q@cdtUKCE54Ry}Ws z*%V-UdJ3+-=4$xjSHBKvBAb-#2_%QmibNii@MGkx9K@i?Zzt-pX6w%^SpvGXc99j4kD zV+{N7BM(*2<9E>e1A@y+{I{x%sT9T0p9BU{B!a2QY52<5zX6-J?S`%xZ(@1j>``!r zX(n^B7@3h0GJ3Nrlrcw;V^OAQMKIz0+tne!iL-PqncL(cR~go%ZKcQET%eNx=8|`X z6OjP1ni&-`?nHqCuHLZ#D0ImbpDC99!d0cRXl+U;YoaPi7FJFEJ>+Y*ra;T zONNj$*?JOj=D{%VI+rea&%$ldBq%b22nkxtQ$Ar+LCE^Z((bcSC|hQwwJ##|I7#U{ z^n%)pqZsiit`vI@$l{2Z4l`RFk@c}*={qqvrCUfLH1YQi3O}pkZ^Nl~lPIEPzB$zq z>cl$q8Ov)&jduGh&uG*p(u%`21@f+}@s(4(q6w9RSgB!5usTVWzZU{fA~r_~o$bs8 zVEHSm4hGl*0}RV-;WutR5J59kk_I>xb8KHLP}s|8OJaJgghNXO+rXnkWOyl4gE@rO~H{B^be8?v)qN8CF%IO1uWqcp{B*z zYl4QL^^jo+u#lX{Cba?`ROn~U44^Td=k^x7<^XTPZbw=dMXW}x;14^^;4+B z=20{9h_PC7_e3t;;su|+MO{0oN@0i^@D>7fR#`qpVK&c}$Mut$mpMhn`xuM8@;ptrMnbB5k=O%#IHpciMk+h*7 z6f z6yG+I3klA#e023B`d`!wkO)~J_$+J2z%4&TN@*%BJRcX`vhzBrRz`63}icpmd8eKmV+*B_bW z^?$mZ%K39<#er3YYockagHt%5{iC|4cKf=>w{QiF)p6>S)A(sexzHU+HI>ouPDT<6cI|H(_d=>2weL%Bq%GBIhDMa`F@ zN0br4z!*g25*9NraDkSsiVX445}@2G!H&FcEYW?g{@OH5-7j3SlEMP!Z$Kkw=^)oI4Df1J%87pzOs&=MJ({NFQqrEQ96{*Vcy^ z@=*10TtWsz$aJc#J}At3bBd8NO-U>SpH#!!bPqL~M`6a*&PGJ1-Aj~mAyrz{`j1F3+n|lJeH=_b^os!z8c1znl!z5+YLJ7_Ti!@#V{|-tU z_2s--g(D%(W+B33M9&|VtL6a}RdGO;*@6Y*@bmM}gY7$a!Zeq7yQ$(C#bpdh*!%_e z>w#!7=uVQKXuU~4G45eO$xxJI&~5@sf~L%A6Cd9n{LqKs%U}OGY}vj8s2k&1xdHSd zaP`@t5h{)uE0}jXvdDat7_`5%EYX=asQ5R&eC@T^oYQ%r)J>}Ixps`Gj#<(+tozTi zIJ==EA{RZj%Q~?BD%!}>Z%L^o>q^BXv>nWjOhc|(u@qLXSZ1Y?09K`e)vca}!c$zD zNl7>(ldCX%du{cK73!vXs;Oq1TZr_6RELC5X8e>Tqah)IjE2}Q=1Vu zt;r6{8^F{S{RbY<&(V5CP}0>yZTv=-{eUn&KfF9C}O1nZQ5J<>q zsONrC$}Pv`xq$QlfKF13W%K7f7@ zEuW-jexLI&{&V<0NiA_s!d|b(1h?~!ibe&`inx{c&UrDM@)S+;v|?AFQ(m4{aa8e3P_d>feOC&ig@pWZmi;0hSsYnIDt%jAjtT{G6UcQ{!HUPrj$4$Z z-PC(IN5@_XqRi~VOUTh{4CBPkxrSTr6r&lCF$u-j4sCOz1m^{f0>5yP>%U2CX4&c&y=9?4NBQL`L)bzDgYzC)CGmAKPLaKLa|1TP#7WQ*dH~zY7CC=< z#vnbuk-UUF({L#g9Z+_95M>uH%~iUpS5GuvqXZff}u3OTVFO%E%c2 zP^+ws(?_{fCs$p%BxJ79qJpC4f0wnLMfWfO1QQL{v+O80dAb&g$dpvPlxT2cx=E1t z5kQF5T}7xk)LCycYtd*=SZd~vQa6ZQu|9j*%4ROmOCeCRz+u;diiKV(iK7E!hrwUH=?-#|abBVQ#GP>YM3VTsvzBhaH3SQ*XfU|E*Xj~` zd0#2s6@bdyt~{p2jiB7pu|yl=GlNo(ea^~+ip%52Evu5338r?N7dJ;PKhUc?WMd8G zm`in_IV2kCQ_ju#;>hLT{T`*6OfJv$k=0?8OdegeZbzQCGEv!xtg5poBCDgra%`c? z7yPUo#w@=hQSstkYe6uJpJUchWo=->MXyk^MjJ8tdXrtF2-8k|)~d^>j;D|KVm=IA z>xR79Wso-kXCC4bS1_rA`D9(L>SAjI=g@p!40B>s4T=W4jMQe{jvc#T`}XZZpP02G zcuW=@Ns=SgQZ4~#&kjf-$2(F|;rZ>i@4hfT)`1rD1-39YS6~YpaV3wqG&Zp=jqPKU z4vi_>tTOaYqv4)a`<`>v9|tdXf}w3rmuYGhLNE+~Yd{lR#>owmZHzJh-TU7UpZN4= zU?#OU$S{{Gc@ni=wV;)Ut?kGJR}zLbt5&UmUtDkj9CpaTM%@+eriN(3nNTqBLT~4k zb8|K(lo`;fZ#l-`N0X2g{?gSp@#*(W?&W9Bi$7vU)W@cbdm!Qk?ODLa!xd6eN z+({@O(G44%I7s+wpd^v^S7Vu-jaRRT?hNY9ojNF*E78WJ6n>2+ME0u){-S~G#*8p+ zEKJq9xYzd^XHTa2R!yCB&^8v!oy@1A+`-*nz^qIp^Wgggh-9T#Zzr7 z4#$5j|Ba(Fhmj-6RY)8S_M;#R(LQsRNoQt)A#Zkrsh3hth`(L(I2G!nBOysD|18WT z=%x%60qzP zq}-!28LehQDRHHk<{JhFS4NmQehnA}$+ z)m?d$Uo40;_Yv)|pF;}KwjOFU8-(lN(jY?~5F54Ttoeg7CWyhG1itwj7KW9&W%ZW= z4M_fvvIeeDX9+bWY0hdMtEDDX!4F2tVkG0cRSYV2LJ6ngvm?2P_4Tt^yqqe%kzrbv zh+qF$M`hOJMG^gh*%u1Gm@|kiaV3N1O>N8K)Yoh|XrTEo8}vgg-@Gy(qeR7;qx4SAi@ux3!q@~oP*?fJ`YZ~cho!!13{LX2wTpk%H!jxV@^|<{*u9%zeFi(w|Yh7VKZ0=ec)&^Sya+(Qyo$l!=saKm)PtoNq zx4ob_hHTb2xs6>voj&^&-TW(I)kDj~**iZhIj^+d8zWj&(`@Fh*3G|{Ay;StP4hrVF$KP1kEQ+S#ikwbYU(*5_{R@ zr;X!!^dBIkZ&-|7Vo7BB*>0Cy-cIpbi@R5JZ}G%|c_Y4LI4WjOew)C(;K& z2HS#pr#^$pZO>hNju@;Rvh9|$!3Op z70*Te@5rkUvGk`zlV16#ungkgL@%QU)M#iaQV41+*;O2qj-M_B83S2W5nDmgi>erl zqZ(x|%v4)=*o2DKpQN8$hk(ogAW1sVN&Hpv9FU+jBHg7{GUybd@5vqk$Q@Fyn@X`k zD~`wpAnV_eM9y~Cwa+PxCc=ABL&^H>lvCJSSCn?x8YjuLyMt^svjj#cH($0<`jT>K zsi)o?P_ZY0_P$P@VUlG(jWy;?UpW)(AM17ekl z^T0z7!VJGSc217F_%g@48x1*W&q+wL4|9kBh6734az}ZjrRNHe9-sn4s!Jp<>obdZ zdgyb(wrql3Q&T3)oEdpkPpwzeibFGIf+!>L zS(@FP!zu$VgS7~S(F1x6hYG$!shzN`a-ECvibS~;hcJpO;)z9qNTI@3-_N4bETcgz z7^;qLA|Uzqz>#>A$*F0$<@VcQ^PUODbfu?ClN6HN7cilrG9N5_YB3?l&M)ywMCO~L zMhmUf)4W_iHz6jqrc@ka$xB|7k1mM&`q2kfhR9AZlhj70jdIm5kaTolq0&p@l4=Np z--M5MNKiP*7BF@!2x?^wRrg*NAD(eb;}7TF`a>~ep}S2)%h+y0KnXQxjj2MsB*_yZkax-YCIKk)5^3=S}9!HLr;Yu%G>St z!yvqqebFd4>##E@4Q1_Tc{VIQICFL{I1YmX+1vVnNIirzbW@<{Nw{WTl$EC+!7fM> z5$QECD0|F0oK!qtin;QN+pSreBDe_M5R55vXCg6$_#A^7r7}AP{kUIyxeUm zJ=O+KT0o#SovAgJBc+c@0j{?(;?GI$i#ddBPK+vf54U=cJ_gDzd=R89s{S zJt_&;M4khgN)6&u9^Pn|`9k zCP4=@X$5JI5R<~t6K6Ho;7p3npV@;yhKknL=0}kpGuV1ox-MfyCy=i%MF?eyFoNT{ z@R(sh{ZMiw5laWT6%NYa-U@`)(O~i$uauOVm;^Op%{6^Opv0Q~ypE`{9Ijt;bpJa0 z-xQr-gf9*t$IM9dmHlJ%Ak|?0fD&)i_g``(;R{Sg;fh z-T0m3B;L~6gc}gB&Qwsw^{n4f98$Y)#o|x}ghJ%$`KhcOBhbhmLGhTeSC6x&LMTR6 ziELKdZ0SAO*3F?o3EDN5gc{TLP=RX6n4KjYyo@GS>WRnH<|a_NRzn)jG?Qthe9^zD z3?w5P+yJb~A1ZW0=xso%<@bP^Llg-M_%)Sh96iMaP8JS+6uM} zWb;7IJgdg+QUqmA7VSXGq62@r$`uW*EhCTdmeYZr%=q8L6f+pIkUX(Om4&&Vw&lR$ z#f#v{PkbV5-nt!%EU?|X5G6x5mn&HFh+Aw_JU-3b1{ki0mUm4O8)e2#hxkxIeaPHD zn51NBd=PT0cmzwEh1MLJ7dvDW$$*n2F~4=ryk{TXvb2RN1 zNs9{Am&UU8PMzroU=&Xg8YpTO&BG~6HLx?2>DeqN#nlG|zRg9rJ|k>qNnkI-^8?dK z1wuB%E(&EOXqrKzpL%KGi}TNIS?C9tPr=FG=c860(IY4Kq@)gcU7~`y<4rE13zU1!KqF({LIhGi0gj*H7T*w>$5{0sQ!5C1D{-@PY)d_NkL`>kEN#!`2TKWI7V1VI&LJW7zA zCk>ZS%;=J?$PJ>=cU7#r(&iF0$I@QHxD#~92I0W7r;s$!KT~!y$;P)3qM5`r$h#*n z;)w&QIGj>vBu9cfxqti#Cs>S*obm+o^`%>*Dp2n<$4)GUtkch3N2NL?_8|y3yvW6LLM&wwa=4L*0LYAfC zqO8uDG(Pg)IH>$tQTglCDi;>R%Wt`;LF-gogK#7$J0A>Ovlag77CSEq1!9NCdv3z> zm*%OPfL{*CqxM7)s+bVC6xSo2c>%|AhKR#rRY?w^u%Vo$0m!K#Nm^eD~9vSXLMHlEHBKZP}Uo0OSEc|@qRjK$#0nP;*g%i zmX@uy3M7@q0i6~GUPX*|3PceL%h9;zFVM5HJX$vZPiseZ<&H+q;DMmk`z3h4~asf|xOH zD2v)uFLU8RyDV-RJk6q$qj^+M6G`d_0K*~men5gb=Wcp19UMXJc37+qENKHrziE76 z_A%0&Kvf$N^gbQQcp_WW#0mpyJF><#I{EuRN7A&zQGD67N=5&)rA)JOfQ-JB7^=M@ z64vq55blGpJmQDTuWafJ?Xs}-yU}jrVGJND{#eVFM2~0mqBe%Ox>j!zG6e?-2g_(B z+-OM~gOEv-4JL}sLEh+k4kB=GdB&>5Y9O($G?=TfR2)Q5bqk2|y>J;GSfUy-^79Dk z3;IJQd|@EjJPn}j9~5&bxn&Ega*7a`91N4z<;$!ksNCEnmtX1O&7fK<3ygL=aN`zM z%L|KJecbF3fh@9BP%_k*xjiC5IGp z@u(<}`!&c|us91Vk6dm}J#K%MiolwXU?KD277tsC(JWTK^||V(Uzo3 zgg#*ho!A#Mc=2reR(};`Pu_Oe3Yen`YJo!o*wD=kNn)0Mw$xiAZ0?oTU#dL)rMfN- zp)vt1&%^+Jh04`LyONWfxe&Jk)#QM=fBo$0qj`1NY$5Wfw=#6BGP9dyh|;Nl z^2b5@Ot_G{jdq)q!Yg*ClbG6|AJAX^lKsnGdQzPF)J&pMp<=6l2ZIQPTX_3)MOg2Z z%uO<0a%|4f)v@Z$C{IaX{9fb^d1UEei3Y}A0Z9)PVO2>y$nSLZC@wWDc~f4G-jHdL zp;BN%w@M?2Y83}*{qtzp1(reDE@J#KohI_+|FE9z-?7SULrb&6S_ANW)JCpgMgZo* zfX0sdW!~as?S|P$R4O`(QW+s4yF7NT&h_&STGnW|Kk9BlR*rChaY99y|F$l^Mu zndVUYRH2S?tns`d8xakT3ghDp<%SdvbLy^C+1UQqTIM_|AR3&q5^E}}7ROLcDz?JU_U8q4<$K-v`y8Nn|llj!Jz%HN6gM{Rp2imFt^3*s~Q9>*XYrFTfV}w(3sWb?r_&shh{_V1%n~rUDN`W#u zKhdP(Rsl;cl%aq&urRQzesRWU1+hX&SZn3d>xQ?~lv3p0MLqbgNXk&jpb@%^o;z8p z&6l@9@WQ2XnQr{UI@&!eT-}aS;gxqhd10)ia`B&~ik+M2r(^qL%!HwV&`e{Bk|okh znf#U5Z=jrc7Qydqdjii^aFqxD5i*yUmDP=GW5kNlZ!uyjn*~E@)R-j-<5cBQ6t+&D zb>59OA|z;#N1UpNZ6u)djfB}Ug{vUUjVBEZddm@y&O_Kj;~a37R0^g46&9KZ!>EdO zU?loWm!auAbg!hTwfP2vgLWV!GcO%BawD-LT@#pq>0IU~a~hdHCN$=sjdw-O1S=Ud zL5I*@>Wn-Ol41#kmR&!a?2lfns+t`dan zCCQ^eDi%Mjr8wGZj3Q7(7;9YBrk|3s_5@GfuUJ4RO0nPgrd-J{-vpn`Oo-mNQu zZUf=G3MI3i&G|Cc-KgYn+}?MT_0I~%2Zuipk<2k#G}1Q2`#_da-6SEI7ra@3KuHc6 zBW=Xl6qiW4T}Z~pgd|HUFPXA8Q9}4<&#-LcL2dm6Yvk!}^KLcKNfVKLG(c| zZKeob)?RUPxzDb_^{gPwDgLtyJQ^+T7vlF}j9v09kz*>s>#ldx=~W^LZ} zhHAe3P-&!8-xx`6{S7Oe4aG95|*K`zm(L~~rh`H4pjk_wLpm8)+ zqX|-*Ek$q|iNXOK)o8fB@``yYow+>PdYOD`=&3`C{Zy$Q2HR{TFEUNLay!>4FS=i; zOjk<5Xc5_it84aO>s#$lNT9rE`fI6d?v<52`8-;^Z+0Ca(hUW=JWmZP=7!W5(9FoCJAJ zUCuNqb28O@%SkI9P7f(jfkqRputmC3SC4AQLp4Co-KUnl#QQQ%%V;&7ksmLNe`4O% zE0aUEWmo#S56V_2l&gqcV}t;+$AbJJ&{lzWl^D{-V3r?b>M$su1AB$ua)>>!TYZvH zTtDpHn`VyVj+)4*28KB6tu}^OIi5&Zf2PKH3;vDby4qDZ%OGD`l4B?l(ImOmjiO4zXRe}I)c#^ zlQ|fX*-7(TL~`n8HS$QQH&7ki(AC!qKE7<`H-dGTls?W69B@g^XnPl%pp%S=yWhmUeEstMAas9o>pqry z(qYBuh!vGCH)aJ_dLEs1YNdi!pXxZWv7{Oe<)oIXwm{tuSXwl(;AiETp}a1hjN~tK zl(IpVCOLW*07nAPW(deumHd;RaCJU17pot^H%CnTh&DM`4+HutoxK_}lEMn0$DWRA zCaKiTPkR9r;bjIy_96SkX)lemXd-sTEH7sw-0%96Z)1qm^+Zb0HmKzJY%-;cY2JVD z{qVm({1IGp!%d=n_5C2I*VB9)CK;2_NSt{F%{a4{@>2L>r_?YB00On$g3=#5CM`+a0Xh#Zn_rxyu;(ZFk%SU;OIV;K2P3G;OV2m71JT ztAG?!vKWRGJd^~kTrrqQNA(FB^_83?6H_e$osqs>+*tjozDFaQ<(Zw~!&Z|R_Gjl0 z+2l{EdDDvfM2NgEXz_X7f~5GIy5>$FP%~{FxQZ*a($mTNp{7~CTzuITuzPZ1FwD6I zDmhAL$&!zD#uxrB+a_Gp6|JN=o9)=w{MEhNJEQU^-)iUvml8A|aAR!LEMBw_7LG3v z#GKo>vT4ocQQmK7gaBkSG|JGNs5>A}!f)HY6DDRR!6hRsEj7(@=iA^VUAAN~EFK>R z?HVJK+8|>JXb(yRRh2Y;OyECw3*RJOIGviHs5>KY5@0i}U z>6ohEkrK4_XQ3+P)Z3RV;^Fj%YJXHy8db&!a9AbzOtZ;(dKZ`4CY{6$+b|Lbn4Tdc zC1v)y`Tj*)G{~#vl8m`j_Uq{IW&vK;oqHx=5Bu;+*-R6y3T15)u!!uUaE78GD*Sn3$S@J=0yc zZ3xV&MEuM+9RS&?2T6oEehY3G+Z#5i!IdkPsDcV%Y}OMiUB7MeLWm<}6L~FbwNC+k z=m+_(F@7UK3r0E*6W%0dF%LqQ-q6oV&jOkbHG?0W!P%#Z1EC*?=0+{4=?+X)M|+K= zq%y-u4X5asve*K$dXfnTc4wKx5VFIw(&*S&P&G6Z=Bkh=AKywdP#Z9#a8#sdl7yLB zwuwf10gGrYo*LwFZjwE~X9Udx$!~I-p%mrmGo{e4P#oRI-ZQZD@eaKN3acb$%4O*E ziuDwo-b-w?hX{b#Te}}gj~A62w|=r#!a3hISr&GI3%+~5bEHIBCTP>0X1G}e#N=VC zcydiAEe zrTJ2w#p;Q`mw>XrHp5i}p~jXIRChG$w5|5AI+Kh~gN%@cszuZ>5gU`KjzswqjRtL$ zOfFT0qlkA{6kt#cx?phXw~bGhKE3&GCGm>Q$`l=jDODU~e8flrMkYy`#--F@WJ^c* zuqIjV9#=E8BnvGfkV+#XQ;SiSPF4g#v&@M0%N7Hak-uuHY{OM&LncQvfmEd)Lwo*r zBa~6W``JUaKWK4QHu0#SPpA&yf7Y&A1*bjX6j-ukiCWgBAb0#TW=q{vZtjR^Y-XRC z5gRP}iTJN8muIq1Q0RS;=uBWoDYGclPXoUF@@U+cwy}YY%MSxeKP*_|{>J76P;HWCWz53@BIR zTwQ{^V0eQq)@?+D1dUMKSv|mNi-fiKp$8lY?|t{5!`gN0AnBlZmTCqGk{0-Vf8B1X zh%pg6|I;(mDj~HP(k4!z&20!A-@Fj=V;1gEp=PmkXr!iache@nO!89!#i*wyC&dJ_ zb=wx$wrx9X*su}SKl&&riP{S$8Eocuq=w`$W-Tez$ z!ymNYez5Pp`!EKrNsR)Nptp20>oUpAQHLoRrL*Pih_vKmo9i)Zo0yn{M<3k)_uh9e z+{uD0{X?9aARUZL(8@okqkqKhGHbojpttgyx zkUq`E`~(wbHZbAkp+_EuJMX#+?qFl#rkihuTW-G#?z-oG*v-Zajdeh;O!8eDnx^ug zh$jOVeVNlBEmb z@WT&=!;d(ag?S2W*}5HWy76YX{f;}~r{|vs7hZA+JiK88YxcxQO>_P3@D|{ZtS~Ck zdoa00MQ^Oq76i&gmS)lGt`u6*`r;*v;n2el5uYbL@eG(`4Eq5lT|aRD190`V*TF9@ zy8?cB#TBrAfl!A~k{F-HhIcDaW(oI`EUFFZ{_u*MP`7(Ii z@yEeq9`hJD`>dzK-S?aWKmN(N@RhH8i>X95!4w-4UA01;3k&O*KoOV55-R5fFbK%I zzj`6e`N^CTWjD)fwP@i&IP{Q%;eh@3hbKMhiE!y$8(xOQ2nF+@;?ih4*HM-4iI}+r=NT> zy!Mr^hHrlBf8ihg`NOb>goEUHgLt)3FZ!K|%^9=I!#KtMoJG&ol6v{EP6t-6SOL#G z`z-kK7d{Jbdc$wS+LbF{9HrGuwr{RK^8orlg79>t{#w8F#;Xhq&hNQ#^NrVEHOODr z)&H3G$wh!!8(NJ}WPy5+3p3nr%wr#OG`#gqZ-j4r^^5RpXFZv1W6c1TZivo4Fw&=P zgapl9t8~b;l6(HNF(CTu5>%UpMfv0z5_)S~$|>e35MROGeM`KpIOp&TLC!Co?ASA5j`5BjNm`3x zrGU-F+lA?_^no#x zc41~lnqf|NyP!9ZwArM#h%xrVm@)Yx`vnoNOxVCcgessGP_&p*!9~;J6$K@cy^fU+ zAR7oty`&1^*DEQ=Pp68-i{sRPE@_K9s#?YNZ=Unav*Agnp8+5F_y2^C{M*07j>!pO zvg=+&IWm*?Eb5?pFx3*?z)WXK=1eNButcP{4Xt-nQEU5%Xf7o?oZf6uX_EWWwwJV> zzWCKHn&!8SKCBzHkK7yB~7sA#eoS6xwH>ePH$KRj`V!9ysG3 z8yge4NIk?k6W+072W;B75jJnxD(uT2xbHr=``&xu!AI7^BkVVKc*E^zrzWRhYGwxH zadwpe>CRI$Hq3@2*&fDQV&G(+ed-UZ6N{3W%FhCjm*$|EnKhOu$9G+SAx_b(L8*23 zLJOO~isdWd9dCUzEM2k${{0i5fQL42fT`&jAQN~r7<7Z1gsId)3;t=P*+f099${Nv z)_u~Wyf_&R@G*V#(MQ0CKll%DB-`cw(pSF@_dooIlJ;Quu*W%M-}TB!c$8q$?V2@f zV4pRsVgLR1hsPd!Ec-kLPC4;JIP%CNVeRVGjA@Tqyg@OZRILw`FK=@#f=Zt(hgXS` zvZq*_M;_e>x8HFG+Vg;M*-~4;O3y*u;aq!`P|2Mews;k*VzDv)EFqfE1C4-i(i?nGuLFT}} z|5_Rk7-E2>Y6YYH-PWhp%z1YxFF$905}?8|mX^iJQ!tCtG~H!tzb(k~+jreM_@j5c z1J*Id_xUe=8Lq$ecD0l*C_+;x(L8D1it04nsuj!O@WT#=V~;!nPCMmPc;XqS3+B9X z#Y(wyQj)B&X3&0uO}R6l6e4*e=~~XQ^iljQV;E-|k%RZ&7Y^BfKX}Gd&SZ~Y4;wdc zf@^NL9O-xj$x4=+xeF>C6&5*bA)hH{+i7TmhvJD4+5J!87r<8?XSS^%z2-Ruu+=KA zzTEYRTbE$6bXP223a|Uk*TTL`CGf$IeiW|1`8K9^Lm0k+hdRs27!SY5;HX27fRi47 z0-W}QC&0<4o(v}*cN~+TS1a8wSdyb2eeUsQkzz&^>Vdr$cJ-NAbE|SB>ZTAbC^Kn! z-*s!?S!X>B&VKsSVcU-FaO2H4!8O-j57+S%oR?h=_uhZM@QotcjWVVmQa=?hP-`+d zQP32Elet5Z#Zy0)bhJ&Mfwz!nSaw=P$D;hOWoHPB6v=i0WjL~e2RHdb)ueD*0`Hs_;AR5NJMzTGs6r9%0$2d?1rK`lqQ63;1KVqfDGFl2VJ#lB|Pufo&(!13vgIf`xijp;o;7tW}p>H&j(T=%D8(&$QGsKiv^hMxUiw{j(% z^`s}mlb>)JJn-PdaN)%l!}ovkW4Q9FYv6&0AIuI*P$1)`y3Ns}1_OXsi0qfs4rK+3 zr2yS}7!j{*poQL*bXwnySstH{fTI|5e*JI#7EDe|z<+-F)3BYXJJM=qF<3-q9iie7 zd+C{LLU-==GVQg(Tw2JkRsyidWloq(%{HXO$W;lidf7|i!TTS8&wc63@DST1lWsKo zcMWTho13Ipw($iE;l$&QV>{{3gtM4R;grXpC^q=G6^7_u(hgS1Whi9#c*C&AAliS( zyyQCXqmDQP4mtRhaMn|w0yo}zEByFpKZEc7@Q3i=0}qPRo7q)n1ER%wctm+tLH^nq z;L!c|hj+f^t>QM5kACc9uzmM#m7~O=N@5QUhfLLthfwnjkkm#IcS6RA+<%S@^1#@CARWh5$kWuP;yp+Lk_ zF2DLJ*fTw)T82d6-!NTf^^;Qr7H;kbbq3zwqOe%< zt_)s19H;9g!k-8GAhB6Bg+r=O0_)f&^jqKX23WUlANZ@k`#adln6$eZ!P(hhFF`#9 zZO|}-4nBT!oiYctLjjeZUJM-jT^R1Uj9LF!x)xW*r=J_>u6;v(AEFUU?aO@he|ujQVQma-$}3_hnMZc*`iz zEw)dy;XcZ3XjiI%$j!sK0HcWUh9}5y*x2X&hP79IX&>ou$Qf_Heb>NmzUmdwWt-7| z@mGJ%_8ii}DQOfC!=U97S+s}V%xG}QtYPk2OCWrsWEk^D1tOVW6W}(+k9o||@WJ=J zA6|9NYvID1CV1J4UjzpqbRg3^k1I(eW{}Sf@HX6M zpS7@d?HV}xm?N3`<4pKC(_jAgm%qwZB~wD8)h2#DyJ*GG1Rc%ZTg1Zle98FCy45S- zH7|P^+Qj}^j=N852Am6Mz9Nz!l_rmIx zD};N~z9uuqggPwxSxOg0=aBK_?JMaMb z+dqFdeD)I`gVRnv5jx^FF;c#aC36<_<(--8RTt*!m6flo9*GyvZAVJ1kEmBt_`%fr zcqUo;xm%jl`RJ2=e6w>Q+X#KtOJ54#{K9|1|9#~-ux9BJwxZ}-Wh+wG0TjKIV<64H zx9U&e(q}Fio8~c~)-&TF4dkw$>lIuA5V#P)4O>T8^Wzo4&Rg>sJD&BP_p3c#b6YkP zpbxatKw*Np&+3)%ox&~!f;MCVkZIK$m~o8VmFh&JMgiw= z!pKP%b4INq8Qa^KI^uE194*unb*1R>&KMm3*vG>A{`Niawl}>I4%u&CW4t$N8!AHq zYrn$|KNLRn!GC~1eCu1`@y9+^?$Tg(2TGJt2I_yZ#uC!?)bb|#JtqiQL|1*f&ER>PZq_jh3N z!f_^5$EqMu_`W#)xMSfD-u@PN$%|hIOBO8vTY5s}cxdlJDoh5KE?x}pdgmX&pa0>z z!~qZ#uzNyeL7{ybc;v9NmON_fuMXTejS^hCuBX(%*Jk+!c9f#j(=RNqT05F=9A zK~j$@l@vmxFM%CZ_#?`mtgLrh(QYO*>m8P*3*ICcOEKtv)U3fzQ@`K^&xa?TaYn{e z)h1Wy!{2cyMo&2P6!_CWdMEtGi(bGs0>@MiRGn{8wW#P}OqzbZO4_BciM>4gk}(Lz z7*l@POJ4*Z`Nw~N=REx^SjZ3Kgu1;~fuoF6YNZn+P}Rw$*AfkLHkb94IR^DYpjR-b zFqPdouXs7z{N8uKB~*E$V0}?pMKI_j^LI)5pAzO-=9kulf$TlWX5_j|hfyR0uoS5Y zdyr-NK=oguJ|Gndc_pjQywQ0l{pj0_$?dUUUArz>O zykIr^a9y%_@7svm`BA?Aa(w_5?HTgBta_bzYF*Sz#)uyoNvan!wN z+6e=*c_StBDPpO)37{%%=aUqCbjr4_I5uqA$4*CddLXS(B~flp=?__bQPHwCeHaCP zE{-0P2#Z;to%NKb!t>rCnwo}t@4FW^ZrJEN*H_hxdA}?5jKa6FDT^dF;Q%~U=448gk-QjT z5tB4mE?*}681K8^enMI$RZFnbF&GvDmvvjaY9+kng)e|>uDd=c3G;HEcG{`%p1*iE zoPOftA?fgE+H1k6Og6&>22Qh@ch+Op)o{XbkAc7Vqd$b@i(*`JA_P5Ih}|FlJ5hP-v5uBpM*5lqDjfg9c`EnW z%~rsC)s?VK<^|&mnUuO17B5)@%eimwg$t~9u$U*`LA_ zPdSMZ1{vcfP@%G-TKSdc=}$-GmeZ;;mG!H~4_s?G@`FO*V9)6Tit{YJK8r#z6Tys* zeazAD|6c!_aQ6fE!Fj*}wBd*27(##?TalQc^AzS^A7 z4yn1QVbE^EP^31HOkaN|vBKyuhRy#jTeckb+jkwD!~}pRKlw>;;)y2-^F?tnM}k?J zb>=7UxIbDxW2;r~**M#8-?i|Zv(ADWZ@LL?y!8$_xu#8WY1NTZ%@dVyC4-hj*neW9 zH-@QsPG`ZG(rVZ?h*hoHBUq;VW{rm)c@%EG<4%w|P1|b3&(|eFvY51yfV92<uSns$;>z<$h)xJ`kr@Kr+t9KK8Lp=lq9o_EXLj2U5sk3eEJnn^u#3T&Fz-Kv!1U{HXZj zj(;qi^U9aOU964ozW;v6PQCcSsi9`5mjJ(U=Jvbq@vg|=u<6cQ-8u*{XPpXWLDZTQ zwL4xuHW-uUmmyzx*%k1GuYMhlI`VM%b+)Se^%uN=2{y~Ebm}t3UdDtKR|$=0GXdtu zKm8fpeCzE@fPn$PObAhhtkgkcE~xID1}F=)xptTV^r~+zk0(S0>7^`@2Psk|E#^OD zKKwd&v0nkMmM~M@an*-ZiFBC?WY@$bJoxBFxb&)P;NL#+X?WSIUjzU3<*&l7J(Da9 zZ_5r0mRW?sZwP-P+W?fhWfb%Hp-kHU^FMhPJnQVI!-54Js6RMH7g%DglCxe3#H*Q` z=+R|Mm%=$Oe;NGNt6naAKjdz$H$O>9f7xfCFyjKnipAc8>jpk);Rn?x^jv*UWSDNk zkGdr+y$<`^fl2mq+ny=7>%m9h>YHzcZ~yRI__M$I8~EdQzZ-sa)m6~d_ecg0%M7+{ z_yx>|A9669`NT6|&C2D2aA@J=7!#GeeE_mA?{vrI%@4W>c-LQ!T=zuxlM8hM-&e#|{=IEouRZ~36)vH&+ zTi*Icwz>5zSTfczI_DO>Lf$;IeDMPK!*{$5&Ux9(VKH06BNowdKUCHO#F$g+MYRZY zzBl!;YeZTer%dD_`I%wD%tMhMiyQXL0+dujN{PvsQ1UKGx8_28n!jg31v0kN?(H}v= z1g>SDE}=DGvc3a2{D{Nh)RRtz)yr1EAHVYt;dQS%hcT4JqE60{V)2m^h@EHIFJ49e!imw(Zycb9A@NLFo3FG2bM2c2Jd?N+l7tvxVY?A-9TvBn~VM=P?ir~ zzJ)YUQQnfWYRFZerDZW(I&&M~EfK{S0%P4|hfORV0oLju8$;oP-m>m|Q!1-Yz{c*vI`L{E@{GU2@D($FL3Gy-=lQ!Z=s&rCir)FRlW0i847kK4n9n1B2D$Hi^+cd%8b01dNrC_EWH^O?^OoBgvr zE+TZ$()$zIy632qN!1`LmrU=Jm?us-l)KAjF??MYufZf!dGJdtzw(W5z~-%6hAKAl zDUn}EfA&+K3jgOfUjzHDSq-DGl$)QBD+qp&GkUrYnv~B^PBLwFMbJjPV9kUGH3ojHzqmbw9}btYC$tXVIQcW z;3elzKQLBme2tHBjGicPen{QA5(gCyv#VpXSJ?Zf2k@F~+O`$G_U&)OC0AY!Gh`dI z0XRxQ@bjU-2g2_Qf{b@MaKiDAg(nEFbg}9xFnYnl{DQ>M%xWvYax41`7=9L3^)b*t zoJqg+_uc@{Wm1_4j&hR@k$NjJR<(ISShYcz9hAwKV%)GERQsC7QyZ2D)2yuj`XB!R zU-;6On4Y?8t=_#jg|x26jvuxPvIh@8;xIV$(1T&YcqeCqI84-F(9IT5>+BK?Zvs$p z#9WwoJ+)umAq{8_YmA6N!3NIlci##B^_8!{-S^xFX&Ne*WYP}521!D}TaVR}Ss$PF z4tzTh+rDY4G}`$PzTUF1rG)xV<(X4T`^Ui1Dk&6fFxlxS28X70%33BBmNHU@O0Ks} zFaIXsmo?A?ZtXm^1uy@~WlQ0Ye*bN7%HvNE)&e@FD1QO@+FH1Lrj`P=3M!o52S^ev zNkff!ZP1gTHC3oFGBGs;|L~9h1V6pt0&$a#6V|G~Uo!GXNMu{-e&*l!<;Q0|?J2N$ z;ljaG7vq+#5jU!2DMn7Sby76Wd$8brE=zT?%gku@_Yx4;3n>VUw1z7O;f^gp}k zB6#*Mej)V2tClT?VZb@~GE2z%)|Tb6GVR#010H$gVOam@2H3Q5Gi=$qRou$V)kEAA zi?`pBMT=nh@};njwcP;+902?6yDzL=vj)Z&EC4Af0t~ZXOTilb*rShvKX}s{;m`l} zy>RdP4cRNjDTiUNz;j4Oz|T!7RD1Bv_D42uf`9wZPr$LqJQfaT60MfB2a+vFAwaNr z#vh*cl&8R_zwqAxyLQhS8AUK?UetuN$qQi-gR2jH;z;jkiw3g%VQBvaj)ZJ6x!pM0jg(=QOx9k_m--FFU8%2~2NA@b6A zZ2$VM$1y4uQvVoM5rPbHXKy7lF0bf?iN508mWZ z$-a5PbDs_OKlm{G<@?_+S53w@M-qq;UJaB_ur33W^pJ`2JZeWBP$DbJs6ke-12gQ~ zrB_`A-}=sX;2m#yi&eMclO9<1BxmXb!QZ^4PI~;~VbP+6Jz0`9g=z+^ZlZ8Z(**iw z&}I><{&C1L#GK`eh*U$EU5POdb=aNN@2YFAgFElO2aY=82pH>F2ZHpZLY8!iE@|d! zuqp0TT+cJS!4%Lf9FB{jUHL*2DzHz>T9lrZ+z=pOviXW z-1qQ9Os%m?+_Eg#s9NceVsExf1PXmiR9iBJzkA~pJiKuO-1Xpna5G071@tsL=&meg&U!*d47XY} zV^=#$BLKm$SaEN>@kXX!orEQtLC@1UiL>8_9)1Kq@ySoYSHJc@uzu5KAw|!qJrlD0 zL)aTe1*?4rGF&EIZQr?@eeQ;P?ztZ>zVuS~;+MY&?|<*#!tuu+?(|32mtPLgf9`X{eV7Aj zC6Ca!D6!8z`uiDI3@|r5d7@?pTqNh<0bIE z4}Tc$;!^YE1WXf`kWo#%s%&I)=0JKr?5-3J@3Y@iOmF?@wyp5P3w{pIe!;K9r#|yJ zn3$MyobNYE%fV*U4-%noKIEW-;MGk1a>T(0iyPQ6R|zXl1s&zGS85GZE3_;gi4(3G z{#mVoO$~jUs3H?yX5f}PZio9He$e=8cbcQHeF(}dKC1Fvw|ecYZmLG*EIJR-n4k=} zJ0aoDbu%&9dDn!xLsr9{bcPFk!KnS&!1S)uGx}y|v=~&N#bf!37mggqJbuuEn^7WQ zvdB69QB0N9cZv=@|g%pQdtc0imvu44VJtdkxQc`cvTzuYWz0sFxMS z&|EaO%S9fRO(2nd#7ye)on}^1>dwo<1TTA+_2v4F8{wY&?oo3Vx+DQ*ZDS9DlE8jD zpuCAl-X;XIf=U$!pKlWcFpj!Stp+%&s0~BSNC%XO_j@=!U=9hO%W!uxJ+zdd=O_v{ zUl4XNY4v+Q{4u=ikN*@N*|fo(00=xzVZZRu4=D&n&6qU%x{Yr-{rD$LdY^mV!)wANj5V>Q5-rvE(Va`3cd@OHGdwCTY47Gt-5?*mhy|zLIA$)vs)3M+Hl!VeW zeKgaPl>2ScRU-PXJ$vBXpIrcNedoJi^R{h}9j~F{WX!WBYn=%gT_#*~nfQL*1s4i+ z+V8*REpXPEPtNrJvw|Y#49!7tHghv6P?|E?OkE ztC}{o!vv#Jj9}0mQno_STyIuWMkZax9Ym3^)+Zth#WAg>z@|4h-AT9j<_{>ZF?aNy zbkJ%VcT$Wlc8L&*&S@-9byStUpRSG&nt+t)*p8jM;HzK%2K?pUyPn+=p3v{t)dhW1n;LhS;sc1 z**s6ov`=%0Nl#Brv%P}}aK^ZJiRCfvHmNiISrEyKDvPsA`Q}V{>F(*N$x)6FZq? zV%yHdwr!ge+qP}nwr!hl-_I|2`_rlFuCCL&PVcq$y2O)CZ9cSpu36a(+o>=S!h^bS zJ5=+D=yf~r0|EeaAz;pd%U+c<(zkOrmOf49A10+S>AUVFUmtzHFu6ZZL+rTATZ#UV z+bS_^K~zU7zQJVW#r_d<=NF?Dn8mC;o!s#g1;-l2?OxZ zuQE_`nYyaD#Bt?(#uHA2m zN2~FsrM4QtGuDecm~R&V`$dYDJNV@~kMxZ>@GQ~8Um7T7xSbU=xRjSgP`=7UCp|BJ zJQ9}J{$Hep?sQX<62a8xym=y(Ybp_@qgqKf8#H_Gs1E)fO~ z(|ED8p|X-}kjU4gG-`}xs+c6DGYF*QMs4$k5SF22zW! zHjW6JFWqD9Qnl3MZNbH!5aAakp2M!c-EbKNZm8g|HU7+OfApe0T0P{Ul=3pio6Vsb zEUEA(7Nw~eMk8WOdNrVlWIASzeRg>f`9>j5gfV_C{Sxp|gC{+@(n3b_ze9URvsN(% zBB1%nE<$+IT^hvQUW?o!f2%+vwrg~{V6uC$9^=U(A5?Phog9F}CChVy|1r?GzpVlz zX(d#HE%UWQ^M17b1VsAS*V$PKs~ly?sP&_yyw`L;bH2`s@&3YNIfBqv2^7iYh938P zSa4KFhj)WcY2kqG(4jv3E`Zc_@L3`0QEKpsn}A4|(Y&l(U}WYo2B$}owh)wIlwmgO z0inYIHiVx+fyI zB_PyEF;6$^=h$oYhqFYKDZxawN)6DP*7CuXA67en@~_{>1$HLaU~5pSH$cpV@|}{0 zx1^;}(O2jrwu6)|D8pjV2dQ@NqucF%L-vLxRXAt*?v$U>{0|tu_Hxv|+8w!EvkP$1&2QEM=6Tici>W|UT zX_WOu`cQNS%QD!+6w^@{$Ff8lLopLl?^8ae#>HC;Upqq|L&F=oGah#=zEO(LI-Am> ztdI^Nj2y>bZ&bW3N;{F{P-pJn?6RdJj=>0aU2H$;8GhEF# zW=_Y(#B_LhaUfJ9<9%R(gby0uj5SepcwH5is;Js zBEnwIJevRPSn9%x5jsFc-Dz7~xV8M#g8xe6Rh#kS-#v?xdP){K(-aG}22kPYZvXv! zHQ&!P>9`LiMvt21kJ!QA7nzs0a{ z;Z{PsKem%H|KW)(W6ky&M*WBQGS8&X2Q^#6rL!4kqDAAdRVpn^HJnHyeB=EqK%iuI z+aKcZ(YyXUWhxq#pgH*zR_UjS!cw2{i4Y$xPNr7;OLG+v0& zMuViIYE7up2Jd)Waoo16_Mj|R9-0VIU4%7~n&97+Nz+D0{>8y)=oL)Xw@8Bo^n%@Y zSGKT_;`hzz-76mrFxz4qtMkt%m|q~*CoY@L_i%yx$+VHgR9OJacZ zJxe71<`RV@jx#|Cj(Q^idjX97B&o(IK>C*)h}fK>!rm`v{G;MKp$kG4Vw&IhvFp~) zohcjmR-`A}#iE`K19LE3$+TwQqsCeKD{oq!3=tVojwEn`CCtODpf7T{5NP9ymkPKE^e<_A8ylC#rSdTeaoCSAjc`1u3vb}e<@uxN7`GoM?W|1ml_GY+}4gI?P(gXRPjG&YvP*xF=m#!FP1)1SR|9&(yn}z*v0{=aP zOdj_w&Ls3*I9vHP(^uaj6>v`M&DeS6x((3vq<1R7Pd=?iIp4h zXtX-}?Y7*I4Sdr1NOoHZ7?dw<8jzq7kWi$pg{TZ(aWxMdscM;%vyS8h#W~^NCo#4CnC0lFi?=)HJ@%Cye8%Lp3y$JcWd9J%t{_J@i2g8o+9WlJYzh3=3 zaH>sqyV8;b_zT?yPt7Thi^J+{h|jyjjd;Ayc;d_FMO(u=b899Vz4GR4NHG?mKoR0Xh%M-9Y6?VUY&kW zm-FT1KANQHGh7|s#p;OyQe2AK7Oy+kC$#D}>*CXBfALz?Aw%@6M@D!~a+>Vfak#Ly zA_+b_dzG0xPj8A63!Pv(M_RGTyL9y_zrFUn4)(?hq%RLHP(VWLzma|sE(HB^2!HPc zb&dTe2iG(i`5gjxo?(K8F!`3Bmzkj~ArI(@?CuE9((0nF!Qc$#b!sJZfOXCn6Jgue z*PfWs9Xl_f{Uy2+1??#mcibbq*7Jqn^~gA-?{QK3xCKlo?$dOsi#*=)Qno)+VhacY z|I9aCyunJ5NDYv0zW{mz8+zS>QC!ktFrs5}!x4MOh7yLmUU(mbP4$QDW5S!&j=>2~ z+x@+t)oG+pqPg$I+4o)#_QC)Voe%;?B9AWQ0dx)zAVyVX{G~5l*Xn1HAkMqU(yRv|v6{)$2Z4_( zSXL)ywLHNFoK` zs7-rKC8E)~MCKzNc;ub@&G|phwJNPTyzRT^mfoB1=O2~$vh+wLk{{}q=rw1lcLxo{ zc&GI89op&C+XHTLFAm4C%pDw_Zap{*I<3*}23JuwOG1xZk=QnHnc7a#mQ9Dq+bhNd z)<1pGK$X{P-G-2xt~+0QdX9}hU{Sr7;ZNd1#8S#MqrzpVBWtVf>kHWsH=kcE{n&sm zj3${O<)-nnl6BJ_5Ob|UJ-ZV0^;&Y$SH0D7bfb<}YX29{;Bw6Z=oIy@hU5>eFAALC zjM)OADfy@LPx%o|Uv-!fU^vFAjo>gYEjkZba6E?_PGy!9c7GU^zBYr~e8kVddDD48 zUzaENugXspS{jju2Rft0D(;a#g7x@(@|?JYRo((06YF(Z)5gWC&#R3(wn`6??~~DO zA!8ee!Q=a3kEpp_dk`$MU#Te&V#4KR5KPN`Nu@Samlm!ek`f||Vhkd}njZZhk=w>E zpo5gOqJZuchV->|OUU}~BzvnaCSq)DwfwY}zpH77a}N4uBQja-;!2d0_jGkj<5YZB z_@y*(=>57zZzrH*e^t~HqP#tl2_@Z6^TZYlhtr<9^=CCIhQ2e-We0}oGW1`nwQHTm zP}V~KvOyOP!Q)psRzqoq%sY)Pt>4{fPh$ng^DsFPorx2S5gO(IiluO6Y^%{kFnpbD zAikps|9NdyR1!By_8qK8nniAg%a94pOw6nG{w4YgPlL@A&Z_N|277iHu$-wUOG%Ck zHD2qEk6yHN2ozftlYp9`X0-gqBJm{O-A9&dor*q8+Xpkv13hI?3BEW9 zjnY(Zg7DJlGV^-R2XByAg2~ zxr_AQ$6RBid zp=Ia8sW`UMjAvGknS|jKy1fR{|60~2C*eH#NNkmET(BE5koPzZ4{9BjsO>px6V%){ z{^Dp5(I|RhzK7gkQjUA{1@o!4T(HbUofl*I%8N|4^1hs5HlLOx$Nb9SFmuJpRFB8Y znxc@Fmgzm5eB{=63}s>_sTo%Mg~4vo)&@49)&;5sW}-f5{g6Vh4iie?MTFP+0~}jM zyfoX0kWzM^ZycmrbnSL!dX|SLGnf0$E z@Vk^kHI3r^lEUOCDbuQ$`$SE)W4H~M?eR<4JVRuH6*h8FwN=^* zeE!2UL57;nx*}SaYjhjRF?miZ%cE4a(xu%(pS`Hy!%?9&LOnWrAcm@*ItGHQ>hb%Z z4;@ycQK?bBI#DuYO90jRv9Cz_BJGORzf#bE9YGAG6HHsNuBJrP)P!Fu7A`C?xZRr? ze^a*OH~>5drH#c8*QOgBaEOIj?X+Un_fl&RYM0-_?_pf&drVuboReBN~IUlPlvNBBS-Rqk|Y@&87fZ z1sD~PZK+D4>U<_e4dz71`RmpT*;fR^X;(&0a!o#zBHMEQxa#zM56|z+33!k^SCuII z7)jm&P`KqKdP}~mz2Z?hoLhm1)Pm?_*4+o?{e8A7La$o^!KJt?`mB!8H{U&6|4z`k zu5GE8J0eLWk%4_IVY)1jOOe$Z{wa`k;}T*yPo zofE9Y3~is1uPr~Xa;x1L6|5*&e;&qCX=-31HhZl?o}+B674<67!uEu5V^JpdPV&b8 zUQBltliIgQ9~>)WwAcho)wH4zxI29zg{08Fgi~Y!O{mf{xPb755?}w@G{xsWPAv#L z6lRHFGYmbIR96n`3BM&i=%FD{Wuh4&FmHS8KiT#_-T~q5Cvd#@(!A~j-Ts*&^oL}# z0-0a75K+k?1F)K}ITEOp9Hp6$!(95781Cc9o{-s7hTCsBnOx5b@EZ@c)tS0zYY)3} zLOWksRR~|a(Z9?`VpeI;DRDA0vqLUy+OfayyKVwkdXA>-uHaWD9xWOL6c&!wLzLYm z=pzx0Cw_E&_h9otPqQI14t6KqnUrj~0Z3-Z*YZ_DMY3(Q$%{QL^z&p+`93-tlmt#~ zgr>@1oz3HE65)DE3HVV^MhFy;gO(HzTMCzEN^wYj$AG$xJPaW#*`DLoO_Ti`mWVCh z{at^H0sYsK%56RX38(LT{Cyh1p6s{8Q2B0ZP5PF5>?u*gjGCaF2*z`n;@a zXWQ`x^!DcG&Hi=rq#G!M)jAlT%f+N?X&^|YL|%#m6>y#tUz2_HT5zD%ZHCK!Ph>ud zaaUlwmIaOst;a~5<=p;V^H{IXXK?)RZjEPy`F?Jqr<~vZEo9=+f%a4OD|Y zCS^cn++;>huFM*(=hjq9FX7jaZr_jB#fDy3()hSe0B;(L2)#LpG9EOz=>~*A+m2*P z5wsZCEd1$IKSsl7&&r=89!UcG}VhFI{y2Up9sJEqsSlx{$e z&(6oLL9tNAUPe%^Hw#InZVzxXGlb5vvA%k7JDQ97Ae-oGBnGYD3Gan^?GEopuU8+_ z2m$ros}Szt)*17!i+_MGHfycZ*85%p>_glD7EnC9~kK((*&Ik>R<7QyVB z=J8DRJJ6MYxZM>(97wLxB&M8V(J?{^Wsl~&R&zrzoc|9yFA}q6_B&S05tr0r=Y{C` z@U#sAec8f1R57)9u*g0&^rl|W4AtYwLHu)MXcBS-q~r63ep@!1%Z_cXH`o*G~gD8LcLe6KpA|t zA9m*_7(z2_djfebdp8A|w~wRF&rEZ`8N9Y(a|hPh?K4^#T^MdG&}&{zb)gI9A&E4k zIcbwIk1r|_#%A(L43@l-=JI%=$z9}nV`jJrc|U7@AXcI);u`>0OEbVU%AgPDp01O{*|;it^mv*jx%<-0A>@J zu6;9m%^TN9Gm4sX$3?x66QGEEa2IS=L5&%LC4tkPAEBC=1W{GKP^lLvb0{hOJEO*&_FIx0=&}sbGvRGsS@9&iJ#?3&Eyj3C7hi6p`g^zT4 z!>*d4>C!El1@N6?GU|NfYTXx1UgzX|Kz`oFW_ndtcA%83Y(-1CXw$9XjDxOwlrVm0 zL3rC!9?kEfo$_P};$9D`hWp6Q#}&yP#7}}P#C`n-!us~S@U$LA(CqF#UFeTYZ++Io zP>meUJZT#9uMVZYR!K)}H5*b?syBf^{Hc5Qfq2$#!O*$S$Lvc|)d9!+4!DZX_=lAW zN@UOVA*Fk#=(fC&4HMZ)qe2EZYVI-!RV@aEt0hKvTnTwXK>M@&uDI3#K%;pd83==a zj02|Lr!;e=K(9L}#lCDlhGB}3;WTuLHQJ^xKs6?)z3|o4!ys(sZ^T5QXGxi!Re61Q zkjnps0G^V77~ji;+b_Z&q-)<(8r*B*`OU0lvAFUP0*J*&afvL@p2q&Be-*p8BW;mnF?KS%M^yVMVrTI z$3%DVUdseEdh`fz#Q;u=o;5J4vP7w|&*V40j|SHPkrXWmR4??DsMHQ(<|wLiJtjCD zftl7}i@xzP73tNzkj$#Q`ZrS9kV4(50&$6;9V`%x$VTSdUZVq;O%CF5PRdq25SM**6qu4`uxuofp1s$?2fdOtJFQGpV z?JIyxDT1-alW@yvj5LSEiBS_uxgA{rfD8TSBN-c`Y>s$|h)wqJBsTYwh(LA|Sa$rL zhG=xOWK6x5giJn{>s64iiQ>ab&z(%`&0eTpeum@@j-R|#FsA_kl9~4*U(uh#)iajZ zxcj4TzEuSy=p)N(?|~X8(wTSYZe3iWq|cDqv*_oAGh5g9mRt@U%u*Nl=rX+R5-djh z&4oOzHs3gLFFEuA-7Il;T7bKo3}}ZhY&r?5+W{hIK`c}nUiD^ zI(VKL>Ig=C%kQV*AD^F(+d(C{;G@VC!S7Bh^NQhUk{+mhH_O!TXNI3oIlYl+?c1lH zuRQjM=@*#!H7v^SHs@Q6m&&@A{=ImWm)^(RsNUzNTr#xx6PcjW5aMdH`m`{sY}WqqsYC_1I>l^(<(A;3dSG6DX+?pe{6tlD9j&DI;n1&aPu(J zk^60-cIZzePYH%j%IvT^Znv68646U@=C27SXNkn)V|n|jKH_*yA$R~vU2ihLNI99X z5iUeDtNh|wy94p_Ea#iaYNH(#5LoX%D`T_}9YR~M2~p>Bz^0Y+R!GrDqjQe}P*hm- zwUTzx9D_bUD`qVpVeTsG9q2+Ybb|L6=+#!`iFGr7HkpZUnj5G>ad^cX4QJT;-{g4G zdp&IIU>rz2YQ&$y7?BaKWu3P+SDMUfVI7Jt;U}5#mtW!slKXmwlY3qP9&7)Y?~jpP zuAQH}bgiarE(NB0l-A_pCO?KVvGrywRFb6RNhyn9d21~wXf>$rdtztKZ8YI)wOXC$ z0*KCwYR}z$DTdHLGn(*#X&J<+LXO2q`6W}Na5UFDmo*Q?Rq|2}b0RItx2=ux6Jm11FQp(QCvs zaycGB)iB6gopD7Ts%#HcnbVZ)az9Z@V7s*6dYw0ym1z!qhHG!v%NF8_mM5K--CnRA zzS7>6et&FiYFmXt5rK%xd~Vyd+1+{RJRt6Hk}5xhLFtiN4ifW@6dTMmzU+qncP~X? zc)roJ_5+dOWP4xX3iVKK)q*OgXfiJq`6bov@9rJcgkyzQ=m9zJXXe{OX4yb8DTI*1 zL6$aZ#7YhzGDoSsLR11s!tY(kT^`>L*V}`Knb0k-rF>a8cw@xzJ)t!q9RReG^O9-W zuetMS!oFue5?Qd-$t^*Y9f6k=`f7f+v|S;Nk>^Ij?`{Tr5>tItmS$YE~}HABZ4aF50$)t-}c!*ODu+tbIH~S3H(jE)7;(Lh)sTC z_Py4F-LIQ3O{|ZMo?yc7OVip=CO>8P=e`>LrNYum+1K?Wy=LOqNmFk4?eAo^fx8i& zzuW89aAD_|qc?Jmx{0w?E}lFpg;9O0KBct286@!&8~6#*_eMr(%ONtjdwhIP<^Ywv ze=FwSQAlMsyl@=rvv`VD0)IpbOm#4^IkPpaM<+hi6x(bMG`0iH;~Ra zE69xd+r;jjbWxqv-LEquf?s=fOh4#JU^3x^3*1K*xRgpP*X&YH#=+V1>WjbVg0ojPl!+Opu_rRCxQ0bSljY71Cv=-AQdGK4 zdib?!p2|UUYFT~AuXJ`mB=^mt8`=icZSMOYp#H)4$#9#8*oipI4PA~<$hg=MXqSDn z4-UHv@KqqcX5MTxhUIQIN8NNk0ff@j_<&2## z9mO3*g_Ld>qw+&8|CV@+T9^UIptw;1XreItuHRQGj6S?)w`iu*p)^GrxU3%D_%Ak0 zsl5`+ZxCLM$J7IlBw4zgT4egFHiCsoy^9fHL9{~18KKSs5Ej^roWG|Iq_FY z$oSv3IKv%J;us8Ez6`d3mYxTEw=>&LtZAR|v?c`1!}$x>-ZCX2sbqSL9HCVDS0nPH z?%kDa*o{?$Z_(je+qNf+*1clfy=boMppWYgL{_U+AWwkd5Wv*GFBdcF-#|T?l-^VN zAG<{bvHm+NXS?}uihjcw9*nZE|&6Z%VRm+?5)2v>Fk~7XL0?vCZ3#b@Tq=H_nrw21z}AKBIhd z*!6htt{O%M>3%ew^s*>Y8XGWUk1J_$nxssGxhX}vp~w$Wk}SmX8NyW4(Ys~n|nVsjY)C8ap0j#eQk ztTDaDP#-`;7%3rE&D&e4%PhkSzpK}1XezdM6F6?$j9glP#7YvgB&u#d+sn=jjam|g zL-Xj`$B2e3HbMX0khn0v%I3&VJl$8?_e^) z_uf_kG}{k?aj2B&puRTV|E6Cj%8edSVX~_CH7Cd52Oty)?JMJzd|k@_5dgD{rbR>_ z-h2D!3<%r9#Pj~Hq@#TnB!w2eS{&ItxAy)eZ~1pJY72?0o?S&Y+vCyBG!+D1)|h#o z-@R)Sqge2D*|i52Q~OhDxb{lIqA|CoL=3K~di0&E-FbIbI>mN*`)5|@md*Evca?_; zI9Cg-Fjf15tx|*ZSo~3k9pM;j-{p|eWUFXk`O>K`Psu)x>~scbw^Hv#Q9&SP?83Ga zns==5lg|Mf{MdS9 zuj}Rqa{2fL>&8csoj8)cj(tkw${$I?H5GxS1nLT%{IRD6DR9;E^U^MFMoY{H9Wcc= z*a5?)lGz|Agc%SYaCN6Lg_+0w0!nRI$OCV$?E=nkFKd1CH1L4&aoG#L9h>nXV71;( zJQGlmO-wx8AV1gwn?_$C$V<9s`sn)6qRk%lLeff3>S$@)RZ7(jgVbyjU#WIctBBT7 z<0J0aZ2Md_{fN%G1yI=0x}T?P8=hORN|G~&+@O_v$9pPyJ~_`esvp>_=eNtWo+a31zAF9!E^OcrB7vHYdbOtc z-w0fc@2#x0ip)l`QX8K>XRXmZpkZ7@Pvr* zwF!#}E?rPjhF?wb%o{mIxw zYwBp2Y~KQxL^CVtyAOZAj`n;599fz{TPcw2KD{i@yxAWqtWw1_>__XHr9D<>J4-T( zWwuIxIpNJyHQwSZ`If}jGXuv5<;UnD-fy#AEovP4&qm2O_h7kTi*JBQIabgsF=#t3 z(A~zxc;g}P-tx15Ju2y22|zwZh;lko{1F*pLSC7i{xc(7@%67<81l(mp9|rPIR1K6 z#TW@Jb1m=*CE}qsUvda!FGBYVhWDM2Fc8@kpnrKo&(wc{4zi>wH?areiO#WlR3%~ zas9mtt=lL-h?q!LJ8)wt`R4GqVA3oNf?P=Qa0DA-nT-P+nZ#n14Gl>WlAC-whI14!(;0BP<`I%ev@gR~KTkpKKzB#efZdz;d4LC)BC@i{p5zsm<*nyebZTrp zKoQB>vU(QGs0b{RD>#PbjZaf!GHHmfU>`wybR)NFkV?-?_AUXYDz@$?TzlUigt2T9 zVy%ay9~p+(qS;O9KieQ4Hj3M zZZPYyApY~K!5(Elb1l3c$>7P!jEZ%=C>ycOR&2k!9nju#y8$TrzyQ-SY-yPaSW&97 z)V2C;T2br==Q|X=*f`@A0 zX~y(fN+58=Wy#kdU~n^ z34%k>fN7k`IWyZvv*KeZNq_*N8LW_PJfp#0^yb?P3%oRS(m9yixqULg?2`Ab!FV2` z-J9}*&P$jP!eL|UrPuR&k8n3*=Y#ihy#Z3Ij4p(Hyb6Ca_q(1avZSVHK4+6!yyEZB z0gihwHk@;|(hQPm)J;l}ftmSZBbMq(Uc?F{`(Ca#b#U^W;M2{wOcp+H(7zxWM z6)s8FkK+~9!M@+4J^j^LTzf+dZoHQbE_ACe9DkR)F{aeY)_B!Nd-TBrVInTEIN9wZ z1-jw@+e1hdb#>Pr#On=%H#G0}8$+)X_0yC|_CoN(gOsD(Z&8U@NBHzF2Ziru5GXyH ztQnI|j6lKOV{YqfSwS*LxG==FiE0lN0m?sPA5ADou$mqVezWmw5N@i*t%>d~qHWrrXx~0W`ap0b7 z;jF0?EZ9uwwlf6FDPDsd?fJb@tSP9eTsjpjIm|fAU|upqG2La_iF%5HptL>DThnj( z-^zOMU;b)o7a8f^CALi{wjBo=tl-BinA%NhYYJYBktm1@S?ZHNqeEymidI zcO$fAT1;IBXs>(b9MqI+-ga{mY3Gi3#W{^i&UVL|VWV&80{)wQn&Wg~nrJv+UWQ+u z=0=6{l9SYd$Fc9GqYxuNVAJoZ~w3SVR8l=R;ro*&w-eI>jv9RC|RyY9RIN#AM?6LS?R7Ltcm z=dY#y)6!>wlK5Uk@K*=DIg?d_;~ZNKhi8_%Vxh1d@<;E9+!k4ED;j?%`k@G4nt|&v zwRMPKYVh36_Phzy{k%7D>zAPD#|5}x?3&AY!vIW%p}-PcX#K2`l<|0$@;Mt?slsG@BZ`8n(^6#y}i2mfpWRrhUap*O03{M7{R8#5A8-$RlNs!W}>fpYZwCZ zuig_3uwO|KPG1Y|W`l%5Px|!$za==A?;cxWwgh3kE_KRsF#yTR4HNTuX=-=T!F);KkH=x#Ei-&3i7c*5UGpR%cQ0hFQN){8+G^oZqbO5a&n?BaJRGjL@ za@oy;&)5abJ+NO7OL$=^a$eos=3ui&3NMuOd%j+Rohw#)BhV-G#`Z;K&!Wn@pw@)w z3+PUn=>F-IlHL=Wj(eu!n2bbU)tWE-b-RrV-LoiW>p7gC*i|I|W4qmrujnI@!&KJ5 zT7jIez5X2Z>tA@Xg2!mP1=MQ$i3{E&0hTu#l>j1$WHgy(&hSL0A5$CZ?bE`#l_a99 zu7HL>zQlUD00hLxJ9%4XMw-GnQn6FVef!1kxMhuh(nLxhbPN}PEXSDH#(B((cT=lj-k;^09zpPAxocP8B^aD{Qkz# ziV8C3m$>CH6T2I(U3r1YVx5~&`9HcS`|p4=4~Fhbm^+)Zc{00O;Ew?Tfci3&(1-o9 z!3Mw5I7cPQoI$-awM=+eFOz8j!F2VqCpz9O-1(R^A^L@}n45{IukcX&KP%GPQ;)Z{ zAODZN>5psE8P~AwW0w~LB@Zj{EqC4ZN`$VG;(jo1_Og=-f6Os;(lP++z_aV{oe8tleX zQNw~wmdC&CEduPhs6HMc~+JX03GEP-1?gLn(^AoNuAYt$9U5LQywrY2eVma~RmOjqWh;$aOUk*%KUwricp^yp?KO}Sv=@TywnffE^u(j>&e?%49fqoAn@~3 zA@s+Z*5&AWlEpeLI5ittbxV`-#L$t)_3nKJYnS3KEETCS8+Ld`^~sZ$N|!?L+sT*hq}JDsv3Tk^MsjsAxaj6lo`_7k#fd|1Zo=sICA7d* z=x9cl5O6u=B8K#)H`WGUQx`G)w}?+V<5Xhu6%p32OPRe^ni|pl`Bi-Z%bY$GN{z-; z8F5GcKX7sNazaq}@QlT+S5T>BsRLL^rF)SDxy+u6$he}|ZG8vB^xtQa7|Vu}fP(1W z9c6@lhBIui7W@5*GavR5kuRjh#NT9mjU@Y$m= z#y=MN!(2pt?04k!B~%l0MrMVg*pEqu-J1R*853RbG-stuMHj-bAGGB^GGB(d7;I$) zQ=P@!u6v7SA}+0*=jgu5^W4a1fpK-yu=h*X=MO(ZMAHQ$1`~vWpe{SIgsY7+uHVFr zL>_CQRDt;~$%m%!ZCCy zuzbn~QI|4UW{?B1#I__Tx*74gA{wA)qSxDVR(fGsDBmJAPZ8rcJS|)0@0!b}IyJ({ zWn1En`uLg5+!~! z*k?dCcC%|t(l<)aU+khpbwR*a&{5~wq;#CvxIb3<-{s2A|AXeJ$OtNArEPr37tBrc z-P$@O$n}yf$Q}wg2Wkau3!nVqye!~(3qb;UhYgG<${6yg{60!uL$$GrB~<94j}|OQ+=a)wz?foQB4BPKd9hgO)M ztlA!~?cy*~+^t@6yh%ZoGkX9``M6##8E;(qi zGg6WjEu<5a&Kn{kqU0n?%}x!V5{)^7EBnWdJM^W{xKC@)D7uJ!QEQ*#*Y*;pAr+k` z_{RkX?WnfL0WG>l?T)yA8W$T^EB=`E)B|sj8iyjm{`qSb6cL5Zv~Yo0GJwd=Rz=jf zyR3QyWE9p5?X|k`L{XJuAtN*0e~QbcUP6EUG7C28OGmC)h4qjw9pYuM&d3XIxmpVt zc6hiq1zk9%@I6&u?zxbIs$+sQITV1IS3Af5mAt0QAmA>{rE2aiCbyAtwc=~09=<%! zT{BI;o9ZC+3Y(J*Wm*tcP|Q|qJ)})*G$jXH9;Vc@a~~lK7N(~G^LGiqPZ?}{gsxiT z7S2^>xjb$ewpxP_lowYjvuKd}8ryOz70Ffm4ER|&T2_ipr^CMrZ^Q>32q?-a=l>H} zT>%`n=Ef{o%aSBlR0^ceq$U&zvUMH=OXMAzH|J`3^&~!bRB5f%Jn3Fa#Bx4hLp^m_ zuNi5zpzt7v_sb0OX$WiAS{^W$>6Nb_&f5~t*We5hSix;;N{h5M5Gw*d!yH;~+iwvP zvs9^n>BaPciNSSanJeK8sMOTb2;tTYV-~CU%VL12U0P$4jcSH%5V;l_Yi>w!;)0U% zVK%Mb!`e_GfL0*MpG}ps*!5HkypS&K|1lP z=J_`ZxWpidNET=Tygw9{KP=JDk&kQRylRcxXvQQRbcIMA%UZTyYHq@&X@;#7i9vUa zyia=CKGFplo($cxsyX{kvvYw=EKm|uRoo8vF1mEkKPHfLnI47xZLXH)EBQmWvyw9f zfgy6*iiHeOl54FAyKpeBV|1=IfZKre=RKLetGm-?+M~vP47j@sN9b>S^*{B|0Nk&E zEhIQE*>0xe+q^L%KN#Qx?M)RcfJw612439(;C@9S=fEW(^B}K!cAA*_Xs{m@MhJbC z<|Xo5y#Y6((Fir56}=!+63z47N@KXM{QDG>?*KbRR$6wmw_8@fV)?(Hyd9Qq5w-8M z`n)UcdTZ75Hk*&9oBy-x7(y!n=3rgwCf0K5zV> zzHGZ3Xc`!ZsI&I~yl6foAa7OoEv$ZdCuztOu`Is=RuHU_bR{1-@s=@C{THzl5&`#K zYe5f4-02|L`&^7q<3*TZOxkw0^+tk{WXeN_dud4rq$b3cfv_KXk7i?-D7d32TKfsY z-XcJQ*PSVQ{ay2Pu_8B8i03VOdt6cdejGm(`E3ekA83e*FSGhRltPxHpO=OD-|B%0 zenz4>BF`+8fgfb$FsL_vHmvA)UR{qWA7Ha!rt7|xtA20HlSOvVIAok>#7(m*S*1Au zmJI?XJ_WoO4DjE*R%@{s!p!+TOt29dG`m*Mkm30uW8gTCr>XwzZO-b*hLot6R(py| z!a+Y2lqmfKFUkklq3cV|&dyE!nn;doy^v4IOXe&uMSbF;05u~J%H)95$kIW*DEXE- zRu=`8i5jc-m~K*<=(Y%CK33j39RD-Zs(-eB=c@x?=%3tl?}a?cgDP;E;ks@*OeCX5 z^Xwf{o!g|XcAeB&T{4&yiU0P7MN90VPw2g8H`-#|j^yklCJhsyYbUPj#&S-(hOFYt z?hv3bJMU)RQAvl=*&IwKx^jAQs2X973Erv+{FWEe7tG1tD9PdW%xmK3ky*1Iqj_8r z%3@MqoH>okMh@a5xVlUHI)-DCu%A&2Xo(^_qgcD%H6`r&xE9MJw_rAlF5y0s$l!z> zzFF-y{HU5pVOZl}W^M?YccP+MZ%w4^+OA7ud!Lc=i(|MzfS`3-e#oWfCsAzNy7M0v zx@mbWhuWI;-sgGv=$Bf-KE;~uIcvU0Id)Qh#O8OIDjuq@e97c-`FUX@ zV5~FV-!=03l+bLk@?0JqJYrE$eva;F^yXRjw z@Ben(mXiVAqCCvABsgVoH2e;I;Fz?nU(XvU^c=f>Ni-=nynf`*cxJ5Pf|E*vKgHanEvJS;@xiD)T=gp*mkFfhpANJW z^e0&rX>5q3Vi93ER3~G97av^lFIwD23S5Lye$#$T!&LS=!BW;_G?}(!94XXN5lN1C zc5nRAH^NKvQN>K28pAhmMz^M<;?nQwphjmNaeCr&`4ad{M$74vQZsd8g3jhJm`blN zuf1hf_Z+pY*D9{G;W}jFyT3A;V*K?v8HG6`*|4#6wL(X5w#a0?O|hKjBO(Ag0wFGD{ENo*;D#ZYTE4@qWkWf zqTckK9!(j&{u`AgF#qy$;DRC)qJ*ZfupnD0J`A5p#`jXaq(F_{mv7*lJ;Xrkl%Tho zZNk-vH_Et{dsSETwEb(IRASgk<6IrmiOZ#o21_jdz`UM?Rd;kfSdrN7)2@`doajYVgVm-=XbZ$9f|9f^M-e&P6wf5FK~zM z=RT$!WB2MyTKBLi?zWxp1Do%HKAfl3Nc7Rz&56_FXRU5!q<}Z%T)A^E+w67~;JYIe5hs;}=|S4FlftEJC<*sH6TS7tJUZg#f!^BVJ)_&A{U m{I5LySA_mw7fiahKcIrY$ls3A!^MFBF9{J@;c7v>fd2!X!1lKQ literal 0 HcmV?d00001 diff --git a/public/logo_maincolor.png b/public/logo_maincolor.png new file mode 100644 index 0000000000000000000000000000000000000000..7e5567098263f8f35dd6b3963a5769bb32e791dd GIT binary patch literal 15191 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 literal 0 HcmV?d00001 diff --git a/src/components/business/Chat/ChatList.jsx b/src/components/business/Chat/ChatList.jsx index f7c66ad..6c4fce5 100644 --- a/src/components/business/Chat/ChatList.jsx +++ b/src/components/business/Chat/ChatList.jsx @@ -1,5 +1,7 @@ import React, {useEffect, useState} from 'react'; import '../../common/Chat/ChatApp.css'; +import Button from "../../common/Button/Button"; +import FormattedTime from "../../common/Chat/FormattedTime"; /** * 채팅 리스트 컴포넌트 @@ -42,23 +44,42 @@ const ChatList = ({api, onChatRoomClick, closeModal}) => { return (
-

대화

+

대화

{data && data.map((chatRoom, index) => ( -
handleChatRoomClick(chatRoom)}> -

{chatRoom[0]} {chatRoom[2]} {chatRoom[3]}{' '}

-
+
handleChatRoomClick(chatRoom)}> +
+ 기본 이미지 +
+

{chatRoom[2]}

+
+
+
+ +
))}
+
- +
+ diff --git a/src/components/business/FloatingButton/FloatingButton.css b/src/components/business/FloatingButton/FloatingButton.css index ed98fe7..a3882dc 100644 --- a/src/components/business/FloatingButton/FloatingButton.css +++ b/src/components/business/FloatingButton/FloatingButton.css @@ -21,13 +21,13 @@ .floating-button-modal { position: fixed; - top: calc(64%); /* 버튼 바로 위에 위치하도록 수정 */ + top: calc(50% - 10px); /* 버튼 바로 위에 위치하도록 수정 */ right: 20px; /* 화면 오른쪽에 위치하도록 수정 */ transform: translate(0, -50%); overflow: auto; outline: none; border-radius: 25px; - box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.4); background-color: #fff; /* 배경 색상 추가 */ /* 추가적인 스타일 설정 */ } diff --git a/src/components/business/FloatingButton/FloatingButton.jsx b/src/components/business/FloatingButton/FloatingButton.jsx index 89bd0f3..354c8bb 100644 --- a/src/components/business/FloatingButton/FloatingButton.jsx +++ b/src/components/business/FloatingButton/FloatingButton.jsx @@ -1,5 +1,5 @@ import React, {useState} from 'react'; -import './FloatingButton.css'; // 스타일 파일을 추가합니다. +import './FloatingButton.css'; import Modal from 'react-modal'; import ChatApi from "../../../api/chatApi"; import ChatRoom from "../../business/Chat/ChatRoom"; @@ -13,17 +13,14 @@ import ChatList from "../../business/Chat/ChatList"; */ const FloatingButton = () => { const [modalIsOpen, setModalIsOpen] = useState(false); - // const [buttonPosition, setButtonPosition] = useState({ top: 0, left: 0 }); const [selectedChatRoom, setSelectedChatRoom] = useState(null); const openModal = () => { const button = document.querySelector('.floating-button'); if (button) { const rect = button.getBoundingClientRect(); - // setButtonPosition({ top: rect.bottom + window.scrollY, left: rect.left + window.scrollX }); } setModalIsOpen(true); - document.body.style.overflow = 'hidden'; }; /** diff --git a/src/components/common/Chat/ChatApp.css b/src/components/common/Chat/ChatApp.css index 827a4dc..6a8009d 100644 --- a/src/components/common/Chat/ChatApp.css +++ b/src/components/common/Chat/ChatApp.css @@ -12,13 +12,13 @@ .content { padding: 20px; overflow-y: auto; + /*background-color: #f0f0f0;*/ } .bottom-nav { position: absolute; bottom: 0; width: 100%; - background-color: #f0f0f0; padding: 10px; } From 00e4d48449c4ffd45ace66cd8230abc62c38c1b7 Mon Sep 17 00:00:00 2001 From: sangminee Date: Thu, 7 Mar 2024 13:34:25 +0900 Subject: [PATCH 10/10] =?UTF-8?q?[CHORE]=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/administrator/adminPlanDetail.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/administrator/adminPlanDetail.jsx b/src/pages/administrator/adminPlanDetail.jsx index af74bf9..74a7891 100644 --- a/src/pages/administrator/adminPlanDetail.jsx +++ b/src/pages/administrator/adminPlanDetail.jsx @@ -26,7 +26,7 @@ const AdminPlainDetail = () => { const handleWait = async () => { console.log(longPlanId); try { - alert("정말 입정 대기 시키실 건가요?") + alert("정말 입점 대기 시키실 건가요?") await AdminPlanApi.postWait(longPlanId); alert("입정 대기 완료되었습니다.") navigate("/admin/plan"); // 페이지 이동