diff --git a/package-lock.json b/package-lock.json index 43ff23e..f4b70cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@hookform/resolvers": "^5.2.2", "@pbe/react-yandex-maps": "^1.2.5", + "@stomp/stompjs": "^7.3.0", "@tailwindcss/vite": "^4.2.4", "@tanstack/react-query": "^5.100.5", "@testing-library/dom": "^10.4.1", @@ -27,6 +28,7 @@ "react-hook-form": "^7.74.0", "react-router-dom": "^7.14.2", "react-scripts": "5.0.1", + "sockjs-client": "^1.6.1", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.4", "web-vitals": "^2.1.4", @@ -3475,6 +3477,12 @@ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", "license": "MIT" }, + "node_modules/@stomp/stompjs": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@stomp/stompjs/-/stompjs-7.3.0.tgz", + "integrity": "sha512-nKMLoFfJhrQAqkvvKd1vLq/cVBGCMwPRCD0LqW7UT1fecRx9C3GoKEIR2CYwVuErGeZu8w0kFkl2rlhPlqHVgQ==", + "license": "Apache-2.0" + }, "node_modules/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", @@ -8482,6 +8490,15 @@ "node": ">=0.8.x" } }, + "node_modules/eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -16099,6 +16116,34 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/sockjs-client": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.1.tgz", + "integrity": "sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==", + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "eventsource": "^2.0.2", + "faye-websocket": "^0.11.4", + "inherits": "^2.0.4", + "url-parse": "^1.5.10" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://tidelift.com/funding/github/npm/sockjs-client" + } + }, + "node_modules/sockjs-client/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", diff --git a/package.json b/package.json index a768b5c..8cf36cf 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "dependencies": { "@hookform/resolvers": "^5.2.2", "@pbe/react-yandex-maps": "^1.2.5", + "@stomp/stompjs": "^7.3.0", "@tailwindcss/vite": "^4.2.4", "@tanstack/react-query": "^5.100.5", "@testing-library/dom": "^10.4.1", @@ -22,6 +23,7 @@ "react-hook-form": "^7.74.0", "react-router-dom": "^7.14.2", "react-scripts": "5.0.1", + "sockjs-client": "^1.6.1", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.4", "web-vitals": "^2.1.4", diff --git a/src/App.js b/src/App.js index 6fbbee0..d84c47a 100644 --- a/src/App.js +++ b/src/App.js @@ -2,6 +2,9 @@ import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; import { AuthProvider } from './context/AuthContext'; import RegisterPage from './components/Authentication'; import MainFeed from './components/MainFeed'; +import ChatPage from './components/ChatPage'; +import ChatListPage from './components/ChatListPage'; +import './styles/chat.css'; function App() { return ( @@ -12,6 +15,8 @@ function App() { } /> } /> + } /> + } /> diff --git a/src/components/PostOnFeed.jsx b/src/components/PostOnFeed.jsx index ea82c2e..074c69d 100644 --- a/src/components/PostOnFeed.jsx +++ b/src/components/PostOnFeed.jsx @@ -3,9 +3,25 @@ import CalendarIcon from "./icons/CalendarIcon"; import PhoneIcon from "./icons/PhoneIcon"; import MapIcon from "./icons/MapIcon"; import HeartIcon from "./icons/HeartIcon"; +import { useNavigate } from "react-router-dom"; +import { useChats } from "../hooks/useChats"; +import { useAuthContext } from "../context/AuthContext"; import { API_URL } from "../config/authConstants"; export default function PostOnFeed({ ad, liked, onLike, onEdit, isOwner }) { + const navigate = useNavigate(); + const { createOrGetChat } = useChats(); + const { isAuthenticated } = useAuthContext(); + + const handleContact = async (e) => { + e.stopPropagation(); + try { + const chat = await createOrGetChat(ad.userId, ad.id); + navigate(`/chats/${chat.id}`); + } catch (err) { + console.error(err); + } + }; const imageUrl = ad.images?.[0] ? `${API_URL}${ad.images[0]}` : null; // ✅ Формируем строку адреса из city + district @@ -53,6 +69,11 @@ export default function PostOnFeed({ ad, liked, onLike, onEdit, isOwner }) { )}
+ {isAuthenticated && !isOwner && ( + + )} {onEdit && isOwner && (