ServerCard.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import Image from "next/legacy/image"
  2. import { FormattedMessage, useIntl } from "react-intl"
  3. import { Blurhash } from "react-blurhash"
  4. import LinkButton from "./LinkButton"
  5. import type { Server } from "../types/api"
  6. import { categoriesMessages } from "../data/categories"
  7. import { formatNumber } from "../utils/numbers"
  8. import SkeletonText from "./SkeletonText"
  9. /**
  10. * Individual Server cards.
  11. * Omitting server prop renders a skeleton.
  12. */
  13. const ServerCard = ({ server }: { server?: Server }) => {
  14. const intl = useIntl()
  15. return (
  16. <div className="grid grid-rows-[auto_1fr_auto] rounded-md border border-gray-3 p-4">
  17. <div className="relative h-26 overflow-hidden rounded-md bg-gray-2 lg:h-40">
  18. {server ? (
  19. <>
  20. {server.blurhash && (
  21. <Blurhash hash={server.blurhash} width="100%" height="100%" />
  22. )}
  23. <Image
  24. src={server.proxied_thumbnail}
  25. layout="fill"
  26. objectFit="cover"
  27. alt=""
  28. unoptimized
  29. />
  30. </>
  31. ) : (
  32. <div className="h-full w-full rounded-md bg-gray-3" />
  33. )}
  34. </div>
  35. <div className="pb-5">
  36. <p className="b4 mt-4 mb-2 !font-semibold uppercase text-gray-2">
  37. {server ? (
  38. <>
  39. <span>
  40. {server.category in categoriesMessages
  41. ? intl.formatMessage(categoriesMessages[server.category])
  42. : server.category}
  43. </span>
  44. {server?.approval_required && (
  45. <span className="before:px-1 before:content-['·']">
  46. <FormattedMessage
  47. id="servers.approval_required"
  48. defaultMessage="Sign-ups reviewed manually"
  49. />
  50. </span>
  51. )}
  52. </>
  53. ) : (
  54. <SkeletonText className="w-[16ch]" />
  55. )}
  56. </p>
  57. <p className="b1 !font-700 mb-2">
  58. {server ? server.domain : <SkeletonText className="w-[14ch]" />}
  59. </p>
  60. <p className="b3 line-clamp-5 [unicode-bidi:plaintext]">
  61. {server ? (
  62. server.description
  63. ) : (
  64. <>
  65. <SkeletonText className="w-[27ch]" />
  66. <SkeletonText className="w-[26ch]" />
  67. <SkeletonText className="w-[12ch]" />
  68. </>
  69. )}
  70. </p>
  71. </div>
  72. <div className="">
  73. {server ? (
  74. <LinkButton
  75. href={`https://${server.domain}/auth/sign_up`}
  76. light={server.approval_required}
  77. fullWidth
  78. size="small"
  79. >
  80. {server.approval_required ? (
  81. <FormattedMessage
  82. id="servers.apply_for_an_account"
  83. defaultMessage="Apply for an account"
  84. />
  85. ) : (
  86. <FormattedMessage
  87. id="servers.create_account"
  88. defaultMessage="Create account"
  89. />
  90. )}
  91. </LinkButton>
  92. ) : (
  93. <div className="flex h-10 rounded border-2 border-gray-3" />
  94. )}
  95. </div>
  96. </div>
  97. )
  98. }
  99. export default ServerCard