import { Box, Button, Checkbox, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Icon, IconButton, Text, theme, Tooltip, } from "@prismicio/editor-ui"; import Link from "next/link"; import type { FC } from "react"; import { Card, CardFooter, CardMedia, CardStatus } from "@/components/Card"; import { CardProps } from "@/components/Card/Card"; import { countMissingScreenshots, getScreenshotUrl } from "@/domain/slice"; import { StatusBadge, type StatusBadgeProps, } from "@/features/changes/StatusBadge"; import { SLICES_CONFIG } from "@/features/slices/slicesConfig"; import { AddPhotoAlternateIcon } from "@/icons/AddPhotoAlternateIcon"; import { ComponentUI } from "@/legacy/lib/models/common/ComponentUI"; type SharedSliceCardProps = { isDeleted?: boolean; onUpdateScreenshot?: () => void; slice: ComponentUI; variant: "outlined" | "solid"; variationId?: string; } & ( | /* * Props for rendering a `Card` with a Next.js `Link` component (or with a * non-interactive element if `isDeleted` is true). */ { mode: "navigation"; action: Action; replace?: boolean; selected?: boolean; } // Props for rendering a `Card` with an interactive (selectable) element. | { mode: "selection"; action: Action | { type: "checkbox" }; onSelectedChange: (selected: boolean) => void; selected: boolean; } ); type Action = | { type: "menu"; onRemove: () => void; onRename: () => void; removeDisabled?: boolean; } | { type: "remove"; onRemove: () => void } | ({ type: "status" } & Omit); export const SharedSliceCard: FC = (props) => { const { action, isDeleted = false, onUpdateScreenshot, selected = false, slice, variant, variationId, } = props; const variation = ComponentUI.variation(slice, variationId); if (!variation) return null; const src = getScreenshotUrl(slice, variation); const disabled = isDeleted; const canUpdateScreenshot = !disabled && !!onUpdateScreenshot; const disableOverlay = variant === "outlined"; const hasVariationId = variationId !== undefined; let modeProps: CardProps; if (props.mode === "selection") { modeProps = { disabled, interactive: true, onClick: () => { props.onSelectedChange(!selected); }, } as const; } else if (!disabled) { modeProps = { component: Link, href: SLICES_CONFIG.getBuilderPagePathname({ libraryName: slice.href, sliceName: slice.model.name, variationId: variation.id, }), interactive: true, replace: props.replace, } as const; } else { modeProps = { interactive: false } as const; } const variantProps = variant === "outlined" ? ({ size: "small", variant: "outlined" } as const) : {}; return ( {src !== undefined ? ( ) : undefined } src={src} /> ) : ( No screenshot available {canUpdateScreenshot && !disableOverlay ? ( ) : undefined} )} event.stopPropagation()}> ) : action.type === "menu" ? ( {canUpdateScreenshot && disableOverlay ? ( } > Update screenshot ) : undefined} } > Rename {action.removeDisabled === true && hasVariationId ? ( ) : ( )} ) : action.type === "remove" ? ( !disabled && action.onRemove()} hiddenLabel="Remove slice" /> ) : action.type === "status" ? ( ) : undefined } subtitle={ <> {hasVariationId ? variation.id : `${slice.model.variations.length} variation${ slice.model.variations.length > 1 ? "s" : "" }`} } title={hasVariationId ? variation.name : slice.model.name} /> {canUpdateScreenshot && !hasVariationId && countMissingScreenshots(slice) > 0 ? ( Missing screenshot ) : undefined} ); }; type UpdateScreenshotButtonProps = { onClick: () => void }; const UpdateScreenshotButton: FC = (props) => ( ); type RemoveDropdownMenuItemProps = { disabled: boolean; onSelect: () => void; }; const RemoveDropdownMenuItem: FC = (props) => ( } > Delete );