Add login formatting

This commit is contained in:
Owen
2026-05-28 21:38:40 -07:00
parent c1ef5b4fbe
commit 9617eb2bd7
3 changed files with 323 additions and 189 deletions

View File

@@ -8,8 +8,14 @@ import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import type { SignSshKeyResponse } from "@server/private/routers/ssh";
import { GetBrowserTargetResponse } from "@server/routers/resource";
import { Card, CardContent } from "@app/components/ui/card";
import LoginCardHeader from "@app/components/LoginCardHeader";
import {
Card,
CardContent,
CardHeader,
CardTitle,
CardDescription
} from "@app/components/ui/card";
import Link from "next/link";
type FormState = {
username: string;
@@ -300,126 +306,163 @@ export default function SshClient({
if (error) {
return (
<Card className="w-full">
<LoginCardHeader subtitle="SSH" />
<CardContent className="pt-6">
<p className="text-destructive text-sm">{error}</p>
</CardContent>
</Card>
<div>
<div className="text-center mb-2">
<span className="text-sm text-muted-foreground">
Powered by{" "}
<Link
href="https://pangolin.net/"
target="_blank"
rel="noopener noreferrer"
className="underline"
>
Pangolin
</Link>
</span>
</div>
<Card className="w-full">
<CardHeader>
<CardTitle>SSH</CardTitle>
</CardHeader>
<CardContent>
<p className="text-destructive text-sm">{error}</p>
</CardContent>
</Card>
</div>
);
}
return (
<>
{!connected && (
<Card className="w-full">
<LoginCardHeader subtitle="Connect via SSH" />
<CardContent className="pt-6">
<div className="space-y-4">
<Field label="Username" id="username">
<Input
id="username"
value={form.username}
onChange={(e) =>
setForm({
...form,
username: e.target.value
})
}
placeholder="root"
/>
</Field>
<Field label="Password" id="password">
<Input
id="password"
type="password"
value={form.password}
onChange={(e) =>
setForm({
...form,
password: e.target.value
})
}
placeholder={
form.privateKey
? "Optional with key auth"
: ""
}
/>
</Field>
<Field
label="Private Key (optional)"
id="privateKey"
<div>
<div className="text-center mb-2">
<span className="text-sm text-muted-foreground">
Powered by{" "}
<Link
href="https://pangolin.net/"
target="_blank"
rel="noopener noreferrer"
className="underline"
>
<Textarea
id="privateKey"
value={form.privateKey}
onChange={(e) =>
setForm({
...form,
privateKey: e.target.value
})
}
placeholder="Paste your private key here (PEM format)…"
rows={5}
className="font-mono text-xs"
/>
<div className="mt-1.5 flex items-center gap-2">
<Button
type="button"
variant="outline"
size="sm"
onClick={() =>
fileInputRef.current?.click()
Pangolin
</Link>
</span>
</div>
<Card className="w-full">
<CardHeader>
<CardTitle>Sign in to SSH</CardTitle>
<CardDescription>
Enter your credentials to access xxxx
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<Field label="Username" id="username">
<Input
id="username"
value={form.username}
onChange={(e) =>
setForm({
...form,
username: e.target.value
})
}
>
Upload key file
</Button>
{form.privateKey && (
<button
placeholder="root"
/>
</Field>
<Field label="Password" id="password">
<Input
id="password"
type="password"
value={form.password}
onChange={(e) =>
setForm({
...form,
password: e.target.value
})
}
placeholder={
form.privateKey
? "Optional with key auth"
: ""
}
/>
</Field>
<Field
label="Private Key (optional)"
id="privateKey"
>
<Textarea
id="privateKey"
value={form.privateKey}
onChange={(e) =>
setForm({
...form,
privateKey: e.target.value
})
}
placeholder="Paste your private key here (PEM format)…"
rows={5}
className="font-mono text-xs"
/>
<div className="mt-1.5 flex items-center gap-2">
<Button
type="button"
className="text-xs text-muted-foreground underline"
variant="outline"
size="sm"
onClick={() =>
setForm((prev) => ({
...prev,
privateKey: ""
}))
fileInputRef.current?.click()
}
>
Clear
</button>
)}
</div>
<input
ref={fileInputRef}
type="file"
className="hidden"
accept=".pem,.key,.pub,*"
onChange={handleKeyFile}
/>
</Field>
Upload key file
</Button>
{form.privateKey && (
<button
type="button"
className="text-xs text-muted-foreground underline"
onClick={() =>
setForm((prev) => ({
...prev,
privateKey: ""
}))
}
>
Clear
</button>
)}
</div>
<input
ref={fileInputRef}
type="file"
className="hidden"
accept=".pem,.key,.pub,*"
onChange={handleKeyFile}
/>
</Field>
{connectError && (
<p className="text-destructive text-sm">
{connectError}
</p>
)}
{connectError && (
<p className="text-destructive text-sm">
{connectError}
</p>
)}
<Button
onClick={() => connect()}
loading={connecting}
disabled={
!form.username ||
(!form.password && !form.privateKey)
}
className="w-full"
>
{connecting ? "Connecting..." : "Connect"}
</Button>
</div>
</CardContent>
</Card>
<Button
onClick={() => connect()}
loading={connecting}
disabled={
!form.username ||
(!form.password && !form.privateKey)
}
className="w-full"
>
{connecting ? "Connecting..." : "Connect"}
</Button>
</div>
</CardContent>
</Card>
</div>
)}
{connected && (