{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "script-installer",
  "title": "Script Installer",
  "description": "Installs, updates and removes the app's storefront script, one row per storefront.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "@ikas/animated-check",
    "@ikas/badge",
    "@ikas/banner",
    "@ikas/button",
    "@ikas/confirm-button",
    "@ikas/utils"
  ],
  "files": [
    {
      "path": "registry/ikas/script-installer.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { StoreIcon } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Button } from \"@/components/ui/button\"\nimport { CopyIconButton } from \"@/components/ikas/animated-check\"\nimport { Banner } from \"@/components/ikas/banner\"\nimport { ConfirmButton } from \"@/components/ikas/confirm-button\"\n\ntype ScriptStatus = \"installed\" | \"outdated\" | \"not-installed\"\n\ntype Storefront = {\n  id: string\n  name: string\n  domain?: string\n  status: ScriptStatus\n}\n\ntype ScriptInstallerProps = {\n  /** Public URL of the script the app injects into the storefront. */\n  scriptUrl: string\n  storefronts: Storefront[]\n  /** Install or update. Resolve when done; the row shows a loading state meanwhile. */\n  onInstall: (storefrontId: string) => Promise<void> | void\n  /** Removes the script. Resolve when done. */\n  onRemove: (storefrontId: string) => Promise<void> | void\n  className?: string\n}\n\nconst statusBadge: Record<ScriptStatus, { label: string; status: \"success\" | \"warning\" | \"neutral\" }> = {\n  installed: { label: \"Kurulu\", status: \"success\" },\n  outdated: { label: \"Güncel değil\", status: \"warning\" },\n  \"not-installed\": { label: \"Kurulu değil\", status: \"neutral\" },\n}\n\n/**\n * Storefront script install / update / remove, one row per storefront.\n * Warns when the script URL cannot be reached from a storefront (localhost).\n */\nfunction ScriptInstaller({ scriptUrl, storefronts, onInstall, onRemove, className }: ScriptInstallerProps) {\n  const [busy, setBusy] = React.useState<Record<string, \"install\" | \"remove\" | undefined>>({})\n  const isLocal = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1)/.test(scriptUrl)\n\n  async function run(id: string, kind: \"install\" | \"remove\") {\n    setBusy((b) => ({ ...b, [id]: kind }))\n    try {\n      await (kind === \"install\" ? onInstall(id) : onRemove(id))\n    } finally {\n      setBusy((b) => ({ ...b, [id]: undefined }))\n    }\n  }\n\n  return (\n    <div data-slot=\"script-installer\" className={cn(\"flex flex-col gap-4\", className)}>\n      <div className=\"flex items-center gap-2 rounded-lg bg-muted px-3 py-1.5 shadow-inset\">\n        <span className=\"shrink-0 text-[12px] text-muted-foreground\">Script</span>\n        <code className=\"min-w-0 flex-1 truncate font-mono text-[12.5px]\">{scriptUrl}</code>\n        <CopyIconButton value={scriptUrl} size=\"icon-xs\" label=\"Script adresini kopyala\" />\n      </div>\n\n      {isLocal && (\n        <Banner status=\"danger\" variant=\"surface\" title=\"Script storefront tarafından yüklenemez\">\n          Adres localhost olduğu için tarayıcı storefront&apos;tan erişimi engeller. Uygulamayı bir tünel veya genel bir domain üzerinden açıp script&apos;i yeniden kurun.\n        </Banner>\n      )}\n\n      <ul className=\"flex flex-col divide-y rounded-lg border\">\n        {storefronts.map((s) => {\n          const state = busy[s.id]\n          const badge = statusBadge[s.status]\n          return (\n            <li key={s.id} className=\"flex flex-wrap items-center gap-3 px-4 py-3\">\n              <span className=\"flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted text-icon\">\n                <StoreIcon className=\"size-4\" />\n              </span>\n              <div className=\"flex min-w-0 flex-1 flex-col\">\n                <span className=\"truncate text-sm font-medium\">{s.name}</span>\n                {s.domain && <span className=\"truncate text-[13px] text-muted-foreground\">{s.domain}</span>}\n              </div>\n              <Badge status={badge.status} dot={s.status === \"installed\"}>\n                {badge.label}\n              </Badge>\n              <div className=\"flex items-center gap-2\">\n                {s.status !== \"not-installed\" && (\n                  <ConfirmButton size=\"sm\" variant=\"ghost\" confirmLabel=\"Kaldırılsın mı?\" disabled={Boolean(state)} onConfirm={() => run(s.id, \"remove\")}>\n                    Kaldır\n                  </ConfirmButton>\n                )}\n                {s.status !== \"installed\" && (\n                  <Button size=\"sm\" variant={s.status === \"outdated\" ? \"outline\" : \"solid\"} loading={state === \"install\"} disabled={Boolean(state)} onClick={() => run(s.id, \"install\")}>\n                    {s.status === \"outdated\" ? \"Güncelle\" : \"Kur\"}\n                  </Button>\n                )}\n              </div>\n            </li>\n          )\n        })}\n      </ul>\n    </div>\n  )\n}\n\nexport { ScriptInstaller, type ScriptInstallerProps, type ScriptStatus, type Storefront }\n",
      "type": "registry:component",
      "target": "@components/ikas/script-installer.tsx"
    }
  ],
  "docs": "https://builders.ikas.com/tr/docs/app-development/ui-kit/components/script-installer",
  "categories": [
    "forms"
  ],
  "type": "registry:component"
}