From 39f2f2968ae969870efc2e6a7342d4247f0ad947 Mon Sep 17 00:00:00 2001 From: Agustin Kassis Date: Mon, 20 Apr 2026 13:35:49 -0300 Subject: [PATCH 01/11] chore: remove workshops page No longer shipping the Talleres page. Drops the entire app/workshops directory and its references from the navbar, footer and layout keywords. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/layout.tsx | 1 - app/workshops/WorkshopsList.tsx | 243 -------------------------------- app/workshops/page.tsx | 32 ----- components/Footer.tsx | 1 - components/Navbar.tsx | 1 - 5 files changed, 278 deletions(-) delete mode 100644 app/workshops/WorkshopsList.tsx delete mode 100644 app/workshops/page.tsx diff --git a/app/layout.tsx b/app/layout.tsx index 5d1af19..3ca867b 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -39,7 +39,6 @@ export const metadata: Metadata = { "Argentina", "LaWallet", "Hackatón", - "Taller", "Blossom", ], authors: [{ name: "La Crypta Labs" }], diff --git a/app/workshops/WorkshopsList.tsx b/app/workshops/WorkshopsList.tsx deleted file mode 100644 index a7ecba2..0000000 --- a/app/workshops/WorkshopsList.tsx +++ /dev/null @@ -1,243 +0,0 @@ -"use client"; - -import { motion } from "framer-motion"; -import { useState } from "react"; -import { ArrowRight, Clock, Globe, MapPin, Users } from "lucide-react"; -import { cn } from "@/lib/cn"; - -type Workshop = { - id: string; - title: string; - level: "Principiante" | "Intermedio" | "Avanzado"; - topic: "bitcoin" | "lightning" | "nostr" | "crypto"; - duration: string; - format: "presencial" | "online" | "híbrido"; - description: string; - instructor: string; - seats?: string; - next?: string; -}; - -const WORKSHOPS: Workshop[] = [ - { - id: "bitcoin-101", - title: "Bitcoin 101 — Tu primer sat", - level: "Principiante", - topic: "bitcoin", - duration: "3h", - format: "híbrido", - description: - "Wallets, direcciones, fees, mempool. Salís con tus primeros sats, un backup que entendés y el coraje para gastarlos.", - instructor: "Lucas M.", - seats: "30 cupos", - next: "26 Abr", - }, - { - id: "lightning-dev", - title: "Lightning para desarrolladores", - level: "Intermedio", - topic: "lightning", - duration: "6h · 2 sesiones", - format: "híbrido", - description: - "BOLT11, BOLT12, LNURL y Nostr Wallet Connect — integraciones prácticas con LND y CLN.", - instructor: "Ana P.", - seats: "20 cupos", - next: "3 May", - }, - { - id: "nostr-apps", - title: "Construí una app Nostr en un finde", - level: "Intermedio", - topic: "nostr", - duration: "8h · 2 sesiones", - format: "híbrido", - description: - "Del repo en blanco a una app Nostr en producción — NIP-01, NIP-07, relays, zaps y deploy.", - instructor: "Martín R.", - seats: "25 cupos", - next: "11 May", - }, - { - id: "self-custody", - title: "Autocustodia, de cero a hardware", - level: "Principiante", - topic: "bitcoin", - duration: "4h", - format: "presencial", - description: - "Frases semilla, passphrases, multisig, hardware wallets. Con equipos reales en la mano.", - instructor: "Clara G.", - seats: "15 cupos", - next: "18 May", - }, - { - id: "running-ln-node", - title: "Operar un nodo Lightning", - level: "Avanzado", - topic: "lightning", - duration: "6h", - format: "presencial", - description: - "Elegí canales, administrá liquidez, mantenete online. Te vas con un plan y una guía para abrir.", - instructor: "Tomás F.", - seats: "12 cupos", - next: "1 Jun", - }, - { - id: "crypto-primitives", - title: "Criptografía para builders", - level: "Intermedio", - topic: "crypto", - duration: "4h", - format: "online", - description: - "Hashes, firmas, secp256k1, Schnorr. Justo la matemática necesaria, mucha intuición.", - instructor: "Silvina O.", - seats: "Abierto", - next: "8 Jun", - }, - { - id: "taproot-miniscript", - title: "Taproot y Miniscript", - level: "Avanzado", - topic: "bitcoin", - duration: "5h", - format: "presencial", - description: - "Diseñá políticas de gasto reales, escribí Miniscript, debuggealo en el mempool.", - instructor: "Diego A.", - seats: "15 cupos", - next: "15 Jun", - }, - { - id: "nip46-bunker", - title: "NIP-46 firma remota a fondo", - level: "Avanzado", - topic: "nostr", - duration: "3h", - format: "online", - description: - "Arquitectura, modelo de amenazas y una implementación de referencia de un firmante remoto de Nostr.", - instructor: "Federico L.", - seats: "Abierto", - next: "22 Jun", - }, -]; - -const TOPIC_STYLE: Record = { - bitcoin: "bg-bitcoin/10 text-bitcoin border-bitcoin/30", - lightning: "bg-lightning/10 text-lightning border-lightning/30", - nostr: "bg-nostr/10 text-nostr border-nostr/30", - crypto: "bg-cyan/10 text-cyan border-cyan/30", -}; - -const LEVEL_STYLE: Record = { - Principiante: "bg-success/10 text-success border-success/30", - Intermedio: "bg-cyan/10 text-cyan border-cyan/30", - Avanzado: "bg-nostr/10 text-nostr border-nostr/30", -}; - -const TOPICS: { id: Workshop["topic"] | "all"; label: string }[] = [ - { id: "all", label: "Todos los temas" }, - { id: "bitcoin", label: "Bitcoin" }, - { id: "lightning", label: "Lightning" }, - { id: "nostr", label: "Nostr" }, - { id: "crypto", label: "Cripto" }, -]; - -export default function WorkshopsList() { - const [topic, setTopic] = useState<(typeof TOPICS)[number]["id"]>("all"); - const filtered = - topic === "all" ? WORKSHOPS : WORKSHOPS.filter((w) => w.topic === topic); - - return ( -
-
- {TOPICS.map((t) => { - const active = topic === t.id; - return ( - - ); - })} -
- -
- {filtered.map((w, i) => ( - -
- - {w.topic} - - - {w.level} - -
- -

- {w.title} -

-

- {w.description} -

- -
-
- - {w.duration} -
-
- {w.format === "online" ? ( - - ) : ( - - )} - {w.format} -
-
- - {w.seats ?? "Abierto"} -
-
- Próximo: {w.next} -
-
- - -
- ))} -
-
- ); -} diff --git a/app/workshops/page.tsx b/app/workshops/page.tsx deleted file mode 100644 index 37a7ae3..0000000 --- a/app/workshops/page.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import type { Metadata } from "next"; -import PageHero from "@/components/ui/PageHero"; -import WorkshopsList from "./WorkshopsList"; -import { GraduationCap } from "lucide-react"; - -export const metadata: Metadata = { - title: "Talleres", - description: - "Talleres gratuitos sobre Bitcoin, Lightning, Nostr y criptografía — dictados por la gente que los construye.", -}; - -export default function WorkshopsPage() { - return ( - <> - } - title={ - <> - Aprendé haciendo. - - } - description="Talleres prácticos para todos los niveles — desde tu primera transacción hasta operar tu propio nodo Lightning. Gratis, abiertos y grabados." - /> -
-
- -
-
- - ); -} diff --git a/components/Footer.tsx b/components/Footer.tsx index 336ac03..63ffac6 100644 --- a/components/Footer.tsx +++ b/components/Footer.tsx @@ -16,7 +16,6 @@ const COLS = [ title: "Comunidad", links: [ { href: "/hackathons", label: "Hackatones" }, - { href: "/workshops", label: "Talleres" }, { href: "https://lacrypta.ar", label: "La Crypta", diff --git a/components/Navbar.tsx b/components/Navbar.tsx index 9e25693..65797f6 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -17,7 +17,6 @@ const NAV_LINKS = [ { href: "/infrastructure", label: "Infraestructura" }, { href: "/projects", label: "Proyectos" }, { href: "/hackathons", label: "Hackatones" }, - { href: "/workshops", label: "Talleres" }, ]; export default function Navbar() { From 9fa3813ece7e976d4c697c4c2b55cbcf66daa6ea Mon Sep 17 00:00:00 2001 From: Agustin Kassis Date: Mon, 20 Apr 2026 13:36:04 -0300 Subject: [PATCH 02/11] style(logo): larger bolder LABS wordmark aligned to baseline Bumps LABS from 11px to 14px (~27%), switches to font-black and uses self-end with a small bottom margin so its baseline lines up with the "la crypta" descent instead of the SVG vertical center. Co-Authored-By: Claude Opus 4.7 (1M context) --- components/Logo.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/Logo.tsx b/components/Logo.tsx index a22f520..832430a 100644 --- a/components/Logo.tsx +++ b/components/Logo.tsx @@ -54,7 +54,7 @@ export default function Logo({ ))} {showLabs && ( - + LABS )} From 36b6b587111da697d6b37711a506b7a6e255a56e Mon Sep 17 00:00:00 2001 From: Agustin Kassis Date: Mon, 20 Apr 2026 13:36:50 -0300 Subject: [PATCH 03/11] feat(toast): global toast notification system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context-based Toast provider mounted at the root so any component can fire notifications from anywhere. Three kinds — error, success, info — stack at top-right with framer-motion animations. Errors default to 10s, others 4s, and duration:0 makes them sticky. Sits at z-[200] so it renders above modals. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/layout.tsx | 9 ++- components/Toast.tsx | 153 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 components/Toast.tsx diff --git a/app/layout.tsx b/app/layout.tsx index 3ca867b..561ba26 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -3,6 +3,7 @@ import { Inter, Space_Grotesk, JetBrains_Mono } from "next/font/google"; import "./globals.css"; import Navbar from "@/components/Navbar"; import Footer from "@/components/Footer"; +import { ToastProvider } from "@/components/Toast"; const inter = Inter({ variable: "--font-inter", @@ -69,9 +70,11 @@ export default function RootLayout({ className={`${inter.variable} ${spaceGrotesk.variable} ${jetbrainsMono.variable} h-full antialiased scroll-smooth`} > - -
{children}
-