Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mastodon
GitHub Repository: mastodon/joinmastodon
Path: blob/main/components/ServerCard.tsx
1006 views
1
import Image from "next/legacy/image"
2
import { FormattedMessage, useIntl } from "react-intl"
3
import { Blurhash } from "react-blurhash"
4
5
import LinkButton from "./LinkButton"
6
import type { Server } from "../types/api"
7
import { categoriesMessages } from "../data/categories"
8
import SkeletonText from "./SkeletonText"
9
10
/**
11
* Individual Server cards.
12
* Omitting server prop renders a skeleton.
13
*/
14
const ServerCard = ({ server }: { server?: Server }) => {
15
const intl = useIntl()
16
return (
17
<div className="grid grid-rows-[auto_1fr_auto] rounded-md border border-gray-3 p-4">
18
<div className="relative h-26 overflow-hidden rounded-md bg-gray-2 lg:h-40">
19
{server ? (
20
<>
21
{server.blurhash && (
22
<Blurhash hash={server.blurhash} width="100%" height="100%" />
23
)}
24
25
<Image
26
src={server.proxied_thumbnail}
27
layout="fill"
28
objectFit="cover"
29
alt=""
30
unoptimized
31
/>
32
</>
33
) : (
34
<div className="h-full w-full rounded-md bg-gray-3" />
35
)}
36
</div>
37
38
<div className="pb-5">
39
<p className="b4 mt-4 mb-2 !font-semibold uppercase text-gray-2">
40
{server ? (
41
<>
42
<span>
43
{server.category in categoriesMessages
44
? intl.formatMessage(categoriesMessages[server.category])
45
: server.category}
46
</span>
47
{server?.approval_required && (
48
<span className="before:px-1 before:content-['·']">
49
<FormattedMessage
50
id="servers.approval_required"
51
defaultMessage="Sign-ups reviewed manually"
52
/>
53
</span>
54
)}
55
</>
56
) : (
57
<SkeletonText className="w-[16ch]" />
58
)}
59
</p>
60
<p className="b1 !font-700 mb-2">
61
{server ? (
62
<a
63
href={`https://${server.domain}`}
64
target="_blank"
65
rel="noopener" // Deliberately including referrer so servers can see where people are coming from.
66
className="hover:underline"
67
>
68
{server.domain}
69
</a>
70
) : (
71
<SkeletonText className="w-[14ch]" />
72
)}
73
</p>
74
<p className="b3 line-clamp-5 [unicode-bidi:plaintext] [word-break:break-word]">
75
{server ? (
76
server.description
77
) : (
78
<>
79
<SkeletonText className="w-[27ch]" />
80
<SkeletonText className="w-[26ch]" />
81
<SkeletonText className="w-[12ch]" />
82
</>
83
)}
84
</p>
85
</div>
86
87
<div className="">
88
{server ? (
89
<LinkButton
90
href={`https://${server.domain}/auth/sign_up`}
91
light={server.approval_required}
92
fullWidth
93
size="small"
94
allowReferrer
95
>
96
{server.approval_required ? (
97
<FormattedMessage
98
id="servers.apply_for_an_account"
99
defaultMessage="Apply for an account"
100
/>
101
) : (
102
<FormattedMessage
103
id="servers.create_account"
104
defaultMessage="Create account"
105
/>
106
)}
107
</LinkButton>
108
) : (
109
<div className="flex h-10 rounded border-2 border-gray-3" />
110
)}
111
</div>
112
</div>
113
)
114
}
115
116
export default ServerCard
117
118