بلاک‌ها · معرفی محصول

فرصت‌های شغلی

پیش‌نمایش تمام‌صفحه

هیرو با عکس‌های تیم، مزایا با آیکون، موقعیت‌های باز با فیلترِ تیم (تب) و ردیفِ کلیک‌پذیر با تیم و محل و نوعِ همکاری، حالتِ خالی و ارسالِ رزومهٔ آزاد.

۱. نصب کامپوننت‌ها

این بلاک از ۸ آیتم دیگ استفاده می‌کند: badgebuttoncontrol-sizeempty-stateiconspersianrevealtoggle-group

پکیج‌منیجر پیش‌فرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/empty-state.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.json
pnpm dlx digdesign@latest add https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/empty-state.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.json
yarn dlx digdesign@latest add https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/empty-state.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.json
bunx --bun digdesign@latest add https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/empty-state.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.json

۲. کد صفحه

کد را در app/<route>/page.tsx بگذارید و متن‌ها، داده و هندلرها را با محصول خودتان عوض کنید.

careers.tsx
"use client"

import * as React from "react"

import { ChevronLeftIcon, ClockIcon, GlobeIcon, HeartIcon, SparklesIcon, UsersIcon, WalletIcon } from "@/components/icons"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { EmptyState, EmptyStateDescription, EmptyStateTitle } from "@/components/ui/empty-state"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
import { Reveal } from "@/components/ui/reveal"
import { toFaDigits } from "@/lib/persian"
import { stockImages } from "@/lib/stock-images"

const JOBS = [
  { title: "توسعه‌دهندهٔ ارشدِ فرانت‌اند", team: "فنی", place: "تهران · هیبرید", type: "تمام‌وقت" },
  { title: "توسعه‌دهندهٔ بک‌اند (Go)", team: "فنی", place: "دورکاری", type: "تمام‌وقت" },
  { title: "طراحِ محصول", team: "محصول", place: "تهران", type: "تمام‌وقت" },
  { title: "مدیرِ محصول", team: "محصول", place: "تهران · هیبرید", type: "تمام‌وقت" },
  { title: "کارشناسِ فروشِ سازمانی", team: "فروش", place: "تهران", type: "تمام‌وقت" },
  { title: "کارشناسِ پشتیبانی", team: "فروش", place: "دورکاری", type: "پاره‌وقت" },
]

const PERKS = [
  { icon: <WalletIcon />, title: "حقوقِ رقابتی", text: "بازبینی دوبار در سال و پاداشِ عملکرد" },
  { icon: <GlobeIcon />, title: "دورکاری و هیبرید", text: "هر جا بهتر کار می‌کنی" },
  { icon: <HeartIcon />, title: "بیمهٔ تکمیلی", text: "برای خودت و خانواده" },
  { icon: <SparklesIcon />, title: "بودجهٔ یادگیری", text: "دوره، کتاب و کنفرانس" },
]

/**
 * فرصت‌های شغلی: هیرو با عکسِ تیم، مزایا با آیکون، فهرستِ موقعیت‌ها با فیلترِ تیم
 * (تب) و ردیفِ کلیک‌پذیرِ هر موقعیت، و حالتِ «موقعیتِ مناسب نیست؟».
 */
export default function CareersBlock() {
  const [team, setTeam] = React.useState("همه")
  const visible = JOBS.filter((job) => team === "همه" || job.team === team)

  return (
    <ControlSizeProvider size="xl" asChild>
      <main className="flex flex-col">
        <section className="mx-auto flex w-full max-w-6xl flex-col items-center gap-10 px-4 py-16 text-center sm:px-6 lg:py-24">
          <div className="flex max-w-2xl flex-col items-center gap-4">
            <Badge variant="soft">فرصت‌های شغلی</Badge>
            <h1 className="text-4xl leading-snug font-black sm:text-5xl sm:leading-snug">بیا با هم چیزی بسازیم که آدم‌ها هر روز استفاده کنند</h1>
            <p className="text-lg leading-8 text-muted-foreground">تیمی کوچک با اثرِ بزرگ؛ {toFaDigits(JOBS.length)} موقعیتِ باز داریم.</p>
          </div>
          <div className="grid w-full grid-cols-3 gap-3">
            {[stockImages.personWoman1, stockImages.studioSunlit, stockImages.personMan1].map((image, index) => (
              // eslint-disable-next-line @next/next/no-img-element -- عکس از کتابخانهٔ تصویرِ دیگ
              <img key={image.src} src={image.src} alt="" className={`w-full rounded-xl object-cover ${index === 1 ? "aspect-[4/3]" : "mt-8 aspect-[4/5]"}`} />
            ))}
          </div>
        </section>

        <section aria-labelledby="careers-perks" className="bg-subtle py-20">
          <div className="mx-auto flex w-full max-w-6xl flex-col gap-10 px-4 sm:px-6">
            <h2 id="careers-perks" className="text-3xl font-black">
              چرا این‌جا؟
            </h2>
            <ul className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
              {PERKS.map((perk, index) => (
                <Reveal asChild key={perk.title} delay={index * 100}>
                  <li className="flex flex-col gap-3 rounded-xl border border-border bg-card p-6">
                    <span aria-hidden className="flex size-11 items-center justify-center rounded-xl bg-[color-mix(in_oklab,var(--brand-secondary)_12%,var(--card))] text-brand-secondary [&>svg]:size-5">
                      {perk.icon}
                    </span>
                    <span className="font-bold">{perk.title}</span>
                    <span className="text-sm text-muted-foreground">{perk.text}</span>
                  </li>
                </Reveal>
              ))}
            </ul>
          </div>
        </section>

        <section aria-labelledby="careers-jobs" className="mx-auto flex w-full max-w-4xl flex-col gap-8 px-4 py-24 sm:px-6">
          <div className="flex flex-wrap items-end justify-between gap-4">
            <div className="flex flex-col gap-2">
              <h2 id="careers-jobs" className="text-3xl font-black">
                موقعیت‌های باز
              </h2>
              <p className="text-muted-foreground">رزومه را مستقیم برای همان موقعیت بفرست.</p>
            </div>
            <ToggleGroup type="single" variant="segmented" value={team} onValueChange={(value) => value && setTeam(value as string)} aria-label="تیم">
              {["همه", "فنی", "محصول", "فروش"].map((item) => (
                <ToggleGroupItem key={item} value={item}>
                  {item}
                </ToggleGroupItem>
              ))}
            </ToggleGroup>
          </div>

          {visible.length === 0 ? (
            <EmptyState variant="bordered">
              <EmptyStateTitle>فعلاً موقعیتی در این تیم نیست</EmptyStateTitle>
              <EmptyStateDescription>رزومه‌ات را بفرست؛ موقعیت که باز شد خبرت می‌کنیم.</EmptyStateDescription>
            </EmptyState>
          ) : (
            <ul className="flex flex-col divide-y divide-border border-y border-border">
              {visible.map((job) => (
                <li key={job.title} className="group relative flex flex-wrap items-center gap-4 py-6">
                  <div className="flex min-w-0 flex-1 flex-col gap-2">
                    <a href="#" className="text-lg font-bold outline-none after:absolute after:inset-0 group-hover:text-brand-secondary focus-visible:after:ring-[3px] focus-visible:after:ring-ring/50">
                      {job.title}
                    </a>
                    <span className="flex flex-wrap items-center gap-4 text-sm text-muted-foreground">
                      <span className="flex items-center gap-1.5">
                        <UsersIcon aria-hidden className="size-4" />
                        {job.team}
                      </span>
                      <span className="flex items-center gap-1.5">
                        <GlobeIcon aria-hidden className="size-4" />
                        {job.place}
                      </span>
                      <span className="flex items-center gap-1.5">
                        <ClockIcon aria-hidden className="size-4" />
                        {job.type}
                      </span>
                    </span>
                  </div>
                  <span aria-hidden className="flex size-10 items-center justify-center rounded-full border border-border transition-colors group-hover:border-foreground group-hover:bg-foreground group-hover:text-background [&>svg]:size-4">
                    <ChevronLeftIcon />
                  </span>
                </li>
              ))}
            </ul>
          )}

          <div className="flex flex-col items-start gap-4 rounded-xl bg-muted p-6 sm:flex-row sm:items-center sm:justify-between">
            <div className="flex flex-col gap-1">
              <span className="font-bold">موقعیتِ مناسبت را پیدا نکردی؟</span>
              <span className="text-sm text-muted-foreground">رزومه‌ات را بفرست؛ همیشه دنبالِ آدم‌های خوبیم.</span>
            </div>
            <Button variant="outline" className="bg-background">
              ارسالِ رزومه
            </Button>
          </div>
        </section>
      </main>
    </ControlSizeProvider>
  )
}