-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathProfileHeader.tsx
More file actions
93 lines (80 loc) · 2.77 KB
/
ProfileHeader.tsx
File metadata and controls
93 lines (80 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"use client";
import { EnsAvatar, NameDisplay } from "@namehash/namehash-ui";
import type { Name } from "enssdk";
import type { ENSNamespaceId } from "@ensnode/ensnode-sdk";
import { ExternalLinkWithIcon } from "@/components/link";
import { Card, CardContent } from "@/components/ui/card";
import { beautifyUrl } from "@/lib/beautify-url";
interface ProfileHeaderProps {
name: Name;
namespaceId: ENSNamespaceId;
headerImage?: string | null;
websiteUrl?: string | null;
}
export function ProfileHeader({ name, namespaceId, headerImage, websiteUrl }: ProfileHeaderProps) {
// Parse header image URI and only use it if it's HTTP/HTTPS
// TODO: Add support for more URI types as defined in ENSIP-12
// See: https://docs.ens.domains/ensip/12#uri-types
const getValidHeaderImageUrl = (headerImage: string | null | undefined): string | null => {
if (!headerImage) return null;
let url: URL;
try {
url = new URL(headerImage);
} catch {
return null;
}
if (url.protocol === "http:" || url.protocol === "https:") return headerImage;
// For any other URI types (ipfs, data, NFT URIs, etc.), fallback to default
return null;
};
const normalizeWebsiteUrl = (url: string | null | undefined): URL | null => {
if (!url) return null;
try {
try {
return new URL(url);
} catch {
return new URL(`https://${url}`);
}
} catch {
return null;
}
};
const validHeaderImageUrl = getValidHeaderImageUrl(headerImage);
const normalizedWebsiteUrl = normalizeWebsiteUrl(websiteUrl);
return (
<Card className="overflow-hidden mb-8">
<div
className="h-48 bg-blue-500"
style={{
backgroundImage: validHeaderImageUrl ? `url(${validHeaderImageUrl})` : undefined,
backgroundSize: "cover",
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
}}
/>
<CardContent className="pt-6">
<div className="flex items-start justify-between">
<div className="flex items-center gap-4">
<EnsAvatar
className="-mt-16 h-20 w-20 ring-4 ring-white"
name={name}
namespaceId={namespaceId}
/>
<div className="flex-1">
<h1>
<NameDisplay className="text-3xl font-bold" name={name} />
</h1>
<div className="flex items-center gap-3 mt-1">
{normalizedWebsiteUrl && (
<ExternalLinkWithIcon href={normalizedWebsiteUrl.toString()} className="text-sm">
{beautifyUrl(normalizedWebsiteUrl)}
</ExternalLinkWithIcon>
)}
</div>
</div>
</div>
</div>
</CardContent>
</Card>
);
}