optimize posts images and other improvements
This commit is contained in:
parent
9c3e631c78
commit
ec3bccb0de
@ -28,10 +28,10 @@
|
|||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
"lucide-react": "^0.396.0",
|
"lucide-react": "^0.396.0",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
|
"marked": "^13.0.1",
|
||||||
"node-html-parser": "^6.1.13",
|
"node-html-parser": "^6.1.13",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-markdown": "^9.0.1",
|
|
||||||
"rehype-pretty-code": "^0.13.2",
|
"rehype-pretty-code": "^0.13.2",
|
||||||
"rehype-slug": "^6.0.0",
|
"rehype-slug": "^6.0.0",
|
||||||
"sanitize-html": "^2.13.0",
|
"sanitize-html": "^2.13.0",
|
||||||
|
41
pnpm-lock.yaml
generated
41
pnpm-lock.yaml
generated
@ -62,6 +62,9 @@ importers:
|
|||||||
markdown-it:
|
markdown-it:
|
||||||
specifier: ^14.1.0
|
specifier: ^14.1.0
|
||||||
version: 14.1.0
|
version: 14.1.0
|
||||||
|
marked:
|
||||||
|
specifier: ^13.0.1
|
||||||
|
version: 13.0.1
|
||||||
node-html-parser:
|
node-html-parser:
|
||||||
specifier: ^6.1.13
|
specifier: ^6.1.13
|
||||||
version: 6.1.13
|
version: 6.1.13
|
||||||
@ -71,9 +74,6 @@ importers:
|
|||||||
react-dom:
|
react-dom:
|
||||||
specifier: ^18.3.1
|
specifier: ^18.3.1
|
||||||
version: 18.3.1(react@18.3.1)
|
version: 18.3.1(react@18.3.1)
|
||||||
react-markdown:
|
|
||||||
specifier: ^9.0.1
|
|
||||||
version: 9.0.1(@types/react@18.3.3)(react@18.3.1)
|
|
||||||
rehype-pretty-code:
|
rehype-pretty-code:
|
||||||
specifier: ^0.13.2
|
specifier: ^0.13.2
|
||||||
version: 0.13.2(shiki@1.9.0)
|
version: 0.13.2(shiki@1.9.0)
|
||||||
@ -1648,9 +1648,6 @@ packages:
|
|||||||
html-escaper@3.0.3:
|
html-escaper@3.0.3:
|
||||||
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
|
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
|
||||||
|
|
||||||
html-url-attributes@3.0.0:
|
|
||||||
resolution: {integrity: sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==}
|
|
||||||
|
|
||||||
html-void-elements@3.0.0:
|
html-void-elements@3.0.0:
|
||||||
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
|
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
|
||||||
|
|
||||||
@ -1898,6 +1895,11 @@ packages:
|
|||||||
markdown-table@3.0.3:
|
markdown-table@3.0.3:
|
||||||
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
||||||
|
|
||||||
|
marked@13.0.1:
|
||||||
|
resolution: {integrity: sha512-7kBohS6GrZKvCsNXZyVVXSW7/hGBHe49ng99YPkDCckSUrrG7MSFLCexsRxptzOmyW2eT5dySh4Md1V6my52fA==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
mdast-util-definitions@6.0.0:
|
mdast-util-definitions@6.0.0:
|
||||||
resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==}
|
resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==}
|
||||||
|
|
||||||
@ -2377,12 +2379,6 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^18.3.1
|
react: ^18.3.1
|
||||||
|
|
||||||
react-markdown@9.0.1:
|
|
||||||
resolution: {integrity: sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@types/react': '>=18'
|
|
||||||
react: '>=18'
|
|
||||||
|
|
||||||
react-refresh@0.14.2:
|
react-refresh@0.14.2:
|
||||||
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
|
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -4811,8 +4807,6 @@ snapshots:
|
|||||||
|
|
||||||
html-escaper@3.0.3: {}
|
html-escaper@3.0.3: {}
|
||||||
|
|
||||||
html-url-attributes@3.0.0: {}
|
|
||||||
|
|
||||||
html-void-elements@3.0.0: {}
|
html-void-elements@3.0.0: {}
|
||||||
|
|
||||||
htmlparser2@8.0.2:
|
htmlparser2@8.0.2:
|
||||||
@ -5017,6 +5011,8 @@ snapshots:
|
|||||||
|
|
||||||
markdown-table@3.0.3: {}
|
markdown-table@3.0.3: {}
|
||||||
|
|
||||||
|
marked@13.0.1: {}
|
||||||
|
|
||||||
mdast-util-definitions@6.0.0:
|
mdast-util-definitions@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/mdast': 4.0.4
|
'@types/mdast': 4.0.4
|
||||||
@ -5748,23 +5744,6 @@ snapshots:
|
|||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
scheduler: 0.23.2
|
scheduler: 0.23.2
|
||||||
|
|
||||||
react-markdown@9.0.1(@types/react@18.3.3)(react@18.3.1):
|
|
||||||
dependencies:
|
|
||||||
'@types/hast': 3.0.4
|
|
||||||
'@types/react': 18.3.3
|
|
||||||
devlop: 1.1.0
|
|
||||||
hast-util-to-jsx-runtime: 2.3.0
|
|
||||||
html-url-attributes: 3.0.0
|
|
||||||
mdast-util-to-hast: 13.2.0
|
|
||||||
react: 18.3.1
|
|
||||||
remark-parse: 11.0.0
|
|
||||||
remark-rehype: 11.1.0
|
|
||||||
unified: 11.0.5
|
|
||||||
unist-util-visit: 5.0.0
|
|
||||||
vfile: 6.0.1
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
react-refresh@0.14.2: {}
|
react-refresh@0.14.2: {}
|
||||||
|
|
||||||
react-remove-scroll-bar@2.3.6(@types/react@18.3.3)(react@18.3.1):
|
react-remove-scroll-bar@2.3.6(@types/react@18.3.3)(react@18.3.1):
|
||||||
|
@ -5,9 +5,16 @@ const { src, alt } = Astro.props;
|
|||||||
---
|
---
|
||||||
|
|
||||||
<Image
|
<Image
|
||||||
|
id="img"
|
||||||
src={src}
|
src={src}
|
||||||
alt={alt}
|
alt={alt}
|
||||||
width={1092}
|
width={1092}
|
||||||
height={986}
|
height={986}
|
||||||
class="w-auto h-auto rounded-md aspect-auto"
|
class=".markdown-image w-auto h-auto rounded-md aspect-auto"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const image = document.getElementById("img")!;
|
||||||
|
|
||||||
|
image.setAttribute("loading", "eager");
|
||||||
|
</script>
|
||||||
|
38
src/components/microblog-item.astro
Normal file
38
src/components/microblog-item.astro
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
import { marked } from "marked";
|
||||||
|
import formatDate from "@/utils/format-date";
|
||||||
|
import type { MicroblogsResponse, TagsResponse } from "@/utils/pocketbase";
|
||||||
|
|
||||||
|
type Props = MicroblogsResponse<unknown> & {
|
||||||
|
props: {
|
||||||
|
tags: TagsResponse[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const props = Astro.props;
|
||||||
|
const content = marked.parse(props.content);
|
||||||
|
---
|
||||||
|
|
||||||
|
<article class="rounded-md border px-4 py-2">
|
||||||
|
<header class="mb-2">
|
||||||
|
<div class="flex items-center justify-between text-sm">
|
||||||
|
<span class="font-light">
|
||||||
|
{formatDate(new Date(props.published))}{" "}
|
||||||
|
</span>
|
||||||
|
<span class="text-sm font-thin">
|
||||||
|
{new Date(props.published).toLocaleTimeString()}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-1">
|
||||||
|
{
|
||||||
|
props &&
|
||||||
|
props.expand.tags &&
|
||||||
|
props.expand.tags.map(
|
||||||
|
(tag: any) =>
|
||||||
|
tag && <span class="text-sm">#{tag.name} </span>,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main set:html={content} />
|
||||||
|
</article>
|
@ -1,41 +0,0 @@
|
|||||||
import ReactMarkdown from "react-markdown";
|
|
||||||
import type { MicroblogsResponse, TagsResponse } from "@/utils/pocketbase";
|
|
||||||
import formatDate from "@/utils/format-date";
|
|
||||||
|
|
||||||
type Props = MicroblogsResponse<unknown> & {
|
|
||||||
expand: {
|
|
||||||
tags: TagsResponse[];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function MicroblogItem(props: Props) {
|
|
||||||
return (
|
|
||||||
<article className="rounded-sm border px-4 py-2">
|
|
||||||
<header className="mb-2">
|
|
||||||
<div className="flex items-center justify-between text-sm">
|
|
||||||
<span className="font-light">
|
|
||||||
{formatDate(new Date(props.published))}{" "}
|
|
||||||
</span>
|
|
||||||
<span className="text-sm font-thin">
|
|
||||||
{new Date(props.published).toLocaleTimeString()}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="mt-1">
|
|
||||||
{props.expand &&
|
|
||||||
props.expand.tags &&
|
|
||||||
props.expand.tags.map(
|
|
||||||
(tag) =>
|
|
||||||
tag && (
|
|
||||||
<span className="text-sm" key={tag.id}>
|
|
||||||
#{tag.name}{" "}
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<main>
|
|
||||||
<ReactMarkdown>{props.content}</ReactMarkdown>
|
|
||||||
</main>
|
|
||||||
</article>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
import { navItems } from "@/utils/nav-links";
|
|
||||||
import MobileMenu from "@/components/mobile-menu";
|
|
||||||
import logo from "@/assets/logo.png";
|
import logo from "@/assets/logo.png";
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
|
import { navItems } from "@/utils/nav-links";
|
||||||
|
import MobileMenu from "@/components/mobile-menu";
|
||||||
import LinkButton from "@/components/link-button";
|
import LinkButton from "@/components/link-button";
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -23,6 +23,7 @@ import LinkButton from "@/components/link-button";
|
|||||||
src={logo}
|
src={logo}
|
||||||
width={80}
|
width={80}
|
||||||
height={80}
|
height={80}
|
||||||
|
loading="eager"
|
||||||
class="w-auto h-auto"
|
class="w-auto h-auto"
|
||||||
alt="juancmandev logo"
|
alt="juancmandev logo"
|
||||||
/>
|
/>
|
||||||
@ -31,7 +32,7 @@ import LinkButton from "@/components/link-button";
|
|||||||
<section class="hidden items-center md:flex">
|
<section class="hidden items-center md:flex">
|
||||||
<ul class="flex items-center gap-1">
|
<ul class="flex items-center gap-1">
|
||||||
{
|
{
|
||||||
navItems.map((navItem) => (
|
navItems.map((navItem: any) => (
|
||||||
<li class="w-max h-max">
|
<li class="w-max h-max">
|
||||||
<LinkButton
|
<LinkButton
|
||||||
variant="link"
|
variant="link"
|
||||||
|
@ -11,7 +11,7 @@ interface Props {
|
|||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const allPages = await getCollection("pages");
|
const allPages = await getCollection("pages");
|
||||||
|
|
||||||
return allPages.map((page) => ({
|
return allPages.map((page: CollectionEntry<"pages">) => ({
|
||||||
params: { slug: page.slug },
|
params: { slug: page.slug },
|
||||||
props: { page },
|
props: { page },
|
||||||
}));
|
}));
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
---
|
---
|
||||||
import PostItem from "@/components/post-item";
|
import PostItem from "@/components/post-item";
|
||||||
import Layout from "@/layouts/Layout.astro";
|
import Layout from "@/layouts/Layout.astro";
|
||||||
|
import { sortContentByDate } from "@/utils/sorts";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
|
||||||
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
|
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
|
||||||
allPosts.sort(
|
sortContentByDate(allPosts);
|
||||||
(a, b) =>
|
|
||||||
Date.parse(b.data.date.toString()) - Date.parse(a.data.date.toString()),
|
|
||||||
);
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Blog" description="Check my projects.">
|
<Layout title="Blog" description="Check my projects.">
|
||||||
@ -17,7 +15,7 @@ allPosts.sort(
|
|||||||
</section>
|
</section>
|
||||||
<ul class="mt-4 flex flex-col gap-4">
|
<ul class="mt-4 flex flex-col gap-4">
|
||||||
{
|
{
|
||||||
allPosts.map((blogpost) => (
|
allPosts.map((blogpost: any) => (
|
||||||
<li>
|
<li>
|
||||||
<PostItem
|
<PostItem
|
||||||
type="blog"
|
type="blog"
|
||||||
|
@ -3,22 +3,17 @@ import Layout from "@/layouts/Layout.astro";
|
|||||||
import LinkButton from "@/components/link-button";
|
import LinkButton from "@/components/link-button";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
import PostItem from "@/components/post-item";
|
import PostItem from "@/components/post-item";
|
||||||
|
import { sortContentByDate } from "@/utils/sorts";
|
||||||
|
|
||||||
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
|
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
|
||||||
allPosts.sort(
|
sortContentByDate(allPosts);
|
||||||
(a, b) =>
|
|
||||||
Date.parse(b.data.date.toString()) - Date.parse(a.data.date.toString()),
|
|
||||||
);
|
|
||||||
const last3Blogs = allPosts.slice(0, 3);
|
const last3Blogs = allPosts.slice(0, 3);
|
||||||
|
|
||||||
const allProjects = await getCollection(
|
const allProjects = await getCollection(
|
||||||
"portfolio",
|
"portfolio",
|
||||||
({ data }) => data.draft !== true,
|
({ data }) => data.draft !== true,
|
||||||
);
|
);
|
||||||
allProjects.sort(
|
sortContentByDate(allProjects);
|
||||||
(a, b) =>
|
|
||||||
Date.parse(b.data.date.toString()) - Date.parse(a.data.date.toString()),
|
|
||||||
);
|
|
||||||
const last3Projects = allProjects.slice(0, 3);
|
const last3Projects = allProjects.slice(0, 3);
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -46,7 +41,7 @@ const last3Projects = allProjects.slice(0, 3);
|
|||||||
<h2 class="text-3xl">Latest posts</h2>
|
<h2 class="text-3xl">Latest posts</h2>
|
||||||
<ul class="mt-4 flex flex-col gap-4">
|
<ul class="mt-4 flex flex-col gap-4">
|
||||||
{
|
{
|
||||||
last3Blogs.map((blogpost) => (
|
last3Blogs.map((blogpost: any) => (
|
||||||
<li>
|
<li>
|
||||||
<PostItem
|
<PostItem
|
||||||
type="blog"
|
type="blog"
|
||||||
@ -66,7 +61,7 @@ const last3Projects = allProjects.slice(0, 3);
|
|||||||
<h2 class="text-3xl">Latest projects</h2>
|
<h2 class="text-3xl">Latest projects</h2>
|
||||||
<ul class="mt-4 flex flex-col gap-4">
|
<ul class="mt-4 flex flex-col gap-4">
|
||||||
{
|
{
|
||||||
last3Projects.map((project) => (
|
last3Projects.map((project: any) => (
|
||||||
<li>
|
<li>
|
||||||
<PostItem
|
<PostItem
|
||||||
type="portfolio"
|
type="portfolio"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
import MicroblogItem from "@/components/microblog-item";
|
import MicroblogItem from "@/components/microblog-item.astro";
|
||||||
import Layout from "@/layouts/Layout.astro";
|
import Layout from "@/layouts/Layout.astro";
|
||||||
import { createServerClient } from "@/utils/pocketbase";
|
import { createServerClient } from "@/utils/pocketbase";
|
||||||
|
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
---
|
---
|
||||||
import PostItem from "@/components/post-item";
|
import PostItem from "@/components/post-item";
|
||||||
import Layout from "@/layouts/Layout.astro";
|
import Layout from "@/layouts/Layout.astro";
|
||||||
|
import { sortContentByDate } from "@/utils/sorts";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
|
||||||
const allProjects = await getCollection(
|
const allProjects = await getCollection(
|
||||||
"portfolio",
|
"portfolio",
|
||||||
({ data }) => data.draft !== true,
|
({ data }) => data.draft !== true,
|
||||||
);
|
);
|
||||||
allProjects.sort(
|
sortContentByDate(allProjects);
|
||||||
(a, b) =>
|
|
||||||
Date.parse(b.data.date.toString()) - Date.parse(a.data.date.toString()),
|
|
||||||
);
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Blog" description="Long format about thoughts and other topics.">
|
<Layout title="Blog" description="Long format about thoughts and other topics.">
|
||||||
@ -20,7 +18,7 @@ allProjects.sort(
|
|||||||
</section>
|
</section>
|
||||||
<ul class="mt-4 flex flex-col gap-4">
|
<ul class="mt-4 flex flex-col gap-4">
|
||||||
{
|
{
|
||||||
allProjects.map((project) => (
|
allProjects.map((project: any) => (
|
||||||
<li>
|
<li>
|
||||||
<PostItem
|
<PostItem
|
||||||
type="portfolio"
|
type="portfolio"
|
||||||
|
@ -12,7 +12,6 @@ export const navItems: TNavItem[] = [
|
|||||||
label: "Portfolio",
|
label: "Portfolio",
|
||||||
to: "/portfolio",
|
to: "/portfolio",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "Microblog",
|
label: "Microblog",
|
||||||
to: "/microblog",
|
to: "/microblog",
|
6
src/utils/sorts.ts
Normal file
6
src/utils/sorts.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export function sortContentByDate(array: any[]) {
|
||||||
|
array.sort(
|
||||||
|
(a: any, b: any) =>
|
||||||
|
Date.parse(b.data.date.toString()) - Date.parse(a.data.date.toString()),
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user