diff --git a/package-lock.json b/package-lock.json index b37d204..81486f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "lottie-react": "^2.4.1", "react": "^19.1.0", "react-dom": "^19.1.0", - "react-router-dom": "^7.6.0" + "react-router-dom": "^7.6.0", + "react-toastify": "^11.0.5" }, "devDependencies": { "@commitlint/cli": "^19.8.1", @@ -2003,6 +2004,15 @@ "node": ">=0.8" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -4995,6 +5005,19 @@ "react-dom": ">=18" } }, + "node_modules/react-toastify": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.5.tgz", + "integrity": "sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1" + }, + "peerDependencies": { + "react": "^18 || ^19", + "react-dom": "^18 || ^19" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", diff --git a/package.json b/package.json index 431189b..001689f 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "lottie-react": "^2.4.1", "react": "^19.1.0", "react-dom": "^19.1.0", - "react-router-dom": "^7.6.0" + "react-router-dom": "^7.6.0", + "react-toastify": "^11.0.5" }, "lint-staged": { "src/**/*.{ts,html}": [ diff --git a/src/App.jsx b/src/App.jsx index 079f8fb..f01ad92 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -9,25 +9,31 @@ import MainLayout from "./layouts/MainLayout.jsx"; import Preloader from "./pages/Preloader/Preloader"; import ProfilePage from "./pages/Profile/ProfilePage.jsx"; import PrivateRoutesWrapper from "./components/ProtectedRoutes/PrivateRoutesWrapper.jsx"; +import { ToastContainer } from "react-toastify"; +import 'react-toastify/dist/ReactToastify.css' function App() { return ( - - }> - } /> - } /> - }> - } /> - } /> - } /> - {/* Add more protected routes here */} + <> + + + + }> + } /> + } /> + }> + } /> + } /> + } /> + {/* Add more protected routes here */} + + } /> - } /> - - } /> - + } /> + + ); } diff --git a/src/assets/Toast/Like/heart_left.svg b/src/assets/Toast/Like/heart_left.svg new file mode 100644 index 0000000..a08b24f --- /dev/null +++ b/src/assets/Toast/Like/heart_left.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/assets/Toast/Like/heart_right.svg b/src/assets/Toast/Like/heart_right.svg new file mode 100644 index 0000000..4bf8f80 --- /dev/null +++ b/src/assets/Toast/Like/heart_right.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/components/Toast/ToastContent.css b/src/components/Toast/ToastContent.css new file mode 100644 index 0000000..ea9f592 --- /dev/null +++ b/src/components/Toast/ToastContent.css @@ -0,0 +1,77 @@ +.Toastify__toast { + background: transparent !important; + padding: 0 !important; + width: 0.5vw !important; + height: 0.1vw !important; + display: flex; + justify-content: center; + align-items: center; + position: relative; + text-align: center; + white-space: nowrap; +} + +.toast-message { + font-family: 'Poppins'; + font-weight: 400; + font-style: 'regular'; + font-size: 1.8vw; + white-space: nowrap; + letter-spacing: 2%; +} + +.like-toast { + background: #D96C81 !important; + color: #541312 !important; + width: 42vw !important; + height: 1vw !important; + top: 3vw; + border: 0.245rem solid; + opacity: 90%; + box-shadow: 0px 0.8vw 0.8vw #731d1c4f !important; + display: flex; + border-color: #ffffff; + border-bottom-color: #999999; + border-radius: 78.65px !important; + padding-top: 1.5vw; + padding-right: 8vw; + padding-bottom: 1.5vw; + padding-left: 8vw; + justify-content: center; + align-items: center; + position: relative; + text-align: center; + white-space: nowrap; +} + +.toast-icon.left, +.toast-icon.right { + width: 7vw; + height: 10vw; + position: absolute; + top: 50%; + transform: translateY(-50%); + opacity: 0; + animation: fadeIn 0.6s ease forwards 0.4s; + z-index: 0; +} + +.toast-icon.left { + left: -3.5vw; +} + +.toast-icon.right { + right: -3.5vw; + +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(-50%) scale(0.8); + } + to { + opacity: 1; + transform: translateY(-50%) scale(1); + } +} \ No newline at end of file diff --git a/src/components/Toast/ToastContent.jsx b/src/components/Toast/ToastContent.jsx new file mode 100644 index 0000000..108cfae --- /dev/null +++ b/src/components/Toast/ToastContent.jsx @@ -0,0 +1,35 @@ +import React, { useEffect, useState } from "react"; +import './ToastContent.css'; +import heartLeftIcon from '../../assets/Toast/Like/heart_left.svg'; +import heartRightIcon from '../../assets/Toast/Like/heart_right.svg'; + +const ToastTemplate = { + like: { + className: 'like-toast', + leftIcon: heartLeftIcon, + rightIcon: heartRightIcon, + message: "Crush initiated. Let’s hope it’s mutual ✨", + } + // more templates will be added here +} + +const ToastContent = ({ type }) => { + const [showIcons, setShowIcons] = useState(false); + const ToastTemplates = ToastTemplate[type]; + + useEffect(() => { + const timer = setTimeout(() => setShowIcons(true), 400); + return () => clearTimeout(timer); + }, []); + + return ( +
+ {showIcons && } +

{ToastTemplates.message}

+ {showIcons && } +
+); + +}; + +export default ToastContent; diff --git a/src/components/Toast/useCustomToast.jsx b/src/components/Toast/useCustomToast.jsx new file mode 100644 index 0000000..de9de85 --- /dev/null +++ b/src/components/Toast/useCustomToast.jsx @@ -0,0 +1,23 @@ +import { toast } from 'react-toastify'; +import ToastContent from './ToastContent'; + +const useCustomToast = () => { + const showToast = (type) => { + toast(, { + toastClassName: ({type}) => `toast-shell ${type}-toast`, + position: "top-center", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: false, + pauseOnHover: false, + draggable: false, + closeButton: false, +}); + + + }; + + return { showToast }; +}; + +export default useCustomToast;