پرتوپرتو

صفحه تحلیل

الگوی ساخت صفحه تحلیل اینفلوئنسر با ترکیب کامپوننت‌های دامنه‌ای

چه زمانی از این الگو استفاده کنید؟

این الگو برای ساخت صفحاتی طراحی شده که اطلاعات جامع یک حساب کاربری یا اینفلوئنسر را نمایش می‌دهند. مواردی مانند:

  • صفحه پروفایل اینفلوئنسر: نمایش کامل اطلاعات، نرخ تعامل، احساسات مخاطبان و محتوای اخیر
  • تحلیل عمیق حساب کاربری: بررسی روند رشد فالوور، عملکرد محتوا و توزیع احساسات
  • گزارش عملکرد: ارائه خلاصه‌ای از معیارهای کلیدی و تغییرات آن‌ها در بازه زمانی مشخص

نمونه بصری

کارت‌های اطلاعاتی — صفحه تحلیل

خلاصه کمپین

داده‌های ۳۰ روز گذشته

بهترین محتوا

۵ پست برتر دوره

آکاردئون — FAQ


ساختار کلی صفحه

صفحه تحلیل از PageContainer با اندازه large و PageHeader با breadcrumb برای بازگشت به لیست تشکیل شده است. بخش اصلی صفحه از PageSection با orientation="horizontal" استفاده می‌کند تا پروفایل در کنار محتوای اصلی قرار بگیرد.

import {
  PageContainer,
  PageHeader,
  PageHeaderBreadcrumb,
  PageHeaderTitle,
  PageHeaderDescription,
  PageSection,
  PageSectionMain,
  PageSectionAside,
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbPage,
} from '@parto-system-design/ui'

function AnalysisPage() {
  return (
    <PageContainer size="large">
      <PageHeader size="large">
        <PageHeaderBreadcrumb>
          <Breadcrumb>
            <BreadcrumbItem>
              <BreadcrumbLink href="/influencers">اینفلوئنسرها</BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbItem>
              <BreadcrumbPage>سارا احمدی</BreadcrumbPage>
            </BreadcrumbItem>
          </Breadcrumb>
        </PageHeaderBreadcrumb>
        <PageHeaderTitle>تحلیل پروفایل</PageHeaderTitle>
        <PageHeaderDescription>بررسی عملکرد و تحلیل محتوای سارا احمدی در شبکه‌های اجتماعی</PageHeaderDescription>
      </PageHeader>

      <PageSection orientation="horizontal">
        <PageSectionAside>{/* کارت پروفایل و پلتفرم‌ها */}</PageSectionAside>
        <PageSectionMain>{/* بخش‌های تحلیل، احساسات، محتوا و معیارها */}</PageSectionMain>
      </PageSection>
    </PageContainer>
  )
}

بخش پروفایل (Aside)

در ستون کناری، ProfileCard اطلاعات خلاصه اینفلوئنسر را نمایش می‌دهد و SocialPlatformBadge مشخص می‌کند داده‌ها از کدام پلتفرم‌ها جمع‌آوری شده‌اند.

import { ProfileCard, SocialPlatformBadge } from '@parto-system-design/ui'
import { Users } from 'lucide-react'

function ProfileAside() {
  return (
    <div className="space-y-4">
      <ProfileCard
        name="سارا احمدی"
        username="sara.ahmadi"
        avatarSrc="/avatars/sara-ahmadi.jpg"
        followers={245000}
        followersIcon={<Users className="h-3.5 w-3.5" />}
        onCardClick={() => console.log('مشاهده پروفایل کامل')}
      />

      <div className="flex flex-wrap gap-2">
        <SocialPlatformBadge platform="instagram" variant="badge" showLabel />
        <SocialPlatformBadge platform="twitter" variant="badge" showLabel />
        <SocialPlatformBadge platform="youtube" variant="badge" showLabel />
      </div>
    </div>
  )
}

اگر به جای کارت عمودی، نمایش افقی‌تری نیاز دارید، از ProfileInfo استفاده کنید:

import { ProfileInfo } from '@parto-system-design/ui'

;<ProfileInfo
  name="سارا احمدی"
  username="sara.ahmadi"
  avatarSrc="/avatars/sara-ahmadi.jpg"
  infoText="آخرین به‌روزرسانی: ۱۵ فروردین ۱۴۰۵"
/>

بخش تحلیل نرخ تعامل

نسخه کامل — EngagementRate

برای تحلیل اصلی صفحه از نسخه کامل استفاده کنید. این کامپوننت نوار تقسیم‌بندی شده با ۶ سطح، مثلث شاخص و کارت اطلاعات دسته‌بندی را نمایش می‌دهد.

import { EngagementRate } from '@parto-system-design/ui'

;<EngagementRate currentRate={0.0342} followers={245000} locale="fa" showCategoryCard={true} />

مقدار currentRate به صورت اعشاری وارد می‌شود (مثلا 0.0342 برای 3.42%). کامپوننت به صورت خودکار بر اساس تعداد فالوورها، دسته مناسب (نانو، میکرو، متوسط، ماکرو، مگا) را تشخیص می‌دهد و سطح نرخ تعامل را مشخص می‌کند.

نسخه فشرده — EngagementRateBar

برای نمایش در کارت‌ها، جداول مقایسه‌ای یا فضاهای محدود از نسخه فشرده استفاده کنید:

import { EngagementRateBar } from '@parto-system-design/ui'

;<EngagementRateBar currentRate={0.0342} followers={245000} locale="fa" />

چه زمانی از کدام نسخه استفاده کنید؟

حالتکامپوننتدلیل
صفحه تحلیل اصلیEngagementRateنمایش کامل با کارت دسته‌بندی و جزئیات
کارت خلاصه در داشبوردEngagementRateBarفضای محدود، فقط نوار و درصد
جدول مقایسه اینفلوئنسرهاEngagementRateBarنمایش فشرده در سلول جدول
صفحه جزئیات پروفایلEngagementRateکاربر انتظار تحلیل عمیق دارد

بخش تحلیل احساسات

توزیع کلی احساسات

از SentimentDistribution با حالت bars برای نمایش توزیع کلی احساسات نظرات استفاده کنید:

import { SentimentDistribution } from '@parto-system-design/ui'

;<SentimentDistribution data={{ positive: 3420, negative: 890, neutral: 1540 }} variant="bars" showCounts />

نشان‌های احساسات فردی

برای نمایش برچسب‌های احساسات در کنار محتوا یا نظرات:

import { SentimentBadge } from '@parto-system-design/ui'

;<div className="flex flex-wrap gap-2">
  <SentimentBadge sentiment="positive" count={3420} />
  <SentimentBadge sentiment="negative" count={890} />
  <SentimentBadge sentiment="neutral" count={1540} />
  <SentimentBadge sentiment="mixed" count={230} />
</div>

نمودار تفکیک احساسات بر اساس موضوع

برای نمایش توزیع احساسات در موضوعات مختلف از PartoBarChart یا PartoPieChart استفاده کنید:

import { PartoBarChart } from '@parto-system-design/ui'

const sentimentByTopic = [
  { موضوع: 'کیفیت محصول', مثبت: 820, منفی: 120, خنثی: 340 },
  { موضوع: 'خدمات پشتیبانی', مثبت: 540, منفی: 380, خنثی: 210 },
  { موضوع: 'قیمت‌گذاری', مثبت: 310, منفی: 490, خنثی: 180 },
  { موضوع: 'تجربه کاربری', مثبت: 670, منفی: 95, خنثی: 420 },
]

;<div className="h-[400px]">
  <PartoBarChart
    data={sentimentByTopic}
    keys={['مثبت', 'منفی', 'خنثی']}
    indexBy="موضوع"
    margin={{ top: 20, right: 20, bottom: 50, left: 80 }}
    padding={0.3}
    groupMode="stacked"
  />
</div>

برای نمایش نسبت کلی احساسات در نمودار دایره‌ای:

import { PartoPieChart } from '@parto-system-design/ui'

const sentimentData = [
  { id: 'مثبت', label: 'مثبت', value: 3420 },
  { id: 'منفی', label: 'منفی', value: 890 },
  { id: 'خنثی', label: 'خنثی', value: 1540 },
]

;<div className="h-[300px]">
  <PartoPieChart
    data={sentimentData}
    innerRadius={0.5}
    padAngle={0.7}
    cornerRadius={3}
    activeOuterRadiusOffset={8}
    enableArcLinkLabels={false}
  />
</div>

بخش محتوا

گرید پست‌های اخیر

از InstagramPost با حالت vertical برای نمایش پست‌های اخیر اینفلوئنسر استفاده کنید. توجه داشته باشید که این کامپوننت همیشه در حالت LTR رندر می‌شود (استاندارد برند اینستاگرام).

import { InstagramPost } from '@parto-system-design/ui'

const recentPosts = [
  {
    media: [{ type: 'image' as const, url: '/posts/post-1.jpg', aspectRatio: '1:1' as const }],
    postType: 0,
    caption: 'امروز در رویداد فناوری تهران شرکت کردیم. تجربه فوق‌العاده‌ای بود! #تکنولوژی #تهران',
    profile: {
      username: 'sara.ahmadi',
      fullName: 'Sara Ahmadi',
      avatarUrl: '/avatars/sara-ahmadi.jpg',
    },
    stats: { likes: 18420, comments: 342, views: 52300, shares: 128 },
    publishTime: new Date('2025-03-28'),
  },
  {
    media: [{ type: 'image' as const, url: '/posts/post-2.jpg', aspectRatio: '1:1' as const }],
    postType: 0,
    caption: 'معرفی محصول جدید! خیلی هیجان‌زده هستم که بالاخره می‌توانم با شما به اشتراک بگذارم.',
    profile: {
      username: 'sara.ahmadi',
      fullName: 'Sara Ahmadi',
      avatarUrl: '/avatars/sara-ahmadi.jpg',
    },
    stats: { likes: 24100, comments: 567, views: 71200, shares: 245 },
    publishTime: new Date('2025-03-25'),
  },
]

;<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
  {recentPosts.map((post, index) => (
    <InstagramPost key={index} variant="vertical" {...post} />
  ))}
</div>

تحلیل نظرات

از CommentCard برای نمایش نظرات به همراه برچسب‌های تحلیلی و شاخص احساسات استفاده کنید:

import { CommentCard } from '@parto-system-design/ui'

;<div className="space-y-3">
  <CommentCard
    text="محتوای خیلی خوبی بود. کیفیت تصاویر و نوع ارائه واقعاً حرفه‌ای است. منتظر محتوای بیشتر هستم."
    tags={[
      { title: 'رضایت از کیفیت', probability: 94, color: '#16a34a' },
      { title: 'درخواست محتوای بیشتر', probability: 87, color: '#22c55e' },
    ]}
    sentiment="positive"
  />

  <CommentCard
    text="متاسفانه اطلاعات ارائه‌شده دقیق نبود و منابع معتبری ذکر نشده بود. لطفاً بیشتر تحقیق کنید."
    tags={[
      { title: 'عدم دقت اطلاعات', probability: 91, color: '#dc2626' },
      { title: 'نبود منبع معتبر', probability: 85, color: '#ef4444' },
    ]}
    sentiment="negative"
  />

  <CommentCard
    text="موضوع جالبی بود ولی کاش بیشتر توضیح می‌دادید. نه خیلی خوب بود نه خیلی بد."
    tags={[{ title: 'نظر ترکیبی', probability: 78, color: '#a3a3a3' }]}
    sentiment="neutral"
  />
</div>

بخش معیارها و آمار

گرید کارت‌های متریک

از MetricCard برای نمایش معیارهای کلیدی مانند رشد فالوور، روند تعامل و فراوانی انتشار استفاده کنید:

import {
  MetricCard,
  MetricCardHeader,
  MetricCardLabel,
  MetricCardContent,
  MetricCardValue,
  MetricCardDifferential,
  MetricCardSparkline,
} from '@parto-system-design/ui'
import { Users, Heart, FileText } from 'lucide-react'

const followerData = [
  { value: 238000, timestamp: '1404-12-01' },
  { value: 239200, timestamp: '1404-12-08' },
  { value: 240100, timestamp: '1404-12-15' },
  { value: 241800, timestamp: '1404-12-22' },
  { value: 243500, timestamp: '1404-12-29' },
  { value: 245000, timestamp: '1405-01-07' },
]

const engagementData = [
  { value: 3.1, timestamp: '1404-12-01' },
  { value: 3.3, timestamp: '1404-12-08' },
  { value: 3.0, timestamp: '1404-12-15' },
  { value: 3.5, timestamp: '1404-12-22' },
  { value: 3.4, timestamp: '1404-12-29' },
  { value: 3.42, timestamp: '1405-01-07' },
]

const postFrequencyData = [
  { value: 12, timestamp: '1404-12-01' },
  { value: 15, timestamp: '1404-12-08' },
  { value: 10, timestamp: '1404-12-15' },
  { value: 14, timestamp: '1404-12-22' },
  { value: 18, timestamp: '1404-12-29' },
  { value: 16, timestamp: '1405-01-07' },
]

;<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
  <MetricCard>
    <MetricCardHeader>
      <MetricCardLabel icon={<Users className="h-3.5 w-3.5" />}>تعداد فالوورها</MetricCardLabel>
    </MetricCardHeader>
    <MetricCardContent>
      <MetricCardValue>۲۴۵,۰۰۰</MetricCardValue>
      <MetricCardDifferential variant="positive">+۲.۹٪</MetricCardDifferential>
    </MetricCardContent>
    <MetricCardSparkline data={followerData} dataKey="value" />
  </MetricCard>

  <MetricCard>
    <MetricCardHeader>
      <MetricCardLabel icon={<Heart className="h-3.5 w-3.5" />}>نرخ تعامل</MetricCardLabel>
    </MetricCardHeader>
    <MetricCardContent>
      <MetricCardValue>۳.۴۲٪</MetricCardValue>
      <MetricCardDifferential variant="positive">+۰.۱۲٪</MetricCardDifferential>
    </MetricCardContent>
    <MetricCardSparkline data={engagementData} dataKey="value" />
  </MetricCard>

  <MetricCard>
    <MetricCardHeader>
      <MetricCardLabel icon={<FileText className="h-3.5 w-3.5" />}>تعداد پست ماهانه</MetricCardLabel>
    </MetricCardHeader>
    <MetricCardContent>
      <MetricCardValue>۱۶</MetricCardValue>
      <MetricCardDifferential variant="negative">-۱.۲٪</MetricCardDifferential>
    </MetricCardContent>
    <MetricCardSparkline data={postFrequencyData} dataKey="value" />
  </MetricCard>
</div>

نشانگر روند و نمایش آمار

برای نمایش سریع اعداد کلیدی با نشانگر تغییر از StatDisplay و TrendIndicator استفاده کنید:

import { StatDisplay, TrendIndicator } from '@parto-system-design/ui'
import { Eye, MessageCircle, Share2 } from 'lucide-react'

;<div className="grid grid-cols-2 gap-4 sm:grid-cols-4">
  <StatDisplay value={245000} label="فالوورها" icon={<Users />} trend={<TrendIndicator value={2.9} />} />

  <StatDisplay value={52300} label="میانگین بازدید" icon={<Eye />} trend={<TrendIndicator value={5.2} />} />

  <StatDisplay value={342} label="میانگین نظرات" icon={<MessageCircle />} trend={<TrendIndicator value={-1.3} />} />

  <StatDisplay value={128} label="میانگین اشتراک‌گذاری" icon={<Share2 />} trend={<TrendIndicator value={8.7} />} />
</div>

حالت بارگذاری

تمامی کامپوننت‌های دامنه‌ای از prop isLoading پشتیبانی می‌کنند. برای بخش‌هایی که isLoading ندارند از Skeleton استفاده کنید.

import {
  PageContainer,
  PageHeader,
  PageHeaderTitle,
  PageSection,
  PageSectionMain,
  PageSectionAside,
  Skeleton,
  EngagementRate,
  SentimentDistribution,
  MetricCard,
  MetricCardHeader,
  MetricCardLabel,
  MetricCardContent,
  StatDisplay,
} from '@parto-system-design/ui'

function AnalysisPageSkeleton() {
  return (
    <PageContainer size="large">
      <PageHeader size="large">
        <Skeleton className="h-4 w-32" />
        <Skeleton className="h-8 w-48 mt-2" />
        <Skeleton className="h-4 w-64 mt-1" />
      </PageHeader>

      <PageSection orientation="horizontal">
        <PageSectionAside>
          {/* اسکلتون پروفایل */}
          <div className="space-y-4">
            <div className="flex flex-col items-center gap-3 rounded-lg border border-border p-6">
              <Skeleton shape="circle" size="lg" />
              <Skeleton className="h-5 w-32" />
              <Skeleton className="h-4 w-24" />
              <Skeleton className="h-4 w-20" />
            </div>
            <div className="flex gap-2">
              <Skeleton className="h-6 w-24 rounded-full" />
              <Skeleton className="h-6 w-20 rounded-full" />
              <Skeleton className="h-6 w-22 rounded-full" />
            </div>
          </div>
        </PageSectionAside>

        <PageSectionMain>
          {/* اسکلتون نرخ تعامل */}
          <EngagementRate currentRate={0} followers={0} isLoading />

          {/* اسکلتون احساسات */}
          <div className="mt-6">
            <SentimentDistribution data={{ positive: 0, negative: 0, neutral: 0 }} isLoading />
          </div>

          {/* اسکلتون معیارها */}
          <div className="mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
            {Array.from({ length: 3 }).map((_, i) => (
              <MetricCard key={i}>
                <MetricCardHeader>
                  <MetricCardLabel>
                    <Skeleton className="h-4 w-24" />
                  </MetricCardLabel>
                </MetricCardHeader>
                <MetricCardContent>
                  <Skeleton className="h-8 w-20" />
                </MetricCardContent>
              </MetricCard>
            ))}
          </div>

          {/* اسکلتون آمار */}
          <div className="mt-6 grid grid-cols-2 gap-4 sm:grid-cols-4">
            {Array.from({ length: 4 }).map((_, i) => (
              <StatDisplay key={i} value={0} label="" isLoading />
            ))}
          </div>

          {/* اسکلتون پست‌ها */}
          <div className="mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
            {Array.from({ length: 3 }).map((_, i) => (
              <div key={i} className="rounded-lg border border-border overflow-hidden">
                <Skeleton className="h-64 w-full" />
                <div className="p-3 space-y-2">
                  <div className="flex items-center gap-2">
                    <Skeleton shape="circle" size="sm" />
                    <Skeleton className="h-4 w-24" />
                  </div>
                  <Skeleton className="h-3 w-full" />
                  <Skeleton className="h-3 w-3/4" />
                </div>
              </div>
            ))}
          </div>
        </PageSectionMain>
      </PageSection>
    </PageContainer>
  )
}

بهترین شیوه‌ها

چیدمان

  • از ProfileCard در ستون کناری (PageSectionAside) استفاده کنید، نه در بخش اصلی محتوا. کارت پروفایل عمودی است و در ستون کناری بهتر جای می‌گیرد.
  • از PageSection با orientation="horizontal" برای چیدمان پروفایل در کنار محتوای تحلیلی استفاده کنید.
  • در صفحات موبایل، چیدمان افقی به صورت خودکار به عمودی تبدیل می‌شود.

نرخ تعامل

  • در صفحه تحلیل اصلی از EngagementRate (نسخه کامل با کارت دسته‌بندی) استفاده کنید.
  • از EngagementRateBar برای نماهای مقایسه‌ای، جداول و کارت‌های خلاصه استفاده کنید.
  • مقدار currentRate همیشه به صورت اعشاری وارد می‌شود (0.0342 نه 3.42).

پلتفرم‌ها

  • همیشه SocialPlatformBadge را نمایش دهید تا کاربر بداند داده‌ها از کدام پلتفرم جمع‌آوری شده‌اند.
  • اگر داده‌ها از چند پلتفرم هستند، همه نشان‌ها را کنار هم نمایش دهید.

بارگذاری

  • برای کامپوننت‌هایی که prop isLoading دارند (مانند EngagementRate، SentimentDistribution، StatDisplay) از همین prop استفاده کنید.
  • برای بخش‌های سفارشی از Skeleton با ابعاد مناسب استفاده کنید.
  • حالت بارگذاری را برای تمام بخش‌های صفحه پیاده‌سازی کنید تا کاربر ساختار صفحه را قبل از بارگذاری کامل ببیند.

داده‌ها

  • از اعداد واقع‌گرایانه در نمونه‌ها و تست‌ها استفاده کنید. نرخ تعامل 3.42% برای یک اینفلوئنسر با 245,000 فالوور (دسته میکرو) واقع‌بینانه است.
  • برای SentimentDistribution داده‌های خام عددی ارسال کنید — کامپوننت به صورت خودکار درصدها را محاسبه می‌کند.
  • در CommentCard مقدار probability عددی بین ۰ تا ۱۰۰ است و نشان‌دهنده اطمینان مدل تحلیل احساسات است.