@ieltsrealtest/ui
Version:
Reusable UI components for IELTS Real Test platform, built with React and TypeScript.
149 lines (148 loc) • 13.7 kB
JavaScript
/* 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;