Untitled
unknown
plain_text
a month ago
14 kB
1
Indexable
import React, { useState } from 'react';
import { Check, X, RotateCcw } from 'lucide-react';
const FrenchVocabApp = () => {
const vocabulary = [
{ nl: "de activiteit", fr: "l'activité", gender: "f" },
{ nl: "de anorak", fr: "l'anorak", gender: "m" },
{ nl: "de bikini", fr: "le bikini", gender: "m" },
{ nl: "de pet", fr: "la casquette", gender: "f" },
{ nl: "de wandelschoen", fr: "la chaussure de marche", gender: "f" },
{ nl: "de kust", fr: "la côte", gender: "f" },
{ nl: "de zonnebrandcrème", fr: "la crème solaire", gender: "f" },
{ nl: "de veldfles", fr: "la gourde", gender: "f" },
{ nl: "de regenjas", fr: "l'imper", gender: "m" },
{ nl: "het internet", fr: "l'internet", gender: "m" },
{ nl: "de verrekijker", fr: "les jumelles", gender: "f" },
{ nl: "het boek", fr: "le livre", gender: "m" },
{ nl: "de zonnebril", fr: "les lunettes de soleil", gender: "f" },
{ nl: "het zwempak", fr: "le maillot de bain", gender: "m" },
{ nl: "de zee", fr: "la mer", gender: "f" },
{ nl: "de berg", fr: "la montagne", gender: "f" },
{ nl: "het museum", fr: "le musée", gender: "m" },
{ nl: "de paraplu", fr: "le parapluie", gender: "m" },
{ nl: "het park", fr: "le parc", gender: "m" },
{ nl: "het zwembad", fr: "la piscine", gender: "f" },
{ nl: "het ijs", fr: "la glace", gender: "f" },
{ nl: "het strand", fr: "la plage", gender: "f" },
{ nl: "de rivier", fr: "la rivière", gender: "f" },
{ nl: "de rugzak", fr: "le sac à dos", gender: "m" },
{ nl: "het shoppen", fr: "le shopping", gender: "m" },
{ nl: "de zwemshort", fr: "le short de bain", gender: "m" },
{ nl: "de vakantie", fr: "les vacances", gender: "f" },
{ nl: "het dorp", fr: "le village", gender: "m" },
{ nl: "de reis", fr: "le voyage", gender: "m" },
{ nl: "het klimmen in bomen", fr: "l'accrobranche", gender: "f" },
{ nl: "het beachvolley", fr: "le beachvolley", gender: "m" },
{ nl: "het wielrennen", fr: "le cyclisme", gender: "m" },
{ nl: "het klimmen", fr: "l'escalade", gender: "f" },
{ nl: "het voetbal", fr: "le foot", gender: "m" },
{ nl: "het padel", fr: "le padel", gender: "m" },
{ nl: "de wandeling", fr: "la randonnée", gender: "f" },
{ nl: "het snowboarden", fr: "le snowboard", gender: "m" },
{ nl: "het skiën", fr: "le ski", gender: "m" },
{ nl: "het paragliden", fr: "le parapente", gender: "m" },
{ nl: "de maand", fr: "le mois", gender: "m" },
{ nl: "de week", fr: "la semaine", gender: "f" },
{ nl: "het weekend", fr: "le weekend", gender: "m" },
{ nl: "het weer", fr: "le temps", gender: "m" },
{ nl: "de herfst", fr: "l'automne", gender: "m" },
{ nl: "in de herfst", fr: "en automne", gender: null },
{ nl: "de winter", fr: "l'hiver", gender: "m" },
{ nl: "in de winter", fr: "en hiver", gender: null },
{ nl: "de zomer", fr: "l'été", gender: "m" },
{ nl: "in de zomer", fr: "en été", gender: null },
{ nl: "de lente", fr: "le printemps", gender: "m" },
{ nl: "in de lente", fr: "au printemps", gender: null },
{ nl: "Duitsland", fr: "l'Allemagne", gender: "f" },
{ nl: "Oostenrijk", fr: "l'Autriche", gender: "f" },
{ nl: "België", fr: "la Belgique", gender: "f" },
{ nl: "Bulgarije", fr: "la Bulgarie", gender: "f" },
{ nl: "Kroatië", fr: "la Croatie", gender: "f" },
{ nl: "Cyprus", fr: "Chypre", gender: null },
{ nl: "Denemarken", fr: "le Danemark", gender: "m" },
{ nl: "Spanje", fr: "l'Espagne", gender: "f" },
{ nl: "Estland", fr: "l'Estonie", gender: "f" },
{ nl: "de Verenigde Staten", fr: "les États-Unis", gender: "m" },
{ nl: "Finland", fr: "la Finlande", gender: "f" },
{ nl: "Frankrijk", fr: "la France", gender: "f" },
{ nl: "Griekenland", fr: "la Grèce", gender: "f" },
{ nl: "Hongarije", fr: "la Hongrie", gender: "f" },
{ nl: "Ierland", fr: "l'Irlande", gender: "f" },
{ nl: "Italië", fr: "l'Italie", gender: "f" },
{ nl: "Letland", fr: "la Lettonie", gender: "f" },
{ nl: "Litouwen", fr: "la Lituanie", gender: "f" },
{ nl: "Luxemburg", fr: "le Luxembourg", gender: "m" },
{ nl: "Malta", fr: "Malte", gender: null },
{ nl: "Marokko", fr: "le Maroc", gender: "m" },
{ nl: "Noorwegen", fr: "la Norvège", gender: "f" },
{ nl: "Nederland", fr: "les Pays-Bas", gender: "m" },
{ nl: "Polen", fr: "la Pologne", gender: "f" },
{ nl: "Portugal", fr: "le Portugal", gender: "m" },
{ nl: "Roemenië", fr: "la Roumanie", gender: "f" },
{ nl: "het Verenigd Koninkrijk", fr: "le Royaume-Uni", gender: "m" },
{ nl: "Slowakije", fr: "la Slovaquie", gender: "f" },
{ nl: "Slovenië", fr: "la Slovénie", gender: "f" },
{ nl: "Zweden", fr: "la Suède", gender: "f" },
{ nl: "Zwitserland", fr: "la Suisse", gender: "f" },
{ nl: "Tsjechië", fr: "la Tchéquie", gender: "f" },
{ nl: "Turkije", fr: "la Turquie", gender: "f" },
{ nl: "bruinen", fr: "bronzer", gender: null },
{ nl: "dansen", fr: "danser", gender: null },
{ nl: "lezen", fr: "lire", gender: null },
{ nl: "zwemmen", fr: "nager", gender: null },
{ nl: "nemen", fr: "prendre", gender: null },
{ nl: "zonnen", fr: "prendre un bain de soleil", gender: null },
{ nl: "bezoeken", fr: "visiter", gender: null },
{ nl: "voorbereiden", fr: "préparer", gender: null },
{ nl: "kijken", fr: "regarder", gender: null },
{ nl: "blijven", fr: "rester", gender: null },
{ nl: "zich vermaken", fr: "s'amuser", gender: null },
{ nl: "zich uitrusten", fr: "se reposer", gender: null },
{ nl: "rondhangen", fr: "traîner", gender: null },
{ nl: "saai", fr: "ennuyeux", gender: null },
{ nl: "volgende", fr: "prochain", gender: null },
{ nl: "muziek luisteren", fr: "écouter de la musique", gender: null },
{ nl: "op sociale media zijn", fr: "être sur les réseaux sociaux", gender: null },
{ nl: "een videogame spelen", fr: "jouer à un jeu vidéo", gender: null },
{ nl: "vakantie doorbrengen", fr: "passer les vacances", gender: null },
{ nl: "met het vliegtuig", fr: "en avion", gender: null },
{ nl: "met de boot", fr: "en bateau", gender: null },
{ nl: "met de auto", fr: "en voiture", gender: null },
{ nl: "met de trein", fr: "en train", gender: null },
{ nl: "met de bus", fr: "en autocar", gender: null },
{ nl: "met de camper", fr: "en camping-car", gender: null },
{ nl: "met de TGV", fr: "en TGV", gender: null },
{ nl: "het scoutskamp", fr: "le camp scout", gender: "m" },
{ nl: "de camping", fr: "le camping", gender: "m" },
{ nl: "de hittegolf", fr: "la canicule", gender: "f" },
{ nl: "de rondrit", fr: "le circuit", gender: "m" },
{ nl: "het meer", fr: "le lac", gender: "m" },
{ nl: "het landschap", fr: "le paysage", gender: "m" },
{ nl: "het vakantieproject", fr: "le projet de vacances", gender: "m" },
{ nl: "de selfie", fr: "le selfie", gender: "m" },
{ nl: "de sportstage", fr: "le stage de sport", gender: "m" },
{ nl: "het bordspel", fr: "le jeu de société", gender: "m" },
{ nl: "de smoothie", fr: "le smoothie", gender: "m" },
{ nl: "de serie", fr: "la série", gender: "f" },
{ nl: "de trampoline", fr: "le trampoline", gender: "m" },
{ nl: "de video", fr: "la video", gender: "f" },
{ nl: "ontdekken", fr: "découvrir", gender: null },
{ nl: "verkennen", fr: "explorer", gender: null },
{ nl: "trampolinespringen", fr: "faire du trampoline", gender: null },
{ nl: "wassen", fr: "laver", gender: null },
{ nl: "posten", fr: "poster", gender: null },
{ nl: "zich baden", fr: "se baigner", gender: null },
{ nl: "zich afspelen", fr: "se passer", gender: null },
{ nl: "reizen", fr: "voyager", gender: null },
{ nl: "voorbij", fr: "passé", gender: null },
{ nl: "boven", fr: "au-dessus de", gender: null },
{ nl: "eergisteren", fr: "avant-hier", gender: null },
{ nl: "over een week", fr: "dans huit jours", gender: null },
{ nl: "het is donker", fr: "il fait sombre", gender: null },
{ nl: "twee weken geleden", fr: "il y a quinze jours", gender: null },
{ nl: "verschrikkelijk", fr: "terrible", gender: null }
];
const [answers, setAnswers] = useState({});
const [showResults, setShowResults] = useState(false);
const normalize = (str) => {
return str
.toLowerCase()
.trim()
.replace(/\./g, '')
.replace(/\s+/g, ' ')
.replace(/'/g, "'");
};
const handleInputChange = (index, value) => {
setAnswers({ ...answers, [index]: value });
};
const checkAnswers = () => {
setShowResults(true);
};
const reset = () => {
setAnswers({});
setShowResults(false);
};
const isCorrect = (index) => {
const userAnswer = normalize(answers[index] || '');
const correctAnswer = normalize(vocabulary[index].fr);
return userAnswer === correctAnswer;
};
const score = showResults
? vocabulary.filter((_, i) => isCorrect(i)).length
: 0;
return (
<div style={{ maxWidth: '800px', margin: '0 auto', padding: '20px', fontFamily: 'system-ui, -apple-system, sans-serif' }}>
<h1 style={{ color: '#2563eb', marginBottom: '10px' }}>Franse Woordjes Oefenen 🇫🇷</h1>
<p style={{ color: '#64748b', marginBottom: '30px' }}>Schrijf de Franse vertaling voor elk woord</p>
{showResults && (
<div style={{
background: score === vocabulary.length ? '#dcfce7' : '#dbeafe',
padding: '20px',
borderRadius: '12px',
marginBottom: '30px',
border: `2px solid ${score === vocabulary.length ? '#16a34a' : '#2563eb'}`
}}>
<h2 style={{ margin: '0 0 10px 0', color: '#1e293b' }}>
Je score: {score}/{vocabulary.length}
</h2>
<p style={{ margin: 0, color: '#475569', fontSize: '16px' }}>
{score === vocabulary.length ? '🎉 Perfect! Alle woorden correct!' :
score >= vocabulary.length * 0.8 ? '👏 Heel goed gedaan!' :
score >= vocabulary.length * 0.6 ? '💪 Goed bezig, blijf oefenen!' :
'📚 Blijf oefenen, je komt er wel!'}
</p>
<button
onClick={reset}
style={{
marginTop: '15px',
padding: '10px 20px',
background: '#2563eb',
color: 'white',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
gap: '8px',
fontSize: '16px'
}}
>
<RotateCcw size={18} />
Opnieuw beginnen
</button>
</div>
)}
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
{vocabulary.map((item, index) => {
const correct = showResults && isCorrect(index);
const incorrect = showResults && !isCorrect(index);
return (
<div
key={index}
style={{
display: 'flex',
alignItems: 'center',
gap: '15px',
padding: '15px',
background: incorrect ? '#fee2e2' : correct ? '#dcfce7' : '#f8fafc',
borderRadius: '8px',
border: `2px solid ${incorrect ? '#ef4444' : correct ? '#16a34a' : '#e2e8f0'}`
}}
>
<div style={{ minWidth: '30px', color: '#64748b', fontWeight: '500' }}>
{index + 1}.
</div>
<div style={{ flex: '0 0 250px', fontWeight: '500', color: '#1e293b' }}>
{item.nl}
</div>
<input
type="text"
value={answers[index] || ''}
onChange={(e) => handleInputChange(index, e.target.value)}
disabled={showResults}
placeholder="Typ het Franse woord..."
style={{
flex: 1,
padding: '10px 12px',
border: '2px solid #cbd5e1',
borderRadius: '6px',
fontSize: '16px',
background: showResults ? '#f1f5f9' : 'white',
color: '#1e293b'
}}
/>
{showResults && (
<div style={{ minWidth: '24px' }}>
{correct ? (
<Check size={24} color="#16a34a" strokeWidth={3} />
) : (
<X size={24} color="#ef4444" strokeWidth={3} />
)}
</div>
)}
{incorrect && (
<div style={{ minWidth: '200px', color: '#dc2626', fontSize: '14px' }}>
→ {item.fr}
</div>
)}
</div>
);
})}
</div>
{!showResults && (
<button
onClick={checkAnswers}
style={{
marginTop: '30px',
padding: '15px 30px',
background: '#2563eb',
color: 'white',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
fontSize: '18px',
fontWeight: '600',
width: '100%'
}}
>
Nakijken
</button>
)}
</div>
);
};
export default FrenchVocabApp;
Editor is loading...
Leave a Comment