From d0ab9db2a8a180cd2a190fdfd5a21151c6672385 Mon Sep 17 00:00:00 2001 From: juancmandev Date: Thu, 25 Jul 2024 16:03:52 -0600 Subject: [PATCH 01/22] add videos page, new video --- src/components/post-item.tsx | 2 +- src/content/config.ts | 6 + .../videos/nadie-entiende-la-privacidad.mdx | 187 ++++++++++++++++-- src/pages/blog/index.astro | 43 ++-- src/pages/portfolio/index.astro | 47 +++-- src/pages/videos/[...slug].astro | 42 ++++ src/pages/videos/index.astro | 38 ++++ src/utils/nav-links.ts | 8 +- tsconfig.json | 2 +- 9 files changed, 313 insertions(+), 62 deletions(-) create mode 100644 src/pages/videos/[...slug].astro create mode 100644 src/pages/videos/index.astro diff --git a/src/components/post-item.tsx b/src/components/post-item.tsx index d5934c7..588b597 100644 --- a/src/components/post-item.tsx +++ b/src/components/post-item.tsx @@ -5,7 +5,7 @@ type Props = { slug: string; date: Date | string; title: string; - type: "blog" | "portfolio"; + type: "blog" | "portfolio" | "videos"; }; export default function PostItem(props: Props) { diff --git a/src/content/config.ts b/src/content/config.ts index d100e44..b5f9475 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -30,8 +30,14 @@ const pages = defineCollection({ }), }); +const videos = defineCollection({ + type: "content", + schema: contentSchema +}) + export const collections = { blog, portfolio, pages, + videos }; diff --git a/src/content/videos/nadie-entiende-la-privacidad.mdx b/src/content/videos/nadie-entiende-la-privacidad.mdx index 338c396..baf8082 100644 --- a/src/content/videos/nadie-entiende-la-privacidad.mdx +++ b/src/content/videos/nadie-entiende-la-privacidad.mdx @@ -1,29 +1,184 @@ --- title: Nadie Entiende la Privacidad -description: - Hablar de privacidad es complicado, ya que no todo el mundo la entiende de - verdad. +description: Hablar de privacidad es complicado, ya que muy pocos la entienden. tags: - Tech - Freedom - Libre -image: https://img.youtube.com/vi/Wlw6rscU4gI/maxresdefault.jpg +image: /blog/how-computers-works/banner.jpg imageCaption: Video thumbnail. -date: 6/3/2024 +date: 7/25/2024 author: Juan Manzanero rss: true --- - +![Open laptop](@/assets/blog/how-computers-works/banner.jpg) _An open laptop. +Photo by +[Philipp Katzenberger](https://unsplash.com/@fantasyflip?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText') +on +[Unsplash](https://unsplash.com/photos/iIJrUoeRoCQ?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)_ -Cuando respecto a la privacidad, por lo general la respuesta de la gente es "como si tuviese algo que ocultar" o "es imposible ocultar todo lo que hacemos", y es justo a esas frases cuando digo que nadie entiende la privacidad. +## Lo que los normies dicen al escuchar "privacidad" -La privacidad es una necesidad humana, un derecho, está en nuestra naturaleza. Prueba de ello, cuando vas a un baño público, generalmente cierras la puerta, o intentas usar un espacio donde no haya gente cerca. Y es que todos sabemos qué se hace cuando se va al baño, pero todos queremos tener un momento de privacidad para hacer nuestras necesidades, ya que es algo que no queremos compartir con extraños. +"¿Por qué te interesa la privacidad?, ¿acaso haces algo ilegal?" + +"A mi no me interesa la privacidad, ni que tuviese algo que esconder." + +"De todas formas somos espiados, no vale la pena preocuparse por la privacidad." + +Estas son solo algunas de las respuestas más comunes cuando se menciona la +palabra "privacidad", pero esto solo aplica en el ecosistema digital. + +## No es que tengas algo que ocultar, la privacidad es un derecho humano + +Curioso, porque la mayoria de las personas cuando vamos al baño, cerramos la +puerta; son muy contadas las personas a las que permitiríamos entrar. + +¿Por qué?, digo, todos sabemos lo que se hace en un baño, pero aún así, es un +espacio personal donde queremos estar a solas. + +Y es que de eso se trata la privacidad, es una necesidad humana, un derecho. + +La gente confunde privacidad con secretismo, creen que por querer ocultar algo, +es porque sabemos que es malo. + +Pero ir al baño a satisfacer nuestras necesidas fisiológicas no es algo ilegal. + +Entonces, ¿por qué la gente en general es tan cínica con respecto a la +privacidad? + +## La conveniencia de los servicios de las Big Tech a cambio de tus datos + +Bueno, no es sorpresa que la mayoría de estas personas son normies, gente que +usa Windows/macOS en sus PCs, quienes usan todos los servicios "gratuitos" de +Google, Facebook, Microsoft y Apple. + +Estas empresas, las conocidas como "Big Tech" no son organizaciones sin ánimos +de lucro que crean servicios gratuitos, para nada.\_createMdxContent + +Al contrario, son de las empresas más poderosas que han existido en la historia +de la humanidad, y su valor en la bolsa no deja de crecer. + +Y es simple, aunque puedas pagar por algunas funcionalidades premium en sus +servicios, la realidad es que su verdadero producto eres **TÚ**, para ser más +específico, tus datos. + +Google Chrome y Microsoft Edge no son gratuitos, recolectan tus datos para +venderte anuncios personalizados. + +Tus fotos que guardas en Google Photos son analizadas por Google, pero dirás que +no te tomas fotos sin ropa... + +## No hizo algo ilegal, pero fue castigado + +No necesariamente debes evitar subir ese tipo de fotos (sin prejuicios), prueba +de ello está este caso de un padre de un bebé en San Francisco, California. + +En resumidas cuentas, un padre tomó fotos de los genitales de su hijo debido a +un problema, se las envió a su doctor de confianza para que realizara un +diagnóstico (esto fue durante la pandemia, en 2021). + +El problema fue que el padre tenía su celular con Android con el backup de fotos +con Google Photos, y dicha foto fue subida a los servers de Google. + +Google desde luego tiene bots que analizan las fotos que son subidas para evitar +almacenar cosas ilegales, como pornografía infantil, y es debido a esto que el +padre fue flaggeado por el algoritmo de Google como un criminal. + +Su cuenta de Google fue deshabilitada, perdió acceso a su celular y a todos sus +datos que tenía almacenados en los servicios de Google, y desde luego, Google +notificó a la policía. + +Después del juicio, el jurado declaró que no se había cometido crimen alguno, +pero Google se negó a restaurar el acceso a la cuenta del padre. + +Esta persona no tenía algo que esconder, y aún así fue castigado por una Big +Tech, no solo prohibiendo acceso a su cuenta, sino incluso notificando a la +policía. + +Y este es el problema cuando delegas tus fotos a una empresa que analiza cada +imagen que subes, estás a la merced de los "Términos y Condiciones", o en este +caso, a la interpretación de un bot de los Términos y Condiciones. + +Desde luego, nadie quiere que usen los servers de Google para guardar contenido +ilegal, pero estas medidas terminan afectando a personas que no cometieron un +crimen. + +## Preocuparse por la privacidad es como preocuparse por tu salud, poco a poco antes que sea demasiado tarde + +Lo sé, comenzar a preocuparse por la privacidad es intimidante, ya que es un +tema en el que hay que indagar bastante, ya que la mayoría de las personas son +muy ignorantes al respecto, pero no es necesario formatear todos tus drivers y +comenzar a usar alguna distro de Linux enfocada en privacidad desde el día cero. +Puedes comenzar dando pequeños pasos. + +Este tema no es uno de blanco y negro, de ignorancia total o absoluta paranoia, +es más bien un espectro, en donde puedes situarte poco a poco más del lado de la +privacidad, pero sin llegar a ser extremista. + +## Primeros pasos y alternativas + +Por ejemplo, comienza cambiando tu navegador de Internet, en lugar de Chrome o +Edge, podrías usar Brave, o mejor aún, Firefox con un User.js como BetterFox, +otra alternativa es LibreWolf, un fork de Firefox con mejoras en seguridad y +privacidad. + +Igual lo ideal es que no uses el gestor de contraseñas que viene por defecto en +tu navegador, lo ideal es que uses uno independiente como Bitwarden o Proton +Pass, estos cuentan con add-ons para navegadores basados en Chrome y Firefox. + +De igual manera un gran paso que puedes tomar es cambiando tu email en lugar de +utilizar Outlook o Gmail, una buena alternativa es Proton Mail. + +A su vez, intenta usar menos redes sociales, o como mínimo no compartas lo que +estás haciendo en ese momento, ya que puedes revelar información que no te +gustaría que sea usada en tu contra. + +## Sigue así + +Una vez que hayas tomados estos primeros pasos, lo ideal es que liberes por +completo tus dispositivos. + +En tu computadora para empezar, instalando alguna distro de Linux, una muy buena +para gente novata en Linux es Linux Mint, basada en una de las distros más +populares (Ubuntu) pero sin las malas decisiones que ha implementado Canonical +(la empresa detrás de Ubuntu). + +De igual manera tu celular es un dispositivo muy delicado, y desafortunadamente +difícil de liberar. + +Para empezar, si usas un iPhone, lo mejor que podrías hacer es jailbreakearlo, +pero no es muy viable usar un iPhone si lo que te preocupa es la privacidad. + +Y sí, Apple profesa mucho que los iPhones son seguros, pero eso es mentira +(hablaré más de esto en el futuro). + +El dispositivo ideal sería un Android, en específico un Google Pixel reciente, +ya que estos se pueden instalar un Custom ROM de Android, una buena opción es +GrapheneOS. + +Repito, no hace falta que tomes todos estos pasos de una, puedes ir poco a poco. + +## No caigas en la trampa del cinismo o el pesimismo + +Pero dirás: "las empresas ya tienen mis datos, de nada me sirve preocuparme +ahora". + +Eso es una estupidez, es como que alguien venga a golpearte y tu no te defiendas +ya que ya te golpearon; no, lo primero que haces es defenderte. + +De eso se trata la privacidad hoy en día, es un tema de defensa de los derechos, +no querer ocultar actividades ilegales. + +Curiosamente, los políticos se preocupan más por su privacidad, y no +necesariamente para ocultar sus obras de caridad, pero el gobierno es quien más +va a querer restar bloqueos para poder espiar a sus ciudadanos, tal es el caso +de Estados Unidos, o en casos más extremos; China y Corea del Norte. + +En fin, espero que con este video pienses dos veces cuando escuches a un normie +que no tiene nada que esconder, con lo cual puedes responder "si bien no tengo +algo que esconder, tampoco tengo algo en particular que quiera compartir +contigo". + +No permitas que 1984 de George Orwell pase de ser ciencia ficción a una +predicción del futuro. diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro index 82210dc..4edb269 100644 --- a/src/pages/blog/index.astro +++ b/src/pages/blog/index.astro @@ -4,27 +4,32 @@ import Layout from "@/layouts/Layout.astro"; import { sortContentByDate } from "@/utils/sorts"; import { getCollection } from "astro:content"; +const pageData = { + title: "Blog", + description: "Long format about thoughts and other topics.", +}; + const allPosts = await getCollection("blog", ({ data }) => data.draft !== true); sortContentByDate(allPosts); --- - -
-

Blog

-

Long format about thoughts and other topics.

-
- + +
+

{pageData.title}

+

{pageData.description}

+
+
    + { + allPosts.map((blogpost: any) => ( +
  • + +
  • + )) + } +
diff --git a/src/pages/portfolio/index.astro b/src/pages/portfolio/index.astro index 6a7cd77..5ce723e 100644 --- a/src/pages/portfolio/index.astro +++ b/src/pages/portfolio/index.astro @@ -4,30 +4,35 @@ import Layout from "@/layouts/Layout.astro"; import { sortContentByDate } from "@/utils/sorts"; import { getCollection } from "astro:content"; +const pageData = { + title: "Portfolio", + description: "Check my projects.", +}; + const allProjects = await getCollection( - "portfolio", - ({ data }) => data.draft !== true, + "portfolio", + ({ data }) => data.draft !== true ); sortContentByDate(allProjects); --- - -
-

Portfolio

-

Check my projects.

-
-
    - { - allProjects.map((project: any) => ( -
  • - -
  • - )) - } -
+ +
+

{pageData.title}

+

{pageData.description}

+
+
    + { + allProjects.map((project: any) => ( +
  • + +
  • + )) + } +
diff --git a/src/pages/videos/[...slug].astro b/src/pages/videos/[...slug].astro new file mode 100644 index 0000000..63f00a2 --- /dev/null +++ b/src/pages/videos/[...slug].astro @@ -0,0 +1,42 @@ +--- +import Layout from "@/layouts/Layout.astro"; +import { getCollection } from "astro:content"; +import type { CollectionEntry } from "astro:content"; +import components from "@/components/mdx/wrapper"; +import formatDate from "@/utils/format-date"; + +interface Props { + project: CollectionEntry<"videos">; +} + +export async function getStaticPaths() { + const allProjects = await getCollection( + "videos", + ({ data }) => data.draft !== true + ); + + return allProjects.map((project) => ({ + params: { slug: project.slug }, + props: { project }, + })); +} + +const { project } = Astro.props; +const { Content } = await project.render(); +--- + + +
+

{project.data.title}

+ +
+

+ Posted: + {project.data.date && formatDate(new Date(project.data.date))} +

+
+
diff --git a/src/pages/videos/index.astro b/src/pages/videos/index.astro new file mode 100644 index 0000000..f5cd636 --- /dev/null +++ b/src/pages/videos/index.astro @@ -0,0 +1,38 @@ +--- +import PostItem from "@/components/post-item"; +import Layout from "@/layouts/Layout.astro"; +import { sortContentByDate } from "@/utils/sorts"; +import { getCollection } from "astro:content"; + +const pageData = { + title: "Videos", + description: "Guiones de los videos de mi canal de YouTube.", +}; + +const allVideos = await getCollection( + "videos", + ({ data }) => data.draft !== true +); +sortContentByDate(allVideos); +--- + + +
+

{pageData.title}

+

{pageData.description}

+
+
    + { + allVideos.map((video: any) => ( +
  • + +
  • + )) + } +
+
diff --git a/src/utils/nav-links.ts b/src/utils/nav-links.ts index 31b583c..68b3925 100644 --- a/src/utils/nav-links.ts +++ b/src/utils/nav-links.ts @@ -12,6 +12,10 @@ export const navItems: TNavItem[] = [ label: "Portfolio", to: "/portfolio", }, + { + label: "Videos", + to: "/videos", + }, { label: "Microblog", to: "/microblog", @@ -20,10 +24,6 @@ export const navItems: TNavItem[] = [ label: "Resources", to: "/resources", }, - // { - // label: "Videos", - // to: "/videos", - // }, { label: "About", to: "/about", diff --git a/tsconfig.json b/tsconfig.json index 5fa2cdf..2ce6714 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,6 @@ "@/*": ["./src/*"] }, "jsx": "react-jsx", - "jsxImportSource": "react" + "jsxImportSource": "react", } } From cc65303e3f1892038264fae9e809374814ca261e Mon Sep 17 00:00:00 2001 From: juancmandev Date: Mon, 29 Jul 2024 15:40:52 -0600 Subject: [PATCH 02/22] renew navbar, edit resources page --- package.json | 2 - pnpm-lock.yaml | 444 +-------------------------- src/components/ navigation.tsx | 102 ++++++ src/components/header.astro | 42 +++ src/components/mdx/astro-image.astro | 16 +- src/components/mobile-menu.tsx | 54 ---- src/components/navbar.astro | 53 ---- src/components/ui/scroll-area.tsx | 46 --- src/components/ui/sheet.tsx | 138 --------- src/content/pages/resources.mdx | 59 ++-- src/layouts/Layout.astro | 66 ++-- src/utils/nav-links.ts | 35 --- 12 files changed, 214 insertions(+), 843 deletions(-) create mode 100644 src/components/ navigation.tsx create mode 100644 src/components/header.astro delete mode 100644 src/components/mobile-menu.tsx delete mode 100644 src/components/navbar.astro delete mode 100644 src/components/ui/scroll-area.tsx delete mode 100644 src/components/ui/sheet.tsx delete mode 100644 src/utils/nav-links.ts diff --git a/package.json b/package.json index a7fbb76..7916a69 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,6 @@ "@astrojs/sitemap": "^3.1.6", "@astrojs/tailwind": "^5.1.0", "@astrojs/vercel": "^7.7.2", - "@radix-ui/react-dialog": "^1.1.1", - "@radix-ui/react-scroll-area": "^1.1.0", "@radix-ui/react-slot": "^1.1.0", "@tailwindcss/typography": "^0.5.13", "@types/react": "^18.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8b7496..f3682d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,12 +29,6 @@ importers: '@astrojs/vercel': specifier: ^7.7.2 version: 7.7.2(astro@4.11.3(typescript@5.5.2))(react@18.3.1) - '@radix-ui/react-dialog': - specifier: ^1.1.1 - version: 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-scroll-area': - specifier: ^1.1.0 - version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-slot': specifier: ^1.1.0 version: 1.1.0(@types/react@18.3.3)(react@18.3.1) @@ -635,12 +629,6 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@radix-ui/number@1.1.0': - resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} - - '@radix-ui/primitive@1.1.0': - resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} - '@radix-ui/react-compose-refs@1.1.0': resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} peerDependencies: @@ -650,133 +638,6 @@ packages: '@types/react': optional: true - '@radix-ui/react-context@1.1.0': - resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-dialog@1.1.1': - resolution: {integrity: sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-direction@1.1.0': - resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-dismissable-layer@1.1.0': - resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-focus-guards@1.1.0': - resolution: {integrity: sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-focus-scope@1.1.0': - resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-id@1.1.0': - resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-portal@1.1.1': - resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-presence@1.1.0': - resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-primitive@2.0.0': - resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-scroll-area@1.1.0': - resolution: {integrity: sha512-9ArIZ9HWhsrfqS765h+GZuLoxaRHD/j0ZWOWilsCvYTpYJp8XwCqNG7Dt9Nu/TItKOdgLGkOPCodQvDc+UMwYg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-slot@1.1.0': resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} peerDependencies: @@ -786,42 +647,6 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-callback-ref@1.1.0': - resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-controllable-state@1.1.0': - resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-escape-keydown@1.1.0': - resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-layout-effect@1.1.0': - resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -1118,10 +943,6 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-hidden@1.2.4: - resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} - engines: {node: '>=10'} - aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -1357,9 +1178,6 @@ packages: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} - detect-node-es@1.1.0: - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - deterministic-object-hash@2.0.2: resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} engines: {node: '>=18'} @@ -1555,10 +1373,6 @@ packages: resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} engines: {node: '>=18'} - get-nonce@1.0.1: - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} - get-stream@8.0.1: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} @@ -1687,9 +1501,6 @@ packages: inline-style-parser@0.2.3: resolution: {integrity: sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==} - invariant@2.2.4: - resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} - is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} @@ -2379,36 +2190,6 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} - react-remove-scroll-bar@2.3.6: - resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - react-remove-scroll@2.5.7: - resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - react-style-singleton@2.2.1: - resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -2780,26 +2561,6 @@ packages: peerDependencies: browserslist: '>= 4.21.0' - use-callback-ref@1.3.2: - resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - use-sidecar@1.1.2: - resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -3608,133 +3369,12 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@radix-ui/number@1.1.0': {} - - '@radix-ui/primitive@1.1.0': {} - '@radix-ui/react-compose-refs@1.1.0(@types/react@18.3.3)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: '@types/react': 18.3.3 - '@radix-ui/react-context@1.1.0(@types/react@18.3.3)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.3 - - '@radix-ui/react-dialog@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.3)(react@18.3.1) - aria-hidden: 1.2.4 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.5.7(@types/react@18.3.3)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.3 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-direction@1.1.0(@types/react@18.3.3)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.3 - - '@radix-ui/react-dismissable-layer@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.3 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-focus-guards@1.1.0(@types/react@18.3.3)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.3 - - '@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.3 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-id@1.1.0(@types/react@18.3.3)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.3 - - '@radix-ui/react-portal@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.3 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-presence@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.3 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-primitive@2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-slot': 1.1.0(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.3 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-scroll-area@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.0 - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.3 - '@types/react-dom': 18.3.0 - '@radix-ui/react-slot@1.1.0(@types/react@18.3.3)(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) @@ -3742,32 +3382,6 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 - '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.3)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.3 - - '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.3)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.3 - - '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.3)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.3 - - '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.3)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.3 - '@rollup/pluginutils@4.2.1': dependencies: estree-walker: 2.0.2 @@ -4075,10 +3689,6 @@ snapshots: argparse@2.0.1: {} - aria-hidden@1.2.4: - dependencies: - tslib: 2.6.3 - aria-query@5.3.0: dependencies: dequal: 2.0.3 @@ -4363,8 +3973,6 @@ snapshots: detect-libc@2.0.3: {} - detect-node-es@1.1.0: {} - deterministic-object-hash@2.0.2: dependencies: base-64: 1.0.0 @@ -4581,8 +4189,6 @@ snapshots: get-east-asian-width@1.2.0: {} - get-nonce@1.0.1: {} - get-stream@8.0.1: {} github-slugger@2.0.0: {} @@ -4806,10 +4412,6 @@ snapshots: inline-style-parser@0.2.3: {} - invariant@2.2.4: - dependencies: - loose-envify: 1.4.0 - is-alphabetical@2.0.1: {} is-alphanumerical@2.0.1: @@ -5700,34 +5302,6 @@ snapshots: react-refresh@0.14.2: {} - react-remove-scroll-bar@2.3.6(@types/react@18.3.3)(react@18.3.1): - dependencies: - react: 18.3.1 - react-style-singleton: 2.2.1(@types/react@18.3.3)(react@18.3.1) - tslib: 2.6.3 - optionalDependencies: - '@types/react': 18.3.3 - - react-remove-scroll@2.5.7(@types/react@18.3.3)(react@18.3.1): - dependencies: - react: 18.3.1 - react-remove-scroll-bar: 2.3.6(@types/react@18.3.3)(react@18.3.1) - react-style-singleton: 2.2.1(@types/react@18.3.3)(react@18.3.1) - tslib: 2.6.3 - use-callback-ref: 1.3.2(@types/react@18.3.3)(react@18.3.1) - use-sidecar: 1.1.2(@types/react@18.3.3)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.3 - - react-style-singleton@2.2.1(@types/react@18.3.3)(react@18.3.1): - dependencies: - get-nonce: 1.0.1 - invariant: 2.2.4 - react: 18.3.1 - tslib: 2.6.3 - optionalDependencies: - '@types/react': 18.3.3 - react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -6147,7 +5721,8 @@ snapshots: optionalDependencies: typescript: 5.5.2 - tslib@2.6.3: {} + tslib@2.6.3: + optional: true type-fest@2.19.0: {} @@ -6225,21 +5800,6 @@ snapshots: escalade: 3.1.2 picocolors: 1.0.1 - use-callback-ref@1.3.2(@types/react@18.3.3)(react@18.3.1): - dependencies: - react: 18.3.1 - tslib: 2.6.3 - optionalDependencies: - '@types/react': 18.3.3 - - use-sidecar@1.1.2(@types/react@18.3.3)(react@18.3.1): - dependencies: - detect-node-es: 1.1.0 - react: 18.3.1 - tslib: 2.6.3 - optionalDependencies: - '@types/react': 18.3.3 - util-deprecate@1.0.2: {} vfile-location@5.0.2: diff --git a/src/components/ navigation.tsx b/src/components/ navigation.tsx new file mode 100644 index 0000000..1891976 --- /dev/null +++ b/src/components/ navigation.tsx @@ -0,0 +1,102 @@ +import LinkButton from "@/components/link-button"; +import { + NotebookText, + BriefcaseBusiness, + MonitorPlay, + Newspaper, + PocketKnife, + Info, + Mail, +} from "lucide-react"; + +type TNavItem = { + to: string; + child: React.ReactNode; +}; + +export const navItems: TNavItem[] = [ + { + to: "/blog", + child: ( + <> + + Blog + + ), + }, + { + to: "/portfolio", + child: ( + <> + + Portfolio + + ), + }, + { + to: "/videos", + child: ( + <> + + Videos + + ), + }, + { + to: "/microblog", + child: ( + <> + + Microblog + + ), + }, + { + to: "/resources", + child: ( + <> + + Resources + + ), + }, + { + to: "/about", + child: ( + <> + + About + + ), + }, + { + to: "/contact", + child: ( + <> + + Contact + + ), + }, +]; + +export default function Navigation() { + return ( + + ); +} diff --git a/src/components/header.astro b/src/components/header.astro new file mode 100644 index 0000000..eed1a9e --- /dev/null +++ b/src/components/header.astro @@ -0,0 +1,42 @@ +--- +import logo from "@/assets/logo.png"; +import { Image } from "astro:assets"; +import LinkButton from "@/components/link-button"; +import { ChevronUp, Compass } from "lucide-react"; +--- + +
+
+
+ + juancmandev logo + +
+
+ + + Top + + + + Navigation + +
+
+
diff --git a/src/components/mdx/astro-image.astro b/src/components/mdx/astro-image.astro index f2b2806..ad01068 100644 --- a/src/components/mdx/astro-image.astro +++ b/src/components/mdx/astro-image.astro @@ -5,16 +5,16 @@ const { src, alt } = Astro.props; --- {alt} diff --git a/src/components/mobile-menu.tsx b/src/components/mobile-menu.tsx deleted file mode 100644 index 274934d..0000000 --- a/src/components/mobile-menu.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { ScrollArea } from "@/components/ui/scroll-area"; -import { - Sheet, - SheetContent, - SheetHeader, - SheetTrigger, - SheetClose, -} from "@/components/ui/sheet"; -import { MenuIcon } from "lucide-react"; -import { navItems } from "@/utils/nav-links"; -import { Button } from "@/components/ui/button"; - -export default function MobileMenu() { - return ( - - - - - - - - - - - - - ); -} diff --git a/src/components/navbar.astro b/src/components/navbar.astro deleted file mode 100644 index 2a8bc31..0000000 --- a/src/components/navbar.astro +++ /dev/null @@ -1,53 +0,0 @@ ---- -import logo from "@/assets/logo.png"; -import { Image } from "astro:assets"; -import { navItems } from "@/utils/nav-links"; -import MobileMenu from "@/components/mobile-menu"; -import LinkButton from "@/components/link-button"; ---- - - diff --git a/src/components/ui/scroll-area.tsx b/src/components/ui/scroll-area.tsx deleted file mode 100644 index cf253cf..0000000 --- a/src/components/ui/scroll-area.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from "react" -import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area" - -import { cn } from "@/lib/utils" - -const ScrollArea = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - - {children} - - - - -)) -ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName - -const ScrollBar = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, orientation = "vertical", ...props }, ref) => ( - - - -)) -ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName - -export { ScrollArea, ScrollBar } diff --git a/src/components/ui/sheet.tsx b/src/components/ui/sheet.tsx deleted file mode 100644 index d64a6fa..0000000 --- a/src/components/ui/sheet.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import * as React from "react" -import * as SheetPrimitive from "@radix-ui/react-dialog" -import { cva, type VariantProps } from "class-variance-authority" -import { X } from "lucide-react" - -import { cn } from "@/lib/utils" - -const Sheet = SheetPrimitive.Root - -const SheetTrigger = SheetPrimitive.Trigger - -const SheetClose = SheetPrimitive.Close - -const SheetPortal = SheetPrimitive.Portal - -const SheetOverlay = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -SheetOverlay.displayName = SheetPrimitive.Overlay.displayName - -const sheetVariants = cva( - "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500", - { - variants: { - side: { - top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", - bottom: - "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", - left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", - right: - "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", - }, - }, - defaultVariants: { - side: "right", - }, - } -) - -interface SheetContentProps - extends React.ComponentPropsWithoutRef, - VariantProps {} - -const SheetContent = React.forwardRef< - React.ElementRef, - SheetContentProps ->(({ side = "right", className, children, ...props }, ref) => ( - - - - {children} - - - Close - - - -)) -SheetContent.displayName = SheetPrimitive.Content.displayName - -const SheetHeader = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-) -SheetHeader.displayName = "SheetHeader" - -const SheetFooter = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-) -SheetFooter.displayName = "SheetFooter" - -const SheetTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -SheetTitle.displayName = SheetPrimitive.Title.displayName - -const SheetDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -SheetDescription.displayName = SheetPrimitive.Description.displayName - -export { - Sheet, - SheetPortal, - SheetOverlay, - SheetTrigger, - SheetClose, - SheetContent, - SheetHeader, - SheetFooter, - SheetTitle, - SheetDescription, -} diff --git a/src/content/pages/resources.mdx b/src/content/pages/resources.mdx index a7e282a..103b803 100644 --- a/src/content/pages/resources.mdx +++ b/src/content/pages/resources.mdx @@ -1,30 +1,31 @@ --- title: Resources -description: Here you can find websites, YouTube channels, courses and more stuff that I consume or find interesting. +description: + Here you can find websites, YouTube channels, courses and more stuff that I + consume or find interesting. --- # Resources -Here you can find websites, YouTube channels, courses and more stuff that I -consume or find interesting. +Here you can find **websites**, **YouTube channels**, **courses** and **more** +stuff that I consume or find interesting. -## Programming and Web Development +## Courses and Documentation -To **power-up** my career. +- [fireship.io](https://fireship.io) -### Websites (courses, docs, etc.) +- [MDN Web Docs](https://developer.mozilla.org/en-US) -- [fireship.io](https://fireship.io) - My favorite premium courses about WebDev +## Tech Stack -- [MDN Web Docs](https://developer.mozilla.org/en-US) - Best docs for HTML, CSS - and JS - -### Tech Stack - -Technologies that I use for personal projects and sometimes for work. +- [Astro](https://astro.build/) - Tool for building websites, that's how I built + this one, really useful when you want a static website, but you can do Server + Side Rendering too - [Next.js](https://nextjs.org) - Dynamic and flexible React meta-framework, - used on this Website + previously used on this Website + +- [PocketBase](https://pocketbase.io/) - Fast and light database. - [Supabase](https://supabase.com) - Open Source Backend as a Service alternative for Firebase, uses PostgreSQL and is really good if you're working @@ -35,34 +36,26 @@ Technologies that I use for personal projects and sometimes for work. - [shadcn/ui](https://ui.shadcn.com) - Best components for React, sinergy with TailwindCSS +## YouTube channels -### YouTube channels +- [Mental Outlaw](https://www.youtube.com/channel/UC7YOGHUfC1Tb6E4pudI9STA) -I mostly use YouTube as social media, I think there is still good content. +- [Eric Murphy](https://www.youtube.com/channel/UC5KDiSAFxrDWhmysBcNqtMA) -- [Mental Outlaw](https://www.youtube.com/channel/UC7YOGHUfC1Tb6E4pudI9STA) - Cool guy who talks about Linux, cybersecurity, privacy, and more. +- [Luck Smith](https://www.youtube.com/channel/UC2eYFnH61tmytImy1mTYvhA) -- [Eric Murphy](https://www.youtube.com/channel/UC5KDiSAFxrDWhmysBcNqtMA) - He uploads less videos but I really like his work too. +## Personal Websites ---- +- [Eric Murphy](https://ericmurphy.xyz) -## Inspiration and Learning +- [Luke Smith](https://lukesmith.xyz/) -For writing, thinking or growing my career. +## Favorite Blogs -### Personal Websites - -- [Eric Murphy](https://ericmurphy.xyz) - The guy who inspired me to retake this - side project and create more content - -### Favorite Blogs - -- [Why I Will Never Join Mastodon (or the rest of the Fediverse)](https://ericmurphy.xyz/blog/mastodon) - - Social media is bullshit +- [Why I Will Never Join Mastodon (or the rest of the Fediverse)](https://ericmurphy.xyz/blog/mastodon) - [Create More, Consume Less](https://www.bikobatanari.art/posts/2020/create-more) - - Today people prefers talk about celebrities and other peoples lifes rather - than our own milestones + _Currently offline_ - [My Website is a Personal Museum](https://www.bikobatanari.art/posts/2020/personal-museum) - - The digital form of the three house + _Currently offline_ diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 2252a4d..1c6f461 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -1,12 +1,13 @@ --- +import Header from "@/components/header.astro"; +import Navigation from "@/components/ navigation"; import Footer from "@/components/footer"; -import Navbar from "@/components/navbar.astro"; import "@/styles/globals.css"; interface Props { - title: string; - description: string; - lang?: string; + title: string; + description: string; + lang?: string; } const { title, description, lang } = Astro.props; @@ -14,32 +15,33 @@ const { title, description, lang } = Astro.props; - - - - - - - - - - {title} - - - -
- -
-
- + + + + + + + + + + {title} + + +
+
+ +
+ +
+ diff --git a/src/utils/nav-links.ts b/src/utils/nav-links.ts deleted file mode 100644 index 68b3925..0000000 --- a/src/utils/nav-links.ts +++ /dev/null @@ -1,35 +0,0 @@ -type TNavItem = { - label: string; - to: string; -}; - -export const navItems: TNavItem[] = [ - { - label: "Blog", - to: "/blog", - }, - { - label: "Portfolio", - to: "/portfolio", - }, - { - label: "Videos", - to: "/videos", - }, - { - label: "Microblog", - to: "/microblog", - }, - { - label: "Resources", - to: "/resources", - }, - { - label: "About", - to: "/about", - }, - { - label: "Contact", - to: "/contact", - }, -]; From 56f20e167a76f26a052a0d38600f40dad5f2ef14 Mon Sep 17 00:00:00 2001 From: juancmandev Date: Tue, 30 Jul 2024 08:31:55 -0600 Subject: [PATCH 03/22] fix Luke's name --- src/content/pages/resources.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/pages/resources.mdx b/src/content/pages/resources.mdx index 103b803..71a3e38 100644 --- a/src/content/pages/resources.mdx +++ b/src/content/pages/resources.mdx @@ -42,7 +42,7 @@ stuff that I consume or find interesting. - [Eric Murphy](https://www.youtube.com/channel/UC5KDiSAFxrDWhmysBcNqtMA) -- [Luck Smith](https://www.youtube.com/channel/UC2eYFnH61tmytImy1mTYvhA) +- [Luke Smith](https://www.youtube.com/channel/UC2eYFnH61tmytImy1mTYvhA) ## Personal Websites From 16f07bf63bc82b5e1691f2853dca5014efec11ca Mon Sep 17 00:00:00 2001 From: juancmandev Date: Tue, 30 Jul 2024 22:37:03 -0600 Subject: [PATCH 04/22] start to add spanish content again --- src/components/footer.tsx | 6 +- src/components/header.astro | 40 +++++- src/components/link-button.tsx | 2 + src/components/mdx/astro-image.astro | 2 +- src/components/mdx/copy-button.tsx | 42 ------- .../{ navigation.tsx => navigation.tsx} | 10 +- src/components/post-item.tsx | 2 +- src/layouts/Layout.astro | 14 +-- src/pages/404.astro | 16 +-- src/pages/[...slug].astro | 20 +-- src/pages/blog/[...slug].astro | 38 +++--- src/pages/blog/index.astro | 2 +- src/pages/es/index.astro | 20 +++ src/pages/{ => es}/videos/[...slug].astro | 0 src/pages/{ => es}/videos/index.astro | 2 +- src/pages/index.astro | 119 +++++++++--------- src/pages/microblog.astro | 37 +++--- src/pages/portfolio/[...slug].astro | 42 ++++--- src/pages/portfolio/index.astro | 2 +- 19 files changed, 217 insertions(+), 199 deletions(-) delete mode 100644 src/components/mdx/copy-button.tsx rename src/components/{ navigation.tsx => navigation.tsx} (91%) create mode 100644 src/pages/es/index.astro rename src/pages/{ => es}/videos/[...slug].astro (100%) rename src/pages/{ => es}/videos/index.astro (96%) diff --git a/src/components/footer.tsx b/src/components/footer.tsx index dd84324..5e82f0e 100644 --- a/src/components/footer.tsx +++ b/src/components/footer.tsx @@ -2,7 +2,11 @@ import { Code, RssIcon } from "lucide-react"; import { Button } from "@/components/ui/button"; import formatDate from "@/utils/format-date"; -export default function Footer() { +type Props = { + lang: "en" | "es"; +}; + +export default function Footer(props: Props) { return (
diff --git a/src/components/header.astro b/src/components/header.astro index eed1a9e..c1624ac 100644 --- a/src/components/header.astro +++ b/src/components/header.astro @@ -3,6 +3,27 @@ import logo from "@/assets/logo.png"; import { Image } from "astro:assets"; import LinkButton from "@/components/link-button"; import { ChevronUp, Compass } from "lucide-react"; + +type Props = { + lang: "en" | "es"; +}; + +const locales = { + en: { + to: "/es", + switch_language: "🇲🇽", + top: "Top", + navigation: "Navigation", + }, + es: { + to: "/", + switch_language: "🇺🇸", + top: "Arriba", + navigation: "Navevación", + }, +} as const; + +const { lang } = Astro.props; ---
-
- - - Top +
+ + {locales[lang].switch_language} - + + + {locales[lang].top} + + - Navigation + {locales[lang].navigation}
diff --git a/src/components/link-button.tsx b/src/components/link-button.tsx index c461b57..0b50a50 100644 --- a/src/components/link-button.tsx +++ b/src/components/link-button.tsx @@ -2,6 +2,7 @@ import { Button } from "@/components/ui/button"; type Props = { children: React.ReactNode; + title?: string; href: string; variant?: | "default" @@ -21,6 +22,7 @@ export default function LinkButton(props: Props) {