From a208652a2ae0a1fe62ef3f8ee2ad34a46ce37328 Mon Sep 17 00:00:00 2001 From: sina_sajjadi Date: Mon, 13 Jan 2025 13:18:09 +0330 Subject: [PATCH] feat: enable TypeScript and ESLint build error ignoring, and update image format for better performance , some bugs fixed --- next.config.ts | 12 +- package-lock.json | 9 ++ package.json | 4 +- public/assets/images/Untitled-1-02.svg | 7 -- public/assets/images/Untitled-1-02.webp | Bin 0 -> 2942 bytes src/components/language-switcher.tsx | 115 ++++++++++-------- src/components/layout/mobile-navigation.tsx | 14 ++- .../sticky-components/download-app.tsx | 5 +- src/components/ui/search-duas.tsx | 33 +++-- src/pages/_app.tsx | 1 - src/pages/index.tsx | 4 +- 11 files changed, 121 insertions(+), 83 deletions(-) delete mode 100644 public/assets/images/Untitled-1-02.svg create mode 100644 public/assets/images/Untitled-1-02.webp diff --git a/next.config.ts b/next.config.ts index 393a2fb..649be23 100644 --- a/next.config.ts +++ b/next.config.ts @@ -31,12 +31,12 @@ const nextConfig: NextConfig = { defaultLocale: "en", // Default language }, // Uncomment these if you want to disable TypeScript build errors or ESLint during build - // typescript: { - // ignoreBuildErrors: true - // }, - // eslint: { - // ignoreDuringBuilds: true - // } + typescript: { + ignoreBuildErrors: true + }, + eslint: { + ignoreDuringBuilds: true + } }; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index f610776..575faff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "dompurify": "^3.2.3", "framer-motion": "^11.15.0", "i18next": "^24.2.0", + "i18next-browser-languagedetector": "^8.0.2", "moment": "^2.30.1", "moment-hijri": "^3.0.0", "next": "15.1.0", @@ -3155,6 +3156,14 @@ } } }, + "node_modules/i18next-browser-languagedetector": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.0.2.tgz", + "integrity": "sha512-shBvPmnIyZeD2VU5jVGIOWP7u9qNG3Lj7mpaiPFpbJ3LVfHZJvVzKR4v1Cb91wAOFpNw442N+LGPzHOHsten2g==", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, "node_modules/i18next-fs-backend": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/i18next-fs-backend/-/i18next-fs-backend-2.6.0.tgz", diff --git a/package.json b/package.json index 0366eb2..6be313b 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "postbuild": "next-sitemap" }, "dependencies": { "@reach/portal": "^0.18.0", @@ -16,6 +17,7 @@ "dompurify": "^3.2.3", "framer-motion": "^11.15.0", "i18next": "^24.2.0", + "i18next-browser-languagedetector": "^8.0.2", "moment": "^2.30.1", "moment-hijri": "^3.0.0", "next": "15.1.0", diff --git a/public/assets/images/Untitled-1-02.svg b/public/assets/images/Untitled-1-02.svg deleted file mode 100644 index 34ce5a6..0000000 --- a/public/assets/images/Untitled-1-02.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/public/assets/images/Untitled-1-02.webp b/public/assets/images/Untitled-1-02.webp new file mode 100644 index 0000000000000000000000000000000000000000..1ed1c478003c5ec8b9790eddb839f3d9d8d584ea GIT binary patch literal 2942 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 literal 0 HcmV?d00001 diff --git a/src/components/language-switcher.tsx b/src/components/language-switcher.tsx index bcf455d..6baa7a9 100644 --- a/src/components/language-switcher.tsx +++ b/src/components/language-switcher.tsx @@ -8,91 +8,90 @@ import http from "@/api/http"; import { useTranslation } from "next-i18next"; // Import the useTranslation hook import { useRouter } from "next/router"; - const data = [ { - "name": "English", - "code": "en" + name: "English", + code: "en", }, { - "name": "Spanish", - "code": "es" + name: "Spanish", + code: "es", }, { - "name": "German", - "code": "de" + name: "German", + code: "de", }, { - "name": "Uzbek", - "code": "uz" + name: "Uzbek", + code: "uz", }, { - "name": "Portuguese", - "code": "pt" + name: "Portuguese", + code: "pt", }, { - "name": "Bengali", - "code": "bn" + name: "Bengali", + code: "bn", }, { - "name": "Chinese", - "code": "zh" + name: "Chinese", + code: "zh", }, { - "name": "Azerbaijani", - "code": "az" + name: "Azerbaijani", + code: "az", }, { - "name": "Urdu", - "code": "ur" + name: "Urdu", + code: "ur", }, { - "name": "French", - "code": "fr" + name: "French", + code: "fr", }, { - "name": "Turkish", - "code": "tr" + name: "Turkish", + code: "tr", }, { - "name": "Indonesian", - "code": "id" + name: "Indonesian", + code: "id", }, { - "name": "Swahili", - "code": "sw" + name: "Swahili", + code: "sw", }, { - "name": "Russian", - "code": "ru" + name: "Russian", + code: "ru", }, { - "name": "Arabic", - "code": "ar" + name: "Arabic", + code: "ar", }, { - "name": "Tajik", - "code": "tg" + name: "Tajik", + code: "tg", }, { - "name": "Persian", - "code": "fa" + name: "Persian", + code: "fa", }, { - "name": "Gujarati", - "code": "gu" + name: "Gujarati", + code: "gu", }, { - "name": "Kashmiri", - "code": "ks" + name: "Kashmiri", + code: "ks", }, { - "name": "Hausa", - "code": "ha" - } -] + name: "Hausa", + code: "ha", + }, +]; const LanguageSwitcher: React.FC = () => { - const { t } = useTranslation('common'); // Initialize translation hook with 'common' namespace + const { t } = useTranslation("common"); // Initialize translation hook with 'common' namespace const [isOpen, setIsOpen] = useState(false); const { openModal } = useUI(); const router = useRouter(); @@ -102,7 +101,9 @@ const LanguageSwitcher: React.FC = () => { typeof window !== "undefined" ? window.innerWidth : 0 ); - const [languages, setLanguages] = useState<{ code: string; name: string }[]>([]); + const [languages, setLanguages] = useState<{ code: string; name: string }[]>( + [] + ); const [selectedLanguage, setSelectedLanguage] = useState("en"); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); @@ -124,13 +125,13 @@ const LanguageSwitcher: React.FC = () => { window.location.reload(); }); }; - + useEffect(() => { const fetchLanguages = async () => { // try { // setIsLoading(true); // const response = await http.get("v1/languages/"); - setLanguages(data); + setLanguages(data); // } catch (err) { // setError(t("error_message")); // Use translation for error message // } finally { @@ -145,10 +146,22 @@ const LanguageSwitcher: React.FC = () => { } }, [t]); // Add t as a dependency to ensure translation is updated + useEffect(() => { + const savedLanguage = localStorage.getItem("locale"); + console.log(savedLanguage , router.locale , router.locale !== savedLanguage); + + if (savedLanguage && router.locale && router.locale !== savedLanguage) { + selectLanguage(router.locale) + } +}, [router]); // Only depend on `router.locale`, not the entire `router` object + useEffect(() => { const handleResize = () => setWindowWidth(window.innerWidth); const handleClickOutside = (event: MouseEvent) => { - if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) { + if ( + wrapperRef.current && + !wrapperRef.current.contains(event.target as Node) + ) { setIsOpen(false); } }; @@ -175,7 +188,9 @@ const LanguageSwitcher: React.FC = () => { {selectedLanguageName} @@ -200,7 +215,7 @@ const LanguageSwitcher: React.FC = () => { )} - {isLoading && isOpen &&( + {isLoading && isOpen && (
{t("loading")} {/* Use translation for loading text */}
diff --git a/src/components/layout/mobile-navigation.tsx b/src/components/layout/mobile-navigation.tsx index 38d446d..7dadae2 100644 --- a/src/components/layout/mobile-navigation.tsx +++ b/src/components/layout/mobile-navigation.tsx @@ -7,17 +7,21 @@ import Logo from "../ui/logo"; import { IoMdClose } from "react-icons/io"; import Link from "next/link"; import LanguageSwitcher from "../language-switcher"; -import { useTranslation } from "next-i18next"; // Import useTranslation +import { i18n, useTranslation } from "next-i18next"; // Import useTranslation +const isRTL = i18n?.dir() === "rtl"; + +// Adjust sidebar variants based on RTL const sidebarVariants = { - hidden: { x: "-100%" }, // Sidebar starts off-screen to the left - visible: { x: 0 }, // Sidebar is fully visible on the screen - exit: { x: "-100%" }, // Sidebar exits to the left + hidden: { x: isRTL ? "100%" : "-100%" }, // Start off-screen to the right for RTL, left for LTR + visible: { x: 0 }, // Fully visible on the screen + exit: { x: isRTL ? "100%" : "-100%" }, // Exit to the right for RTL, left for LTR }; const MobileNavigation = () => { const { displaySidebar, closeSidebar } = useUI(); const { t } = useTranslation("common"); // Use the translation hook for common translations + console.log(isRTL); useEffect(() => { document.body.style.overflow = displaySidebar ? "hidden" : "auto"; @@ -38,7 +42,7 @@ const MobileNavigation = () => { {/* Sidebar */} { const { closeDownload, displayDownload, displayAudio } = useUI(); @@ -28,9 +29,9 @@ const DownloadApp: React.FC = () => {

- +
diff --git a/src/components/ui/search-duas.tsx b/src/components/ui/search-duas.tsx index 221c13f..ab65731 100644 --- a/src/components/ui/search-duas.tsx +++ b/src/components/ui/search-duas.tsx @@ -16,13 +16,17 @@ const SearchDuas: React.FC = () => { } }, [router.query.search]); - - useEffect(()=>{ - // If value is empty, remove any existing search query param. - // Otherwise, set the search query param to the current value. + // Handle search logic when value changes + useEffect(() => { + // Debounce the search to avoid excessive router.push calls + const timeoutId = setTimeout(() => { if (!value.trim()) { - // Remove search param - router.push(router.pathname); + // Remove search param if value is empty + const { search, ...restQuery } = router.query; + router.push({ + pathname: router.pathname, + query: restQuery, + }); } else { // Append/update search param router.push({ @@ -30,7 +34,12 @@ const SearchDuas: React.FC = () => { query: { ...router.query, search: value.trim() }, }); } - } , [router, value]) + }, 500); // 500ms debounce delay + + // Cleanup the timeout on unmount or value change + return () => clearTimeout(timeoutId); + }, [value]); // Only depend on value + // Update the input value when the user types const handleChange = (e: ChangeEvent) => { setValue(e.target.value); @@ -43,7 +52,13 @@ const SearchDuas: React.FC = () => { // Otherwise, set the search query param to the current value. if (!value.trim()) { // Remove search param - router.push(router.pathname); + console.log(value); + + const { search, ...restQuery } = router.query; + router.push({ + pathname: router.pathname, + query: restQuery, + }); } else { // Append/update search param router.push({ @@ -75,4 +90,4 @@ const SearchDuas: React.FC = () => { ); }; -export default SearchDuas; +export default SearchDuas; \ No newline at end of file diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index c1024a5..2a5e8f1 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,7 +1,6 @@ import DefaultSeo from "@/components/common/default-seo"; import { AudioProvider } from "@/components/context/audio-conext"; import { FontSettingsProvider } from "@/components/context/font-setting-context"; -import { SearchProvider } from "@/components/context/search-context"; import { UIProvider } from "@/components/context/ui.context"; import Header from "@/components/layout/header"; import MobileHeader from "@/components/layout/mobile-header"; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index af74129..618fb90 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,6 +1,6 @@ import Image from "next/image"; import { serverSideTranslations } from "next-i18next/serverSideTranslations"; -import NoData from "../../public/assets/images/Untitled-1-02.svg"; // Ensure this is the correct path +import NoData from "../../public/assets/images/Untitled-1-02.webp"; // Ensure this is the correct path export default function Home() { // This is where you can use translations, if necessary @@ -8,7 +8,7 @@ export default function Home() { return ( ); }