UNPKG

@ieltsrealtest/ui

Version:

Reusable UI components for IELTS Real Test platform, built with React and TypeScript.

149 lines (148 loc) 13.7 kB
/* eslint-disable @typescript-eslint/no-unused-vars */ "use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import Link from "next/link"; import Image from "next/image"; import { useState, useEffect, useMemo } from "react"; import { FaInfoCircle, FaUserShield, FaRegHandshake, FaPhoneAlt, FaEnvelope, FaFacebookF, FaMapMarkerAlt, FaPaperPlane, } from "react-icons/fa"; import { FiX } from "react-icons/fi"; import AuthDialog from "../../common/AuthDialog/AuthDialog"; const Footer = ({ isDev = false }) => { const [isLoggedIn, setIsLoggedIn] = useState(false); const [userName, setUserName] = useState(""); const [avatar, setAvatar] = useState(""); const [feedback, setFeedback] = useState(""); const [category, setCategory] = useState("Feedback"); const [openFeedback, setOpenFeedback] = useState(false); const [authDialogOpen, setAuthDialogOpen] = useState(false); const [showSuccess, setShowSuccess] = useState(false); const [showError, setShowError] = useState(false); const { USER_BASE_URL, USER_API_BASE_URL, API_BASE_URL } = useMemo(() => { if (isDev) { return { USER_BASE_URL: "https://dev.youready.net/ielts/user", USER_API_BASE_URL: "https://devapi.youready.net/ielts/user/api/", API_BASE_URL: "https://devapi.youready.net/ielts/portal/api/", }; } return { USER_BASE_URL: "https://www.youready.net/ielts/user", USER_API_BASE_URL: "https://api.youready.net/ielts/user/api/", API_BASE_URL: "https://api.youready.net/ielts/portal/api/", }; }, [isDev]); useEffect(() => { const userStr = sessionStorage.getItem("user"); const cachedUser = userStr ? JSON.parse(userStr) : null; let userFields = []; if (!cachedUser?.avatar) userFields.push("avatar"); if (!cachedUser?.first_name || !cachedUser?.last_name) { userFields.push("first_name", "last_name"); } if (cachedUser?.avatar) setAvatar(cachedUser.avatar); if (cachedUser?.first_name && cachedUser?.last_name) { setUserName(`${cachedUser.first_name} ${cachedUser.last_name}`); } const handleSessionExpired = () => { sessionStorage.removeItem("user"); setIsLoggedIn(false); }; if (userFields.length === 0) { setIsLoggedIn(!!cachedUser); return; } const userAPIUrl = `${USER_API_BASE_URL}profile/users/?fields=${userFields.join(",")}`; const fetchUserData = async () => { try { let res = await fetch(userAPIUrl, { method: "GET", headers: { "Content-Type": "application/json" }, credentials: "include", }); if (res.status === 401 || res.status === 400) { const refreshUrl = `${USER_API_BASE_URL}auth/refresh_Token/`; const refreshRes = await fetch(refreshUrl, { method: "POST", credentials: "include", }); if (refreshRes.ok) { res = await fetch(userAPIUrl, { method: "GET", headers: { "Content-Type": "application/json" }, credentials: "include", }); } else { handleSessionExpired(); return; } } if (!res.ok) throw new Error("Failed to fetch user data"); const data = await res.json(); const user = data.data || {}; const updatedUser = { ...cachedUser, ...user }; sessionStorage.setItem("user", JSON.stringify(updatedUser)); if (user.avatar && !cachedUser?.avatar) setAvatar(user.avatar); if (user.first_name && user.last_name && (!cachedUser?.first_name || !cachedUser?.last_name)) { setUserName(`${user.first_name} ${user.last_name}`); } setIsLoggedIn(true); } catch (error) { setIsLoggedIn(false); } }; fetchUserData(); }, []); const handleSubmit = async (e) => { e.preventDefault(); if (!feedback.trim()) return; try { const res = await fetch(`${API_BASE_URL}feedback/`, { method: "POST", credentials: "include", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ content: feedback, user_name: userName, avatar: avatar, category: category, }), }); if (res.ok) { // alert("Thank you for your feedback!"); setFeedback(""); setOpenFeedback(false); setShowSuccess(true); } else { setShowError(true); ; } } catch (err) { setShowError(true); } }; return (_jsxs("footer", { className: "bg-[#FFF9F1] max-lg:pb-[100px]", children: [_jsxs("div", { className: "py-6 mt-12 grid grid-cols-1 gap-6 sm:gap-10 text-sm text-black", children: [_jsxs("div", { className: "flex justify-around sm:w-[40%] w-full", children: [_jsxs("div", { className: "ms-0 sm:ms-20 space-x-7", children: [_jsx("h4", { className: "font-semibold mb-2 text-[#A11D33] flex items-center", children: _jsx(Image, { src: "https://ieltsrealtest.s3.us-east-1.amazonaws.com/public/common/Logo+ngang_.png", alt: " ", width: 100, height: 52, className: "-translate-y-2" }) }), _jsxs("ul", { className: "space-y-2 -translate-y-2", children: [_jsxs("li", { className: "flex items-center hover:text-[#A11D33]", children: [_jsx(FaInfoCircle, { className: "mr-2" }), _jsx(Link, { href: isDev ? "https://dev.youready.net/ielts/about-us/" : "https://www.youready.net/ielts/about-us/", children: " About Us" })] }), _jsxs("li", { className: "flex items-center hover:text-[#A11D33]", children: [_jsx(FaUserShield, { className: "mr-2" }), _jsx(Link, { href: isDev ? "https://dev.youready.net/ielts/privacy-policy/" : "https://www.youready.net/ielts/privacy-policy/", children: "Privacy Policy" })] }), _jsxs("li", { className: "flex items-center hover:text-[#A11D33]", children: [_jsx(FaRegHandshake, { className: "mr-2" }), _jsx(Link, { href: isDev ? "https://dev.youready.net/ielts/terms-of-use/" : "https://www.youready.net/ielts/terms-of-use/", children: "Terms of Use" })] }), _jsxs("li", { className: "flex items-center hover:text-[#A11D33]", children: [_jsx(FaRegHandshake, { className: "mr-2" }), _jsx(Link, { href: isDev ? "https://dev.youready.net/ielts/disclaimer/" : "https://www.youready.net/ielts/disclaimer/", children: "Disclaimer" })] })] })] }), _jsx("div", { className: "flex justify-end", children: _jsxs("div", { children: [_jsx("p", { className: "font-bold w-[110px] h-[52px] text-black flex items-center hover:text-[#A11D33]", children: _jsx(Link, { href: isDev ? "https://dev.youready.net/ielts/contact-us/" : "https://www.youready.net/ielts/contact-us/", children: "CONTACT US" }) }), _jsxs("ul", { className: "space-y-2 translate-y-[7px]", children: [_jsx("li", { className: "flex items-center", children: _jsxs("a", { className: "flex items-center hover:text-[#A11D33]", href: "tel:+84389338042", children: [_jsx(FaPhoneAlt, { className: "mr-2" }), "Hotline"] }) }), _jsx("li", { className: "flex items-center", children: _jsxs("a", { className: "flex items-center hover:text-[#A11D33]", href: "mailto:eyecode@eyecodetech.com", children: [_jsx(FaEnvelope, { className: "mr-2" }), "Email"] }) }), _jsx("li", { children: _jsxs("a", { className: "flex items-center hover:text-[#A11D33]", href: "https://www.facebook.com/youreadyforielts", children: [_jsx(FaFacebookF, { className: "mr-2" }), "Facebook"] }) }), _jsx("li", { className: "flex items-center", children: _jsxs("a", { className: "flex items-center hover:text-[#A11D33]", href: "https://maps.app.goo.gl/uWchP4MCoEULdCwK8", children: [_jsx(FaMapMarkerAlt, { className: "mr-2" }), "Location"] }) })] })] }) })] }), _jsx("div", { className: `fixed inset-0 ${openFeedback ? "" : "hidden"} z-50 bg-black/30 flex items-center justify-center p-4`, onClick: () => setOpenFeedback(false), children: _jsxs("div", { className: "bg-[#FFEBD3] rounded-2xl w-full max-w-lg p-6 relative shadow-lg", onClick: (e) => e.stopPropagation(), children: [_jsx("button", { className: "absolute top-4 right-4 text-gray-700 hover:text-black cursor-pointer", onClick: () => setOpenFeedback(false), children: _jsx(FiX, { size: 22 }) }), _jsxs("form", { onSubmit: handleSubmit, children: [_jsx("h2", { className: "text-2xl font-bold mb-1", children: "Send us your feedback!" }), _jsxs("p", { className: "text-sm text-gray-700 mb-4", children: ["Found a bug or have a suggestion?", _jsx("br", {}), "Tell us what\u2019s on your mind."] }), _jsx("textarea", { placeholder: "Describe your issue or idea...", className: "w-full bg-white h-40 p-3 border border-gray-300 rounded resize-none focus:outline-none focus:ring-2 focus:ring-red-300 mb-4", value: feedback, onChange: (e) => setFeedback(e.target.value) }), _jsx("div", { className: "flex items-center space-x-6 mb-6", children: ["Bug", "Feedback", "Feature Request"].map((option) => (_jsxs("label", { className: "flex items-center space-x-2 cursor-pointer", children: [_jsx("input", { type: "radio", name: "category", value: option, checked: category === option, onChange: () => setCategory(option), className: "accent-red-500" }), _jsx("span", { children: option })] }, option))) }), _jsx("button", { type: "submit", className: "w-full bg-red-600 text-white py-3 rounded-lg font-medium hover:bg-red-700 transition disabled:opacity-50", disabled: !isLoggedIn || !feedback.trim(), title: !isLoggedIn ? "Please log in to submit feedback" : "", children: "Send Feedback" })] })] }) }), _jsxs("div", { className: "sm:absolute right-[100px] max-sm:px-7", children: [_jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col sm:flex-row space-x-0 sm:space-x-2 mt-4 sm:mt-0", children: [_jsxs("button", { type: "button" // không submit ở đây, chỉ mở modal , // check login ở đây để hiện tooltip onClick: async () => { if (!isLoggedIn) { setAuthDialogOpen(true); // Mở modal đăng nhập return; } setOpenFeedback(true); // Nếu đã đăng nhập thì mở modal góp ý }, className: "bg-red-600 text-white px-4 py-2 mt-2 sm:mt-0 rounded flex items-center", children: [_jsx(FaPaperPlane, { className: "mr-2" }), "Leave us feedback"] }), _jsx(AuthDialog, { isOpen: authDialogOpen, onClose: () => setAuthDialogOpen(false), onSignIn: () => { setAuthDialogOpen(false); window.location.href = `${USER_BASE_URL}/pages/auth/signin/`; }, description: "You need to login to send feedback." })] }), _jsx("p", { className: "mt-8 sm:mt-20 text-center sm:text-left", children: "\u00A92025 IELTSrealTest, Inc. All rights reserved." })] })] }), showSuccess && (_jsx("div", { className: "fixed inset-0 bg-black/50 bg-opacity-40 flex items-center justify-center z-50", children: _jsxs("div", { className: "bg-white rounded-lg shadow-lg max-w-sm w-full p-6 text-center relative", children: [_jsx("div", { className: "mb-4 bg-orange-100 rounded-full flex items-center justify-center w-16 h-16 mx-auto", children: _jsx(Image, { src: "https://ieltsrealtest.s3.us-east-1.amazonaws.com/public/common/Logo+ngang_.png", alt: "Logo", width: 60, height: 60 }) }), _jsx("h2", { className: "text-green-700 font-bold text-lg mb-2", children: "Feedback sent successfully!" }), _jsx("p", { className: "text-gray-600 mb-4", children: "We have received your feedback." }), _jsx("button", { onClick: () => setShowSuccess(false), className: "bg-red-600 text-white font-[18px] px-4 py-2 rounded hover:bg-red-700", children: "OK" })] }) })), showError && (_jsx("div", { className: "fixed inset-0 bg-black/50 bg-opacity-40 flex items-center justify-center z-50", children: _jsxs("div", { className: "bg-white rounded-lg shadow-lg max-w-sm w-full p-6 text-center relative", children: [_jsx("div", { className: "mb-4 bg-orange-100 rounded-full flex items-center justify-center w-16 h-16 mx-auto", children: _jsx(Image, { src: "https://ieltsrealtest.s3.us-east-1.amazonaws.com/public/common/Logo+ngang_.png", alt: "Logo", width: 60, height: 60 }) }), _jsx("h2", { className: "text-red-700 font-bold text-lg mb-2", children: "Failed to send feedback" }), _jsx("p", { className: "text-gray-600 mb-4", children: "Failed to send your feedback. Please try again." }), _jsx("button", { onClick: () => setShowError(false), className: "bg-red-600 text-white px-4 py-2 rounded hover:bg-red-700", children: "Close" })] }) }))] })); }; export default Footer;