-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Expand file tree
/
Copy pathTutorialMetadata.tsx
More file actions
122 lines (111 loc) · 3.85 KB
/
Copy pathTutorialMetadata.tsx
File metadata and controls
122 lines (111 loc) · 3.85 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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"use client"
import { useLocale, useTranslations } from "next-intl"
import { Lang, Skill, TranslationKey } from "@/lib/types"
import { TutorialFrontmatter } from "@/lib/interfaces"
import CopyToClipboard from "@/components/CopyToClipboard"
import Emoji from "@/components/Emoji"
import Translation from "@/components/Translation"
import TutorialTags from "@/components/TutorialTags"
import { cn } from "@/lib/utils/cn"
import { getLocaleTimestamp } from "@/lib/utils/time"
import { Flex } from "./ui/flex"
import InlineLink from "./ui/Link"
import { Tag } from "./ui/tag"
export type TutorialMetadataProps = {
frontmatter: TutorialFrontmatter
timeToRead: number
}
// Key within the "page-developers-tutorials" namespace
export const getSkillTranslationId = (skill: Skill): TranslationKey =>
`page-tutorial-${Skill[skill.toUpperCase() as keyof typeof Skill]}`
const TutorialMetadata = ({
frontmatter,
timeToRead,
}: TutorialMetadataProps) => {
const locale = useLocale()
const t = useTranslations("page-developers-tutorials")
const hasSource = frontmatter.source && frontmatter.sourceUrl
const published = frontmatter.published
const author = frontmatter.author
const team = frontmatter.team
const address = frontmatter.address
const hasTags = !!frontmatter.tags?.length
const hasSkill = !!frontmatter.skill
const hasTopRow = hasTags || hasSkill
return (
<Flex className="flex-col justify-between border-b-0 border-border pb-2 lg:border-b">
{hasTopRow && (
<Flex className="mb-8 w-full items-center justify-between">
{hasTags && (
<Flex className="w-full flex-wrap gap-2">
<TutorialTags tags={frontmatter.tags!} />
</Flex>
)}
{hasSkill && (
<Tag
variant="outline"
className="mb-2 self-start whitespace-nowrap"
>
{t(getSkillTranslationId(frontmatter.skill as Skill))}
</Tag>
)}
</Flex>
)}
<Flex
className={cn(
"text-text300 mb-6 flex-wrap gap-4 text-sm",
hasTopRow && "-mt-4"
)}
>
{author && (
<div>
<Emoji className="me-2 text-sm" text=":writing_hand:" />
{author}
</div>
)}
{team && (
<div>
<Emoji className="me-2 text-sm" text=":office_building:" />
{team}
</div>
)}
{hasSource && (
<div>
<Emoji className="me-2 text-sm" text=":books:" />
<InlineLink href={frontmatter.sourceUrl}>
{frontmatter.source}
</InlineLink>
</div>
)}
{published && (
<div>
<Emoji className="me-2 text-sm" text=":calendar:" />{" "}
{getLocaleTimestamp(locale! as Lang, published)}
</div>
)}
<div>
<Emoji className="me-2 text-sm" text=":stopwatch:" />
{timeToRead} {t("comp-tutorial-metadata-minute-read")}
</div>
</Flex>
{address && (
<Flex className="text-text300 -mt-4 mb-6 flex-wrap text-sm">
<CopyToClipboard text={address}>
{(isCopied) => (
<div className="cursor-pointer overflow-hidden bg-background-highlight px-1 font-mono text-sm text-ellipsis text-primary hover:bg-primary-hover hover:text-body-inverse">
<span className="uppercase">
<Translation id="page-developers-tutorials:comp-tutorial-metadata-tip-author" />
</span>{" "}
{address} {isCopied && <Translation id="copied" />}{" "}
{isCopied && (
<Emoji className="text-sm" text=":white_check_mark:" />
)}
</div>
)}
</CopyToClipboard>
</Flex>
)}
</Flex>
)
}
export default TutorialMetadata