{"version":3,"file":"RecentActivityWidget-BQXZR4_G.cjs","names":["useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","useShellTranslation","getActivityIcon","describeActor","initialsForActor","User","formatActivityRelativeTime","formatActivityTime","useWidgetInteraction","useOptionalStore","getActivityDateKey","formatActivityDateHeader","borderWidthClasses","borderColorClasses","ErrorState","EmptyActivityIcon","getFontSizeField","getColorField","getPaddingField","getBorderRadiusField","getBorderWidthField","getBorderColorField"],"sources":["../../widgets/src/hooks/use-activities.preview.ts","../../widgets/src/hooks/use-activities.ts","../../widgets/src/widgets/RecentActivityWidget.tsx"],"sourcesContent":["import type { Activity } from \"@fluid-app/portal-core/widgets-api-types\";\n\nconst now = new Date();\n\nfunction minutesAgo(minutes: number): string {\n  return new Date(now.getTime() - minutes * 60_000).toISOString();\n}\n\nexport const PREVIEW_DATA: Activity[] = [\n  {\n    id: 1,\n    userName: \"Sarah Johnson\",\n    actor: { type: \"contact\", name: \"Sarah Johnson\" },\n    avatarUrl: null,\n    activityType: \"Order Placed\",\n    targetName: \"Wellness Starter Kit\",\n    timestamp: minutesAgo(12),\n    slug: \"order_placed\",\n    title: \"New order placed\",\n    description: \"Wellness Starter Kit\",\n    readAt: null,\n    urgent: true,\n    details: {\n      type: \"order\",\n      contactName: \"Sarah Johnson\",\n      orderTotal: \"129.99\",\n    },\n  },\n  {\n    id: 2,\n    userName: \"Mike Chen\",\n    actor: { type: \"contact\", name: \"Mike Chen\" },\n    avatarUrl: null,\n    activityType: \"New Lead\",\n    targetName: \"Signed up from Instagram link\",\n    timestamp: minutesAgo(45),\n    slug: \"new_lead\",\n    title: \"New lead\",\n    description: \"Signed up from Instagram link\",\n    readAt: null,\n    urgent: true,\n    details: {\n      type: \"contactLead\",\n      contactName: \"Mike Chen\",\n      leadType: \"instagram\",\n    },\n  },\n  {\n    id: 3,\n    userName: \"Visitor from Austin, TX\",\n    // A real visitor, so the preview exercises the muted, translated treatment\n    // rather than showing contact styling under a visitor's label.\n    actor: { type: \"visitor\", city: \"Austin\", state: \"TX\" },\n    avatarUrl: null,\n    activityType: \"Page Views\",\n    targetName: \"Viewed product catalog (3 pages)\",\n    timestamp: minutesAgo(90),\n    slug: \"page_views\",\n    title: \"Page viewed\",\n    description: \"Viewed product catalog (3 pages)\",\n    readAt: minutesAgo(60),\n    urgent: false,\n    details: {\n      type: \"pageView\",\n      resourceName: \"Product catalog\",\n    },\n  },\n  {\n    id: 4,\n    userName: \"Lisa Park\",\n    actor: { type: \"contact\", name: \"Lisa Park\" },\n    avatarUrl: null,\n    activityType: \"Video Complete\",\n    targetName: \"Watched: Getting Started Guide\",\n    timestamp: minutesAgo(180),\n    slug: \"video_complete\",\n    title: \"Video finished\",\n    description: \"Watched: Getting Started Guide\",\n    readAt: minutesAgo(120),\n    urgent: false,\n    details: {\n      type: \"video\",\n      contactName: \"Lisa Park\",\n      mediumTitle: \"Getting Started Guide\",\n    },\n  },\n];\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-activities.preview\";\nimport type { ActivitiesPage } from \"@fluid-app/portal-core/widgets-api\";\n\nexport type {\n  Activity,\n  ActivitySlug,\n} from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type UseActivitiesData = ActivitiesPage;\n\nexport function useActivities(args?: {\n  daysAgo?: number;\n}): UseQueryResult<UseActivitiesData, Error> {\n  const widgetsApi = useWidgetsApi();\n  const { isPreview } = useWidgetPreviewContext();\n  const { baseUrl } = useDataSourceRegistryConfig();\n\n  return useQuery({\n    queryKey: [\n      \"portal-widget-use\",\n      \"activities\",\n      args?.daysAgo ?? null,\n      isPreview ? \"preview\" : baseUrl,\n    ] as const,\n    queryFn: ({ signal }) => widgetsApi.fetchActivities(args, signal),\n    enabled: !isPreview,\n    ...(isPreview && {\n      // Omit totalCount entirely (rather than setting it to undefined) so\n      // tsconfig's exactOptionalPropertyTypes accepts the placeholder shape.\n      placeholderData: {\n        activities: PREVIEW_DATA,\n        nextCursor: null,\n      } satisfies UseActivitiesData,\n    }),\n  });\n}\n","import { useEffect, useMemo, useState, type ComponentProps } from \"react\";\nimport type React from \"react\";\nimport type {\n  BackgroundValue,\n  BorderRadiusOptions,\n  BorderWidthOptions,\n  ColorOptions,\n  FontSizeOptions,\n  PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport {\n  borderColorClasses,\n  borderWidthClasses,\n  getBorderColorField,\n  getBorderRadiusField,\n  getBorderWidthField,\n  getColorField,\n  getFontSizeField,\n  getPaddingField,\n} from \"../core/fields\";\nimport { useActivities, type Activity } from \"../hooks/use-activities\";\nimport { useWidgetInteraction } from \"../contexts/WidgetInteractionContext\";\nimport { useOptionalStore } from \"@fluid-app/portal-react/hooks/use-optional-store\";\nimport { useShellTranslation } from \"@fluid-app/portal-core/shell-translation-api-context\";\nimport { ErrorState } from \"../components/error-state\";\nimport {\n  describeActor,\n  EmptyActivityIcon,\n  formatActivityDateHeader,\n  formatActivityRelativeTime,\n  formatActivityTime,\n  getActivityDateKey,\n  getActivityIcon,\n  initialsForActor,\n} from \"@fluid-app/portal-core/activity-presentation\";\nimport { User } from \"lucide-react\";\n\n// ---------- helpers ----------\n\nconst RELATIVE_TIME_REFRESH_MS = 60_000;\nconst DEFAULT_MAX_ITEMS_TO_SHOW = 6;\nconst MAX_ITEMS_TO_SHOW_LIMIT = 20;\n\n// Window matches the Mobile Recent Activity widget, which reads the same\n// days_ago=7 feed, so a rep sees one number across both surfaces.\nconst RECENT_ACTIVITY_DAYS = 7;\n\n// The Activity screen opens on all activity, not this window, so its feed is a\n// superset of what the chip counts. Same split as mobile, where only the Past\n// tab is windowed.\nconst ACTIVITY_SCREEN_SLUG = \"activity\";\n\nconst getColorCssValue = (color: ColorOptions): string =>\n  color === \"transparent\" ? \"transparent\" : `var(--color-${color})`;\n\nconst normalizeMaxItemsToShow = (value: number): number => {\n  if (!Number.isFinite(value)) return DEFAULT_MAX_ITEMS_TO_SHOW;\n  return Math.min(MAX_ITEMS_TO_SHOW_LIMIT, Math.max(1, Math.floor(value)));\n};\n\n// Suppresses the eyebrow when the admin's title already contains it, so a title\n// of \"Recent Activity\" doesn't render as \"RECENT / Recent Activity\". Compared\n// against the translated eyebrow rather than a literal, or the check would only\n// ever work in English.\nconst shouldRenderEyebrow = (\n  showEyebrow: boolean,\n  titleText: string,\n  eyebrowText: string,\n): boolean =>\n  showEyebrow &&\n  !titleText.trim().toLowerCase().includes(eyebrowText.trim().toLowerCase());\n\n/**\n * Whether the row has nobody to show a face for. Read off the actor rather than\n * sniffed out of the label, which matched the English \"unknown visitor\" and so\n * decided the avatar correctly in one language of the thirty-four.\n */\nconst hasNoKnownPerson = (activity: Activity): boolean =>\n  activity.actor.type !== \"contact\";\n\n// ---------- avatar ----------\n\ntype AvatarProps = {\n  activity: Activity;\n  textColor: ColorOptions;\n  accentColor: ColorOptions;\n  surfaceColor: ColorOptions;\n  showTypeBadge: boolean;\n};\n\nfunction Avatar({\n  activity,\n  textColor,\n  accentColor,\n  surfaceColor,\n  showTypeBadge,\n}: AvatarProps) {\n  const { t } = useShellTranslation();\n  const TypeIcon = getActivityIcon(activity.slug);\n  const { label } = describeActor(activity.actor, t);\n  const unknown = hasNoKnownPerson(activity);\n  const initials = initialsForActor(activity.actor);\n  // 3-tier fallback: image → initials → person icon. If avatarUrl 404s or\n  // fails to decode, flip to the next tier instead of showing a broken image.\n  const [failedAvatarUrl, setFailedAvatarUrl] = useState<string | null>(null);\n  const avatarUrl = activity.avatarUrl;\n  const showImage = Boolean(avatarUrl) && failedAvatarUrl !== avatarUrl;\n\n  return (\n    <div className=\"relative shrink-0\">\n      {showImage ? (\n        <img\n          src={avatarUrl ?? undefined}\n          alt={unknown ? \"\" : label}\n          width={36}\n          height={36}\n          loading=\"lazy\"\n          onError={() => setFailedAvatarUrl(avatarUrl)}\n          className=\"size-9 rounded-full object-cover\"\n          style={{\n            boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n          }}\n        />\n      ) : initials ? (\n        <div\n          className={`flex size-9 items-center justify-center rounded-full text-[11px] font-bold tracking-[0.04em] text-${textColor}/80`}\n          style={{\n            background: `color-mix(in oklch, var(--color-${accentColor}) 12%, transparent)`,\n            boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n          }}\n          aria-label={label}\n        >\n          {initials}\n        </div>\n      ) : (\n        <div\n          className={`flex size-9 items-center justify-center rounded-full`}\n          style={{\n            background: `color-mix(in oklch, var(--color-${textColor}) 5%, transparent)`,\n            boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n          }}\n          aria-label={label}\n        >\n          <User className={`size-3.5 text-${textColor}/55`} />\n        </div>\n      )}\n\n      {/* Type badge — shows what kind of event, regardless of avatar kind. */}\n      {showTypeBadge && (\n        <span\n          className={`bg-${accentColor} text-${accentColor}-foreground absolute -right-0.5 -bottom-0.5 flex size-4 items-center justify-center rounded-full`}\n          style={{\n            boxShadow: `0 0 0 2px ${getColorCssValue(surfaceColor)}`,\n          }}\n          aria-hidden=\"true\"\n        >\n          <TypeIcon style={{ width: 8, height: 8 }} />\n        </span>\n      )}\n    </div>\n  );\n}\n\n// ---------- activity row ----------\n\ntype ActivityRowProps = {\n  activity: Activity;\n  accentColor: ColorOptions;\n  textColor: ColorOptions;\n  surfaceColor: ColorOptions;\n  showRelativeTime: boolean;\n  nowMs: number;\n};\n\nfunction ActivityRow({\n  activity,\n  accentColor,\n  textColor,\n  surfaceColor,\n  showRelativeTime,\n  nowMs,\n}: ActivityRowProps) {\n  const { t } = useShellTranslation();\n  // Same helper the Activity screen uses, so an anonymous visitor reads and looks\n  // the same on both surfaces rather than each wording it its own way.\n  const { label, muted } = describeActor(activity.actor, t);\n  const timeText = showRelativeTime\n    ? formatActivityRelativeTime(activity.timestamp, nowMs)\n    : formatActivityTime(activity.timestamp);\n\n  const absoluteTooltip = new Date(activity.timestamp).toLocaleString(\"en-US\", {\n    weekday: \"short\",\n    month: \"short\",\n    day: \"numeric\",\n    hour: \"numeric\",\n    minute: \"2-digit\",\n  });\n\n  return (\n    <li\n      role=\"article\"\n      className=\"relative flex items-start gap-3 rounded-md p-2\"\n    >\n      <Avatar\n        activity={activity}\n        textColor={textColor}\n        accentColor={accentColor}\n        surfaceColor={surfaceColor}\n        showTypeBadge\n      />\n\n      <div className=\"flex min-w-0 flex-1 flex-col\">\n        <div className=\"flex items-baseline gap-2\">\n          <p\n            className={`min-w-0 flex-1 truncate text-[13px] leading-tight font-semibold text-${textColor}`}\n          >\n            {activity.activityType}\n          </p>\n          <span\n            title={absoluteTooltip}\n            className={`shrink-0 font-mono text-[10px] font-medium tabular-nums text-${textColor}/45`}\n          >\n            {timeText}\n          </span>\n        </div>\n        <p\n          className={`mt-0.5 truncate text-[12px] leading-snug text-${textColor}/65`}\n        >\n          <span\n            className={`font-semibold text-${textColor}/85${muted ? \" italic\" : \"\"}`}\n          >\n            {label}\n          </span>\n          {activity.targetName && (\n            <>\n              <span className={`mx-1 text-${textColor}/35`}>·</span>\n              <span>{activity.targetName}</span>\n            </>\n          )}\n        </p>\n      </div>\n    </li>\n  );\n}\n\n// ---------- widget ----------\n\ntype RecentActivityWidgetProps = ComponentProps<\"div\"> & {\n  titleEnabled?: boolean;\n  titleText?: string;\n  titleFontSize?: FontSizeOptions;\n  titleColor?: ColorOptions;\n\n  background?: BackgroundValue;\n  textColor?: ColorOptions;\n  accentColor?: ColorOptions;\n  padding?: PaddingOptions;\n  borderRadius?: BorderRadiusOptions;\n  borderWidth?: BorderWidthOptions;\n  borderColor?: ColorOptions;\n\n  maxItemsToShow?: number;\n\n  // Polish (additive)\n  showTimeline?: boolean;\n  showRelativeTime?: boolean;\n  showCountChip?: boolean;\n  showEyebrow?: boolean;\n};\n\nfunction useRelativeTimeNow(): number {\n  const [nowMs, setNowMs] = useState(() => Date.now());\n\n  useEffect(() => {\n    const timer = window.setInterval(() => {\n      setNowMs(Date.now());\n    }, RELATIVE_TIME_REFRESH_MS);\n\n    return () => window.clearInterval(timer);\n  }, []);\n\n  return nowMs;\n}\n\nexport function RecentActivityWidget({\n  titleEnabled = true,\n  titleText = \"Activity\",\n  titleFontSize = \"xl\",\n  titleColor = \"foreground\",\n\n  background = { type: \"solid\", color: \"background\" },\n  textColor = \"foreground\",\n  accentColor = \"primary\",\n  padding = 4,\n  borderRadius = \"md\",\n  borderWidth = \"thin\",\n  borderColor = \"muted\",\n\n  maxItemsToShow = 6,\n\n  // showTimeline is intentionally not destructured. The spine it once\n  // controlled is no longer rendered. The prop stays on the type so saved\n  // widget configs don't fail schema validation.\n  showRelativeTime = true,\n  showCountChip = true,\n  showEyebrow = true,\n\n  className,\n  onClick: onClickProp,\n  ...props\n}: RecentActivityWidgetProps): React.JSX.Element {\n  const backgroundColor = background.color || \"background\";\n  const backgroundImage =\n    (background.resource?.image_url || background.resource?.imageUrl) &&\n    background.type === \"image\"\n      ? `url(${background.resource.image_url || background.resource.imageUrl})`\n      : \"none\";\n\n  // Rep-facing copy reads the same shell keys the Activity screen does, so the two\n  // surfaces cannot drift. The untranslated strings further down are builder field\n  // labels and descriptions, which the editor shows an admin rather than a rep.\n  const { t } = useShellTranslation();\n\n  // Absent in the builder preview, which is how the preview stays inert.\n  const { onNavigate } = useWidgetInteraction();\n  // The Activity screen is tenant-flagged (PORTAL_ACTIVITY_SCREEN). Without it\n  // the widget is a plain summary again: no click-through to offer.\n  const { data: store } = useOptionalStore();\n  const canNavigate =\n    Boolean(onNavigate) && store?.activity_screen_enabled === true;\n\n  const goToActivityScreen = () => {\n    if (!canNavigate) return;\n    onNavigate?.(ACTIVITY_SCREEN_SLUG);\n  };\n\n  // Clicking anywhere on the card navigates, but the card is not itself a\n  // control — the \"View all\" button below is, so keyboard and screen-reader\n  // users get a real target without nesting interactive elements.\n  const handleRootClick = (event: React.MouseEvent<HTMLDivElement>) => {\n    onClickProp?.(event);\n    if (event.defaultPrevented) return;\n    goToActivityScreen();\n  };\n\n  const { data, isLoading, isError } = useActivities({\n    daysAgo: RECENT_ACTIVITY_DAYS,\n  });\n  // Stabilize the empty-fallback reference so downstream `useMemo` deps don't\n  // see a fresh `[]` on every render.\n  const activities = useMemo(() => data?.activities ?? [], [data]);\n  const windowedTotal = data?.totalCount;\n  const nowMs = useRelativeTimeNow();\n  const maxVisibleItems = normalizeMaxItemsToShow(maxItemsToShow);\n  const dayLabels = useMemo(\n    () => ({\n      today: t(\"activity_date_today\"),\n      yesterday: t(\"activity_date_yesterday\"),\n    }),\n    [t],\n  );\n\n  const activitiesToShow = useMemo(() => {\n    if (activities.length === 0)\n      return [] as { date: string; items: Activity[] }[];\n    const groups = new Map<string, Activity[]>();\n    for (const activity of activities.slice(0, maxVisibleItems)) {\n      const key = getActivityDateKey(activity.timestamp);\n      const existing = groups.get(key);\n      if (existing) existing.push(activity);\n      else groups.set(key, [activity]);\n    }\n    return Array.from(groups.entries()).map(([key, items]) => ({\n      // `key` is only a defensive fallback; every group is created with at\n      // least one activity, so the item timestamp is what normally labels it.\n      date: formatActivityDateHeader(\n        items[0]?.timestamp ?? key,\n        nowMs,\n        dayLabels,\n      ),\n      items,\n    }));\n  }, [activities, maxVisibleItems, nowMs, dayLabels]);\n\n  // Prefer the server total. Fall back to the visible list length when the\n  // adapter does not return one, so the widget keeps working before every\n  // data path returns a count.\n  const totalCount =\n    windowedTotal ?? Math.min(activities.length, maxVisibleItems);\n\n  return (\n    <div\n      onClick={canNavigate || onClickProp ? handleRootClick : undefined}\n      className={`@container overflow-hidden rounded-${borderRadius} bg-${backgroundColor} text-${textColor} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} ${canNavigate ? \"cursor-pointer\" : \"\"} ${className ?? \"\"}`}\n      style={{\n        backgroundImage,\n        // Soft ambient lift derived from theme tokens. The configured border\n        // props own the crisp outline so saved border settings stay intact.\n        boxShadow: `0 1px 2px color-mix(in oklch, var(--color-foreground) 4%, transparent), 0 14px 32px -20px color-mix(in oklch, var(--color-foreground) 14%, transparent)`,\n      }}\n      {...props}\n    >\n      <div className={`p-${padding} flex flex-col`}>\n        {/* Header */}\n        {titleEnabled && titleText && (\n          <div className=\"mb-4 flex items-end justify-between gap-3\">\n            <div className=\"flex min-w-0 flex-col\">\n              {shouldRenderEyebrow(\n                showEyebrow,\n                titleText,\n                t(\"activity_widget_eyebrow\"),\n              ) && (\n                <span\n                  className={`text-[10px] font-bold tracking-[0.2em] uppercase text-${textColor}/55`}\n                >\n                  {t(\"activity_widget_eyebrow\")}\n                </span>\n              )}\n              <h2\n                className={`mt-0.5 text-${titleFontSize} leading-tight font-bold tracking-[-0.015em] text-${titleColor}`}\n              >\n                {titleText}\n              </h2>\n              <span\n                className={`mt-0.5 text-xs font-medium text-${textColor}/60`}\n              >\n                {t(\"activity_widget_window\", { days: RECENT_ACTIVITY_DAYS })}\n              </span>\n            </div>\n            <div className=\"flex shrink-0 items-center gap-2\">\n              {!isLoading && !isError && showCountChip && totalCount > 0 && (\n                <span\n                  className={`inline-flex shrink-0 items-center gap-1.5 rounded-full bg-${accentColor}/10 px-2 py-1 text-[10px] font-bold tracking-[0.06em] text-${accentColor}`}\n                >\n                  <span\n                    aria-hidden=\"true\"\n                    className={`size-1.5 rounded-full bg-${accentColor}`}\n                  />\n                  {t(\"activity_widget_updates\", { count: totalCount })}\n                </span>\n              )}\n              {canNavigate && (\n                <button\n                  type=\"button\"\n                  onClick={(event) => {\n                    // The card handles clicks too; stop here so one click is\n                    // one navigation.\n                    event.stopPropagation();\n                    goToActivityScreen();\n                  }}\n                  className={`shrink-0 rounded-md px-1.5 py-1 text-[11px] font-bold text-${accentColor} hover:bg-${accentColor}/10 focus-visible:ring-${accentColor} focus-visible:ring-2 focus-visible:outline-none`}\n                >\n                  {t(\"activity_view_all\")}\n                </button>\n              )}\n            </div>\n          </div>\n        )}\n\n        {/* States */}\n        {isLoading ? (\n          <ActivitySkeleton textColor={textColor} rowCount={maxVisibleItems} />\n        ) : isError ? (\n          <ErrorState />\n        ) : activities.length === 0 ? (\n          <EmptyState textColor={textColor} accentColor={accentColor} />\n        ) : (\n          /* Feed */\n          <div role=\"feed\" className=\"flex flex-col gap-3\">\n            {activitiesToShow.map((group, groupIdx) => (\n              <section\n                key={`${group.date}-${groupIdx}`}\n                className=\"flex flex-col gap-1\"\n              >\n                <header className=\"flex items-center gap-2 px-2\">\n                  <span\n                    className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n                  >\n                    {group.date}\n                  </span>\n                  <span\n                    aria-hidden=\"true\"\n                    className=\"h-px flex-1\"\n                    style={{\n                      background: `color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n                    }}\n                  />\n                </header>\n\n                <ul className=\"relative flex flex-col\">\n                  {/* No timeline spine. An earlier version drew a single\n                      line at the avatar column, which the avatars occluded,\n                      leaving only fragmented stubs between rows. */}\n                  {group.items.map((activity) => (\n                    <ActivityRow\n                      key={activity.id}\n                      activity={activity}\n                      accentColor={accentColor}\n                      textColor={textColor}\n                      surfaceColor={backgroundColor}\n                      showRelativeTime={showRelativeTime}\n                      nowMs={nowMs}\n                    />\n                  ))}\n                </ul>\n              </section>\n            ))}\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n\n// ---------- empty state ----------\n\ntype EmptyStateProps = {\n  textColor: ColorOptions;\n  accentColor: ColorOptions;\n};\n\nfunction EmptyState({ textColor, accentColor }: EmptyStateProps) {\n  const { t } = useShellTranslation();\n\n  return (\n    <div className=\"flex flex-col items-center justify-center gap-3 px-4 py-10\">\n      <div\n        className=\"relative flex size-12 items-center justify-center rounded-full\"\n        style={{\n          background: `color-mix(in oklch, var(--color-${accentColor}) 10%, transparent)`,\n          boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n        }}\n      >\n        <EmptyActivityIcon className={`size-5 text-${accentColor}/80`} />\n      </div>\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className={`text-[13px] font-semibold text-${textColor}/80`}>\n          {t(\"activity_empty_title\")}\n        </p>\n        <p\n          className={`max-w-[24ch] text-center text-[11px] leading-snug text-${textColor}/55`}\n        >\n          {t(\"activity_empty_description\")}\n        </p>\n      </div>\n    </div>\n  );\n}\n\n// ---------- skeleton ----------\n\ntype ActivitySkeletonProps = {\n  textColor: ColorOptions;\n  rowCount: number;\n};\n\nfunction ActivitySkeleton({ textColor, rowCount }: ActivitySkeletonProps) {\n  return (\n    <div className=\"relative flex flex-col\" aria-busy=\"true\">\n      {/* No skeleton spine; the loaded state doesn't draw one either. */}\n      {Array.from({ length: rowCount }, (_, i) => i).map((i) => (\n        <div key={i} className=\"relative flex items-start gap-3 rounded-md p-2\">\n          <div\n            className={`size-9 shrink-0 animate-pulse rounded-full bg-${textColor}/10`}\n          />\n          <div className=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n            <div\n              className={`h-2 w-2/3 animate-pulse rounded-full bg-${textColor}/10`}\n            />\n            <div\n              className={`h-2 w-1/2 animate-pulse rounded-full bg-${textColor}/10`}\n            />\n          </div>\n        </div>\n      ))}\n    </div>\n  );\n}\n\n// ---------- schema ----------\n\nexport const recentActivityWidgetPropertySchema: WidgetPropertySchema = {\n  widgetType: \"RecentActivityWidget\",\n  displayName: \"Recent Activity Widget\",\n  tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n  fields: [\n    // Title\n    {\n      key: \"titleEnabled\",\n      label: \"Widget Title\",\n      type: \"boolean\",\n      description: \"Display the title and eyebrow above the feed\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Title\",\n    },\n    {\n      key: \"titleText\",\n      label: \"Title\",\n      type: \"text\",\n      description: \"Title text displayed above the activity feed\",\n      defaultValue: \"Activity\",\n      tab: \"styling\",\n      group: \"Title\",\n      requiresKeyToBeTrue: \"titleEnabled\",\n    },\n    getFontSizeField({\n      key: \"titleFontSize\",\n      label: \"Title Font Size\",\n      description: \"Font size for the widget title\",\n      defaultValue: \"xl\",\n      tab: \"styling\",\n      group: \"Title\",\n      requiresKeyToBeTrue: \"titleEnabled\",\n    }),\n    getColorField({\n      key: \"titleColor\",\n      label: \"Title Color\",\n      description: \"Color for the widget title\",\n      defaultValue: \"foreground\",\n      tab: \"styling\",\n      group: \"Title\",\n      requiresKeyToBeTrue: \"titleEnabled\",\n    }),\n    {\n      key: \"showEyebrow\",\n      label: \"Show 'RECENT' Eyebrow\",\n      type: \"boolean\",\n      description: \"Small uppercase label above the title\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Title\",\n      requiresKeyToBeTrue: \"titleEnabled\",\n    },\n    {\n      key: \"showCountChip\",\n      label: \"Show Updates Count Chip\",\n      type: \"boolean\",\n      description: \"Accent pill next to the title showing how many updates\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Title\",\n      requiresKeyToBeTrue: \"titleEnabled\",\n    },\n\n    // Feed\n    {\n      key: \"maxItemsToShow\",\n      label: \"Max Items\",\n      type: \"number\",\n      description: \"Maximum number of activity items to display\",\n      defaultValue: DEFAULT_MAX_ITEMS_TO_SHOW,\n      min: 1,\n      max: MAX_ITEMS_TO_SHOW_LIMIT,\n      step: 1,\n      tab: \"styling\",\n      group: \"Feed\",\n    },\n    {\n      key: \"showRelativeTime\",\n      label: \"Relative Timestamps\",\n      type: \"boolean\",\n      description: \"Show 'now / 2m / 1h / 3d' instead of absolute times\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Feed\",\n    },\n\n    // Design\n    {\n      type: \"background\",\n      key: \"background\",\n      label: \"Background\",\n      description: \"Background for the widget container\",\n      defaultValue: { type: \"solid\", color: \"background\" },\n      tab: \"styling\",\n      group: \"Design\",\n    },\n    getColorField({\n      key: \"textColor\",\n      label: \"Text Color\",\n      description: \"Default text color for activity content\",\n      defaultValue: \"foreground\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    getColorField({\n      key: \"accentColor\",\n      label: \"Accent Color\",\n      description:\n        \"Drives the count chip, type badge, initials avatar, and empty-state icon\",\n      defaultValue: \"primary\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    {\n      key: \"separator\",\n      type: \"separator\",\n      label: \"Separator\",\n      tab: \"styling\",\n      group: \"Design\",\n    },\n    getPaddingField({\n      key: \"padding\",\n      label: \"Padding\",\n      description: \"Padding around the widget container\",\n      defaultValue: 4,\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    getBorderRadiusField({\n      key: \"borderRadius\",\n      label: \"Border Radius\",\n      description: \"Border radius for the widget container\",\n      defaultValue: \"md\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    getBorderWidthField({\n      key: \"borderWidth\",\n      label: \"Border Width\",\n      description: \"Border width for the widget container\",\n      defaultValue: \"thin\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    getBorderColorField({\n      key: \"borderColor\",\n      label: \"Border Color\",\n      description: \"Border color for the widget container\",\n      defaultValue: \"muted\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n  ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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CR;EACDA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aACE;GACF,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACDC,mBAAAA,gBAAgB;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACH;CACF"}