280 lines
12 KiB
TypeScript
280 lines
12 KiB
TypeScript
"use client";
|
|
|
|
import { ArrowUp } from "lucide-react";
|
|
import { useEffect, useRef, useState } from "react";
|
|
|
|
import { Avatar, AvatarImage } from "@/components/ui/avatar";
|
|
import {
|
|
Breadcrumb,
|
|
BreadcrumbItem,
|
|
BreadcrumbLink,
|
|
BreadcrumbList,
|
|
BreadcrumbPage,
|
|
BreadcrumbSeparator,
|
|
} from "@/components/ui/breadcrumb";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Separator } from "@/components/ui/separator";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface Content4Props {
|
|
className?: string;
|
|
}
|
|
|
|
const publishedAtLabel = new Intl.DateTimeFormat("fa-IR", {
|
|
year: "numeric",
|
|
month: "long",
|
|
day: "numeric",
|
|
}).format(new Date("2024-06-15"));
|
|
|
|
const Content4 = ({ className }: Content4Props) => {
|
|
const [activeHeader, setActiveHeader] = useState<string | null>(null);
|
|
const headerRefs = useRef<Record<string, HTMLElement>>({});
|
|
const [showBackToTop, setShowBackToTop] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const headers = Object.keys(headerRefs.current);
|
|
|
|
const observerCallback = (entries: IntersectionObserverEntry[]) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting) {
|
|
setActiveHeader(entry.target.id);
|
|
}
|
|
});
|
|
};
|
|
|
|
let observer: IntersectionObserver | null = new IntersectionObserver(
|
|
observerCallback,
|
|
{
|
|
root: null,
|
|
rootMargin: "0px",
|
|
threshold: 1,
|
|
},
|
|
);
|
|
|
|
headers.forEach((headerId) => {
|
|
const element = headerRefs.current[headerId];
|
|
if (element) {
|
|
observer?.observe(element);
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
observer?.disconnect();
|
|
observer = null;
|
|
};
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
if (window.scrollY > 1000) {
|
|
setShowBackToTop(true);
|
|
} else {
|
|
setShowBackToTop(false);
|
|
}
|
|
};
|
|
|
|
window.addEventListener("scroll", handleScroll);
|
|
return () => {
|
|
window.removeEventListener("scroll", handleScroll);
|
|
};
|
|
}, []);
|
|
|
|
const addHeaderRef = (id: string, ref: HTMLElement | null) => {
|
|
if (ref) {
|
|
headerRefs.current[id] = ref;
|
|
}
|
|
};
|
|
return (
|
|
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
|
|
<div className="container">
|
|
<Breadcrumb>
|
|
<BreadcrumbList>
|
|
<BreadcrumbItem>
|
|
<BreadcrumbLink href="/">وبلاگ</BreadcrumbLink>
|
|
</BreadcrumbItem>
|
|
<BreadcrumbSeparator />
|
|
<BreadcrumbItem>
|
|
<BreadcrumbPage>کاوش افقهای تازه</BreadcrumbPage>
|
|
</BreadcrumbItem>
|
|
</BreadcrumbList>
|
|
</Breadcrumb>
|
|
<div className="mt-9 flex flex-col gap-12 md:gap-20">
|
|
<h1 className="max-w-3xl text-start text-xl font-semibold text-balance md:text-2xll">
|
|
روندهای نوین در توسعه وب
|
|
</h1>
|
|
<div className="flex items-center gap-3">
|
|
<Avatar className="border border-border">
|
|
<AvatarImage src="/block-media/shadcnblocks/block/avatar-1.webp" />
|
|
</Avatar>
|
|
<p className="text-sm tracking-tight md:text-base">
|
|
<span className="font-semibold">جین اسمیت</span>
|
|
<span className="ms-1 font-medium text-muted-foreground">
|
|
· {publishedAtLabel}
|
|
</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="relative flex max-w-6xl flex-col-reverse gap-6 lg:mt-32 lg:grid lg:grid-cols-10">
|
|
<div className="lg:col-span-6">
|
|
<img
|
|
src="/block-media/shadcnblocks/block/placeholder-1.svg"
|
|
alt="تصویر نمونه"
|
|
className="max-h-96 w-full rounded-xl border border-border object-cover"
|
|
/>
|
|
<div className="prose mt-6 text-start dark:prose-invert prose-h2:scroll-m-10">
|
|
<p>
|
|
فناوریهای توسعه وب با سرعت زیادی در حال تغییر هستند و آشنایی با ابزارها و رویکردهای جدید، نقش مهمی در موفقیت پروژههای نرمافزاری دارد.
|
|
</p>
|
|
<h2 id="header-1" ref={(ref) => addHeaderRef("header-1", ref)}>
|
|
تحول فریمورکهای فرانتاند
|
|
</h2>
|
|
<p>
|
|
فریمورکهای مدرن با ارائه معماریهای استاندارد، توسعه رابط کاربری را سریعتر، ساختاریافتهتر و قابل نگهداریتر کردهاند.
|
|
</p>
|
|
<p>
|
|
امکاناتی مانند معماری کامپوننتمحور، رندر سمت سرور، مدیریت وضعیت و بهینهسازی عملکرد، کیفیت توسعه محصولات مدرن را به شکل محسوسی افزایش دادهاند.
|
|
</p>
|
|
<img
|
|
src="/block-media/shadcnblocks/block/placeholder-2.svg"
|
|
alt="تصویر نمونه"
|
|
className="max-h-96 w-full rounded-xl border border-border object-cover"
|
|
/>
|
|
<p>
|
|
انتخاب فناوری مناسب باید بر اساس نیازهای پروژه، تجربه تیم، مقیاسپذیری و هزینه نگهداری انجام شود.
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
<p>
|
|
معماری مبتنی بر کامپوننت، قابلیت استفاده مجدد و نگهداری
|
|
بهتر در پروژههای بزرگ را ممکن میسازد.
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
راهحلهای مدیریت state به کنترل جریان داده در اپلیکیشنهای
|
|
پیچیده بهشکل مؤثر و قابل پیشبینی کمک میکنند.
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
<h2 id="header-2" ref={(ref) => addHeaderRef("header-2", ref)}>
|
|
فناوریهای بکاند و اثر آنها
|
|
</h2>
|
|
<p>
|
|
تحولات حوزه بکاند باعث شده توسعه سرویسهای امن، مقیاسپذیر و پرسرعت سادهتر از گذشته باشد.
|
|
</p>
|
|
<img
|
|
src="/block-media/shadcnblocks/block/placeholder-3.svg"
|
|
alt="تصویر نمونه"
|
|
className="max-h-96 w-full rounded-xl border border-border object-cover"
|
|
/>
|
|
<ul>
|
|
<li>
|
|
<p>
|
|
<strong>معماری میکروسرویس </strong>
|
|
با تقسیم اپلیکیشن به سرویسهای کوچک و مستقل، ساخت سیستمهای
|
|
مقیاسپذیر و تابآور را ممکن میسازد.
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<strong>محاسبات بدون سرور </strong>
|
|
اجرای کد بکاند بدون مدیریت سرور، هزینه عملیاتی را کم و
|
|
مقیاسپذیری خودکار را فراهم میکند.
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<strong>نوآوریهای پایگاه داده</strong> از جمله پایگاه داده انعطافپذیر و
|
|
پایگاه داده مدرن، راهحلهای ذخیرهسازی انعطافپذیر و مقیاسپذیر برای
|
|
اپلیکیشنهای مدرن ارائه میدهند.
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
<h2 id="header-3" ref={(ref) => addHeaderRef("header-3", ref)}>
|
|
روندهای آینده در توسعه
|
|
</h2>
|
|
<p>
|
|
هوش مصنوعی، اجرای سریع مرورگر، پردازش لبه و برنامههای وب پیشرونده از مهمترین فناوریهایی هستند که آینده توسعه وب را شکل خواهند داد.
|
|
</p>
|
|
<p>
|
|
سرمایهگذاری روی فناوریهای نوین، علاوه بر افزایش کیفیت محصول، مسیر توسعه و رقابتپذیری کسبوکارها را نیز هموارتر میکند.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<nav
|
|
className="top-6 h-fit lg:sticky lg:col-span-3 lg:col-start-8"
|
|
aria-label="فهرست مطالب"
|
|
>
|
|
<Separator className="my-10 block lg:hidden" />
|
|
<div className="flex flex-col gap-1.5 text-start text-sm lg:text-xs">
|
|
<p className="text-xs text-muted-foreground">در این صفحه</p>
|
|
<ul>
|
|
<li className="py-1.5 transition-colors duration-200">
|
|
<a
|
|
href="#header-1"
|
|
className={cn(
|
|
"block transition-colors duration-200",
|
|
activeHeader === "header-1"
|
|
? "text-muted-foreground lg:text-primary"
|
|
: "text-muted-foreground hover:text-primary",
|
|
)}
|
|
>
|
|
تحول فریمورکهای فرانتاند
|
|
</a>
|
|
</li>
|
|
<li className="py-1.5 transition-colors duration-200">
|
|
<a
|
|
href="#header-2"
|
|
className={cn(
|
|
"block transition-colors duration-200",
|
|
activeHeader === "header-2"
|
|
? "text-muted-foreground lg:text-primary"
|
|
: "text-muted-foreground hover:text-primary",
|
|
)}
|
|
>
|
|
فناوریهای بکاند و اثر آنها
|
|
</a>
|
|
</li>
|
|
<li className="py-1.5 transition-colors duration-200">
|
|
<a
|
|
href="#header-3"
|
|
className={cn(
|
|
"block transition-colors duration-200",
|
|
activeHeader === "header-3"
|
|
? "text-muted-foreground lg:text-primary"
|
|
: "text-muted-foreground hover:text-primary",
|
|
)}
|
|
>
|
|
روندهای آینده در توسعه
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div
|
|
className={cn(
|
|
"hidden opacity-0 transition-opacity duration-200 lg:block",
|
|
showBackToTop && "opacity-100",
|
|
)}
|
|
>
|
|
<Separator className="my-3" />
|
|
<Button
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
|
|
className="gap-1 text-xs text-muted-foreground"
|
|
aria-label="بازگشت به بالای صفحه"
|
|
>
|
|
<ArrowUp className="size-3.5" />
|
|
بازگشت به بالا
|
|
</Button>
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export { Content4 };
|