diff --git a/framework-boilerplates/vite-react/src/App.tsx b/framework-boilerplates/vite-react/src/App.tsx index afe48ac750..9d413dde11 100644 --- a/framework-boilerplates/vite-react/src/App.tsx +++ b/framework-boilerplates/vite-react/src/App.tsx @@ -1,35 +1,606 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from '/vite.svg' -import './App.css' +import React, { useMemo, useState } from "react"; -function App() { - const [count, setCount] = useState(0) +import { motion, AnimatePresence } from "framer-motion"; + +/** + * Tildópolis (Demo sin audio) + * - React + TailwindCSS + Framer Motion + * - Enfoque: comprender reglas (agudas, graves, esdrújulas) y practicar con feedback explicativo. + * - Personaje guía: Profesor Búho 🦉. + * + * Instrucciones (si exportas esto a un proyecto React): + * 1) Crea un proyecto con Vite o CRA, pega este componente y expórtalo como default. + * 2) Asegúrate de tener Tailwind configurado en el proyecto. + * 3) Importa y renderiza en tu App. + */ + +// Utilidad para quitar tildes y mostrar versión "sin ayuda" cuando convenga +const stripAccents = (s) => + s + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .replace(/ü/g, "u"); + +// Banco de palabras con su clasificación y explicación de regla +const WORDS = [ + { + base: "arbol", + correcto: "árbol", + tipo: "grave", + termina: "l", + regla: + "Es una palabra grave. Las graves llevan tilde cuando terminan en consonante que no sea n ni s. Termina en 'l', por eso lleva tilde: árbol.", + }, + { + base: "cama", + correcto: "cama", + tipo: "grave", + termina: "a", + regla: + "Es una palabra grave. Las graves NO llevan tilde cuando terminan en vocal, 'n' o 's'. Termina en vocal, por eso no lleva tilde: cama.", + }, + { + base: "camion", + correcto: "camión", + tipo: "aguda", + termina: "n", + regla: + "Es aguda. Las agudas llevan tilde cuando terminan en vocal, 'n' o 's'. Termina en 'n', por eso lleva tilde: camión.", + }, + { + base: "television", + correcto: "televisión", + tipo: "aguda", + termina: "n", + regla: + "Es aguda. Las agudas llevan tilde si terminan en vocal, 'n' o 's'. Termina en 'n', por eso: televisión.", + }, + { + base: "lapiz", + correcto: "lápiz", + tipo: "grave", + termina: "z", + regla: + "Es grave y termina en consonante que no es 'n' ni 's'. Las graves así SÍ llevan tilde: lápiz.", + }, + { + base: "papel", + correcto: "papel", + tipo: "aguda", + termina: "l", + regla: + "Es aguda, pero NO termina en vocal, 'n' ni 's'. Por eso no lleva tilde: papel.", + }, + { + base: "cafe", + correcto: "café", + tipo: "aguda", + termina: "e", + regla: + "Es aguda y termina en vocal. Las agudas así sí llevan tilde: café.", + }, + { + base: "sofa", + correcto: "sofá", + tipo: "aguda", + termina: "a", + regla: "Es aguda y termina en vocal. Por eso lleva tilde: sofá.", + }, + { + base: "reloj", + correcto: "reloj", + tipo: "aguda", + termina: "j", + regla: + "Es aguda, pero termina en consonante distinta de 'n' o 's'. No lleva tilde: reloj.", + }, + { + base: "corazon", + correcto: "corazón", + tipo: "aguda", + termina: "n", + regla: "Es aguda y termina en 'n'. Lleva tilde: corazón.", + }, + { + base: "cancion", + correcto: "canción", + tipo: "aguda", + termina: "n", + regla: "Es aguda y termina en 'n'. Lleva tilde: canción.", + }, + { + base: "paraguas", + correcto: "paraguas", + tipo: "grave", + termina: "s", + regla: + "Es grave y termina en 's'. Las graves que terminan en vocal, 'n' o 's' NO llevan tilde: paraguas.", + }, + { + base: "compas", + correcto: "compás", + tipo: "aguda", + termina: "s", + regla: + "Es aguda y termina en 's'. Las agudas que terminan en vocal, 'n' o 's' sí llevan tilde: compás.", + }, + { + base: "joven", + correcto: "joven", + tipo: "grave", + termina: "n", + regla: + "Es grave y termina en 'n'. Las graves que terminan en vocal, 'n' o 's' NO llevan tilde: joven.", + }, + { + base: "facil", + correcto: "fácil", + tipo: "grave", + termina: "l", + regla: + "Es grave y termina en consonante que no es 'n' ni 's'. Sí lleva tilde: fácil.", + }, + { + base: "limon", + correcto: "limón", + tipo: "aguda", + termina: "n", + regla: "Es aguda y termina en 'n'. Lleva tilde: limón.", + }, + { + base: "examen", + correcto: "examen", + tipo: "grave", + termina: "n", + regla: + "Es grave y termina en 'n'. Las graves que terminan en vocal, 'n' o 's' NO llevan tilde: examen.", + }, + { + base: "dibujos", + correcto: "dibujos", + tipo: "grave", + termina: "s", + regla: + "Es grave y termina en 's'. Las graves que terminan en vocal, 'n' o 's' NO llevan tilde: dibujos.", + }, + { + base: "murcielago", + correcto: "murciélago", + tipo: "esdrújula", + termina: "o", + regla: + "Es esdrújula (la sílaba tónica es la antepenúltima). ¡Todas las esdrújulas llevan tilde!: murciélago.", + }, + { + base: "telefono", + correcto: "teléfono", + tipo: "esdrújula", + termina: "o", + regla: + "Es esdrújula. Todas las esdrújulas llevan tilde: teléfono.", + }, + { + base: "rapido", + correcto: "rápido", + tipo: "esdrújula", + termina: "o", + regla: + "Es esdrújula. Todas las esdrújulas llevan tilde: rápido.", + }, + { + base: "ingles", + correcto: "inglés", + tipo: "aguda", + termina: "s", + regla: "Es aguda y termina en 's'. Lleva tilde: inglés.", + }, + { + base: "torax", + correcto: "tórax", + tipo: "grave", + termina: "x", + regla: + "Es grave y termina en consonante distinta de 'n' o 's'. Las graves así sí llevan tilde: tórax.", + }, +]; + +const RuleCard = ({ title, children }) => ( + +

{title}

+
{children}
+
+); + +const Chip = ({ children }) => ( + + {children} + +); + +const OwlSpeech = ({ children }) => ( + +
+ {children} +
+
🦉
+
+); + +function useShuffledWords() { + return useMemo(() => { + const w = [...WORDS]; + for (let i = w.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [w[i], w[j]] = [w[j], w[i]]; + } + return w; + }, []); +} + +export default function AppTildopolis() { + const [tab, setTab] = useState("learn"); // learn | practice | game + const shuffled = useShuffledWords(); return ( - <> -
- - Vite logo - - - React logo - -
-

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR -

+
+
+
+
+

+ Tildópolis 🦉 +

+

Aprende tildes con el Profesor Búho

+
+ +
+ + + {tab === "learn" && ( + +
+ +

+ ¡Hola! Soy el Profesor Búho. Hoy te enseño dónde va la tilde 🪄 +

+
    +
  • + Agudas: la voz fuerte está en la última sílaba. camión +
  • +
  • + Graves (llanas): la voz fuerte está en la penúltima. árbol +
  • +
  • + Esdrújulas: la voz fuerte está en la antepenúltima. rápido +
  • +
+
+ +
    +
  • + Agudas ➜ llevan tilde si terminan en vocal, n o s. +
  • +
  • + Graves ➜ llevan tilde si NO terminan en vocal, n o s. +
  • +
  • + Esdrújulassiempre llevan tilde. +
  • +
+
+ +
+
+

✔️ Llevan tilde

+

camión, corazón, inglés, café, lápiz, árbol, rápido

+
+
+

✖️ No llevan tilde

+

cama, papel, reloj, joven, examen, paraguas

+
+
+
+
+ + +
+ )} + + {tab === "practice" && ( + + )} + + {tab === "game" && } +
+ +
+ Hecho con ❤️ para aprender jugando. +
-

- Click on the Vite and React logos to learn more +

+ ); +} + +function LearnPlayground() { + const sample = WORDS.find((w) => w.base === "arbol"); + const [showTip, setShowTip] = useState(false); + + return ( + +

Ejemplo guiado

+

+ ¿Por qué árbol lleva tilde y cama no?

- - ) + +
+
+

+ árbol → es grave y termina en l (consonante ≠ n/s) → + lleva tilde +

+
+
+

+ cama → es grave y termina en vocal → + no lleva tilde +

+
+
+ + + + + {showTip && ( + +
+ Truco del búho: si la palabra es grave y termina en + vocal, n o s, casi nunca lleva tilde. Si termina en otra consonante, casi siempre sí. +
+
+ )} +
+
+ ); } -export default App +function Practice() { + const [index, setIndex] = useState(0); + const [score, setScore] = useState(0); + const [feedback, setFeedback] = useState(null); + const [streak, setStreak] = useState(0); + + const item = WORDS[index % WORDS.length]; + const wordWithoutAccent = stripAccents(item.correcto); + + function answer(tieneTilde) { + const correcto = item.correcto !== wordWithoutAccent; // si la forma correcta tiene tilde visual + const acierta = tieneTilde === correcto; + + setFeedback({ + ok: acierta, + msg: acierta + ? `¡Muy bien! ${item.correcto} ✓` + : `Casi. La forma correcta es ${item.correcto}.`, + regla: item.regla, + }); + + if (acierta) { + setScore((s) => s + 10); + setStreak((r) => r + 1); + } else { + setStreak(0); + } + } + + function next() { + setFeedback(null); + setIndex((i) => i + 1); + } + + return ( + +
+
+

Practica

+
Puntos: {score}
+
+ +
+

¿Esta palabra lleva tilde?

+
+ {stripAccents(item.correcto)} +
+ +
+ + +
+ + + {feedback && ( + +

{feedback.msg}

+

{feedback.regla}

+ +
+ )} +
+
+ +
+ Racha: {streak} {streak >= 3 ? "⭐" : ""} +
+
+ +
+ +
    +
  • Agudas → tilde si terminan en vocal, n o s.
  • +
  • Graves → tilde si NO terminan en vocal, n o s.
  • +
  • Esdrújulas → siempre tilde.
  • +
+
+ +

+ Di la palabra en voz alta y toca con la palma la sílaba que suena más fuerte. ¡Ahí vive la tilde si le toca! 🦉 +

+
+
+
+ ); +} + +function Game({ words }) { + const [i, setI] = useState(0); + const [points, setPoints] = useState(0); + const [msg, setMsg] = useState(""); + const w = words[i % words.length]; + + function pick(tipo) { + const ok = w.tipo === tipo; + setMsg( + ok + ? `¡Correcto! ${w.correcto} es ${w.tipo}.` + : `Ups, ${w.correcto} no es ${tipo}. Es ${w.tipo}.` + ); + setPoints((p) => p + (ok ? 10 : 0)); + } + + return ( + +
+
+

Clasifica la palabra

+
Puntos: {points}
+
+ +
+
+ {stripAccents(w.correcto)} +
+ +
+ {["aguda", "grave", "esdrújula"].map((t) => ( + + ))} +
+ + {msg && ( +
+

{msg}

+

{w.regla}

+ +
+ )} +
+
+ +
+ +
    +
  • Si la fuerza está al final, piensa en aguda (camión).
  • +
  • Si está en el medio, suele ser grave (árbol, cama).
  • +
  • Si está muy al principio, es esdrújula (rápido). +
  • +
+
+ +

Clasifica 10 palabras con 80 puntos o más para ganar la medalla 🏅

+
+
+
+ ); +}