docs: fix command bar position outside modal in category images guide (#13987)

This commit is contained in:
Shahed Nasser
2025-11-06 19:19:43 +02:00
committed by GitHub
parent e42e6f0daa
commit 01a5ce949e
3 changed files with 154 additions and 114 deletions

View File

@@ -616,7 +616,7 @@ Then, create the API route at `src/api/.well-known/jwks.json/route.ts` with the
```ts title="src/api/.well-known/jwks.json/route.ts"
import type {
MedusaRequest,
MedusaResponse
MedusaResponse,
} from "@medusajs/framework/http"
export const GET = async (
@@ -642,7 +642,7 @@ For example, create the API route at `src/api/.well-known/jwks.json/route.ts` wi
```ts title="src/api/.well-known/jwks.json/route.ts"
import type {
MedusaRequest,
MedusaResponse
MedusaResponse,
} from "@medusajs/framework/http"
import crypto from "crypto"
@@ -673,15 +673,15 @@ export const GET = async (
...jwk,
use: "sig",
kid: projectConfig.http.jwtOptions?.keyid || "medusa-key-1",
alg: projectConfig.http.jwtOptions?.algorithm || "RS256"
}]
alg: projectConfig.http.jwtOptions?.algorithm || "RS256",
}],
}
res.status(200).json(jwks)
} catch (error: any) {
return res.status(500).json({
error: "Failed to generate JWKS",
message: error.message
message: error.message,
})
}
}
@@ -820,8 +820,8 @@ export default defineMiddlewares({
{
matcher: "/custom-protected-route*",
middlewares: [jwtAuthMiddleware],
}
]
},
],
})
```
@@ -46877,7 +46877,7 @@ Connection to Redis in module 'workflow-engine-redis' established
- [refundPaymentWorkflow](https://docs.medusajs.com/references/medusa-workflows/refundPaymentWorkflow/index.html.md)
- [refundPaymentsWorkflow](https://docs.medusajs.com/references/medusa-workflows/refundPaymentsWorkflow/index.html.md)
- [validatePaymentsRefundStep](https://docs.medusajs.com/references/medusa-workflows/validatePaymentsRefundStep/index.html.md)
- [validateRefundStep](https://docs.medusajs.com/references/medusa-workflows/validateRefundStep/index.html.md)
- [validateRefundPaymentExceedsCapturedAmountStep](https://docs.medusajs.com/references/medusa-workflows/validateRefundPaymentExceedsCapturedAmountStep/index.html.md)
- [createPaymentSessionsWorkflow](https://docs.medusajs.com/references/medusa-workflows/createPaymentSessionsWorkflow/index.html.md)
- [createRefundReasonsWorkflow](https://docs.medusajs.com/references/medusa-workflows/createRefundReasonsWorkflow/index.html.md)
- [deletePaymentSessionsWorkflow](https://docs.medusajs.com/references/medusa-workflows/deletePaymentSessionsWorkflow/index.html.md)
@@ -46893,10 +46893,12 @@ Connection to Redis in module 'workflow-engine-redis' established
- [createPricePreferencesWorkflow](https://docs.medusajs.com/references/medusa-workflows/createPricePreferencesWorkflow/index.html.md)
- [deletePricePreferencesWorkflow](https://docs.medusajs.com/references/medusa-workflows/deletePricePreferencesWorkflow/index.html.md)
- [updatePricePreferencesWorkflow](https://docs.medusajs.com/references/medusa-workflows/updatePricePreferencesWorkflow/index.html.md)
- [batchImageVariantsWorkflow](https://docs.medusajs.com/references/medusa-workflows/batchImageVariantsWorkflow/index.html.md)
- [batchLinkProductsToCategoryWorkflow](https://docs.medusajs.com/references/medusa-workflows/batchLinkProductsToCategoryWorkflow/index.html.md)
- [batchLinkProductsToCollectionWorkflow](https://docs.medusajs.com/references/medusa-workflows/batchLinkProductsToCollectionWorkflow/index.html.md)
- [batchProductVariantsWorkflow](https://docs.medusajs.com/references/medusa-workflows/batchProductVariantsWorkflow/index.html.md)
- [batchProductsWorkflow](https://docs.medusajs.com/references/medusa-workflows/batchProductsWorkflow/index.html.md)
- [batchVariantImagesWorkflow](https://docs.medusajs.com/references/medusa-workflows/batchVariantImagesWorkflow/index.html.md)
- [createCollectionsWorkflow](https://docs.medusajs.com/references/medusa-workflows/createCollectionsWorkflow/index.html.md)
- [createProductOptionsWorkflow](https://docs.medusajs.com/references/medusa-workflows/createProductOptionsWorkflow/index.html.md)
- [createProductTagsWorkflow](https://docs.medusajs.com/references/medusa-workflows/createProductTagsWorkflow/index.html.md)
@@ -47164,6 +47166,8 @@ Connection to Redis in module 'workflow-engine-redis' established
- [updatePricePreferencesAsArrayStep](https://docs.medusajs.com/references/medusa-workflows/steps/updatePricePreferencesAsArrayStep/index.html.md)
- [updatePricePreferencesStep](https://docs.medusajs.com/references/medusa-workflows/steps/updatePricePreferencesStep/index.html.md)
- [updatePriceSetsStep](https://docs.medusajs.com/references/medusa-workflows/steps/updatePriceSetsStep/index.html.md)
- [addImageToVariantsStep](https://docs.medusajs.com/references/medusa-workflows/steps/addImageToVariantsStep/index.html.md)
- [addImagesToVariantStep](https://docs.medusajs.com/references/medusa-workflows/steps/addImagesToVariantStep/index.html.md)
- [batchLinkProductsToCategoryStep](https://docs.medusajs.com/references/medusa-workflows/steps/batchLinkProductsToCategoryStep/index.html.md)
- [batchLinkProductsToCollectionStep](https://docs.medusajs.com/references/medusa-workflows/steps/batchLinkProductsToCollectionStep/index.html.md)
- [createCollectionsStep](https://docs.medusajs.com/references/medusa-workflows/steps/createCollectionsStep/index.html.md)
@@ -47187,6 +47191,8 @@ Connection to Redis in module 'workflow-engine-redis' established
- [normalizeCsvToChunksStep](https://docs.medusajs.com/references/medusa-workflows/steps/normalizeCsvToChunksStep/index.html.md)
- [parseProductCsvStep](https://docs.medusajs.com/references/medusa-workflows/steps/parseProductCsvStep/index.html.md)
- [processImportChunksStep](https://docs.medusajs.com/references/medusa-workflows/steps/processImportChunksStep/index.html.md)
- [removeImageFromVariantsStep](https://docs.medusajs.com/references/medusa-workflows/steps/removeImageFromVariantsStep/index.html.md)
- [removeImagesFromVariantStep](https://docs.medusajs.com/references/medusa-workflows/steps/removeImagesFromVariantStep/index.html.md)
- [updateCollectionsStep](https://docs.medusajs.com/references/medusa-workflows/steps/updateCollectionsStep/index.html.md)
- [updateProductOptionsStep](https://docs.medusajs.com/references/medusa-workflows/steps/updateProductOptionsStep/index.html.md)
- [updateProductTagsStep](https://docs.medusajs.com/references/medusa-workflows/steps/updateProductTagsStep/index.html.md)
@@ -63834,54 +63840,51 @@ Finally, you'll render the modal. Replace the `// TODO render modal` comment wit
```tsx title="src/admin/components/category-media/category-media-modal.tsx"
return (
<>
{/* TODO show command bar */}
<FocusModal open={open} onOpenChange={handleOpenChange}>
<FocusModal.Trigger asChild>
<Button size="small" variant="secondary">
Edit
</Button>
</FocusModal.Trigger>
<FocusModal open={open} onOpenChange={handleOpenChange}>
<FocusModal.Trigger asChild>
<Button size="small" variant="secondary">
Edit
</Button>
</FocusModal.Trigger>
<FocusModal.Content>
<FocusModal.Header>
<Heading>Edit Media</Heading>
</FocusModal.Header>
<FocusModal.Content>
<FocusModal.Header>
<Heading>Edit Media</Heading>
</FocusModal.Header>
<FocusModal.Body className="flex h-full overflow-hidden">
<div className="flex w-full h-full flex-col-reverse lg:grid lg:grid-cols-[1fr_560px]">
<CategoryImageGallery
existingImages={existingImages}
uploadedFiles={uploadedFiles}
currentThumbnailId={currentThumbnailId}
/>
<CategoryImageUpload
fileInputRef={fileInputRef}
isUploading={uploadFilesMutation.isPending}
onFileSelect={handleUploadFile}
/>
</div>
</FocusModal.Body>
<FocusModal.Footer>
<div className="flex items-center justify-end gap-x-2">
<FocusModal.Close asChild>
<Button size="small" variant="secondary">
Cancel
</Button>
</FocusModal.Close>
<Button
size="small"
onClick={handleSave}
isLoading={isSaving}
>
Save
<FocusModal.Body className="flex h-full overflow-hidden">
<div className="flex w-full h-full flex-col-reverse lg:grid lg:grid-cols-[1fr_560px]">
<CategoryImageGallery
existingImages={existingImages}
uploadedFiles={uploadedFiles}
currentThumbnailId={currentThumbnailId}
/>
<CategoryImageUpload
fileInputRef={fileInputRef}
isUploading={uploadFilesMutation.isPending}
onFileSelect={handleUploadFile}
/>
</div>
{/* TODO show command bar */}
</FocusModal.Body>
<FocusModal.Footer>
<div className="flex items-center justify-end gap-x-2">
<FocusModal.Close asChild>
<Button size="small" variant="secondary">
Cancel
</Button>
</div>
</FocusModal.Footer>
</FocusModal.Content>
</FocusModal>
</>
</FocusModal.Close>
<Button
size="small"
onClick={handleSave}
isLoading={isSaving}
>
Save
</Button>
</div>
</FocusModal.Footer>
</FocusModal.Content>
</FocusModal>
)
```
@@ -84504,7 +84507,7 @@ First, run the following command in the Medusa application's directory to start
npm run dev
```
Then, in a separate terminal, navigate to the Next.js storefront directory and run the following command to start the storefront:
Then, in a separate terminal, navigate to the Next.js Starter Storefront directory and run the following command to start the storefront:
```bash npm2yarn badgeLabel="Storefront" badgeColor="blue"
npm run dev
@@ -85054,7 +85057,7 @@ You show the rental start and end dates if they're available in the line item's
You can now test adding rentable products to the cart in the Next.js Starter Storefront.
First, run both the Medusa server and the Next.js storefront.
First, run both the Medusa server and the Next.js Starter Storefront.
Then, in the storefront, open the product details page for a rentable product. Select the rental start and end dates, then click the "Add to cart" button.
@@ -85077,12 +85080,12 @@ First, you'll create a workflow that contains the logic to create rental orders,
The workflow will have the following steps:
- [useQueryGraphStep](https://docs.medusajs.com/references/helper-steps/useQueryGraphStep/index.html.md): Retrieve cart details.
- [acquireLockStep](https://docs.medusajs.com/references/medusa-workflows/acquireLockStep/index.html.md): Acquire a lock on the cart to prevent race conditions.
- [acquireLockStep](https://docs.medusajs.com/references/medusa-workflows/steps/acquireLockStep/index.html.md): Acquire a lock on the cart to prevent race conditions.
- [validateRentalStep](#validateRentalStep): Validate rental items in the cart.
- [completeCartWorkflow](https://docs.medusajs.com/references/medusa-workflows/completeCartWorkflow/index.html.md): Complete the cart and create the order.
- [useQueryGraphStep](https://docs.medusajs.com/references/helper-steps/useQueryGraphStep/index.html.md): Retrieve order details.
- [createRentalsForOrderStep](#createRentalsForOrderStep): Create rental records for rental items in the order.
- [releaseLockStep](https://docs.medusajs.com/references/medusa-workflows/releaseLockStep/index.html.md): Release the lock on the cart.
- [releaseLockStep](https://docs.medusajs.com/references/medusa-workflows/steps/releaseLockStep/index.html.md): Release the lock on the cart.
You'll implement the `validateRentalStep` and `createRentalsStep` steps used in the workflow. The rest are provided by Medusa out-of-the-box.
@@ -85530,7 +85533,7 @@ You show the rental start and end dates if they're available in the line item's
You can now test creating rental orders in the Next.js Starter Storefront.
First, run both the Medusa server and the Next.js storefront.
First, run both the Medusa server and the Next.js Starter Storefront.
Then, in the storefront, open the cart that contains rental products. Proceed to checkout and complete the order.
@@ -86105,7 +86108,7 @@ You can change the rental status and save the changes. The rental status will be
## Step 14: Handle Order Cancellation
Medusa admin users can cancel orders. So, in this step, you'll customize the order cancellation flow to validate that rental items in the order can be cancelled based on their rental status. You'll also update the rental statuses when an order is cancelled.
Medusa Admin users can cancel orders. So, in this step, you'll customize the order cancellation flow to validate that rental items in the order can be cancelled based on their rental status. You'll also update the rental statuses when an order is cancelled.
### a. Validate Rental Items on Order Cancellation
@@ -90135,13 +90138,27 @@ To create the step, create the file `src/workflows/steps/sync-products.ts` with
If you get a type error on resolving the Algolia Module, run the Medusa application once with the `npm run dev` or `yarn dev` command to generate the necessary type definitions, as explained in the [Automatically Generated Types guide](https://docs.medusajs.com/docs/learn/fundamentals/generated-types/index.html.md).
```ts title="src/workflows/steps/sync-products.ts"
import { ProductDTO } from "@medusajs/framework/types"
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"
import { ALGOLIA_MODULE } from "../../modules/algolia"
import AlgoliaModuleService from "../../modules/algolia/service"
export type SyncProductsStepInput = {
products: ProductDTO[]
products: {
id: string
title: string
description?: string
handle: string
thumbnail?: string
categories: {
id: string
name: string
handle: string
}[]
tags: {
id: string
value: string
}[]
}[]
}
export const syncProductsStep = createStep(
@@ -93810,7 +93827,7 @@ export const createProductsContentfulWorkflow = createWorkflow(
})
const contentfulProducts = createProductsContentfulStep({
products: data as ProductDTO[],
products: data as unknown as ProductDTO[],
})
return new WorkflowResponse(contentfulProducts)
@@ -97971,13 +97988,27 @@ To create the step, create the file `src/workflows/steps/sync-products.ts` with
If you get a type error on resolving the Meilisearch Module, run the Medusa application once with the `npm run dev` or `yarn dev` command to generate the necessary type definitions, as explained in the [Automatically Generated Types guide](https://docs.medusajs.com/docs/learn/fundamentals/generated-types/index.html.md).
```ts title="src/workflows/steps/sync-products.ts"
import { ProductDTO } from "@medusajs/framework/types"
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"
import { MEILISEARCH_MODULE } from "../../modules/meilisearch"
import MeilisearchModuleService from "../../modules/meilisearch/service"
export type SyncProductsStepInput = {
products: ProductDTO[]
products: {
id: string
title: string
description?: string
handle: string
thumbnail?: string
categories: {
id: string
name: string
handle: string
}[]
tags: {
id: string
value: string
}[]
}[]
}
export const syncProductsStep = createStep(
@@ -98115,6 +98146,7 @@ export const syncProductsWorkflow = createWorkflow(
products: data,
} as SyncProductsStepInput)
// @ts-ignore
return new WorkflowResponse({
products: data,
metadata,
@@ -104057,7 +104089,7 @@ while (hasMore) {
products.map(async (prod) => {
const after = await sanityModule.upsertSyncDocument(
"product",
prod as ProductDTO
prod as unknown as ProductDTO
)
upsertMap.push({
@@ -105930,7 +105962,7 @@ To set up instrumentation in Medusa, you need to install the dependencies necess
So, run the following command to install the necessary Sentry dependencies:
```bash npm2yarn
npm install @sentry/node @opentelemetry/api @opentelemetry/exporter-trace-otlp-grpc @sentry/opentelemetry-node
npm install @sentry/node @opentelemetry/api @opentelemetry/exporter-trace-otlp-grpc @sentry/opentelemetry-node @opentelemetry/core@1.x @opentelemetry/sdk-trace-base@1.x @opentelemetry/semantic-conventions@1.x
```
### b. Configure Instrumentation
@@ -110226,6 +110258,8 @@ To learn more about the commerce features that Medusa provides, check out Medusa
- [retrieve](https://docs.medusajs.com/references/js_sdk/admin/PricePreference/methods/js_sdk.admin.PricePreference.retrieve/index.html.md)
- [update](https://docs.medusajs.com/references/js_sdk/admin/PricePreference/methods/js_sdk.admin.PricePreference.update/index.html.md)
- [batch](https://docs.medusajs.com/references/js_sdk/admin/Product/methods/js_sdk.admin.Product.batch/index.html.md)
- [batchImageVariants](https://docs.medusajs.com/references/js_sdk/admin/Product/methods/js_sdk.admin.Product.batchImageVariants/index.html.md)
- [batchVariantImages](https://docs.medusajs.com/references/js_sdk/admin/Product/methods/js_sdk.admin.Product.batchVariantImages/index.html.md)
- [batchVariantInventoryItems](https://docs.medusajs.com/references/js_sdk/admin/Product/methods/js_sdk.admin.Product.batchVariantInventoryItems/index.html.md)
- [batchVariants](https://docs.medusajs.com/references/js_sdk/admin/Product/methods/js_sdk.admin.Product.batchVariants/index.html.md)
- [confirmImport](https://docs.medusajs.com/references/js_sdk/admin/Product/methods/js_sdk.admin.Product.confirmImport/index.html.md)
@@ -116500,6 +116534,8 @@ Download this reference as an OpenApi YAML file. You can import this file to too
- [POST /admin/gift-cards/{id}](https://docs.medusajs.com/api/admin#gift-cards_postgiftcardsid)
- [GET /admin/gift-cards/{id}/orders](https://docs.medusajs.com/api/admin#gift-cards_getgiftcardsidorders)
- [POST /admin/gift-cards/{id}/redeem](https://docs.medusajs.com/api/admin#gift-cards_postgiftcardsidredeem)
- [GET /admin/index/details](https://docs.medusajs.com/api/admin#index_getindexdetails)
- [POST /admin/index/sync](https://docs.medusajs.com/api/admin#index_postindexsync)
- [GET /admin/inventory-items](https://docs.medusajs.com/api/admin#inventory-items_getinventoryitems)
- [POST /admin/inventory-items](https://docs.medusajs.com/api/admin#inventory-items_postinventoryitems)
- [POST /admin/inventory-items/location-levels/batch](https://docs.medusajs.com/api/admin#inventory-items_postinventoryitemslocationlevelsbatch)
@@ -116596,6 +116632,7 @@ Download this reference as an OpenApi YAML file. You can import this file to too
- [GET /admin/products/{id}](https://docs.medusajs.com/api/admin#products_getproductsid)
- [POST /admin/products/{id}](https://docs.medusajs.com/api/admin#products_postproductsid)
- [DELETE /admin/products/{id}](https://docs.medusajs.com/api/admin#products_deleteproductsid)
- [POST /admin/products/{id}/images/{image_id}/variants/batch](https://docs.medusajs.com/api/admin#products_postproductsidimagesimage_idvariantsbatch)
- [GET /admin/products/{id}/options](https://docs.medusajs.com/api/admin#products_getproductsidoptions)
- [POST /admin/products/{id}/options](https://docs.medusajs.com/api/admin#products_postproductsidoptions)
- [GET /admin/products/{id}/options/{option_id}](https://docs.medusajs.com/api/admin#products_getproductsidoptionsoption_id)
@@ -116608,6 +116645,7 @@ Download this reference as an OpenApi YAML file. You can import this file to too
- [GET /admin/products/{id}/variants/{variant_id}](https://docs.medusajs.com/api/admin#products_getproductsidvariantsvariant_id)
- [POST /admin/products/{id}/variants/{variant_id}](https://docs.medusajs.com/api/admin#products_postproductsidvariantsvariant_id)
- [DELETE /admin/products/{id}/variants/{variant_id}](https://docs.medusajs.com/api/admin#products_deleteproductsidvariantsvariant_id)
- [POST /admin/products/{id}/variants/{variant_id}/images/batch](https://docs.medusajs.com/api/admin#products_postproductsidvariantsvariant_idimagesbatch)
- [POST /admin/products/{id}/variants/{variant_id}/inventory-items](https://docs.medusajs.com/api/admin#products_postproductsidvariantsvariant_idinventoryitems)
- [POST /admin/products/{id}/variants/{variant_id}/inventory-items/{inventory_item_id}](https://docs.medusajs.com/api/admin#products_postproductsidvariantsvariant_idinventoryitemsinventory_item_id)
- [DELETE /admin/products/{id}/variants/{variant_id}/inventory-items/{inventory_item_id}](https://docs.medusajs.com/api/admin#products_deleteproductsidvariantsvariant_idinventoryitemsinventory_item_id)
@@ -120243,10 +120281,15 @@ import { DatePicker } from "@medusajs/ui"
- aria-details: (string) Identifies the element (or elements) that provide a detailed, extended description for the object.
- aria-label: (string) Defines a string value that labels the current element.
- aria-labelledby: (string) Identifies the element (or elements) that labels the current element.
- autoComplete: (string) Describes the type of autocomplete functionality the input should provide if any. See \[MDN]\(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefautocomplete).
- autoFocus: (boolean) Whether the element should receive focus on render.
- defaultOpen: (boolean) Whether the overlay is open by default (uncontrolled).
- description: (ReactNode) A description for the field. Provides a hint such as specific requirements for what to choose.
- errorMessage: (union) An error message for the field.
- firstDayOfWeek: (union) The day that starts the week.
- form: (string) The \`\<form>\` element to associate the input with.
The value of this attribute must be the id of a \`\<form>\` in the same document.
See \[MDN]\(https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#form).
- hideTimeZone: (boolean) Whether to hide the time zone abbreviation.
- hourCycle: (union) Whether to display the time in 12 or 24 hour format. By default, this is determined by the user's locale.
- id: (string) The element's unique identifier. See \[MDN]\(https://developer.mozilla.org/en-US/docs/Web/HTML/Global\_attributes/id).
@@ -124306,7 +124349,7 @@ This component is based on the \[Sonner]\(https://sonner.emilkowal.ski/toast) to
This component is based on the \[Toaster component of the Sonner library]\(https://sonner.emilkowal.ski/toaster).
- position: (Position) The position of the created toasts. Default: "bottom-right"
- position: (union) The position of the created toasts. Default: "bottom-right"
- gap: (number) The gap between the toast components. Default: 12
- offset: (union) The space from the edges of the screen. Default: 24
- duration: (number) The time in milliseconds that a toast is shown before it's
@@ -139430,7 +139473,7 @@ export const getCustomPriceWorkflow = createWorkflow(
const price = getCustomPriceStep({
variant: variants[0],
metadata: input.metadata,
} as GetCustomPriceStepInput)
} as unknown as GetCustomPriceStepInput)
return new WorkflowResponse(price)
}

View File

@@ -1385,54 +1385,51 @@ Finally, you'll render the modal. Replace the `// TODO render modal` comment wit
```tsx title="src/admin/components/category-media/category-media-modal.tsx"
return (
<>
{/* TODO show command bar */}
<FocusModal open={open} onOpenChange={handleOpenChange}>
<FocusModal.Trigger asChild>
<Button size="small" variant="secondary">
Edit
</Button>
</FocusModal.Trigger>
<FocusModal open={open} onOpenChange={handleOpenChange}>
<FocusModal.Trigger asChild>
<Button size="small" variant="secondary">
Edit
</Button>
</FocusModal.Trigger>
<FocusModal.Content>
<FocusModal.Header>
<Heading>Edit Media</Heading>
</FocusModal.Header>
<FocusModal.Content>
<FocusModal.Header>
<Heading>Edit Media</Heading>
</FocusModal.Header>
<FocusModal.Body className="flex h-full overflow-hidden">
<div className="flex w-full h-full flex-col-reverse lg:grid lg:grid-cols-[1fr_560px]">
<CategoryImageGallery
existingImages={existingImages}
uploadedFiles={uploadedFiles}
currentThumbnailId={currentThumbnailId}
/>
<CategoryImageUpload
fileInputRef={fileInputRef}
isUploading={uploadFilesMutation.isPending}
onFileSelect={handleUploadFile}
/>
</div>
</FocusModal.Body>
<FocusModal.Footer>
<div className="flex items-center justify-end gap-x-2">
<FocusModal.Close asChild>
<Button size="small" variant="secondary">
Cancel
</Button>
</FocusModal.Close>
<Button
size="small"
onClick={handleSave}
isLoading={isSaving}
>
Save
<FocusModal.Body className="flex h-full overflow-hidden">
<div className="flex w-full h-full flex-col-reverse lg:grid lg:grid-cols-[1fr_560px]">
<CategoryImageGallery
existingImages={existingImages}
uploadedFiles={uploadedFiles}
currentThumbnailId={currentThumbnailId}
/>
<CategoryImageUpload
fileInputRef={fileInputRef}
isUploading={uploadFilesMutation.isPending}
onFileSelect={handleUploadFile}
/>
</div>
{/* TODO show command bar */}
</FocusModal.Body>
<FocusModal.Footer>
<div className="flex items-center justify-end gap-x-2">
<FocusModal.Close asChild>
<Button size="small" variant="secondary">
Cancel
</Button>
</div>
</FocusModal.Footer>
</FocusModal.Content>
</FocusModal>
</>
</FocusModal.Close>
<Button
size="small"
onClick={handleSave}
isLoading={isSaving}
>
Save
</Button>
</div>
</FocusModal.Footer>
</FocusModal.Content>
</FocusModal>
)
```

View File

@@ -6614,7 +6614,7 @@ export const generatedEditDates = {
"app/data-model-repository-reference/methods/upsertWithReplace/page.mdx": "2025-10-28T16:02:30.479Z",
"app/how-to-tutorials/tutorials/agentic-commerce/page.mdx": "2025-10-09T11:25:48.831Z",
"app/storefront-development/production-optimizations/page.mdx": "2025-10-03T13:28:37.909Z",
"app/how-to-tutorials/tutorials/category-images/page.mdx": "2025-10-15T08:57:05.566Z",
"app/how-to-tutorials/tutorials/category-images/page.mdx": "2025-11-06T14:14:45.465Z",
"app/infrastructure-modules/caching/page.mdx": "2025-10-13T11:46:36.452Z",
"app/troubleshooting/subscribers/not-working/page.mdx": "2025-10-16T09:25:57.376Z",
"references/js_sdk/admin/RefundReason/methods/js_sdk.admin.RefundReason.create/page.mdx": "2025-10-21T08:10:56.630Z",