Files
reui-blocks/blocks/changelog5.tsx
T

266 lines
11 KiB
TypeScript

"use client";
import { ArrowUpRight } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { Avatar, AvatarImage } from "@/components/ui/avatar";
import { Separator } from "@/components/ui/separator";
import { cn } from "@/lib/utils";
const changelogs = [
{
title: "معرفی فضای فایل فضای کاری",
category: "ویژگی جدید",
date: "۱ فروردین ۱۴۰۴",
author: "سارا احمدی",
role: "مدیر محصول",
avatar:
"/block-media/shadcnblocks/block/avatar-1.webp",
image:
"/block-media/shadcnblocks/block/placeholder-1.svg",
description: (
<div className="prose dark:prose-invert">
<p>
زیرساخت جدید فضای ذخیره‌سازی ابری امکان مدیریت متمرکز فایل‌ها، اسناد و منابع پروژه را فراهم می‌کند تا اعضای تیم از هر مکان به اطلاعات موردنیاز خود دسترسی داشته باشند.
</p>
<ul>
<li>
<a href="#">کتابخانه فایل‌ها</a> اکنون با فضای ذخیره‌سازی ابری یکپارچه شده است.
</li>
<li>
فایل‌ها را می‌توانید با برچسب، پوشه و فیلترهای پیشرفته دسته‌بندی و سریع‌تر جستجو کنید.
</li>
<li>
در هر بخش از پروژه می‌توانید با{" "}
<strong>استفاده از میانبر</strong> ⌘+F یا از پنل منابع، فایل‌های ذخیره‌شده را به‌سرعت پیدا کنید.
</li>
<li>
در پروژه‌های جدید امکانات زیر در دسترس است:
<ul>
<li>شروع از قالب‌های آماده</li>
<li>وارد کردن فایل‌ها از فضای ابری</li>
<li>همکاری هم‌زمان با اعضای تیم</li>
</ul>
</li>
</ul>
<p>
در نسخه جدید، فضای ذخیره‌سازی پایه برای همه کاربران فعال شده است و قابلیت‌های بیشتری نیز در به‌روزرسانی‌های آینده اضافه خواهد شد. اگر پیشنهادی دارید،
<a href="#"> پیشنهاد خود را</a> در سامانه بازخورد ثبت کنید.
</p>
</div>
),
},
{
title: "دستیار طراحی مبتنی بر هوش مصنوعی",
category: "بهبود",
date: "۲۵ اسفند ۱۴۰۳",
author: "محمد رضایی",
role: "سرپرست تحقیقات هوش مصنوعی",
avatar:
"/block-media/shadcnblocks/block/avatar-2.webp",
image:
"/block-media/shadcnblocks/block/placeholder-2.svg",
description: (
<div className="prose dark:prose-invert">
<p>
نسخه جدید دستیار هوش مصنوعی با دقت بیشتر، سرعت بالاتر و پیشنهادهای کاربردی‌تر منتشر شده است.
</p>
<ul>
<li>۴۰٪ رندر سریع‌تر برای پیشنهادهای تولیدشده با هوش مصنوعی</li>
<li>
الگوریتم جدید تشخیص سبک برای تم‌های طراحی یکپارچه‌تر
</li>
<li>پشتیبانی از پرامپت‌های دقیق‌تر و تنظیمات پیشرفته تولید محتوا</li>
<li>
دستیارهای تخصصی برای تصویرسازی، تایپوگرافی و چیدمان
</li>
</ul>
<p>
این قابلیت‌ها برای همه کاربران فعال شده‌اند. برای آشنایی بیشتر به <a href="#">مرکز آموزش</a> مراجعه کنید.
</p>
</div>
),
},
{
title: "ابزارهای همکاری تیم خلاق",
category: "به‌روزرسانی",
date: "۲۰ اسفند ۱۴۰۳",
author: "امیر حسینی",
role: "طراح ارشد محصول",
avatar:
"/block-media/shadcnblocks/block/avatar-2.webp",
image:
"/block-media/shadcnblocks/block/placeholder-3.svg",
description: (
<div className="prose dark:prose-invert">
<p>
امکانات همکاری تیمی بازطراحی شده‌اند تا هماهنگی میان اعضای تیم، مدیریت بازخوردها و بررسی تغییرات سریع‌تر انجام شود.
</p>
<ul>
<li>ویرایش هم‌زمان با نمایش حضور اعضای تیم</li>
<li>ثبت نظر روی بخش‌های مختلف فایل</li>
<li>تاریخچه نسخه‌ها با امکان مقایسه تغییرات</li>
<li>سامانه تأیید و بازبینی مشتری</li>
</ul>
<p>
برای استفاده مؤثر از این قابلیت‌ها،
<a href="#"> راهنمای همکاری تیمی</a> را مطالعه کنید.
</p>
</div>
),
},
];
interface Changelog5Props {
className?: string;
}
const Changelog5 = ({ className }: Changelog5Props) => {
const [activeSection, setActiveSection] = useState<string | null>(null);
const sectionRefs = useRef<Record<string, HTMLElement>>({});
useEffect(() => {
const sections = Object.keys(sectionRefs.current);
const observerCallback = (entries: IntersectionObserverEntry[]) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setActiveSection(entry.target.id);
}
});
};
let observer: IntersectionObserver | null = new IntersectionObserver(
observerCallback,
{
root: null,
rootMargin: "0px",
threshold: 0.5,
},
);
sections.forEach((sectionId) => {
const element = sectionRefs.current[sectionId];
if (element) {
observer?.observe(element);
}
});
return () => {
observer?.disconnect();
observer = null;
};
}, []);
const addSectionRef = (id: string, ref: HTMLElement | null) => {
if (ref) {
sectionRefs.current[id] = ref;
}
};
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="bg-muted/60 py-20 lg:py-28">
<div className="container">
<div className="flex flex-col items-start gap-4 lg:flex-row">
<span className="flex w-[16%] items-center gap-3 pt-1 text-sm">
<span className="size-2 shrink-0 rounded-full bg-primary" />
تاریخچه نسخه‌ها
</span>
<div>
<h2 className="text-xl">
جدیدترین ویژگی‌ها و بهبودها <br />{" "}
<span className="text-muted-foreground">Pixiol</span>
</h2>
<div className="mt-10 flex items-center gap-4 text-sm">
<a href="#" className="group flex items-center gap-1 underline">
عضویت در به‌روزرسانی‌ها
<ArrowUpRight className="size-4 transition-all group-hover:rotate-45 rtl:rotate-180" />
</a>
<a href="#" className="group flex items-center gap-1 underline">
دنبال کردن در ایکس
<ArrowUpRight className="size-4 transition-all group-hover:rotate-45 rtl:rotate-180" />
</a>
</div>
</div>
</div>
</div>
</div>
<div className="container mt-10 lg:mt-20">
<div className="relative flex">
<div className="sticky top-10 hidden h-fit w-[16%] text-sm lg:block">
<p className="mb-2">خط زمانی</p>
<ul className="flex flex-col gap-2">
{changelogs.map((changelog, idx) => (
<li key={changelog.title}>
<a
href={`#section-${idx + 1}`}
className={cn(
"transition-colors duration-200",
activeSection === `section-${idx + 1}`
? "font-medium text-primary"
: "text-muted-foreground hover:text-primary",
)}
>
{changelog.date}
</a>
</li>
))}
</ul>
</div>
<Separator
orientation="vertical"
className="hidden h-auto data-[orientation=vertical]:h-auto lg:block"
/>
<div className="mx-auto flex max-w-prose flex-col gap-16 lg:gap-24">
{changelogs.map((changelog, idx) => (
<div
key={idx}
id={`section-${idx + 1}`}
ref={(ref) => addSectionRef(`section-${idx + 1}`, ref)}
className="scroll-m-20"
>
<img
src={changelog.image}
alt={changelog.title}
className="mb-8 aspect-video w-full object-cover"
/>
<span className="flex items-center gap-2">
<span className="size-2 shrink-0 rounded-full border border-muted-foreground" />
<p className="text-sm text-muted-foreground">
{changelog.category}
</p>
</span>
<h3 className="mt-2 mb-6 text-3xl">{changelog.title}</h3>
{changelog.description}
<div className="mt-6 flex items-end justify-between border-b border-border pb-4">
<div className="flex items-center gap-4">
<Avatar className="size-10 border border-border">
<AvatarImage
src={changelog.avatar}
alt={changelog.author}
/>
</Avatar>
<div className="flex flex-col">
<p className="text-sm font-medium">{changelog.author}</p>
<p className="text-sm text-muted-foreground">
{changelog.role}
</p>
</div>
</div>
<time className="text-sm text-muted-foreground">
{changelog.date}
</time>
</div>
</div>
))}
</div>
</div>
</div>
</section>
);
};
export { Changelog5 };