import React, { useState, createContext, useContext } from 'react';
import { View, Text, Pressable } from 'react-native';
import { ThemeProvider, useT, T, Screen, Scroll, Header, NavBar, Card, Group, Row, Button, Chip, Pill, Stat, Ring, Bars, Progress, Avatar, TabBar, Tabs, Stack, Icon, Spacer, SectionTitle, Gradient, alpha } from './ui/kit';
const ACCENT = '#22C55E';
const THEME = { dark: { bg: '#07110A', card: '#0F1D13', card2: '#182A1D', line: '#1B2F20', text2: '#93B09A', text3: '#58715E' }, light: { bg: '#EEF7F0', card: '#FFFFFF', card2: '#DCEBDF' } };
const UNITS = [
{ id: 1, name: 'Greetings', icon: 'Hand', c: '#22C55E', done: 5, total: 5 },
{ id: 2, name: 'Café orders', icon: 'Coffee', c: '#F59E42', done: 3, total: 5 },
{ id: 3, name: 'Directions', icon: 'Navigation', c: '#38BDF8', done: 1, total: 5 },
{ id: 4, name: 'Numbers', icon: 'Hash', c: '#A78BFA', done: 0, total: 5 },
{ id: 5, name: 'At the market', icon: 'ShoppingBag', c: '#FF6B9D', done: 0, total: 5 },
];
const QUIZ = [
{ q: 'How do you say "a coffee, please"?', a: ['Un café, por favor', 'Una mesa, por favor', 'La cuenta, por favor', 'Buenos días'], ok: 0 },
{ q: 'What does "la cuenta" mean?', a: ['The table', 'The bill', 'The menu', 'The water'], ok: 1 },
{ q: 'Pick the translation of "to the left"', a: ['A la derecha', 'Todo recto', 'A la izquierda', 'Aquí'], ok: 2 },
];
const Store = createContext(null);
function LearnScreen({ nav }) {
const t = useT();
const { xp } = useContext(Store);
return (
} />
{Math.min(50, xp)}
{xp >= 50 ? 'Daily goal reached' : (50 - xp) + ' XP to your daily goal'}
One short lesson keeps the 14 day streak alive.
{UNITS.map((u, i) => {
const locked = i > 0 && UNITS[i - 1].done < UNITS[i - 1].total;
const current = !locked && u.done < u.total;
return (
nav.push('lesson', { id: u.id })} style={({ pressed }) => [{ alignItems: 'center', marginLeft: (i % 2 ? 90 : -90) }, pressed && { transform: [{ scale: 0.95 }] }]}>
= u.total ? 'Check' : u.icon} size={28} color={locked ? t.text3 : '#fff'} strokeWidth={2.4} />
{u.name}
{current ? : null}
);
})}
);
}
function PracticeScreen({ nav }) {
const t = useT();
return (
{}} />
{}} />
{}} />
{}} />
{[['Ser vs estar', 0.55], ['Numbers 20 to 100', 0.62], ['Past tense', 0.4]].map((w) => (
{w[0]}{Math.round(w[1] * 100)}%
))}
);
}
function LeagueScreen() {
const t = useT();
const people = [['Lena Park', 1240, '#A78BFA'], ['You', 1180, ACCENT], ['Sam Ortiz', 1120, '#F59E42'], ['Noah Reed', 980, '#38BDF8'], ['Ava Chen', 940, '#FF6B9D'], ['Dana Reyes', 870, '#E8B04B']];
return (
Top 3 promote to Diamond. You are 60 XP behind first.
{people.map((p, i) => {i + 1}
} title={p[0]} titleStyle={p[0] === 'You' ? { color: ACCENT, fontWeight: '700' } : null} value={p[1] + ' XP'} />)}
);
}
function Lesson({ nav, params }) {
const t = useT();
const { addXp } = useContext(Store);
const u = UNITS.find((x) => x.id === params.id) || UNITS[1];
const [i, setI] = useState(0);
const [pick, setPick] = useState(null);
const [score, setScore] = useState(0);
const q = QUIZ[i];
const finished = i >= QUIZ.length;
const answer = (j) => { if (pick != null) return; setPick(j); if (j === q.ok) setScore((s) => s + 1); };
const next = () => { if (i + 1 >= QUIZ.length) addXp(10 + score * 5); setI(i + 1); setPick(null); };
return (
} />
{finished ? (
Lesson complete
{score} of {QUIZ.length} correct · +{10 + score * 5} XP
) : (
Question {i + 1} of {QUIZ.length}
{q.q}
{q.a.map((a, j) => {
const state = pick == null ? 'idle' : j === q.ok ? 'ok' : j === pick ? 'bad' : 'dim';
const bg = state === 'ok' ? alpha(t.success, 0.2) : state === 'bad' ? alpha(t.danger, 0.2) : t.card;
const border = state === 'ok' ? t.success : state === 'bad' ? t.danger : 'transparent';
return (
answer(j)} style={({ pressed }) => [{ backgroundColor: bg, borderRadius: 18, padding: 16, borderWidth: 2, borderColor: border, flexDirection: 'row', alignItems: 'center', gap: 12, opacity: state === 'dim' ? 0.5 : 1 }, pressed && pick == null && { transform: [{ scale: 0.98 }] }]}>
{j + 1}
{a}
{state === 'ok' ? : state === 'bad' ? : null}
);
})}
{pick != null ? (
{pick === q.ok ? 'Correct' : 'Not quite'}
{q.a[q.ok]}
) : null}
)}
);
}
function Root({ nav }) {
const [tab, setTab] = useState('learn');
return (
, practice: , league: }} />
);
}
const SCREENS = { root: Root, lesson: Lesson };
export default function App() {
const [xp, setXp] = useState(30);
const addXp = (n) => setXp((x) => x + n);
return (
);
}