- {locale === "fa" ? "در حال حاضر پروژهای در این دستهبندی وجود ندارد. لطفاً دستهبندی دیگری را انتخاب کنید." : "No projects in this category yet. Please try another category."}
+ {isRTL ? "در حال حاضر پروژهای در این دستهبندی وجود ندارد. لطفاً دستهبندی دیگری را انتخاب کنید." : "No projects in this category yet. Please try another category."}
)}
@@ -266,7 +267,7 @@ export default function Projects({ dict }: MyProjectsProps) {
exit={{ opacity: 0, scale: 0.9, y: 20 }}
transition={{ duration: 0.3 }}
onClick={(e) => e.stopPropagation()}
- className="relative w-full max-w-3xl max-h-[90vh] overflow-y-auto rounded-3xl bg-background border border-border shadow-2xl"
+ className="relative w-full max-w-5xl max-h-[90vh] rounded-3xl bg-background border border-border shadow-2xl overflow-hidden"
>
- {selectedProject.images.map((image, idx) => (
-
- ))}
-
+
+ {/* Left: Image */}
+
+ {selectedProject.images.map((image, idx) => (
+
+ ))}
+
+
-
-
- {selectedProject.category}
-
-
- {selectedProject.title}
-
-
- {locale === "fa"
- ? "توضیحات کامل پروژه در این بخش نمایش داده میشود."
- : "Full project description will be displayed here."}
-
-
+ {/* Right: Details */}
+
+
+
+ {selectedProject.category}
+
+
+ {selectedProject.title}
+
-
-
-
- {currentModalIndex + 1} / {filteredProjects.length}
-
-
+
+
+ {selectedProject.category}
+
+
+ {isRTL ? "طراحی وب" : "Web Design"}
+
+
+ {isRTL ? "توسعه" : "Development"}
+
+
+
+
+ {isRTL
+ ? "این پروژه با استفاده از آخرین تکنولوژیهای وب توسعه یافته است. تیم ما با دقت و توجه به جزئیات، راهکاری scalable و maintainable ارائه داده است که نیازهای کسب و کار را به بهترین شکل برآورده میکند. از طراحی رابط کاربری گرفته تا بهینهسازی performance، تمامی جنبههای این پروژه با بالاترین استانداردها پیادهسازی شده است."
+ : "This project was built using the latest web technologies. Our team delivered a scalable and maintainable solution with meticulous attention to detail, meeting business requirements effectively. From UI/UX design to performance optimization, every aspect was implemented to the highest standards."}
+
+
+
+ {/* Navigation */}
+
+
+
+ {currentModalIndex + 1} / {filteredProjects.length}
+
+
+
+
diff --git a/src/app/(routes)/(website)/components/selectLanguage/selectLanguage.tsx b/src/app/(routes)/(website)/components/selectLanguage/selectLanguage.tsx
index 637c247..c63a878 100644
--- a/src/app/(routes)/(website)/components/selectLanguage/selectLanguage.tsx
+++ b/src/app/(routes)/(website)/components/selectLanguage/selectLanguage.tsx
@@ -1,40 +1,29 @@
"use client";
-import { setCookie } from "cookies-next";
-import { LocaleCookieType } from "@/app/types/types";
+import { getCookie, setCookie } from "cookies-next";
import { useRouter } from "next/navigation";
-import { useState } from "react";
+import { useState, useEffect } from "react";
import Link from "next/link";
-interface SelectLanguageProps {
- selectedLocale: LocaleCookieType | undefined;
- defaultLocale: LocaleCookieType | undefined;
-}
-
-export default function SelectLanguage({
- selectedLocale,
- defaultLocale,
-}: SelectLanguageProps) {
+export default function SelectLanguage() {
const router = useRouter();
const [isOpen, setisOpen] = useState(false);
+ const [currentLocale, setCurrentLocale] = useState("");
+
+ useEffect(() => {
+ const sl = getCookie("selectedLocale");
+ const dl = getCookie("defaultLocale");
+ setCurrentLocale(sl || dl || "en");
+ }, []);
return (
- {selectedLocale ? (
-
setisOpen(!isOpen)}
- className="mx-2 mb-[5px] cursor-pointer select-none whitespace-nowrap border-b-2 border-[#FD6F00] px-2 py-[10px] pb-[5px] text-[15px] font-[600] text-[#FD6F00] hover:text-[#FD6F00] xl:text-[20px]"
- >
- {selectedLocale?.value}
-
- ) : (
-
setisOpen(!isOpen)}
- className="mx-2 mb-[5px] cursor-pointer select-none whitespace-nowrap px-2 py-[10px] pb-[5px] text-[15px] font-[600] hover:text-[#FD6F00] xl:text-[20px]"
- >
- {defaultLocale?.value}
-
- )}
+
setisOpen(!isOpen)}
+ className="mx-2 mb-[5px] cursor-pointer select-none whitespace-nowrap border-b-2 border-[#FD6F00] px-2 py-[10px] pb-[5px] text-[15px] font-[600] text-[#FD6F00] hover:text-[#FD6F00] xl:text-[20px]"
+ >
+ {currentLocale}
+
(null);
+ const [locale, setLocale] = useState("en");
+
+ useEffect(() => {
+ const sl = getCookie("selectedLocale");
+ const dl = getCookie("defaultLocale");
+ setLocale(sl || dl || "en");
+ }, []);
+
+ const isRTL = locale === "fa";
const maxIndex = Math.max(0, testimonials.length - 3);
const scrollTo = (index: number) => {
@@ -114,14 +131,14 @@ export default function Testimonials({ dict }: TestimonialsProps) {
transition={{ duration: 0.5, delay: index * 0.1 }}
viewport={{ once: true }}
whileHover={{ y: -10 }}
- className="relative p-8 rounded-3xl glass-panel flex flex-col h-full"
+ className="relative p-6 md:p-8 rounded-3xl glass-panel flex flex-col h-full"
>
-
-
+
@@ -155,20 +172,20 @@ export default function Testimonials({ dict }: TestimonialsProps) {
{testimonials.length > 3 && (
<>
diff --git a/src/app/globals.css b/src/app/globals.css
index 4cac22f..b9bfc7f 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -2,6 +2,10 @@
@tailwind components;
@tailwind utilities;
+html {
+ scroll-behavior: smooth;
+}
+
@layer base {
:root {
--background: 240 10% 98%;
@@ -82,6 +86,20 @@
scrollbar-width: none;
}
+.custom-scrollbar::-webkit-scrollbar {
+ width: 6px;
+}
+.custom-scrollbar::-webkit-scrollbar-track {
+ background: transparent;
+}
+.custom-scrollbar::-webkit-scrollbar-thumb {
+ background: hsl(var(--muted-foreground) / 0.3);
+ border-radius: 999px;
+}
+.custom-scrollbar::-webkit-scrollbar-thumb:hover {
+ background: hsl(var(--muted-foreground) / 0.5);
+}
+
.mesh-gradient {
background-image:
radial-gradient(at 0% 0%, hsla(30, 80%, 50%, 0.15) 0px, transparent 50%),
diff --git a/src/app/lib/functions/dictionaries.ts b/src/app/lib/functions/dictionaries.ts
index 176da17..5c87d6d 100644
--- a/src/app/lib/functions/dictionaries.ts
+++ b/src/app/lib/functions/dictionaries.ts
@@ -1,5 +1,4 @@
import { Dictionary } from "@/app/types/types";
-import "server-only";
const dictionaries: { [key: string]: () => Promise } = {
en: () => import("../dictionaries/en.json").then((module) => module.default),