266 lines
11 KiB
TypeScript
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 };
|