+25
-1
frontend-v2/src/components/CopyableField.tsx
+25
-1
frontend-v2/src/components/CopyableField.tsx
···
4
4
interface CopyableFieldProps {
5
5
value: string;
6
6
label: string;
7
+
variant?: "input" | "inline";
7
8
}
8
9
9
-
export function CopyableField({ value, label }: CopyableFieldProps) {
10
+
export function CopyableField({ value, label, variant = "input" }: CopyableFieldProps) {
10
11
const [copied, setCopied] = useState(false);
11
12
12
13
const handleCopy = async () => {
···
18
19
console.error("Failed to copy:", err);
19
20
}
20
21
};
22
+
23
+
if (variant === "inline") {
24
+
return (
25
+
<div className="flex items-center gap-2 group">
26
+
<span className="text-xs text-zinc-500">{label}:</span>
27
+
<span className="font-mono text-xs text-zinc-600 break-all">
28
+
{value}
29
+
</span>
30
+
<button
31
+
type="button"
32
+
onClick={handleCopy}
33
+
className="p-1 text-zinc-400 hover:text-zinc-300 transition-colors rounded hover:bg-zinc-700/50 flex-shrink-0 opacity-0 group-hover:opacity-100"
34
+
title="Copy to clipboard"
35
+
>
36
+
{copied ? (
37
+
<Check size={14} className="text-green-400" />
38
+
) : (
39
+
<Copy size={14} />
40
+
)}
41
+
</button>
42
+
</div>
43
+
);
44
+
}
21
45
22
46
return (
23
47
<div>
+5
-1
frontend-v2/src/pages/SliceOverview.tsx
+5
-1
frontend-v2/src/pages/SliceOverview.tsx
···
13
13
import { useSessionContext } from "../lib/useSession.ts";
14
14
import { isSliceOwner } from "../lib/permissions.ts";
15
15
import { Plus } from "lucide-react";
16
+
import { CopyableField } from "../components/CopyableField.tsx";
16
17
17
18
export default function SliceOverview() {
18
19
const { handle, rkey } = useParams<{ handle: string; rkey: string }>();
···
101
102
}
102
103
>
103
104
<div className="mb-8">
104
-
<div className="flex items-center gap-3">
105
+
<div className="flex items-center gap-3 mb-4">
105
106
<Avatar
106
107
src={slice?.networkSlicesActorProfile?.avatar?.url}
107
108
alt={`${handle} avatar`}
···
116
117
</p>
117
118
</div>
118
119
</div>
120
+
{slice?.uri && (
121
+
<CopyableField value={slice.uri} label="Slice URI" variant="inline" />
122
+
)}
119
123
</div>
120
124
121
125
{/* Stats Section */}