diff options
Diffstat (limited to 'src/components/templates')
-rw-r--r-- | src/components/templates/MicroBlog.astro | 114 | ||||
-rw-r--r-- | src/components/templates/Search.astro | 67 | ||||
-rw-r--r-- | src/components/templates/SimplePostList.astro | 81 |
3 files changed, 262 insertions, 0 deletions
diff --git a/src/components/templates/MicroBlog.astro b/src/components/templates/MicroBlog.astro new file mode 100644 index 0000000..b7019c5 --- /dev/null +++ b/src/components/templates/MicroBlog.astro @@ -0,0 +1,114 @@ +--- +import Date from "@components/organisms/Date.astro"; +import KeywordsList from "@components/organisms/KeywordsList.astro"; +import { getFirstUserID, getLastUpdate } from "@lib/collection/helpers"; +import { Micro } from "@lib/collection/schemas"; +import type { CollectionEntry, z } from "astro:content"; + +interface Props extends CollectionEntry<"blog"> { + data: z.infer<typeof Micro>; +} + +const micro = Astro.props; +const { id, data, rendered } = micro; +const { title, lang, keywords } = data; +const date = getLastUpdate(micro); +const user = await getFirstUserID(micro); +const display = user?.name ?? user?.email ?? user?.entity ?? ""; +const [first, ...names] = display.split(/\s/); +const last = names.length > 0 ? names[names.length - 1] : ""; +const little = ((first?.[0] ?? "") + (last?.[0] ?? "")).slice(0, 2); +--- +<article> + <header> + <h3 class="title"> + <a href={`/blog/read/${id}`}>{title}</a> + </h3> + <span class="profile_picture">{ + user?.website ? <a href={user.website}>{little}</a> : ( + <span>{little}</span> + ) + }</span> + <div> + {first} {last} <small>· <Date + {date} + locales={lang} + options={{ month: "short", day: "numeric" }} + /></small> + </div> + </header> + <div class="content"> + <small {lang}> + <Fragment set:html={rendered?.html} /> + </small> + <footer> + <div class="keywords small"><KeywordsList {keywords} /></div> + </footer> + </div> + <aside> + <small><a href="/blog/micro/1">Ver todos os microposts</a></small> + </aside> +</article> + +<style is:inline> + .content > [lang] > *:first-child { + margin-block-start: 0; + } + .content > [lang] > *:last-child { + margin-block-end: 0; + } +</style> +<style> + article { + border-radius: calc(var(--size-1) * 1em); + box-shadow: 0 0 calc(var(--size-1) * 1em) var(--color-light); + padding: calc(var(--size-4) * 1em); + display: grid; + grid-template-rows: repeat(3, auto); + grid-template-columns: calc(var(--size-9) * 1em) auto; + gap: calc(var(--size-1) * 1em); + + & > header { + display: contents; + } + + & > aside { + grid-row: 3 / 4; + grid-column: 1 / 3; + border-block-start: 1px solid #e7e7e7; + padding-block-start: calc(var(--size-1) * 1em); + } + } + + .profile_picture { + grid-row: 1 / 3; + grid-column: 1 / 2; + + & > * { + display: inline-grid; + place-content: center; + width: calc(var(--size-9) * 1em); + height: calc(var(--size-9) * 1em); + aspect-ratio: 1 / 1; + background-color: var(--color-active); + color: #fff; + font-weight: 950; + font-size: smaller; + border-radius: calc(infinity * 1px); + text-align: center; + text-transform: uppercase; + } + } + + .title { + display: none; + } + .content { + grid-row: 2/3; + grid-column: 2 / 3; + } + + .keywords { + margin-block-end: 0; + } +</style> diff --git a/src/components/templates/Search.astro b/src/components/templates/Search.astro new file mode 100644 index 0000000..5245643 --- /dev/null +++ b/src/components/templates/Search.astro @@ -0,0 +1,67 @@ +--- +const { site } = Astro; +--- + +<search> + <link rel="dns-prefetch" href="https://www.google.com/search"> + <form + action="https://www.google.com/search" + target="_blank" + rel="external noreferrer search" + role="search" + autocomplete="on" + name="search" + > + <details> + <summary>Pesquisar no website</summary> + <div class="details"> + <p> + <label>Barra de pesquisa <input + name="q" + type="search" + placeholder={`site:${site} consulta de pesquisa`} + value={`site:${site} `} + required + title={`"site:${site} " é usado para que os resultados da pesquisa fiquem restritos a este website`} + pattern={`site:${site} .+`} + size={`site:${site} .+`.length} + /></label> + </p> + <p class="mute"> + <small>Esta pesquisa é efectuada pelo Google e <strong>utiliza + software proprietário.</strong></small> + </p> + <p><button type="submit">🔍 Pesquisar</button></p> + </div> + </details> + </form> +</search> + +<style> + search { + padding-block-end: calc(var(--size-4) * 1em); + } + + summary { + font-size: calc(var(--size-3) * 1rem); + font-weight: bolder; + } + + .details { + border-radius: calc(var(--size-1) * 1em); + border: 1px solid var(--color-light); + margin-block-start: calc(var(--size-1) * 1em); + font-size: calc(var(--size-3) * 1rem); + padding-inline: calc(var(--size-4) * 1em); + padding-block: calc(var(--size-2) * 1em); + + & > p { + margin-block: calc(var(--size-2) * 1em); + line-height: calc(var(--size-8) * 1rem); + } + + & input[type="search"] { + width: 100%; + } + } +</style> diff --git a/src/components/templates/SimplePostList.astro b/src/components/templates/SimplePostList.astro new file mode 100644 index 0000000..0ec33e3 --- /dev/null +++ b/src/components/templates/SimplePostList.astro @@ -0,0 +1,81 @@ +--- +import Date from "@components/organisms/Date.astro"; +import KeywordsList from "@components/organisms/KeywordsList.astro"; +import { getFirstUserID, getLastUpdate } from "@lib/collection/helpers"; +import type { Original } from "@lib/collection/schemas"; +import type { z } from "astro:content"; +import type { CollectionEntry } from "astro:content"; + +interface Props { + posts: (CollectionEntry<"blog"> & { data: z.infer<typeof Original> })[]; +} + +const { posts } = Astro.props; +--- +<ol> + { + await Promise.all(posts.map(async (post) => { + const { id, data } = post; + const { title, description, lang, keywords } = data; + const { name, email, entity } = await getFirstUserID(post); + const display = name ?? email ?? entity; + return ( + <li> + <article> + <h3><a href={`/blog/read/${id}`}>{title}</a></h3> + { + description && + description.split("\n\n").map((paragraph) => ( + <p class="small">{paragraph}</p> + )) + } + + <footer class="small"> + <Date + date={getLastUpdate(post)} + locales={lang} + options={{ + year: "numeric", + month: "long", + day: "numeric", + }} + />{display} + <KeywordsList {keywords} /> + </footer> + </article> + </li> + ); + })) + } +</ol> + +<style> + ol { + margin-inline-start: calc(var(--size-7) * 1em); + margin-block: calc(var(--size-7) * 1em); + & > li { + margin-block-start: calc(var(--size-2) * 1em); + & > article { + padding-inline-end: calc(var(--size-9) * 1em); + + & > p:not(:first-of-type) { + margin-block-start: 1.5em; + } + + & > footer { + display: flex; + flex-direction: column; + gap: calc(var(--size-1) * 1em); + } + } + } + } + + @media (width >= 40rem) { + ol > li > article > footer { + flex-direction: row; + align-items: center; + justify-content: space-between; + } + } +</style> |