Untitled

 avatar
unknown
plain_text
a month ago
14 kB
3
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