{
  "name": "service-product-layout",
  "title": "ServiceProductLayout",
  "description": "Service booking layout with duration, deposit, staff requirements, and cancellation policy.",
  "type": "component",
  "registryDependencies": [
    "product-image-gallery",
    "product-customizer",
    "price",
    "rich-text",
    "cn"
  ],
  "files": [
    {
      "path": "layouts/service-product-layout.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\nimport type { ProductLayoutProps } from \"@cimplify/sdk/react\";\nimport {\n  TwoColumnGrid,\n  RelatedProductsSection,\n  CustomAttributesTable,\n  TagPills,\n} from \"@cimplify/sdk/react\";\nimport { ProductImageGallery } from \"@cimplify/sdk/react\";\nimport { ProductCustomizer } from \"@cimplify/sdk/react\";\nimport { Price } from \"@cimplify/sdk/react\";\nimport { parsePrice, getProductCurrency } from \"@cimplify/sdk\";\nimport { RichText } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\nimport { formatDuration } from \"../utils/format-duration\";\n\nexport function ServiceProductLayout({\n  product,\n  onAddToCart,\n  renderBreadcrumb,\n  relatedProducts,\n  showRelated = true,\n  className,\n}: ProductLayoutProps): React.ReactElement {\n  const images = product.images || (product.image_url ? [product.image_url] : []);\n  const currency = getProductCurrency(product);\n  const hasDeposit = product.deposit_type && product.deposit_type !== \"none\" && product.deposit_amount;\n  const depositAmount = hasDeposit ? parsePrice(product.deposit_amount!) : 0;\n  const cancellationHours = product.cancellation_window_minutes\n    ? Math.floor(product.cancellation_window_minutes / 60)\n    : null;\n\n  return (\n    <div data-cimplify-product-layout=\"service\" className={cn(\"space-y-8\", className)}>\n      {renderBreadcrumb?.(product)}\n\n      <TwoColumnGrid\n        left={\n          <ProductImageGallery\n            images={images}\n            productName={product.name}\n          />\n        }\n        right={\n          <div className=\"space-y-6\">\n            {/* Tags */}\n            <TagPills tags={product.tags || []} />\n\n            {/* Name + Price */}\n            <div>\n              <h1 data-cimplify-product-layout-name className=\"text-3xl lg:text-4xl font-extrabold tracking-tight\">\n                {product.name}\n              </h1>\n              <Price amount={product.default_price} currency={currency} className=\"text-2xl font-bold text-primary mt-2 block\" />\n            </div>\n\n            {/* Service info pills */}\n            <div data-cimplify-product-layout-service-info className=\"flex flex-wrap gap-2\">\n              {product.duration_minutes != null && (\n                <span className=\"inline-flex items-center gap-1.5 px-3 py-1.5 bg-muted text-sm text-muted-foreground rounded-full\">\n                  {formatDuration(product.duration_minutes, product.duration_unit)}\n                </span>\n              )}\n              {hasDeposit && (\n                <span className=\"inline-flex items-center gap-1.5 px-3 py-1.5 bg-muted text-sm text-muted-foreground rounded-full\">\n                  <Price amount={depositAmount} currency={currency} /> deposit\n                </span>\n              )}\n              {product.general_service_capacity != null && product.general_service_capacity > 1 && (\n                <span className=\"inline-flex items-center gap-1.5 px-3 py-1.5 bg-muted text-sm text-muted-foreground rounded-full\">\n                  Up to {product.general_service_capacity} people\n                </span>\n              )}\n              {product.buffer_before_minutes != null && product.buffer_before_minutes > 0 && (\n                <span className=\"inline-flex items-center gap-1.5 px-3 py-1.5 bg-muted text-sm text-muted-foreground rounded-full\">\n                  {product.buffer_before_minutes} min buffer\n                </span>\n              )}\n            </div>\n\n            {/* Description */}\n            <RichText html={product.description} data-cimplify-product-layout-description />\n\n            {/* Staff & Resource requirements */}\n            {(product.requires_specific_staff || product.requires_specific_resource) && (\n              <div data-cimplify-product-layout-requirements className=\"text-sm text-muted-foreground space-y-1\">\n                {product.requires_specific_staff && (\n                  <p>Staff selection required</p>\n                )}\n                {product.requires_specific_resource && (\n                  <p>Resource selection required</p>\n                )}\n              </div>\n            )}\n\n            {/* Custom Attributes */}\n            <CustomAttributesTable attributes={product.custom_attributes || []} />\n\n            {/* Customizer (variants, scheduling, add to cart) */}\n            <ProductCustomizer\n              product={product}\n              onAddToCart={onAddToCart}\n              showSpecialInstructions={false}\n            />\n\n            {/* Cancellation policy */}\n            {(cancellationHours != null || product.no_show_fee) && (\n              <div data-cimplify-product-layout-cancellation className=\"border border-border p-4 space-y-2 text-sm\">\n                <h3 className=\"font-semibold\">Cancellation Policy</h3>\n                {cancellationHours != null && (\n                  <p className=\"text-muted-foreground\">\n                    Free cancellation up to <strong className=\"text-foreground\">{cancellationHours} hours</strong> before the booking\n                  </p>\n                )}\n                {product.no_show_fee && (\n                  <p className=\"text-muted-foreground\">\n                    No-show fee: <Price amount={product.no_show_fee} currency={currency} className=\"font-medium text-foreground\" />\n                  </p>\n                )}\n                {hasDeposit && (\n                  <p className=\"text-muted-foreground\">\n                    {product.deposit_type === \"fixed\"\n                      ? <><Price amount={depositAmount} currency={currency} className=\"font-medium text-foreground\" /> deposit charged at booking</>\n                      : <>{parsePrice(product.deposit_amount!)}% deposit charged at booking</>\n                    }\n                  </p>\n                )}\n              </div>\n            )}\n          </div>\n        }\n      />\n\n      {showRelated && relatedProducts && relatedProducts.length > 0 && (\n        <RelatedProductsSection\n          products={relatedProducts}\n          title=\"Other services\"\n        />\n      )}\n    </div>\n  );\n}\n"
    }
  ]
}
