diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx index b88dcca186..10e7b74bd4 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx @@ -497,12 +497,14 @@ function ProductItemRow({ if (isEditing) { return ( -
-
+
+
- {itemId} + + {itemDisplayName} +
@@ -554,16 +556,54 @@ function ProductItemRow({
- { - const v = e.target.value; - if (v === '' || /^\d*$/.test(v)) setQuantity(v); - if (!readOnly && (v === '' || /^\d*$/.test(v))) updateParent(v); - }} - /> +
+ { + const v = e.target.value; + if (v === '' || /^\d*$/.test(v)) setQuantity(v); + if (!readOnly && (v === '' || /^\d*$/.test(v))) updateParent(v); + }} + /> + {onRemove && ( + + )} +
+
+
+
+ + +
+ {item.expires === 'never' ? 'Never expires' : `${EXPIRES_OPTIONS.find(o => o.value === item.expires)?.label.toLowerCase()}`} + +
+
+ +
+ {EXPIRES_OPTIONS.map((option) => ( + + + + ))} +
+
+
+
- {onRemove && ( - - )} -
-
- Expires: - - -
- {item.expires === 'never' ? 'Never expires' : `${EXPIRES_OPTIONS.find(o => o.value === item.expires)?.label.toLowerCase()}`} - -
-
- -
- {EXPIRES_OPTIONS.map((option) => ( - - - - ))} -
-
-
); @@ -633,7 +638,7 @@ function ProductItemRow({ -
{itemId}
+
{itemDisplayName}
{prettyPrintWithMagnitudes(item.quantity)}
{shortRepeatText}
@@ -667,6 +672,7 @@ function ProductItemRow({ title="Example" icon="code" compact + tooltip="Retrieves this item for the active customer and reads the current quantity they hold." />
@@ -966,7 +972,7 @@ function ProductCard({ id, activeType, product, allProducts, existingItems, onSa
{itemsList.map(([itemId, item]) => { const itemMeta = existingItems.find(i => i.id === itemId); - const itemLabel = itemMeta ? (itemMeta.displayName || itemMeta.id) : 'Select item'; + const itemLabel = itemMeta ? itemMeta.id : 'Select item'; return (
)} diff --git a/apps/dashboard/src/components/code-block.tsx b/apps/dashboard/src/components/code-block.tsx index b5f13b2bd5..6cd98e7e1a 100644 --- a/apps/dashboard/src/components/code-block.tsx +++ b/apps/dashboard/src/components/code-block.tsx @@ -1,7 +1,7 @@ 'use client'; import { useThemeWatcher } from '@/lib/theme'; -import { CopyButton } from "@stackframe/stack-ui"; +import { CopyButton, SimpleTooltip } from "@stackframe/stack-ui"; import { Code, Terminal } from "lucide-react"; import { PrismLight as SyntaxHighlighter } from 'react-syntax-highlighter'; import bash from 'react-syntax-highlighter/dist/esm/languages/prism/bash'; @@ -9,21 +9,25 @@ import python from 'react-syntax-highlighter/dist/esm/languages/prism/python'; import tsx from 'react-syntax-highlighter/dist/esm/languages/prism/tsx'; import typescript from 'react-syntax-highlighter/dist/esm/languages/prism/typescript'; import { dark, prism } from 'react-syntax-highlighter/dist/esm/styles/prism'; +import type { ReactNode } from 'react'; import { cn } from '@/lib/utils'; Object.entries({ tsx, bash, typescript, python }).forEach(([key, value]) => { SyntaxHighlighter.registerLanguage(key, value); }); -export function CodeBlock(props: { +type CodeBlockProps = { language: string, content: string, - customRender?: React.ReactNode, + customRender?: ReactNode, title: string, icon: 'terminal' | 'code', maxHeight?: number, compact?: boolean, -}) { + tooltip?: ReactNode, +}; + +export function CodeBlock(props: CodeBlockProps) { const { theme, mounted } = useThemeWatcher(); let icon = null; @@ -45,7 +49,12 @@ export function CodeBlock(props: { {icon} {props.title} - +
+ {props.tooltip && ( + + )} + +
{props.customRender ??