Pdf | Francuski U 100 Lekcija
// Snimi frazu za trenutnu lekciju function saveCurrentPhrase() if(selectedLessonIndex === null) alert("Prvo kliknite na naziv lekcije da je odaberete."); return; const newPhrase = document.getElementById("phraseText").value.trim(); lessonPhrases[selectedLessonIndex] = newPhrase; saveProgress(); // osvježi prikaz const previewSpan = document.getElementById("existingPhraseSpan"); if(newPhrase) previewSpan.innerText = `"$newPhrase"`; else previewSpan.innerText = "(nema sačuvane fraze)"; alert("Fraza sačuvana za " + lessonTitles[selectedLessonIndex]);
<script> // ------------------------------------------------------------ // 1. GENERIŠI 100 LEKCIJA (naslovi na francuskom + prevod) // Realistični tematski naslovi za "Francuski u 100 lekcija" // ------------------------------------------------------------ const lessonTitles = []; const themes = [ "Uvod i pozdravi", "Abeceda i izgovor", "Brojevi 1-20", "Brojevi 20-100", "Dani u nedelji", "Mjeseci i godišnja doba", "Vrijeme i sat", "Porodica i rodbina", "Opisivanje ljudi", "Boje i pridevi", "Glagol biti (être)", "Glagol imati (avoir)", "Obični glagoli -er", "Obični glagoli -ir", "Obični glagoli -re", "Negacija (ne...pas)", "Pitanja (est-ce que)", "Lične zamjenice", "Prisvojni pridevi", "Pokazne zamjenice", "Određeni i neodređeni član", "Djelomični član", "Pravljenje množine", "Rod imenica", "Opis doma", "Namještaj i sobe", "Hrana i piće", "U restoranu", "Naručivanje jela", "Voće i povrće", "Odjeća i moda", "Trgovina i cijene", "Putovanje i smjerovi", "Grad i mjesta", "Prijevoz (metro, autobus)", "U hotelu", "Na aerodromu", "Izlet i priroda", "Sport i slobodno vrijeme", "Hobiji i interesovanja", "Posao i zanimanja", "Intervju za posao", "Pisanje emaila", "Telefonski razgovor", "Medicina i kod doktora", "Dijelovi tijela", "Hitni slučajevi", "Vrijeme i prognoza", "Buduće vrijeme (futur proche)", "Futur simple", "Prošlo vrijeme (passé composé)", "Nepravilni participi", "Imperfekat (imparfait)", "Poređenje vremena", "Imperativ", "Kondicional (želje)", "Subjonctif (uvod)", "Vežbanje subjonctiva", "Prilozi vremena", "Prilozi mjesta", "Poređenje prideva", "Superlativ", "Veznici i povezivanje", "Izražavanje mišljenja", "Slaganje sa sagovornikom", "Francuski izrazi (locutions)", "Poslovice i izreke", "Kultura i običaji", "Praznici u Francuskoj", "Istorija Francuske", "Poznate ličnosti", "Književnost i citati", "Pjesme i poezija", "Gledanje filmova na francuskom", "Pisanje priče", "Opis fotografije", "Razgovor na poslu", "Poziv u administraciji", "Iznajmljivanje stana", "Prijateljski susret", "Pravljenje planova", "Izvinjenje i izgovori", "Ljutnja i emocije", "Sreća i iznenađenje", "Razlika između francuskog u Kanadi", "Sleng i kolokvijalni izrazi", "Skraćenice (SMS)", "Prezentacija sebe", "Opis dnevne rutine", "Hronologija događaja", "Komparacija kultura", "Prevodi i jezičke zamke", "Lažni prijatelji", "Ponavljanje: glagoli", "Ponavljanje: padeži (odnosi)", "Završni test znanja", "Konverzacija 1: Upoznavanje", "Konverzacija 2: Putovanje", "Konverzacija 3: Posao", "Čitanje vijesti", "Pisanje rezimea" ]; // Make exactly 100 titles for (let i = 1; i <= 100; i++) // final check length while(lessonTitles.length < 100) lessonTitles.push( Lekcija $lessonTitles.length+1: Praktična vežba );
// ------------------------------------------------------------ // 4. RENDER LISTE LEKCIJA (sa pretragom) // ------------------------------------------------------------ let currentSearchTerm = ""; function renderLessonsList(filter = "") const container = document.getElementById("lessonsList"); container.innerHTML = ""; const lowerFilter = filter.toLowerCase(); for (let i = 0; i < lessonTitles.length; i++) const title = lessonTitles[i]; if (lowerFilter && !title.toLowerCase().includes(lowerFilter) && !`lekcija $i+1`.includes(lowerFilter)) continue; const isCompleted = completed[i]; const div = document.createElement("div"); div.className = "lesson-item"; // checkbox const chk = document.createElement("input"); chk.type = "checkbox"; chk.className = "lesson-check"; chk.checked = isCompleted; chk.addEventListener("change", (function(idx) return function(e) completed[idx] = e.target.checked; saveProgress(); renderLessonsList(currentSearchTerm); if(completed[idx]) // opcionalno: mali zvučni efekat nije potreban ; )(i)); // broj const numSpan = document.createElement("span"); numSpan.className = "lesson-number"; numSpan.innerText = i+1; // title const titleSpan = document.createElement("span"); titleSpan.className = "lesson-title" + (isCompleted ? " completed" : ""); titleSpan.innerText = title; titleSpan.style.cursor = "pointer"; titleSpan.addEventListener("click", (function(idx) return function() selectLesson(idx); ; )(i)); // audio button const audioBtn = document.createElement("button"); audioBtn.innerHTML = "🔊"; audioBtn.className = "audio-btn"; audioBtn.title = "Izgovori naslov lekcije (francuski)"; audioBtn.addEventListener("click", (function(frenchText) return function() speakFrench(frenchText); ; )(title.replace(/Lekcija \d+: /, ''))); // izgovara samo temu div.appendChild(chk); div.appendChild(numSpan); div.appendChild(titleSpan); div.appendChild(audioBtn); container.appendChild(div); if(container.children.length === 0) container.innerHTML = "<div style='padding: 2rem; text-align:center'>🔍 Nema lekcija koje odgovaraju pretrazi</div>";
// Odabrana lekcija za fraze let selectedLessonIndex = null; francuski u 100 lekcija pdf
// ------------------------------------------------------------ // 3. SPEECH SYNTHESIS (francuski izgovor) // ------------------------------------------------------------ function speakFrench(text) if (!window.speechSynthesis) alert("Vaš browser ne podržava govor."); return; const utterance = new SpeechSynthesisUtterance(text); utterance.lang = "fr-FR"; utterance.rate = 0.9; window.speechSynthesis.cancel(); // izbjegni preklapanje window.speechSynthesis.speak(utterance);
function resetProgress() if(confirm("Da li ste sigurni? Resetovaćete sav napredak (završene lekcije i sve sačuvane fraze).")) completed.fill(false); lessonPhrases.fill(""); localStorage.setItem("francuski100_completed", JSON.stringify(completed)); localStorage.setItem("francuski100_phrases", JSON.stringify(lessonPhrases)); selectedLessonIndex = null; document.getElementById("currentLessonLabel").innerHTML = "nijedna"; document.getElementById("existingPhraseSpan").innerHTML = "(nema)"; document.getElementById("phraseText").value = ""; updateStats(); renderLessonsList(currentSearchTerm);
// ------------------------------------------------------------ // 5. INICIJALIZACIJA // ------------------------------------------------------------ function init() loadProgress(); renderLessonsList(""); updateStats(); // Event listeners document.getElementById("searchInput").addEventListener("input", (e) => currentSearchTerm = e.target.value; renderLessonsList(currentSearchTerm); ); document.getElementById("resetProgressBtn").addEventListener("click", resetProgress); document.getElementById("savePhraseBtn").addEventListener("click", saveCurrentPhrase); document.getElementById("speakPhraseBtn").addEventListener("click", speakSavedPhrase); document.getElementById("fakePdfHint").addEventListener("click", (e) => e.preventDefault(); alert("Ovaj alat je dodatak za PDF 'Francuski u 100 lekcija'. Preporučujemo da otvorite PDF u drugom tabu ili prozoru pored ovog panela."); ); // default select first lesson optionally if(lessonTitles.length > 0) selectLesson(0); " completed" : ""); titleSpan
<div class="phrase-panel"> <div class="phrase-header">📌 FRAZE ZA LEKCIJU</div> <div id="selectedLessonDisplay" class="selected-info"> <strong>Lekcija:</strong> <span id="currentLessonLabel">nijedna</span> </div> <div class="phrase-input-area"> <label><strong>🇫🇷 Francuska fraza / rečenica:</strong></label> <textarea id="phraseText" rows="3" placeholder="Unesite frazu iz ove lekcije..."></textarea> <button id="savePhraseBtn" class="save-phrase-btn">💾 Sačuvaj frazu za ovu lekciju</button> <button id="speakPhraseBtn" class="save-phrase-btn" style="background:#3b82f6; margin-top: 6px;">🔊 Izgovori sačuvanu frazu</button> </div> <div id="savedPhrasePreview" class="example-phrases"> <strong>📖 Sačuvana fraza:</strong> <span id="existingPhraseSpan">(nema)</span> </div> <div class="example-phrases"> 💡 <em>Primeri: "Bonjour", "Je m'appelle...", "Où est la gare?"</em><br> ⚡ Klik na naziv lekcije → automatski učitava njenu frazu. </div> </div> </div> <footer> 🎧 Dugme zvučnik = izgovor naslova lekcije na francuskom. Sačuvane fraze se čuvaju u vašem browseru. </footer> </div>
<div class="two-columns"> <div class="lessons-panel" id="lessonsList"> <!-- Dinamički generisano 100 lekcija --> </div>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> <title>Francuski u 100 lekcija – Interaktivni pratilac</title> <style> * box-sizing: border-box; font-family: system-ui, 'Segoe UI', 'Roboto', 'Noto Sans', sans-serif; body background: #f1f5f9; margin: 0; padding: 20px; .app-container max-width: 1300px; margin: 0 auto; header background: #1e3a8a; color: white; padding: 1rem 2rem; border-radius: 1.5rem; margin-bottom: 2rem; box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1); h1 margin: 0; font-size: 1.8rem; .sub opacity: 0.9; font-size: 0.9rem; margin-top: 8px; .pdf-link background: #facc15; color: #1e3a8a; padding: 6px 12px; border-radius: 40px; text-decoration: none; font-weight: bold; display: inline-block; margin-top: 8px; .toolbar display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 24px; background: white; padding: 16px 20px; border-radius: 2rem; box-shadow: 0 1px 3px rgba(0,0,0,0.05); align-items: center; .search-box flex: 2; min-width: 200px; .search-box input width: 100%; padding: 10px 16px; border-radius: 40px; border: 1px solid #cbd5e1; font-size: 1rem; .stats background: #e2e8f0; padding: 8px 16px; border-radius: 40px; font-weight: 500; .reset-btn background: #ef4444; color: white; border: none; padding: 8px 20px; border-radius: 40px; cursor: pointer; font-weight: bold; .reset-btn:hover background: #dc2626; .two-columns display: flex; flex-wrap: wrap; gap: 24px; .lessons-panel flex: 2; min-width: 280px; background: white; border-radius: 1.5rem; padding: 1rem; box-shadow: 0 4px 6px rgba(0,0,0,0.05); max-height: 70vh; overflow-y: auto; .phrase-panel flex: 1.2; min-width: 260px; background: white; border-radius: 1.5rem; padding: 1.2rem; box-shadow: 0 4px 6px rgba(0,0,0,0.05); display: flex; flex-direction: column; .lesson-item display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-bottom: 1px solid #eef2ff; transition: background 0.1s; .lesson-item:hover background: #f8fafc; .lesson-check width: 24px; height: 24px; cursor: pointer; accent-color: #1e3a8a; .lesson-number font-weight: 600; background: #e0e7ff; width: 48px; text-align: center; padding: 4px 6px; border-radius: 30px; font-size: 0.8rem; color: #1e3a8a; .lesson-title flex: 1; font-weight: 500; cursor: pointer; .lesson-title.completed text-decoration: line-through; opacity: 0.6; .audio-btn background: none; border: none; font-size: 1.2rem; cursor: pointer; padding: 6px; border-radius: 40px; transition: background 0.2s; .audio-btn:hover background: #e2e8f0; .phrase-header font-weight: bold; font-size: 1.2rem; margin-bottom: 12px; border-left: 5px solid #1e3a8a; padding-left: 12px; .selected-info background: #f1f5f9; border-radius: 1rem; padding: 12px; margin-bottom: 16px; .phrase-input-area margin-top: 12px; .phrase-input-area textarea width: 100%; border-radius: 1rem; border: 1px solid #cbd5e1; padding: 12px; font-family: monospace; resize: vertical; .save-phrase-btn background: #10b981; color: white; border: none; padding: 8px 12px; border-radius: 2rem; margin-top: 8px; cursor: pointer; font-weight: bold; .example-phrases font-size: 0.85rem; color: #475569; margin-top: 10px; border-top: 1px solid #e2e8f0; padding-top: 10px; footer margin-top: 2rem; text-align: center; font-size: 0.8rem; color: #64748b; @media (max-width: 700px) body padding: 12px; .lesson-number width: 38px; </style> </head> <body> <div class="app-container"> <header> <h1>📘 Francuski u 100 lekcija</h1> <div class="sub">Interaktivni pratilac za PDF – pratite napredak, slušajte izgovor, dodajte ključne fraze</div> <a href="#" id="fakePdfHint" class="pdf-link">📄 Otvori PDF (sačuvaj lokalno)</a> </header> <div class="toolbar"> <div class="search-box"> <input type="text" id="searchInput" placeholder="🔍 Pretraži lekcije (npr. 'odmor', 'pitanje')" autocomplete="off"> </div> <div class="stats" id="statsDisplay">0 / 100 završeno</div> <button class="reset-btn" id="resetProgressBtn">Resetuj sav napredak</button> </div> let lessonPhrases = new Array(100).fill("")
function selectLesson(idx)
// ------------------------------------------------------------ // 2. LOCALSTORAGE za napredak i za fraze (po lekcijama) // ------------------------------------------------------------ let completed = new Array(100).fill(false); let lessonPhrases = new Array(100).fill(""); // čuva francuske fraze
function saveProgress() localStorage.setItem("francuski100_completed", JSON.stringify(completed)); localStorage.setItem("francuski100_phrases", JSON.stringify(lessonPhrases)); updateStats(); renderLessonsList(currentSearchTerm);
function speakSavedPhrase() phrase.trim() === "") alert("Nema sačuvane fraze za ovu lekciju. Prvo unesite frazu."); return; speakFrench(phrase);
This is a specific request for a related to the PDF file "Francuski u 100 lekcija" (Serbian/Croatian/Bosnian for "French in 100 Lessons").
