Ctrl K
ComunidadGuías…

src/features/account/primitives.tsx

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { type ReactNode, useState } from 'react'
import { DestructiveConfirmation as DestructiveConfirmationSurface } from '@/components/destructive-confirmation'
import { tt } from '@/lib/i18n'
import { cn } from '@/lib/utils'
import type { DestructiveConfirmation, ListItem } from './types'

export function PanelTitle({
  action,
  title,
  description,
  icon,
}: {
  action?: ReactNode
  title: string
  description: string
  icon: ReactNode
}) {
  return (
    <div className="panelTitle">
      <div className="panelTitleMain">
        <div className="panelTitleIcon" aria-hidden="true">
          {icon}
        </div>
        <div>
          <h2>{title}</h2>
          <p>{description}</p>
        </div>
      </div>
      {action}
    </div>
  )
}

export function StatusPill({ label, value }: { label: string; value: string }) {
  return (
    <div className="statusPill">
      <span>{value}</span>
      <strong>{label}</strong>
    </div>
  )
}

export function SettingsAction({
  action,
  icon,
  meta,
  status,
  title,
  value,
}: {
  action?: ReactNode
  icon: ReactNode
  meta: string
  status?: string
  title: string
  value?: ReactNode
}) {
  return (
    <article className="accountRow settingsAction">
      <div className="accountRowLabel">
        <span className="accountSettingIcon" aria-hidden="true">
          {icon}
        </span>
        <strong>{title}</strong>
        <span>{meta}</span>
      </div>
      <div className="accountRowValue">
        {value ? <div className="block font-medium text-foreground">{value}</div> : null}
        {status ? <span>{status}</span> : null}
      </div>
      <div className="accountRowAction">{action}</div>
    </article>
  )
}

export function SubsectionTitle({ title, description }: { title: string; description: string }) {
  return (
    <div className="subsectionTitle">
      <h3>{title}</h3>
      <p>{description}</p>
    </div>
  )
}

export function ItemList({
  compactEmpty = false,
  empty,
  emptyDescription = tt('Nothing needs attention here.'),
  emptyIcon,
  items,
}: {
  compactEmpty?: boolean
  empty: string
  emptyDescription?: string
  emptyIcon?: ReactNode
  items: ListItem[]
}) {
  return (
    <div className="accountRows itemList">
      {items.length === 0 ? (
        <article className={cn('accountRow itemRow itemRowEmpty', compactEmpty && 'is-compact')}>
          <div className="accountRowLabel">
            {emptyIcon ? (
              <span className="accountEmptyIcon" aria-hidden="true">
                {emptyIcon}
              </span>
            ) : null}
            <strong>{empty}</strong>
            <span>{emptyDescription}</span>
          </div>
        </article>
      ) : (
        items.map((item) => (
          <article className="accountRow itemRow" key={item.id}>
            <div className={cn('accountRowLabel itemRowMain', !item.icon && 'withoutIcon')}>
              {item.icon ? (
                <span className="itemRowIcon" aria-hidden="true">
                  {item.icon}
                </span>
              ) : null}
              <div className="itemRowCopy">
                <strong>{item.title}</strong>
                <span>{item.meta}</span>
                {item.children}
              </div>
            </div>
            <div className="accountRowValue">{item.status}</div>
            <div className="accountRowAction">{item.action}</div>
          </article>
        ))
      )}
    </div>
  )
}

export function DestructiveConfirmationDialog({
  confirmation,
  onClose,
}: {
  confirmation: DestructiveConfirmation | null
  onClose: () => void
}) {
  if (!confirmation) return null
  return (
    <DestructiveConfirmationSurface
      confirmLabel={confirmation.actionLabel}
      description={confirmation.description}
      onClose={onClose}
      onConfirm={() => {
        const confirmed = confirmation
        onClose()
        void confirmed.onConfirm()
      }}
      open
      title={confirmation.title}
    />
  )
}

export function useDestructiveConfirmation() {
  return useState<DestructiveConfirmation | null>(null)
}

export function UnavailableSection({ message }: { message: string }) {
  return (
    <section className="settingsPanel">
      <article className="itemRow itemRowEmpty">
        <div>
          <h3>{message}</h3>
          <p>{tt('Nothing needs attention here.')}</p>
        </div>
      </article>
    </section>
  )
}