{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "quickstart-with-client-side-xmc",
  "title": "Quickstart for Next.js with XMC API examples",
  "description": "A quickstart for next.js Sitecore marketplace apps with XMC API examples",
  "dependencies": [
    "@sitecore-marketplace-sdk/xmc"
  ],
  "registryDependencies": [
    "https://blok.sitecore.com/r/marketplace/next/quickstart.json",
    "https://blok.sitecore.com/r/button.json",
    "https://blok.sitecore.com/r/alert.json",
    "https://blok.sitecore.com/r/skeleton.json",
    "https://blok.sitecore.com/r/separator.json"
  ],
  "files": [
    {
      "path": "src/marketplace/next/components/providers/marketplace-w-xmc.tsx",
      "content": "\"use client\";\n\nimport {\n  type ApplicationContext,\n  ClientSDK,\n} from \"@sitecore-marketplace-sdk/client\";\nimport { XMC } from \"@sitecore-marketplace-sdk/xmc\";\nimport type React from \"react\";\nimport {\n  type ReactNode,\n  createContext,\n  useContext,\n  useEffect,\n  useState,\n} from \"react\";\n\ninterface ClientSDKProviderProps {\n  children: ReactNode;\n}\n\nconst ClientSDKContext = createContext<ClientSDK | null>(null);\nconst AppContextContext = createContext<ApplicationContext | null>(null);\n\nexport const MarketplaceProvider: React.FC<ClientSDKProviderProps> = ({\n  children,\n}) => {\n  const [client, setClient] = useState<ClientSDK | null>(null);\n  const [appContext, setAppContext] = useState<ApplicationContext | null>(null);\n  const [error, setError] = useState<string | null>(null);\n  const [loading, setLoading] = useState<boolean>(false);\n\n  useEffect(() => {\n    if (client) {\n      client.query(\"application.context\").then((res) => {\n        if (res?.data) {\n          setAppContext(res.data);\n          console.log(\"appContext\", res.data);\n        }\n      });\n    }\n  }, [client]);\n\n  useEffect(() => {\n    const init = async () => {\n      const config = {\n        target: window.parent,\n        modules: [XMC],\n      };\n      try {\n        setLoading(true);\n        const client = await ClientSDK.init(config);\n        setClient(client);\n      } catch (error) {\n        console.error(\"Error initializing client SDK\", error);\n        setError(\"Error initializing client SDK\");\n      } finally {\n        setLoading(false);\n      }\n    };\n\n    init();\n  }, []);\n\n  if (loading) {\n    return <div>Attempting to connect to Sitecore Marketplace...</div>;\n  }\n\n  if (error) {\n    return (\n      <div>\n        <h1>Error initializing Marketplace SDK</h1>\n        <div>{error}</div>\n        <div>\n          Please check if the client SDK is loaded inside Sitecore Marketplace\n          parent window and you have properly set your app's extention points.\n        </div>\n      </div>\n    );\n  }\n\n  if (!client) {\n    return null;\n  }\n\n  if (!appContext) {\n    return null;\n  }\n\n  return (\n    <ClientSDKContext.Provider value={client}>\n      <AppContextContext.Provider value={appContext}>\n        {children}\n      </AppContextContext.Provider>\n    </ClientSDKContext.Provider>\n  );\n};\n\nexport const useMarketplaceClient = () => {\n  const context = useContext(ClientSDKContext);\n  if (!context) {\n    throw new Error(\n      \"useMarketplaceClient must be used within a ClientSDKProvider\",\n    );\n  }\n  return context;\n};\n\nexport const useAppContext = () => {\n  const context = useContext(AppContextContext);\n  if (!context) {\n    throw new Error(\"useAppContext must be used within a ClientSDKProvider\");\n  }\n  return context;\n};\n",
      "type": "registry:component",
      "target": "components/providers/marketplace.tsx"
    },
    {
      "path": "src/marketplace/next/components/examples/built-in-auth/with-xmc/list-languages.tsx",
      "content": "\"use client\";\n\nimport {\n  useAppContext,\n  useMarketplaceClient,\n} from \"@/components/providers/marketplace\";\nimport { Alert, AlertDescription } from \"@/components/ui/alert\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardHeader,\n  CardTitle,\n} from \"@/components/ui/card\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport type { Xmapp } from \"@sitecore-marketplace-sdk/xmc\";\nimport { useState } from \"react\";\n\nexport const ListLanguagesFromClientSdk = () => {\n  const client = useMarketplaceClient();\n  const appContext = useAppContext();\n  const [languages, setLanguages] = useState<Xmapp.Language[]>([]);\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState<string | null>(null);\n\n  const fetchLanguages = async () => {\n    setLoading(true);\n    setError(null);\n\n    const contextId = appContext?.resourceAccess?.[0]?.context\n      ?.preview as string;\n    if (!contextId) {\n      setError(\"No context ID available\");\n      setLoading(false);\n      return;\n    }\n\n    const data = {\n      query: {\n        sitecoreContextId: contextId,\n      },\n    };\n\n    try {\n      const languagesResponse = await client.query(\"xmc.sites.listLanguages\", {\n        params: data,\n      });\n      console.log(\"languages from client\", languagesResponse);\n      setLanguages(languagesResponse.data?.data ?? []);\n    } catch (err) {\n      console.log(\"error from client\", err);\n      setError(err instanceof Error ? err.message : \"An error occurred\");\n    } finally {\n      setLoading(false);\n    }\n  };\n\n  return (\n    <Card style={\"outline\"}>\n      <CardHeader>\n        <CardTitle className=\"flex items-center gap-2\">\n          Client SDK Example\n          <Badge colorScheme={\"primary\"}>Client-side</Badge>\n          <Badge colorScheme={\"success\"}>SDK Built-in Auth</Badge>\n        </CardTitle>\n        <CardDescription>\n          Fetch languages using Sitecore Marketplace SDK from client component\n        </CardDescription>\n      </CardHeader>\n      <CardContent className=\"space-y-4\">\n        <Button\n          onClick={fetchLanguages}\n          disabled={loading}\n          className=\"w-full sm:w-auto\"\n        >\n          {loading ? \"Fetching...\" : \"Fetch Languages\"}\n        </Button>\n\n        {error && (\n          <Alert variant=\"danger\">\n            <AlertDescription>{error}</AlertDescription>\n          </Alert>\n        )}\n\n        <div className=\"space-y-2\">\n          <div className=\"flex items-center gap-2\">\n            <span className=\"text-sm font-medium\">Languages found:</span>\n            {loading ? (\n              <Skeleton className=\"h-5 w-8\" />\n            ) : (\n              <Badge>{languages?.length || 0}</Badge>\n            )}\n          </div>\n\n          {languages.length > 0 && (\n            <div className=\"space-y-1\">\n              <p className=\"text-sm text-muted-foreground\">Language names:</p>\n              <div className=\"flex flex-wrap gap-1\">\n                {languages.map((language, index) => (\n                  <Badge key={index}>{language.name}</Badge>\n                ))}\n              </div>\n            </div>\n          )}\n        </div>\n      </CardContent>\n    </Card>\n  );\n};\n",
      "type": "registry:component",
      "target": "components/examples/built-in-auth/with-xmc/list-languages.tsx"
    },
    {
      "path": "src/marketplace/next/components/examples/built-in-auth/with-xmc/page.tsx",
      "content": "\"use client\";\n\nimport { ApplicationContext } from \"@/components/examples/built-in-auth/application-context\";\nimport { ListLanguagesFromClientSdk } from \"@/components/examples/built-in-auth/with-xmc/list-languages\";\nimport { Separator } from \"@/components/ui/separator\";\n\nfunction Examples() {\n  return (\n    <div className=\"container mx-auto p-6 space-y-8 max-w-3xl\">\n      <div className=\"space-y-4\">\n        <h1 className=\"text-3xl font-semibold tracking-tight\">\n          Marketplace SDK Demo\n        </h1>\n        <p className=\"text-muted-foreground\">\n          Marketplace SDK with custom authentication and XMC client-side\n          examples\n        </p>\n      </div>\n\n      <ApplicationContext />\n\n      <Separator />\n\n      <div className=\"space-y-6\">\n        <h2 className=\"text-2xl font-semibold\">Built-in Auth Examples</h2>\n        <div className=\"grid gap-6\">\n          <ListLanguagesFromClientSdk />\n        </div>\n      </div>\n    </div>\n  );\n}\n\nexport default Examples;\n",
      "type": "registry:page",
      "target": "app/page.tsx"
    }
  ],
  "type": "registry:block"
}