303 lines
12 KiB
TypeScript
303 lines
12 KiB
TypeScript
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 };
|