Skip to content

Commit 8fa1588

Browse files
committed
fix: api keys page, empty state
1 parent c96683f commit 8fa1588

File tree

7 files changed

+707
-744
lines changed

7 files changed

+707
-744
lines changed

apps/dashboard/app/(main)/organizations/settings/api-keys/api-key-settings.tsx

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function SkeletonRow() {
3838
function ApiKeysSkeleton() {
3939
return (
4040
<div className="h-full lg:grid lg:grid-cols-[1fr_18rem]">
41-
<div className="divide-y border-b lg:border-b-0 lg:border-r">
41+
<div className="divide-y border-b lg:border-r lg:border-b-0">
4242
<SkeletonRow />
4343
<SkeletonRow />
4444
<SkeletonRow />
@@ -52,20 +52,16 @@ function ApiKeysSkeleton() {
5252
);
5353
}
5454

55-
function EmptyState({ onCreateNew }: { onCreateNew: () => void }) {
55+
function EmptyState() {
5656
return (
5757
<div className="flex h-full flex-col items-center justify-center p-8 text-center">
5858
<div className="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-primary/10">
5959
<KeyIcon className="text-primary" size={28} weight="duotone" />
6060
</div>
6161
<h3 className="mb-1 font-semibold text-lg">No API keys yet</h3>
62-
<p className="mb-6 max-w-sm text-muted-foreground text-sm">
62+
<p className="max-w-sm text-muted-foreground text-sm">
6363
Create your first API key to start integrating with our platform
6464
</p>
65-
<Button onClick={onCreateNew}>
66-
<PlusIcon className="mr-2" size={16} />
67-
Create API Key
68-
</Button>
6965
</div>
7066
);
7167
}
@@ -94,36 +90,42 @@ export function ApiKeySettings({ organization }: ApiKeySettingsProps) {
9490
const [selectedKeyId, setSelectedKeyId] = useState<string | null>(null);
9591

9692
const { data, isLoading, isError, refetch } = useQuery({
97-
...orpc.apikeys.list.queryOptions({ input: { organizationId: organization.id } }),
93+
...orpc.apikeys.list.queryOptions({
94+
input: { organizationId: organization.id },
95+
}),
9896
refetchOnMount: true,
9997
refetchOnReconnect: true,
10098
staleTime: 0,
10199
});
102100

103101
const items = data ?? [];
104102
const activeCount = items.filter((k) => k.enabled && !k.revokedAt).length;
103+
const isEmpty = items.length === 0;
105104

106105
if (isLoading) return <ApiKeysSkeleton />;
107106
if (isError) return <ErrorState onRetry={refetch} />;
108-
if (items.length === 0) return <EmptyState onCreateNew={() => setShowCreateDialog(true)} />;
109107

110108
return (
111109
<>
112110
<div className="h-full lg:grid lg:grid-cols-[1fr_18rem]">
113-
{/* Keys List */}
114-
<div className="flex flex-col border-b lg:border-b-0 lg:border-r">
115-
<div className="flex-1 divide-y overflow-y-auto">
116-
{items.map((apiKey) => (
117-
<ApiKeyRow
118-
apiKey={apiKey}
119-
key={apiKey.id}
120-
onSelect={(id) => {
121-
setSelectedKeyId(id);
122-
setShowDetailDialog(true);
123-
}}
124-
/>
125-
))}
126-
</div>
111+
{/* Keys List / Empty State */}
112+
<div className="flex flex-col border-b lg:border-r lg:border-b-0">
113+
{isEmpty ? (
114+
<EmptyState />
115+
) : (
116+
<div className="flex-1 divide-y overflow-y-auto">
117+
{items.map((apiKey) => (
118+
<ApiKeyRow
119+
apiKey={apiKey}
120+
key={apiKey.id}
121+
onSelect={(id) => {
122+
setSelectedKeyId(id);
123+
setShowDetailDialog(true);
124+
}}
125+
/>
126+
))}
127+
</div>
128+
)}
127129
</div>
128130

129131
{/* Sidebar */}
@@ -135,22 +137,31 @@ export function ApiKeySettings({ organization }: ApiKeySettingsProps) {
135137
</Button>
136138

137139
{/* Stats Card */}
138-
<div className="flex items-center gap-3 rounded border bg-background p-4">
139-
<div className="flex h-10 w-10 items-center justify-center rounded bg-primary/10">
140-
<ShieldCheckIcon className="text-primary" size={20} weight="duotone" />
141-
</div>
142-
<div>
143-
<p className="font-semibold tabular-nums">
144-
{activeCount} <span className="font-normal text-muted-foreground">/ {items.length}</span>
145-
</p>
146-
<p className="text-muted-foreground text-sm">Active keys</p>
140+
{!isEmpty && (
141+
<div className="flex items-center gap-3 rounded border bg-background p-4">
142+
<div className="flex h-10 w-10 items-center justify-center rounded bg-primary/10">
143+
<ShieldCheckIcon
144+
className="text-primary"
145+
size={20}
146+
weight="duotone"
147+
/>
148+
</div>
149+
<div>
150+
<p className="font-semibold tabular-nums">
151+
{activeCount}{" "}
152+
<span className="font-normal text-muted-foreground">
153+
/ {items.length}
154+
</span>
155+
</p>
156+
<p className="text-muted-foreground text-sm">Active keys</p>
157+
</div>
147158
</div>
148-
</div>
159+
)}
149160

150161
{/* Actions */}
151162
<Button asChild className="w-full justify-start" variant="outline">
152163
<a
153-
href="https://www.databuddy.cc/docs/api-keys"
164+
href="https://www.databuddy.cc/docs/getting-started"
154165
rel="noopener noreferrer"
155166
target="_blank"
156167
>
@@ -163,7 +174,8 @@ export function ApiKeySettings({ organization }: ApiKeySettingsProps) {
163174
<div className="mt-auto rounded border border-dashed bg-background/50 p-4">
164175
<p className="mb-2 font-medium text-sm">Security reminder</p>
165176
<p className="text-muted-foreground text-xs leading-relaxed">
166-
Keep your API keys secure. Never share them publicly or commit them to version control.
177+
Keep your API keys secure. Never share them publicly or commit
178+
them to version control.
167179
</p>
168180
</div>
169181
</aside>

apps/dashboard/app/(main)/organizations/settings/danger/transfer-assets.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import { FaviconImage } from "@/components/analytics/favicon-image";
1313
import { Button } from "@/components/ui/button";
1414
import { Skeleton } from "@/components/ui/skeleton";
1515
import { useWebsiteTransfer } from "@/hooks/use-website-transfer";
16-
import { cn } from "@/lib/utils";
1716
import type { Website } from "@/hooks/use-websites";
17+
import { cn } from "@/lib/utils";
1818

1919
interface WebsiteItemProps {
2020
website: Website;
@@ -47,7 +47,9 @@ function WebsiteItem({ website, selected, onClick }: WebsiteItemProps) {
4747
/>
4848
<div className="min-w-0 flex-1">
4949
<p className="truncate text-sm">{website.name ?? website.domain}</p>
50-
<p className="truncate text-muted-foreground text-xs">{website.domain}</p>
50+
<p className="truncate text-muted-foreground text-xs">
51+
{website.domain}
52+
</p>
5153
</div>
5254
</button>
5355
);
@@ -135,7 +137,9 @@ export function TransferAssets({ organizationId }: { organizationId: string }) {
135137
className="mb-3 text-muted-foreground/50"
136138
size={32}
137139
/>
138-
<p className="font-medium text-muted-foreground">No websites to transfer</p>
140+
<p className="font-medium text-muted-foreground">
141+
No websites to transfer
142+
</p>
139143
<p className="mt-1 text-muted-foreground/70 text-sm">
140144
Add websites to your account or organization first
141145
</p>

0 commit comments

Comments
 (0)