feat(ui): CostTrackingSettings/provider_discount_table to shadcn

- @tremor TextInput/Icon/Text + @heroicons Trash/Pencil/Check/X \u2192
  shadcn Input + plain span + lucide Trash2/Pencil/Check/X.
- Edit mode flow preserved (Enter/Escape keys). SimpleTable (already
  Tremor table whitelisted) keeps its shape.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
Cursor Agent 2026-04-23 13:09:11 +00:00
parent 5108965fd9
commit 02779b37ec
No known key found for this signature in database

View file

@ -1,9 +1,12 @@
import React, { useState } from "react";
import { TextInput, Icon, Text } from "@tremor/react";
import { TrashIcon, PencilAltIcon, CheckIcon, XIcon } from "@heroicons/react/outline";
import { Input } from "@/components/ui/input";
import { Check, Pencil, Trash2, X } from "lucide-react";
import { SimpleTable } from "../common_components/simple_table";
import { DiscountConfig } from "./types";
import { getProviderDisplayInfo, handleImageError } from "./provider_display_helpers";
import {
getProviderDisplayInfo,
handleImageError,
} from "./provider_display_helpers";
interface ProviderDiscountTableProps {
discountConfig: DiscountConfig;
@ -44,14 +47,13 @@ const ProviderDiscountTable: React.FC<ProviderDiscountTableProps> = ({
};
const handleKeyDown = (e: React.KeyboardEvent, provider: string) => {
if (e.key === 'Enter') {
if (e.key === "Enter") {
handleSaveEdit(provider);
} else if (e.key === 'Escape') {
} else if (e.key === "Escape") {
handleCancelEdit();
}
};
// Convert discount config to array and sort
const data: ProviderDiscountRow[] = Object.entries(discountConfig)
.map(([provider, discount]) => ({ provider, discount }))
.sort((a, b) => {
@ -71,6 +73,7 @@ const ProviderDiscountTable: React.FC<ProviderDiscountTableProps> = ({
return (
<div className="flex items-center space-x-2">
{logo && (
// eslint-disable-next-line @next/next/no-img-element
<img
src={logo}
alt={`${displayName} logo`}
@ -89,37 +92,45 @@ const ProviderDiscountTable: React.FC<ProviderDiscountTableProps> = ({
<div className="flex items-center gap-2">
{editingProvider === row.provider ? (
<>
<TextInput
<Input
value={editValue}
onValueChange={setEditValue}
onChange={(e) => setEditValue(e.target.value)}
onKeyDown={(e) => handleKeyDown(e, row.provider)}
placeholder="5"
className="w-20"
className="w-20 h-8"
autoFocus
/>
<span className="text-gray-600">%</span>
<Icon
icon={CheckIcon}
size="sm"
<span className="text-muted-foreground">%</span>
<button
type="button"
onClick={() => handleSaveEdit(row.provider)}
className="cursor-pointer text-green-600 hover:text-green-700"
/>
<Icon
icon={XIcon}
size="sm"
className="cursor-pointer text-emerald-600 hover:text-emerald-700 dark:text-emerald-400"
aria-label="Save"
>
<Check className="h-4 w-4" />
</button>
<button
type="button"
onClick={handleCancelEdit}
className="cursor-pointer text-gray-600 hover:text-gray-700"
/>
className="cursor-pointer text-muted-foreground hover:text-foreground"
aria-label="Cancel"
>
<X className="h-4 w-4" />
</button>
</>
) : (
<>
<Text className="font-medium">{(row.discount * 100).toFixed(1)}%</Text>
<Icon
icon={PencilAltIcon}
size="sm"
<span className="font-medium">
{(row.discount * 100).toFixed(1)}%
</span>
<button
type="button"
onClick={() => handleStartEdit(row.provider, row.discount)}
className="cursor-pointer text-blue-600 hover:text-blue-700"
/>
className="cursor-pointer text-primary hover:text-primary/80"
aria-label="Edit"
>
<Pencil className="h-4 w-4" />
</button>
</>
)}
</div>
@ -131,12 +142,14 @@ const ProviderDiscountTable: React.FC<ProviderDiscountTableProps> = ({
cell: (row) => {
const { displayName } = getProviderDisplayInfo(row.provider);
return (
<Icon
icon={TrashIcon}
size="sm"
<button
type="button"
onClick={() => onRemoveProvider(row.provider, displayName)}
className="cursor-pointer hover:text-red-600"
/>
className="cursor-pointer hover:text-destructive"
aria-label="Remove"
>
<Trash2 className="h-4 w-4" />
</button>
);
},
width: "80px",
@ -149,4 +162,3 @@ const ProviderDiscountTable: React.FC<ProviderDiscountTableProps> = ({
};
export default ProviderDiscountTable;