Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ The `redactSensitiveInfo()` function in `lib/utils/logging.ts` automatically red

## Code Quality Guidelines

### Code Formatting

**Always run `pnpm format` after making changes to TypeScript/TSX files.**

The project uses Prettier to enforce consistent code formatting. After editing any `.ts` or `.tsx` files, run:

```bash
pnpm format
```

This ensures all code follows the project's formatting standards and prevents formatting-related issues in pull requests.

### Logging Best Practices

1. **Use descriptive static messages**
Expand Down
108 changes: 43 additions & 65 deletions components/api-keys-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { toast } from 'sonner'
import { Eye, EyeOff, Trash2, CheckCircle2 } from 'lucide-react'
import { Eye, EyeOff } from 'lucide-react'

interface ApiKeysDialogProps {
open: boolean
Expand Down Expand Up @@ -140,72 +140,50 @@ export function ApiKeysDialog({ open, onOpenChange }: ApiKeysDialogProps) {
</DialogDescription>
</DialogHeader>

<div className="space-y-4 py-4">
<div className="space-y-2">
{PROVIDERS.map((provider) => (
<div
key={provider.id}
className="group relative rounded-lg border bg-card p-4 transition-colors hover:bg-accent/30"
>
<div className="flex items-start gap-3">
<div className="flex-1 min-w-0 space-y-3">
<div className="flex items-center justify-between">
<Label htmlFor={provider.id} className="text-sm font-medium">
{provider.name}
</Label>
{savedKeys.has(provider.id) && (
<div className="flex items-center gap-1.5 text-xs text-emerald-600 dark:text-emerald-500">
<CheckCircle2 className="h-3.5 w-3.5" />
<span>Configured</span>
</div>
)}
</div>

<div className="flex gap-2">
<div className="relative flex-1">
<Input
id={provider.id}
type={showKeys[provider.id] ? 'text' : 'password'}
placeholder={savedKeys.has(provider.id) ? '••••••••••••••••' : provider.placeholder}
value={apiKeys[provider.id]}
onChange={(e) => setApiKeys((prev) => ({ ...prev, [provider.id]: e.target.value }))}
disabled={loading}
className="pr-9 h-8 text-sm"
/>
<button
onClick={() => toggleShowKey(provider.id)}
className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors"
type="button"
disabled={loading}
>
{showKeys[provider.id] ? <EyeOff className="h-3.5 w-3.5" /> : <Eye className="h-3.5 w-3.5" />}
</button>
</div>

<div className="flex gap-1.5">
<Button
size="sm"
onClick={() => handleSave(provider.id)}
disabled={loading || !apiKeys[provider.id].trim()}
className="h-8 px-3 text-xs"
>
Save
</Button>
{savedKeys.has(provider.id) && (
<Button
variant="ghost"
size="sm"
onClick={() => handleDelete(provider.id)}
disabled={loading}
className="h-8 w-8 p-0 text-muted-foreground hover:text-destructive transition-colors"
title="Remove API key"
>
<Trash2 className="h-3.5 w-3.5" />
</Button>
)}
</div>
</div>
</div>
<div key={provider.id} className="flex items-center gap-2">
<Label htmlFor={provider.id} className="text-sm w-24 shrink-0">
{provider.name}
</Label>
<div className="relative flex-1">
<Input
id={provider.id}
type={showKeys[provider.id] ? 'text' : 'password'}
placeholder={savedKeys.has(provider.id) ? '••••••••••••••••' : provider.placeholder}
value={apiKeys[provider.id]}
onChange={(e) => setApiKeys((prev) => ({ ...prev, [provider.id]: e.target.value }))}
disabled={loading}
className="pr-9 h-8 text-sm"
/>
<button
onClick={() => toggleShowKey(provider.id)}
className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors"
type="button"
disabled={loading}
>
{showKeys[provider.id] ? <EyeOff className="h-3.5 w-3.5" /> : <Eye className="h-3.5 w-3.5" />}
</button>
</div>
<Button
size="sm"
onClick={() => handleSave(provider.id)}
disabled={loading || !apiKeys[provider.id].trim()}
className="h-8 px-3 text-xs"
>
Save
</Button>
{savedKeys.has(provider.id) && (
<Button
variant="ghost"
size="sm"
onClick={() => handleDelete(provider.id)}
disabled={loading}
className="h-8 px-2 text-xs"
>
Clear
</Button>
)}
</div>
))}
</div>
Expand Down
Loading