Skip to content

Commit 526a904

Browse files
authored
Merge pull request #16 from jerryjuche/staging
Staging
2 parents 8bdafa7 + 447951d commit 526a904

46 files changed

Lines changed: 4362 additions & 407 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,43 @@ extension/*.vsix
9999
extension/tsconfig.tsbuildinfo
100100

101101

102+
# =============================================================================
103+
# DEBUG & DEVELOPMENT ARTIFACTS
104+
# =============================================================================
105+
106+
# Debug dumps and analysis files
107+
debug-dumps/
108+
**/debug-dumps/
109+
110+
# Temporary files and backups
111+
*.tmp
112+
*.temp
113+
*.bak
114+
*.orig
115+
*.rej
116+
*.swp
117+
*.swo
118+
*~
119+
120+
# OS generated files
121+
.DS_Store
122+
.DS_Store?
123+
._*
124+
.Spotlight-V100
125+
.Trashes
126+
ehthumbs.db
127+
Thumbs.db
128+
129+
# IDE files
130+
.vscode/settings.json
131+
.idea/
132+
*.sublime-project
133+
*.sublime-workspace
134+
135+
# Docker
136+
.dockerignore.bak
137+
138+
102139
# =============================================================================
103140
# VERCEL
104141
# =============================================================================
@@ -182,4 +219,73 @@ logs/
182219
codedock-test-dashboard/frontend/node_modules/
183220
codedock-test-dashboard/frontend/.next/
184221
codedock-test-dashboard/frontend/dist/
185-
codedock-test-dashboard/frontend/build/
222+
codedock-test-dashboard/frontend/build/
223+
# Dependencies
224+
node_modules/
225+
**/node_modules/
226+
227+
# Frontend build/cache
228+
.next/
229+
**/.next/
230+
dist/
231+
**/dist/
232+
build/
233+
**/build/
234+
coverage/
235+
**/coverage/
236+
*.tsbuildinfo
237+
238+
# VS Code extension build/package output
239+
extension/out/
240+
extension/dist/
241+
extension/*.vsix
242+
*.vsix
243+
244+
# Local deployment/config
245+
.env
246+
.env.*
247+
!.env.example
248+
.vercel/
249+
debug-dumps/
250+
251+
# Go build artifacts
252+
codedock_test_bin
253+
codedock-server
254+
*.test
255+
*.out
256+
*.coverprofile
257+
258+
# Dependencies
259+
node_modules/
260+
**/node_modules/
261+
262+
# Frontend build/cache
263+
.next/
264+
**/.next/
265+
dist/
266+
**/dist/
267+
build/
268+
**/build/
269+
coverage/
270+
**/coverage/
271+
*.tsbuildinfo
272+
273+
# VS Code extension build/package output
274+
extension/out/
275+
extension/dist/
276+
extension/*.vsix
277+
*.vsix
278+
279+
# Local deployment/config
280+
.env
281+
.env.*
282+
!.env.example
283+
.vercel/
284+
debug-dumps/
285+
286+
# Go build artifacts
287+
codedock_test_bin
288+
codedock-server
289+
*.test
290+
*.out
291+
*.coverprofile

codedock-web/app/layout.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,38 @@
11
import "./globals.css";
22
import type { Metadata } from "next";
33
import { Analytics } from "@vercel/analytics/next";
4-
import { SpeedInsights } from "@vercel/speed-insights/next"
4+
import { SpeedInsights } from "@vercel/speed-insights/next";
55
import Providers from "@/components/ui/providers";
66

77
export const metadata: Metadata = {
88
title: "CodeDock",
9-
description: "CodeDock control plane"
9+
description: "CodeDock control plane",
1010
};
1111

1212
export default function RootLayout({
13-
children
13+
children,
1414
}: Readonly<{
1515
children: React.ReactNode;
1616
}>) {
1717
return (
1818
<html lang="en">
19+
<head>
20+
{/* Preload critical resources */}
21+
<link rel="dns-prefetch" href="//fonts.googleapis.com" />
22+
<link
23+
rel="preconnect"
24+
href="https://fonts.googleapis.com"
25+
crossOrigin=""
26+
/>
27+
{/* Preload critical routes */}
28+
<link rel="prefetch" href="/dashboard" />
29+
<link rel="prefetch" href="/login" />
30+
<link rel="prefetch" href="/register" />
31+
</head>
1932
<body>
2033
<Providers>{children}</Providers>
21-
<Analytics />
22-
<SpeedInsights />
34+
<Analytics />
35+
<SpeedInsights />
2336
</body>
2437
</html>
2538
);

codedock-web/app/register/page.tsx.bak.20260428-040950

Lines changed: 0 additions & 25 deletions
This file was deleted.

codedock-web/components/rooms/invite-create-form.tsx

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// components/rooms/invite-create-form.tsx
22
"use client";
33

4-
import { useState } from "react";
4+
import { useState, useCallback } from "react";
55
import { Button } from "@/components/ui/button";
66
import { Card } from "@/components/ui/card";
77
import { Input } from "@/components/ui/input";
88
import { Label } from "@/components/ui/label";
9+
import { Spinner } from "@/components/ui/spinner";
10+
import { toast } from "sonner";
911

1012
export default function InviteCreateForm({
1113
onCreate,
@@ -18,35 +20,49 @@ export default function InviteCreateForm({
1820
const [expiresInHours, setExpiresInHours] = useState("");
1921
const [maxUses, setMaxUses] = useState("");
2022
const [submitting, setSubmitting] = useState(false);
23+
const [error, setError] = useState<string | null>(null);
2124

22-
async function onSubmit(event: React.FormEvent) {
23-
event.preventDefault();
24-
setSubmitting(true);
25+
const onSubmit = useCallback(
26+
async (event: React.FormEvent) => {
27+
event.preventDefault();
28+
setError(null);
29+
setSubmitting(true);
2530

26-
try {
27-
await onCreate({
28-
expires_in_hours: expiresInHours ? Number(expiresInHours) : undefined,
29-
max_uses: maxUses ? Number(maxUses) : undefined,
30-
});
31+
try {
32+
await onCreate({
33+
expires_in_hours: expiresInHours ? Number(expiresInHours) : undefined,
34+
max_uses: maxUses ? Number(maxUses) : undefined,
35+
});
3136

32-
setExpiresInHours("");
33-
setMaxUses("");
34-
} catch (error) {
35-
window.alert(
36-
error instanceof Error ? error.message : "Invite creation failed",
37-
);
38-
} finally {
39-
setSubmitting(false);
40-
}
41-
}
37+
setExpiresInHours("");
38+
setMaxUses("");
39+
toast.success("Invite token created successfully!");
40+
} catch (err) {
41+
const message =
42+
err instanceof Error ? err.message : "Failed to create invite token";
43+
setError(message);
44+
toast.error("Failed to create invite token", { description: message });
45+
} finally {
46+
setSubmitting(false);
47+
}
48+
},
49+
[onCreate, expiresInHours, maxUses],
50+
);
4251

4352
return (
4453
<Card>
4554
<h3 className="text-base font-semibold text-white">Create invite</h3>
4655
<p className="mt-0.5 text-sm text-[rgb(158,183,211)]">
47-
Both fields are optional. Leave blank for an unlimited, non-expiring token.
56+
Both fields are optional. Leave blank for an unlimited, non-expiring
57+
token.
4858
</p>
4959

60+
{error && (
61+
<div className="mt-4 rounded-lg border border-red-500/30 bg-red-500/5 p-3">
62+
<p className="text-sm text-[rgb(255,160,170)]">{error}</p>
63+
</div>
64+
)}
65+
5066
<form className="mt-5 space-y-4" onSubmit={onSubmit}>
5167
<div className="grid gap-4 sm:grid-cols-2">
5268
<div className="space-y-1.5">
@@ -86,10 +102,17 @@ export default function InviteCreateForm({
86102

87103
<div className="pt-1">
88104
<Button type="submit" disabled={submitting} variant="secondary">
89-
{submitting ? "Creating…" : "Create invite token"}
105+
{submitting ? (
106+
<>
107+
<Spinner size="sm" className="mr-2" />
108+
Creating…
109+
</>
110+
) : (
111+
"Create invite token"
112+
)}
90113
</Button>
91114
</div>
92115
</form>
93116
</Card>
94117
);
95-
}
118+
}

codedock-web/components/rooms/invite-list.tsx

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ function InviteStatusChip({ invite }: { invite: RoomInviteToken }) {
4444
);
4545
}
4646

47-
const exhausted = invite.max_uses != null && invite.uses_count >= invite.max_uses;
47+
const exhausted =
48+
invite.max_uses != null && invite.uses_count >= invite.max_uses;
4849
if (exhausted) {
4950
return (
5051
<span className="inline-flex items-center rounded-full bg-white/[0.06] px-2.5 py-0.5 text-[11px] font-medium text-[rgb(158,183,211)]">
@@ -66,11 +67,13 @@ export default function InviteList({
6667
loading,
6768
error,
6869
onRevoke,
70+
onRetry,
6971
}: {
7072
invites: RoomInviteToken[];
7173
loading: boolean;
7274
error: string | null;
7375
onRevoke: (inviteId: string) => Promise<void>;
76+
onRetry?: () => void;
7477
}) {
7578
return (
7679
<Card>
@@ -99,7 +102,17 @@ export default function InviteList({
99102
))}
100103
</div>
101104
) : error ? (
102-
<p className="text-sm text-[rgb(255,160,170)]">{error}</p>
105+
<div className="rounded-xl border border-red-500/30 bg-red-500/5 p-4">
106+
<p className="text-sm text-[rgb(255,160,170)] mb-3">{error}</p>
107+
{onRetry && (
108+
<button
109+
onClick={onRetry}
110+
className="px-3 py-1.5 text-xs font-medium rounded bg-red-500/20 text-red-300 hover:bg-red-500/30 transition-colors"
111+
>
112+
Try again
113+
</button>
114+
)}
115+
</div>
103116
) : invites.length === 0 ? (
104117
<div className="rounded-xl border border-dashed border-white/10 py-6 text-center">
105118
<p className="text-sm text-[rgb(158,183,211)]">
@@ -118,16 +131,17 @@ export default function InviteList({
118131
<span className="font-mono text-sm font-semibold tracking-[0.14em] text-white">
119132
{invite.code}
120133
</span>
121-
{!invite.is_revoked && (
122-
<CopyCodeButton code={invite.code} />
123-
)}
134+
{!invite.is_revoked && <CopyCodeButton code={invite.code} />}
124135
</div>
125136
{/* Meta row */}
126137
<div className="mt-1 flex items-center gap-2 text-[11px] text-[rgb(158,183,211)]">
127138
<InviteStatusChip invite={invite} />
128139
<span>
129140
{invite.uses_count}
130-
{invite.max_uses != null ? ` / ${invite.max_uses}` : ""} uses
141+
{invite.max_uses != null
142+
? ` / ${invite.max_uses}`
143+
: ""}{" "}
144+
uses
131145
</span>
132146
</div>
133147
</div>
@@ -146,4 +160,4 @@ export default function InviteList({
146160
</div>
147161
</Card>
148162
);
149-
}
163+
}

0 commit comments

Comments
 (0)