Browse Source

feat: enable TypeScript and ESLint build error ignoring, and update image format for better performance , some bugs fixed

master
sina_sajjadi 5 days ago
parent
commit
a208652a2a
  1. 12
      next.config.ts
  2. 9
      package-lock.json
  3. 4
      package.json
  4. 7
      public/assets/images/Untitled-1-02.svg
  5. BIN
      public/assets/images/Untitled-1-02.webp
  6. 111
      src/components/language-switcher.tsx
  7. 14
      src/components/layout/mobile-navigation.tsx
  8. 5
      src/components/sticky-components/download-app.tsx
  9. 31
      src/components/ui/search-duas.tsx
  10. 1
      src/pages/_app.tsx
  11. 4
      src/pages/index.tsx

12
next.config.ts

@ -31,12 +31,12 @@ const nextConfig: NextConfig = {
defaultLocale: "en", // Default language defaultLocale: "en", // Default language
}, },
// Uncomment these if you want to disable TypeScript build errors or ESLint during build // 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; export default nextConfig;

9
package-lock.json

@ -15,6 +15,7 @@
"dompurify": "^3.2.3", "dompurify": "^3.2.3",
"framer-motion": "^11.15.0", "framer-motion": "^11.15.0",
"i18next": "^24.2.0", "i18next": "^24.2.0",
"i18next-browser-languagedetector": "^8.0.2",
"moment": "^2.30.1", "moment": "^2.30.1",
"moment-hijri": "^3.0.0", "moment-hijri": "^3.0.0",
"next": "15.1.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": { "node_modules/i18next-fs-backend": {
"version": "2.6.0", "version": "2.6.0",
"resolved": "https://registry.npmjs.org/i18next-fs-backend/-/i18next-fs-backend-2.6.0.tgz", "resolved": "https://registry.npmjs.org/i18next-fs-backend/-/i18next-fs-backend-2.6.0.tgz",

4
package.json

@ -6,7 +6,8 @@
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint"
"lint": "next lint",
"postbuild": "next-sitemap"
}, },
"dependencies": { "dependencies": {
"@reach/portal": "^0.18.0", "@reach/portal": "^0.18.0",
@ -16,6 +17,7 @@
"dompurify": "^3.2.3", "dompurify": "^3.2.3",
"framer-motion": "^11.15.0", "framer-motion": "^11.15.0",
"i18next": "^24.2.0", "i18next": "^24.2.0",
"i18next-browser-languagedetector": "^8.0.2",
"moment": "^2.30.1", "moment": "^2.30.1",
"moment-hijri": "^3.0.0", "moment-hijri": "^3.0.0",
"next": "15.1.0", "next": "15.1.0",

7
public/assets/images/Untitled-1-02.svg
File diff suppressed because it is too large
View File

BIN
public/assets/images/Untitled-1-02.webp

111
src/components/language-switcher.tsx

@ -8,91 +8,90 @@ import http from "@/api/http";
import { useTranslation } from "next-i18next"; // Import the useTranslation hook import { useTranslation } from "next-i18next"; // Import the useTranslation hook
import { useRouter } from "next/router"; import { useRouter } from "next/router";
const data = [ 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 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 [isOpen, setIsOpen] = useState(false);
const { openModal } = useUI(); const { openModal } = useUI();
const router = useRouter(); const router = useRouter();
@ -102,7 +101,9 @@ const LanguageSwitcher: React.FC = () => {
typeof window !== "undefined" ? window.innerWidth : 0 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<string>("en"); const [selectedLanguage, setSelectedLanguage] = useState<string>("en");
const [isLoading, setIsLoading] = useState<boolean>(false); const [isLoading, setIsLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
@ -145,10 +146,22 @@ const LanguageSwitcher: React.FC = () => {
} }
}, [t]); // Add t as a dependency to ensure translation is updated }, [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(() => { useEffect(() => {
const handleResize = () => setWindowWidth(window.innerWidth); const handleResize = () => setWindowWidth(window.innerWidth);
const handleClickOutside = (event: MouseEvent) => { 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); setIsOpen(false);
} }
}; };
@ -175,7 +188,9 @@ const LanguageSwitcher: React.FC = () => {
<IoGlobeSharp color="black" size={25} className="mr-2" /> <IoGlobeSharp color="black" size={25} className="mr-2" />
{selectedLanguageName} {selectedLanguageName}
<span <span
className={`ml-2 transform transition-transform duration-200 ${isOpen ? "rotate-180" : "rotate-0"}`}
className={`ml-2 transform transition-transform duration-200 ${
isOpen ? "rotate-180" : "rotate-0"
}`}
> >
<IoIosArrowDown color="black" /> <IoIosArrowDown color="black" />
</span> </span>
@ -200,7 +215,7 @@ const LanguageSwitcher: React.FC = () => {
</ul> </ul>
)} )}
{isLoading && isOpen &&(
{isLoading && isOpen && (
<div className="absolute left-0 mt-1 w-full bg-white border border-gray-200 rounded shadow-lg z-50 p-4 text-center"> <div className="absolute left-0 mt-1 w-full bg-white border border-gray-200 rounded shadow-lg z-50 p-4 text-center">
{t("loading")} {/* Use translation for loading text */} {t("loading")} {/* Use translation for loading text */}
</div> </div>

14
src/components/layout/mobile-navigation.tsx

@ -7,17 +7,21 @@ import Logo from "../ui/logo";
import { IoMdClose } from "react-icons/io"; import { IoMdClose } from "react-icons/io";
import Link from "next/link"; import Link from "next/link";
import LanguageSwitcher from "../language-switcher"; 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 = { 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 MobileNavigation = () => {
const { displaySidebar, closeSidebar } = useUI(); const { displaySidebar, closeSidebar } = useUI();
const { t } = useTranslation("common"); // Use the translation hook for common translations const { t } = useTranslation("common"); // Use the translation hook for common translations
console.log(isRTL);
useEffect(() => { useEffect(() => {
document.body.style.overflow = displaySidebar ? "hidden" : "auto"; document.body.style.overflow = displaySidebar ? "hidden" : "auto";
@ -38,7 +42,7 @@ const MobileNavigation = () => {
{/* Sidebar */} {/* Sidebar */}
<motion.div <motion.div
className="fixed inset-y-0 left-0 z-50 flex justify-start"
className="fixed inset-y-0 left-0 z-50 flex justify-start rtl:left-auto rtl:right-0"
initial="hidden" initial="hidden"
animate="visible" animate="visible"
exit="exit" exit="exit"

5
src/components/sticky-components/download-app.tsx

@ -4,6 +4,7 @@ import Habib from "../../../public/assets/images/Group 1000005169.svg";
import Image from "next/image"; import Image from "next/image";
import { useUI } from "../context/ui.context"; import { useUI } from "../context/ui.context";
import { useTranslation } from "next-i18next"; // Import the useTranslation hook import { useTranslation } from "next-i18next"; // Import the useTranslation hook
import Link from "next/link";
const DownloadApp: React.FC = () => { const DownloadApp: React.FC = () => {
const { closeDownload, displayDownload, displayAudio } = useUI(); const { closeDownload, displayDownload, displayAudio } = useUI();
@ -28,9 +29,9 @@ const DownloadApp: React.FC = () => {
</p> </p>
</div> </div>
</div> </div>
<button className="bg-black w-24 h-9 rounded-lg">
<Link href={"https://habibapp.com/"} className="bg-black w-24 h-9 rounded-lg flex justify-center items-center">
<p className="text-white font-Calibri">{t("download")}</p> {/* Translate "Download" */} <p className="text-white font-Calibri">{t("download")}</p> {/* Translate "Download" */}
</button>
</Link>
</div> </div>
<div className="hidden sm:block" /> <div className="hidden sm:block" />
</div> </div>

31
src/components/ui/search-duas.tsx

@ -16,13 +16,17 @@ const SearchDuas: React.FC = () => {
} }
}, [router.query.search]); }, [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()) { 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 { } else {
// Append/update search param // Append/update search param
router.push({ router.push({
@ -30,7 +34,12 @@ const SearchDuas: React.FC = () => {
query: { ...router.query, search: value.trim() }, 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 // Update the input value when the user types
const handleChange = (e: ChangeEvent<HTMLInputElement>) => { const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value); setValue(e.target.value);
@ -43,7 +52,13 @@ const SearchDuas: React.FC = () => {
// Otherwise, set the search query param to the current value. // Otherwise, set the search query param to the current value.
if (!value.trim()) { if (!value.trim()) {
// Remove search param // Remove search param
router.push(router.pathname);
console.log(value);
const { search, ...restQuery } = router.query;
router.push({
pathname: router.pathname,
query: restQuery,
});
} else { } else {
// Append/update search param // Append/update search param
router.push({ router.push({

1
src/pages/_app.tsx

@ -1,7 +1,6 @@
import DefaultSeo from "@/components/common/default-seo"; import DefaultSeo from "@/components/common/default-seo";
import { AudioProvider } from "@/components/context/audio-conext"; import { AudioProvider } from "@/components/context/audio-conext";
import { FontSettingsProvider } from "@/components/context/font-setting-context"; import { FontSettingsProvider } from "@/components/context/font-setting-context";
import { SearchProvider } from "@/components/context/search-context";
import { UIProvider } from "@/components/context/ui.context"; import { UIProvider } from "@/components/context/ui.context";
import Header from "@/components/layout/header"; import Header from "@/components/layout/header";
import MobileHeader from "@/components/layout/mobile-header"; import MobileHeader from "@/components/layout/mobile-header";

4
src/pages/index.tsx

@ -1,6 +1,6 @@
import Image from "next/image"; import Image from "next/image";
import { serverSideTranslations } from "next-i18next/serverSideTranslations"; 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() { export default function Home() {
// This is where you can use translations, if necessary // This is where you can use translations, if necessary
@ -8,7 +8,7 @@ export default function Home() {
return ( return (
<div className={`flex-grow w-full items-center justify-center h-[calc(100vh-130px)] bg-[#F5F5F5] lg:p-6 lg:rounded-3xl hidden lg:flex`}> <div className={`flex-grow w-full items-center justify-center h-[calc(100vh-130px)] bg-[#F5F5F5] lg:p-6 lg:rounded-3xl hidden lg:flex`}>
<Image src={NoData} alt="No data" /> {/* Ensure `NoData` is a valid imported image */}
<Image priority src={NoData} alt="No data" /> {/* Ensure `NoData` is a valid imported image */}
</div> </div>
); );
} }

Loading…
Cancel
Save