diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ea86769a..977cd343 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,8 +14,10 @@ "@fortawesome/react-fontawesome": "^0.2.0", "@react-oauth/google": "^0.12.1", "axios": "^1.6.3", + "framer-motion": "^11.11.8", "install": "^0.13.0", "jwt-decode": "^4.0.0", + "lucide-react": "^0.452.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.26.2", @@ -4287,6 +4289,31 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/framer-motion": { + "version": "11.11.8", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.8.tgz", + "integrity": "sha512-mnGQNEoz99GtFXBBPw+Ag5K4FcfP5XrXxrxHz+iE4Lmg7W3sf2gKmGuvfkZCW/yIfcdv5vJd6KiSPETH1Pw68Q==", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -5368,6 +5395,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "0.452.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.452.0.tgz", + "integrity": "sha512-kNefjOUOGm+Mu3KDiryONyPba9r+nhcrz5oJs3N6JDzGboQNEXw5GB3yB8rnV9/FA4bPyggNU6CRSihZm9MvSw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + } + }, "node_modules/magic-string": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", @@ -7042,6 +7078,12 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "dev": true }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 08bf99f8..6eb95d0c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,8 +17,10 @@ "@fortawesome/react-fontawesome": "^0.2.0", "@react-oauth/google": "^0.12.1", "axios": "^1.6.3", + "framer-motion": "^11.11.8", "install": "^0.13.0", "jwt-decode": "^4.0.0", + "lucide-react": "^0.452.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.26.2", diff --git a/frontend/src/Components/Footer.jsx b/frontend/src/Components/Footer.jsx index ca1790de..5b929450 100644 --- a/frontend/src/Components/Footer.jsx +++ b/frontend/src/Components/Footer.jsx @@ -12,6 +12,8 @@ import { import { Link, useLocation } from "react-router-dom"; import { toast } from "react-toastify"; import GoogleTranslate from "./GoogleTranslate"; +import { motion, AnimatePresence } from "framer-motion"; + const Footer = () => { const [showModal, setShowModal] = useState(false); const [rating, setRating] = useState(0); @@ -23,7 +25,7 @@ const Footer = () => { const backendURL = import.meta.env.VITE_BACKEND_URL; const path = useLocation().pathname; - // Check if the content is smaller than the screen + // Check if the content is smaller than the screen useEffect(() => { const handleResize = () => { const contentHeight = document.documentElement.scrollHeight; @@ -81,25 +83,48 @@ const Footer = () => { const openModal = () => { setSubmitStatus(null); setShowModal(true); - setName(""); setEmail(""); setMessage(""); setRating(0); - setShowModal(true); + }; + + const socialIconVariants = { + hover: { + scale: 1.2, + rotate: 5, + transition: { + duration: 0.3, + yoyo: Infinity + } + }, + tap: { scale: 0.9 }, + }; + + const buttonVariants = { + hover: { scale: 1.05, backgroundColor: "#DC2626", color: "#FFFFFF" }, + tap: { scale: 0.95 }, }; return ( -
+
{path !== "/user" && ( <> -
+
- + TastyTrails - +

© {new Date().getFullYear()} TastyTrails Developer — { @A_l_f_i_y_A - +

- - - - - - - - - - - + {[ + { icon: faInstagramSquare, link: "https://www.instagram.com/alfiya.17.siddiq/" }, + { icon: faLinkedinIn, link: "https://www.linkedin.com/in/alfiya-siddique-987a59240/" }, + { icon: faGithubSquare, link: "https://github.com/AlfiyaSiddique" }, + ].map((social, index) => ( + + 0 ? 'ml-3' : ''} text-red-700`}> + + + + ))} -
- -
- -
+ Feedback - +
- + - {/* Modal */} - {showModal && ( -
-
- {submitStatus === null ? ( - <> - {/* Show the form if no status has been set */} -

Feedback

-
-
- - setName(e.target.value)} - required + + {showModal && ( + + + {submitStatus === null ? ( + <> +

Feedback

+ +
+ + setName(e.target.value)} + required + /> +
+
+ + setEmail(e.target.value)} + required + /> +
+
+ + +
+
+ +
+ {[1, 2, 3, 4, 5].map((star) => ( + = star + ? "text-yellow-400" + : "text-gray-400" + }`} + onClick={() => handleRating(star)} + > + {rating >= star ? "★" : "☆"} + + ))} +
+ {!rating && ( +

+ Rating is required! +

+ )} +
+
+ setShowModal(false)} + > + Close + + + Submit + +
+ + + ) : submitStatus === "success" ? ( +
+ + -
- -
- - setEmail(e.target.value)} - required + +

+ Feedback sent successfully! +

+ setShowModal(false)} + > + Close + +
+ ) : ( +
+ + -
- -
- - -
- -
- -
- {[1, 2, 3, 4, 5].map((star) => ( - = star - ? "text-yellow-400" - : "text-gray-400" - }`} - onClick={() => handleRating(star)} - > - {rating >= star ? "★" : "☆"} - - ))} -
- {!rating && ( -

- Rating is required! -

- )} -
- -
- - -
- - - ) : submitStatus === "success" ? ( -
- -

- Feedback sent successfully! -

- -
- ) : ( -
- -

- Error in sending Feedback! -

- -
- )} -
-
- )} + +

+ Error in sending Feedback! +

+ setShowModal(false)} + > + Close + +
+ )} + + + )} + )}
); }; -export default Footer; +export default Footer; \ No newline at end of file