Files
reui-blocks/blocks/resource2.tsx
T

303 lines
12 KiB
TypeScript
Raw Normal View History

import { ArrowLeft, Facebook, Link, Linkedin, Twitter } from "lucide-react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
interface Resource2Props {
navigation: {
backText: string;
backHref: string;
className?: string;
};
blog: {
title: string;
author: string;
role: string;
date: string;
readTime: string;
imageSrc: string;
content: React.ReactNode;
};
social: {
heading: string;
links: Array<{
icon: "link" | "linkedin" | "twitter" | "facebook";
href: string;
label: string;
}>;
};
illustration: {
imageSrc: string;
imageAlt: string;
};
className?: string;
}
const Resource2 = ({
className,
navigation = {
backText: "همه مقالات",
backHref: "/resources",
},
blog = {
title:
"ساخت وب‌اپلیکیشن‌های پایدار: راهنمای توسعه‌دهنده برای کدنویسی سبز",
author: "سارا چن",
date: "۲۵ آذر ۱۴۰۳",
readTime: "۸ دقیقه مطالعه",
role: "توسعه‌دهنده ارشد",
imageSrc: "/block-media/shadcnblocks/block/avatar-1.webp",
content: (
<>
<p>
دنیای دیجیتال انرژی بیشتری نسبت به کل صنعت هوانوردی مصرف می‌کند. ما
به‌عنوان توسعه‌دهنده مسئولیت داریم برنامه‌هایی بسازیم که نه‌تنها
کاربردی و زیبا باشند، بلکه برای سیاره ما نیز پایدار باشند.
</p>
<h2>ردپای کربنی کد</h2>
<p>
هر خط کدی که می‌نویسیم تأثیر محیطی دارد. از انرژی مصرفی سرورها تا
منابع به‌کاررفته در ساخت دستگاه‌ها، انتخاب‌های دیجیتال ما مهم‌تر از
آنچه فکر می‌کنیم اهمیت دارند.
</p>
<h3>درک تأثیر</h3>
<p>
وب‌اپلیکیشن‌های مدرن به‌شدت پرمصرف هستند. این واقعیت‌های
چشمگیر را در نظر بگیرید:
</p>
<ul>
<li>
<strong>مراکز داده</strong> ۱٪ از برق جهانی را مصرف می‌کنند
</li>
<li>
<strong>پخش ویدیو</strong> ۳٪ از انتشار کربن جهانی را تشکیل
می‌دهد
</li>
<li>
<strong>هرزنامه ایمیل</strong> سالانه ۱۷ میلیون تن CO₂ تولید
می‌کند
</li>
</ul>
<blockquote>
<p>
«پایدارترین کد، کدی است که اصلاً نمی‌نویسید. دومین کد پایدار، کدی
است که کارآمد اجرا می‌شود.»
</p>
</blockquote>
<h2>اصول کدنویسی سبز</h2>
<p>این اصول پایه را هر توسعه‌دهنده باید رعایت کند:</p>
<ol>
<li>
<strong>بهینه‌سازی برای عملکرد:</strong> کد سریع‌تر، انرژی کمتری
مصرف می‌کند
</li>
<li>
<strong>کاهش وابستگی‌ها:</strong> هر پکیج به حجم بسته اضافه
می‌کند
</li>
<li>
<strong>استفاده از الگوریتم‌های کارآمد:</strong> پیچیدگی بهتر یعنی
محاسبه کمتر
</li>
<li>
<strong>پیاده‌سازی استراتژی‌های کش:</strong> کاهش عملیات تکراری
</li>
<li>
<strong>انتخاب هاستینگ سبز:</strong> سرورهای با انرژی تجدیدپذیر
</li>
</ol>
<h3>پیاده‌سازی عملی</h3>
<p>
بیایید چند نمونه مشخص از پیاده‌سازی این اصول را ببینیم:
</p>
<h4>۱ بهینه‌سازی تصویر</h4>
<p>
تصاویر اغلب ۶۰ تا ۸۰ درصد حجم یک صفحه را تشکیل می‌دهند. از
فرمت‌های مدرن مثل WebP یا AVIF استفاده کنید، بارگذاری هوشمند پیاده
کنید و تصاویر با اندازه مناسب سرو کنید.
</p>
<h4>۲ تقسیم کد (تقسیم هوشمند بار)</h4>
<p>
فقط جاوااسکریپتی را بارگذاری کنید که کاربر واقعاً به آن نیاز
دارد. این کار حجم بسته اولیه را کم می‌کند و عملکرد را بهبود
می‌دهد.
</p>
<h4>۳. بهینه‌سازی پایگاه داده</h4>
<p>
کوئری‌های کارآمد بنویسید، ایندکس‌گذاری درست انجام دهید و connection
pooling پیاده کنید تا بار پایگاه داده کاهش یابد.
</p>
<h2>آینده توسعه پایدار</h2>
<p>
با حرکت به جلو، پایداری باید در هر تصمیم توسعه یک ملاحظه اصلی
شود. ابزارهایی مثل <strong>ابزار تست سرعت</strong> و{" "}
<strong>ابزار تحلیل عملکرد</strong> می‌توانند به سنجش تأثیر محیطی
برنامه‌های ما کمک کنند.
</p>
<p>
مسیر توسعه وب پایدار مستمر است، اما هر بهینه‌سازی کوچک به آینده
دیجیتال سبزتر کمک می‌کند. با یک اصل شروع کنید، تأثیر را بسنجید و
به‌تدریج شیوه‌های پایدارتر را به گردش کار توسعه خود اضافه کنید.
</p>
</>
),
},
social = {
heading: "اشتراک‌گذاری این مقاله",
links: [
{ icon: "link", href: "#", label: "کپی لینک" },
{ icon: "linkedin", href: "#", label: "اشتراک در لینکدین" },
{ icon: "twitter", href: "#", label: "اشتراک در X" },
{ icon: "facebook", href: "#", label: "اشتراک در فیسبوک" },
],
},
illustration = {
imageSrc: "/block-media/shadcnblocks/block/placeholder-2.svg",
imageAlt:
"تصویر توسعه وب پایدار با تمرین‌های کدنویسی سبز و تأثیر محیطی",
},
}: Resource2Props) => {
const getIcon = (icon: string, className: string) => {
switch (icon) {
case "link":
return <Link className={`size-4 ${className}`} />;
case "شبکه حرفه‌ای":
return <Linkedin className={`size-4 ${className}`} />;
case "شبکه اجتماعی":
return <Twitter className={`size-4 ${className}`} />;
case "شبکه اجتماعی":
return <Facebook className={`size-4 ${className}`} />;
default:
return null;
}
};
return (
<section dir="rtl" lang="fa" className={cn("", className)}>
<div className="min-h-128 bg-primary text-primary-foreground">
<div className="container py-16">
<div className="grid grid-cols-1 items-start gap-8 lg:grid-cols-3">
<div className="flex h-full max-w-md flex-col justify-between gap-8">
<div className="space-y-6">
<div className="flex items-center gap-2 text-primary-foreground">
<a
href={navigation.backHref}
className="group/nav flex items-center gap-2 transition-all duration-200 hover:gap-4"
>
<ArrowLeft className="size-4 rtl:rotate-180 group-hover/nav:text-primary-foreground" />
<span className="transition-colors group-hover/nav:text-primary-foreground group-hover/nav:underline">
{navigation.backText}
</span>
</a>
</div>
<h1 className="text-start text-3xl leading-tight font-medium">
{blog.title}
</h1>
</div>
<div className="flex flex-col gap-8">
<div className="space-y-2 text-start">
<p className="text-lg text-muted-foreground">{blog.author}</p>
<p className="text-muted-foreground">
{blog.date} • {blog.readTime}
</p>
</div>
<div className="space-y-4 text-start">
<h3>{social.heading}</h3>
<div className="flex gap-3">
{social.links.map((link, index) => (
<Button
key={index}
variant="outline"
size="icon"
className="group/btn h-12 w-12 rounded-full border-border/10 bg-muted/20 transition-colors hover:bg-transparent hover:text-muted"
asChild
>
<a
href={link.href}
aria-label={link.label}
className="flex items-center justify-center"
>
{getIcon(
link.icon,
"text-muted/30 group-hover/btn:text-primary-foreground transition-colors",
)}
</a>
</Button>
))}
</div>
</div>
</div>
</div>
<div className="col-span-2 h-full w-full">
<div className="aspect-video min-h-96 w-full">
<img
src={illustration.imageSrc}
alt={illustration.imageAlt}
className="h-full w-full object-cover"
/>
</div>
</div>
</div>
</div>
</div>
<div className="container mx-auto py-16 md:max-w-2xl xl:max-w-5xl">
<div className="prose max-w-none pb-16 text-start prose-headings:text-foreground prose-p:text-muted-foreground prose-blockquote:border-s-primary prose-blockquote:text-muted-foreground prose-strong:text-foreground prose-em:text-foreground prose-ol:text-muted-foreground prose-ul:text-muted-foreground prose-li:text-muted-foreground">
{blog.content}
</div>
<div className="flex flex-col justify-between gap-8 border-t border-border py-8 md:flex-row">
<div className="flex items-center gap-3">
<Avatar className="size-12 border xl:size-16">
<AvatarImage src={blog.imageSrc} />
<AvatarFallback>{blog.author}</AvatarFallback>
</Avatar>
<div className="text-start">
<p className="font-medium">{blog.author}</p>
<p className="text-sm text-muted-foreground">{blog.role}</p>
</div>
</div>
<div className="space-y-4 text-start">
<h3>{social.heading}</h3>
<div className="flex gap-3">
{social.links.map((link, index) => (
<Button
key={index}
variant="outline"
size="icon"
className="group/btn h-12 w-12 rounded-full border-border bg-muted transition-colors hover:bg-transparent hover:text-muted"
asChild
>
<a
href={link.href}
aria-label={link.label}
className="flex items-center justify-center"
>
{getIcon(
link.icon,
"text-muted-foreground group-hover/btn:text-primary transition-colors",
)}
</a>
</Button>
))}
</div>
</div>
</div>
</div>
</section>
);
};
export { Resource2 };