From 10f36ff4d3b9a9e812c9bad86a63ad0b4bb7b557 Mon Sep 17 00:00:00 2001 From: Julien Oculi Date: Tue, 2 Jul 2024 17:10:07 +0200 Subject: [PATCH] feat(components): :sparkles: refactor and add `BlogCard` and `BlogPost` components --- components/BlogBlocks.css | 164 +++++++++++++++++++++++++++++++++ components/BlogBlocks.tsx | 157 +++++++++++++++++++++++++++++++ components/BlogCard.css | 41 --------- components/BlogCard.tsx | 54 ----------- deno.json | 3 + src/stylesheets/components.css | 2 +- 6 files changed, 325 insertions(+), 96 deletions(-) create mode 100644 components/BlogBlocks.css create mode 100644 components/BlogBlocks.tsx delete mode 100644 components/BlogCard.css delete mode 100644 components/BlogCard.tsx diff --git a/components/BlogBlocks.css b/components/BlogBlocks.css new file mode 100644 index 0000000..f4455e7 --- /dev/null +++ b/components/BlogBlocks.css @@ -0,0 +1,164 @@ +.components__blog_block { + min-width: 10rem; + aspect-ratio: 3 / 4; + display: flex; + flex-direction: column; + box-shadow: 0 0 0.4rem 0.2rem var(--_translucent); + border: var(--_border-size) solid transparent; + background-repeat: no-repeat; + background-size: 80%; + background-position: center var(--_gap); + backdrop-filter: blur(var(--_blur)); + background-color: var(--_background-color); + + &:has(a:focus-visible), + &:hover { + border: var(--_border-size) solid var(--_accent-color); + } + + & h3 { + margin: 0; + padding: var(--_gap) var(--_gap-half); + backdrop-filter: blur(var(--_blur)); + background-color: var(--_translucent); + border-bottom: 1px solid currentColor; + } + + & a { + outline: none; + } +} + +.components__blog_block--card { + max-width: 20rem; +} + +.components__blog_block--placeholder { + animation: var(--animation-blink); +} + +.components__blog_block--fallback { + opacity: 0.5; +} + +:is(.components__blog_block--placeholder, .components__blog_block--fallback) { + h3 { + flex-grow: 1; + border: none; + align-content: center; + text-align: center; + } +} + +.components__blog_block__spacer { + height: 0; +} + +.components__blog_block--card .components__blog_block__spacer { + height: 30%; +} + +.components__blog_block__links { + height: fit-content; + display: flex; + gap: var(--_gap-half); + justify-content: start; + padding: var(--_gap-half); + backdrop-filter: blur(var(--_blur)); + background-color: var(--_translucent); + border-bottom: 1px solid currentColor; + + & > a::before { + content: 'đź”—'; + } +} + +.components__blog_block__tags { + height: fit-content; + display: flex; + gap: var(--_gap-half); + justify-content: start; + padding: var(--_gap-half); + backdrop-filter: blur(var(--_blur)); + background-color: var(--_translucent); + border-bottom: 1px solid currentColor; + + & > span::before { + content: '#'; + } +} + +.components__blog_block__status { + display: block; + padding: var(--_gap-half); + background-color: var(--_translucent); + backdrop-filter: blur(var(--_blur)); +} + +.components__blog_block--card .components__blog_block__status { + position: absolute; + top: var(--_gap-half); + left: var(--_gap-half); + font-size: larger; +} + +.components__blog_block__publisher { + display: block; + padding: var(--_gap-half); + background-color: var(--_translucent); + backdrop-filter: blur(var(--_blur)); +} + +.components__blog_block--card .components__blog_block__publisher { + position: absolute; + top: var(--_gap-half); + right: var(--_gap-half); +} + +.components__blog_block__description { + text-wrap: balance; + flex-grow: 1; + backdrop-filter: blur(var(--_blur)); + padding: var(--_gap-half); +} + +.components__blog_block--card .components__blog_block__description { + min-height: 25%; +} + +.components__blog_block__body { + text-wrap: balance; + flex-grow: 1; + padding: var(--_gap-half); +} + +.components__blog_block__footer { + height: fit-content; + display: flex; + gap: var(--_gap); + justify-content: space-between; + padding: var(--_gap-half); + background-color: var(--_background-color); +} + +.components__blog_post__infos { + display: flex; + gap: var(--_gap-half); + margin-block: var(--_gap-half); + + & > * { + border: none; + padding: var(--_gap-half); + background-color: var(--_translucent); + } +} + +.components__blog_post__description { + margin-block: var(--_gap-half); + font-family: var(--_font-family-code); +} + +.components__blog_block--post { + width: var(--_readable-screen); + margin-inline: auto; +} diff --git a/components/BlogBlocks.tsx b/components/BlogBlocks.tsx new file mode 100644 index 0000000..9199c7e --- /dev/null +++ b/components/BlogBlocks.tsx @@ -0,0 +1,157 @@ +import { Markdown } from ':components/Markdown.tsx' +import { NewsFrontMatter } from ':src/blog/types.ts' + +export type BlogProps = { + title: string + description: string + body: string + author: string + publisher: string + lastUpdate: Date + name: string + url: string + hash: string + options: NewsFrontMatter['x-cohabit'] + tags: NewsFrontMatter['tags'] +} + +export function BlogCard( + { title, description, author, lastUpdate, name, options, tags, publisher }: + BlogProps, +) { + return ( +
+
+

+ {title} +

+ + + + {`@${publisher}`} + + +
+ {description} +
+ +
+ ) +} + +export function BlogPost( + { + title, + description, + author, + lastUpdate, + body, + url, + options, + tags, + publisher, + }: BlogProps, +) { + return ( +
+

{title}

+ + +
+ {description} +
+
+ + {body} + +
+ +
+ ) +} + +function NewsTags({ tags }: Pick) { + return ( +
+ {tags + ? tags.map((tag) => {tag}) + : Aucun tag} +
+ ) +} + +function NewsFooter( + { author, lastUpdate }: Pick, +) { + return ( + + ) +} + +function NewsLinks({ links }: Pick) { + return ( + + ) +} + +function NewsStatus( + { status, long = false }: Pick & { + long?: boolean + }, +) { + const title = status === 'canceled' + ? 'Annulé' + : status === 'current' + ? 'En cours' + : status === 'finished' + ? 'Terminé' + : 'Prévu' + + return ( + + {status === 'canceled' + ? + : status === 'current' + ? + : status === 'finished' + ? + : } + {long ? ` ${title}` : ''} + + ) +} diff --git a/components/BlogCard.css b/components/BlogCard.css deleted file mode 100644 index 6950078..0000000 --- a/components/BlogCard.css +++ /dev/null @@ -1,41 +0,0 @@ -.components__blog_card { - min-width: 10rem; - aspect-ratio: 3 / 4; - display: flex; - flex-direction: column; - padding: var(--_gap-half); - gap: var(--_gap); - box-shadow: 0 0 0.4rem 0.2rem var(--_translucent); - border: var(--_border-size) solid transparent; - background-repeat: no-repeat; - background-size: contain; - - &:has(a:focus-visible), - &:hover { - border: var(--_border-size) solid var(--_accent-color); - } - - & h3 { - margin: 0; - } - - & a { - outline: none; - } -} - -.components__blog_card__spacer { - height: 50%; -} - -.components__blog_card__text { - text-wrap: balance; - flex-grow: 1; -} - -.components__blog_card__footer { - height: fit-content; - display: flex; - gap: var(--_gap); - justify-content: space-between; -} diff --git a/components/BlogCard.tsx b/components/BlogCard.tsx deleted file mode 100644 index 1fb431e..0000000 --- a/components/BlogCard.tsx +++ /dev/null @@ -1,54 +0,0 @@ -type BlogCardProps = { - img: string - title: string - text: string - author: string - lasUpdate: Date - id: string -} - -export function BlogCard( - { img, title, text, author, lasUpdate, id }: BlogCardProps, -) { - return ( -
-
-

- {title} -

-
- {`${text.slice(0, 150)} ...`} -
- -
- ) -} - -const text = - 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui, perferendis enim blanditiis consequatur at porro quod, eligendi alias recusandae modi aliquam non? Quos voluptates quisquam provident animi nisi in ratione.' - -export const blogMock: BlogCardProps[] = Array(50).fill(undefined).map( - (_, index) => { - return { - author: 'PGP', - lasUpdate: randomDate(), - title: `Some title here ${index}`, - text, - img: `url("https://picsum.photos/id/${index}/300/200")`, - id: String(index), - } - }, -) - -function randomDate() { - return new Date(Date.now() - Math.random() * 1e10) -} diff --git a/deno.json b/deno.json index 6eb1ddc..b63bf19 100644 --- a/deno.json +++ b/deno.json @@ -44,7 +44,10 @@ "@simplewebauthn/server": "npm:@simplewebauthn/server@^10.0.0", "@simplewebauthn/types": "npm:@simplewebauthn/types@^10.0.0", "@std/encoding": "jsr:@std/encoding@^0.224.3", + "@std/front-matter": "jsr:@std/front-matter@^0.224.2", "@std/http": "jsr:@std/http@^0.224.4", + "@std/json": "jsr:@std/json@^0.224.1", + "@std/streams": "jsr:@std/streams@^0.224.5", "@univoq/": "https://deno.land/x/univoq@0.2.0/", "gfm": "https://deno.land/x/gfm@0.6.0/mod.ts", "preact": "https://esm.sh/preact@10.19.6", diff --git a/src/stylesheets/components.css b/src/stylesheets/components.css index 21a112c..a66432b 100644 --- a/src/stylesheets/components.css +++ b/src/stylesheets/components.css @@ -3,7 +3,7 @@ @import url('../../components/Heros.css'); @import url('../../components/SponsorCards.css'); @import url('../../components/CohabitInfoTable.css'); -@import url('../../components/BlogCard.css'); +@import url('../../components/BlogBlocks.css'); @import url('../../components/MachineCard.css'); @import url('../../components/ProjectCard.css'); @import url('../../components/AutoGrid.css');