feat(localization): enhance course progress and review messaging across multiple languages
All checks were successful
Deploy to production / deploy (push) Successful in 2m52s
All checks were successful
Deploy to production / deploy (push) Successful in 2m52s
- Added new confirmation titles and messages for resetting and marking lessons as complete in admin and user interfaces. - Expanded course flow and review scheduling messages to improve clarity and user guidance in Cebuano, German, Spanish, and English. - Introduced a new section in the VocabCourseView to display today's recommended steps for users, enhancing the learning experience. - Updated localization files to ensure consistent messaging and improved user engagement across all supported languages.
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
"selectCourse": "Kurso",
|
"selectCourse": "Kurso",
|
||||||
"selectLesson": "Leksiyon",
|
"selectLesson": "Leksiyon",
|
||||||
"reset": "I-reset ang leksiyon niining user",
|
"reset": "I-reset ang leksiyon niining user",
|
||||||
|
"confirmTitle": "Tangtanga ang pag-uswag sa leksiyon",
|
||||||
"confirm": "Tinuod nga tangtangon ang pag-uswag sa leksiyon nga «{lesson}» ni {username}?",
|
"confirm": "Tinuod nga tangtangon ang pag-uswag sa leksiyon nga «{lesson}» ni {username}?",
|
||||||
"success": "Na-reset na ang pag-uswag sa leksiyon.",
|
"success": "Na-reset na ang pag-uswag sa leksiyon.",
|
||||||
"error": "Dili ma-reset.",
|
"error": "Dili ma-reset.",
|
||||||
@@ -41,6 +42,7 @@
|
|||||||
"throughLabel": "Tanang leksiyon hangtod sa numero (lakip)",
|
"throughLabel": "Tanang leksiyon hangtod sa numero (lakip)",
|
||||||
"hint": "I-mark ang kulang o abli nga mga row nga nahuman, lakip ang target score ug unang review wave. Ang nahuman na dili usbon.",
|
"hint": "I-mark ang kulang o abli nga mga row nga nahuman, lakip ang target score ug unang review wave. Ang nahuman na dili usbon.",
|
||||||
"submit": "I-mark nga nahuman hangtod dinhi",
|
"submit": "I-mark nga nahuman hangtod dinhi",
|
||||||
|
"confirmTitle": "I-mark ang mga leksiyon nga nahuman",
|
||||||
"confirm": "I-mark nga nahuman ang tanang leksiyon nga numero ≤ {n} ni {username} niining kurso?",
|
"confirm": "I-mark nga nahuman ang tanang leksiyon nga numero ≤ {n} ni {username} niining kurso?",
|
||||||
"success": "{marked} ka leksiyon nga bag-ong gi-mark nga nahuman ({unchanged} klaro nang nahuman).",
|
"success": "{marked} ka leksiyon nga bag-ong gi-mark nga nahuman ({unchanged} klaro nang nahuman).",
|
||||||
"successNone": "Walay pagbag-o: tanang leksiyon nga naapektuhan ({unchanged}) klaro nang nahuman.",
|
"successNone": "Walay pagbag-o: tanang leksiyon nga naapektuhan ({unchanged}) klaro nang nahuman.",
|
||||||
|
|||||||
@@ -304,7 +304,17 @@
|
|||||||
"courseShareCodePlaceholder": "pananglitan abc123def456",
|
"courseShareCodePlaceholder": "pananglitan abc123def456",
|
||||||
"courseFlowEyebrow": "Agos sa adlaw",
|
"courseFlowEyebrow": "Agos sa adlaw",
|
||||||
"courseFlowTitle": "Maayong ipadayon karon",
|
"courseFlowTitle": "Maayong ipadayon karon",
|
||||||
"courseFlowIntro": "Ang sunod-sunod mosunod sa konsepto: una ang angay nang balikon, dayon ang kasamtangang block, unya ang intensive phase ug sa katapusan ang libre nga pagpalalom.",
|
"courseFlowIntro": "Una ang gisugyot karon nga sunod-sunod sa ibabaw. Sa ubos, ang upat ka bahin: angay nga balik-balik, kasamtangang block, intensive phase, libre nga pagpalalom.",
|
||||||
|
"courseTodayPlanTitle": "Gisugyot karong adlawa",
|
||||||
|
"courseTodayPlanIntro": "Praktikal nga paagi: una ang tanan nga angay na nga mubo nga balik-balik, dayon ang abli nga mga leksiyon sa imong block, unya ang intensive kung naay ipakita. Ang mubo nga balik-balik tulo ka mubo nga petsa human mahuman ang leksiyon ( kasagaran mga 1, 3 ug 7 ka adlaw) aron mahuptan ang mga pulong.",
|
||||||
|
"courseTodayPlanStepReviewDue": "Mubo nga balik-balik karon",
|
||||||
|
"courseTodayPlanStepBlock": "Padayon sa kasamtangang block",
|
||||||
|
"courseTodayPlanStepIntensive": "Intensive nga balik-balik",
|
||||||
|
"courseTodayPlanStepContinue": "Sunod sa imong agianan sa pagkat-on",
|
||||||
|
"courseTodayPlanStepPractice": "Libre nga praktis (opsyonal)",
|
||||||
|
"courseTodayPlanOpen": "Ablihi ang leksiyon",
|
||||||
|
"courseTodayPlanTrainer": "Ablihi ang trainer",
|
||||||
|
"courseTodayPlanEmpty": "Walay gikatakda nga angay karon ug walay klaro nga sunod nga lakang sa block. Pilia ang leksiyon sa ubos o gamita ang libre nga pagpalalom sa trainer.",
|
||||||
"courseFlowReviewStat": "Angay balikon: {count}",
|
"courseFlowReviewStat": "Angay balikon: {count}",
|
||||||
"courseFlowBlockStat": "Aktibong block: {block}",
|
"courseFlowBlockStat": "Aktibong block: {block}",
|
||||||
"courseFlowReviewTitle": "Angay nga balik-balikon",
|
"courseFlowReviewTitle": "Angay nga balik-balikon",
|
||||||
@@ -345,10 +355,20 @@
|
|||||||
"reviewBadgeScheduleInDays": "sunod nga wave sulod sa {count} ka adlaw",
|
"reviewBadgeScheduleInDays": "sunod nga wave sulod sa {count} ka adlaw",
|
||||||
"reviewBadgeScheduleToday": "gitakda ang wave karon",
|
"reviewBadgeScheduleToday": "gitakda ang wave karon",
|
||||||
"reviewBadgeScheduleOverdue": "nilapas na ang wave sukad {count} ka adlaw",
|
"reviewBadgeScheduleOverdue": "nilapas na ang wave sukad {count} ka adlaw",
|
||||||
"reviewStageDay1": "Adlaw 1",
|
"reviewBadgeLineAllDone": "Nahuman na ang tanang mubo nga balik-balik (3×)",
|
||||||
"reviewStageDay3": "Adlaw 3",
|
"reviewBadgeLineDue": "Mubo nga balik-balik: lakang {step} sa 3 · angay na karon",
|
||||||
"reviewStageDay7": "Adlaw 7",
|
"reviewBadgeLineScheduled": "Mubo nga balik-balik: lakang {step} sa 3 · sunod {when}",
|
||||||
"reviewStageCompleted": "Nahuman ang review",
|
"reviewWhenFriendlyTomorrow": "ugma",
|
||||||
|
"reviewWhenFriendlyInDays": "sulod sa {count} ka adlaw",
|
||||||
|
"reviewWhenFriendlyToday": "karon",
|
||||||
|
"reviewWhenFriendlyOverdue": "nilapas na ({count} ka adlaw ang milabay)",
|
||||||
|
"reviewWhenFriendlySoon": "dali ra",
|
||||||
|
"reviewBadgeTooltipDone": "Nahuman na nimo ang tulo nga gisugyot nga mubo nga balik-balik human niini nga leksiyon. Mahimo gihapon kang magpraktis sa trainer.",
|
||||||
|
"reviewBadgeTooltipActive": "Human sa leksiyon, gisugyot sa kurso ang tulo ka mubo nga balik-balik nga nagtika-tika mga 1, 3 ug 7 ka adlaw aron mahuptan ang mga pulong. Ang badge nagpakita kung unsang lakang (1–3) ang aktibo o kanus-a ang sunod nga petsa.",
|
||||||
|
"reviewStageDay1": "Lakang 1 sa 3 (~1 ka adlaw)",
|
||||||
|
"reviewStageDay3": "Lakang 2 sa 3 (~3 ka adlaw)",
|
||||||
|
"reviewStageDay7": "Lakang 3 sa 3 (~7 ka adlaw)",
|
||||||
|
"reviewStageCompleted": "Nahuman na ang tanang mubo nga balik-balik",
|
||||||
"phaseQuickstart": "Paspas nga sugod",
|
"phaseQuickstart": "Paspas nga sugod",
|
||||||
"phaseDailyLife": "Adlaw-adlaw",
|
"phaseDailyLife": "Adlaw-adlaw",
|
||||||
"phaseStabilization": "Pagpalig-on",
|
"phaseStabilization": "Pagpalig-on",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"selectCourse": "Kurs",
|
"selectCourse": "Kurs",
|
||||||
"selectLesson": "Lektion",
|
"selectLesson": "Lektion",
|
||||||
"reset": "Lektion für diesen Nutzer zurücksetzen",
|
"reset": "Lektion für diesen Nutzer zurücksetzen",
|
||||||
|
"confirmTitle": "Lektionsfortschritt löschen",
|
||||||
"confirm": "Fortschritt der Lektion „{lesson}“ für {username} wirklich löschen?",
|
"confirm": "Fortschritt der Lektion „{lesson}“ für {username} wirklich löschen?",
|
||||||
"success": "Lektionsfortschritt wurde zurückgesetzt.",
|
"success": "Lektionsfortschritt wurde zurückgesetzt.",
|
||||||
"error": "Zurücksetzen fehlgeschlagen.",
|
"error": "Zurücksetzen fehlgeschlagen.",
|
||||||
@@ -50,6 +51,7 @@
|
|||||||
"throughLabel": "Alle Lektionen bis Lektionsnummer (einschließlich)",
|
"throughLabel": "Alle Lektionen bis Lektionsnummer (einschließlich)",
|
||||||
"hint": "Setzt fehlende oder offene Einträge auf „abgeschlossen“, inkl. Ziel-Score und erster Review-Welle. Bereits abgeschlossene Lektionen bleiben unverändert.",
|
"hint": "Setzt fehlende oder offene Einträge auf „abgeschlossen“, inkl. Ziel-Score und erster Review-Welle. Bereits abgeschlossene Lektionen bleiben unverändert.",
|
||||||
"submit": "Bis hier als abgeschlossen markieren",
|
"submit": "Bis hier als abgeschlossen markieren",
|
||||||
|
"confirmTitle": "Lektionen als abgeschlossen markieren",
|
||||||
"confirm": "Alle Lektionen mit Nummer ≤ {n} für {username} in diesem Kurs als abgeschlossen markieren?",
|
"confirm": "Alle Lektionen mit Nummer ≤ {n} für {username} in diesem Kurs als abgeschlossen markieren?",
|
||||||
"success": "{marked} Lektion(en) neu als abgeschlossen gesetzt ({unchanged} waren bereits erledigt).",
|
"success": "{marked} Lektion(en) neu als abgeschlossen gesetzt ({unchanged} waren bereits erledigt).",
|
||||||
"successNone": "Keine Änderung: alle betroffenen Lektionen ({unchanged}) waren bereits abgeschlossen.",
|
"successNone": "Keine Änderung: alle betroffenen Lektionen ({unchanged}) waren bereits abgeschlossen.",
|
||||||
|
|||||||
@@ -659,7 +659,17 @@
|
|||||||
"courseShareCodePlaceholder": "z. B. abc123def456",
|
"courseShareCodePlaceholder": "z. B. abc123def456",
|
||||||
"courseFlowEyebrow": "Tagesfluss",
|
"courseFlowEyebrow": "Tagesfluss",
|
||||||
"courseFlowTitle": "Heute sinnvoll weitermachen",
|
"courseFlowTitle": "Heute sinnvoll weitermachen",
|
||||||
"courseFlowIntro": "Die Reihenfolge folgt dem Konzept: fällige Wiederholung zuerst, dann aktueller Block, danach Intensivphase und freie Vertiefung.",
|
"courseFlowIntro": "Zuerst die Tagesempfehlung mit konkreter Reihenfolge. Darunter die vier Bereiche: fällige Kurz-Wiederholung, aktueller Block, Intensivphase, freie Vertiefung.",
|
||||||
|
"courseTodayPlanTitle": "Empfehlung für heute",
|
||||||
|
"courseTodayPlanIntro": "So kannst du vorgehen: zuerst alles unter „Jetzt kurz wiederholen“, dann die offenen Lektionen deines Blocks, danach ggf. die Intensivphase. Kurz-Wiederholungen sind die drei kleinen Termine nach Lektionsende (typisch nach etwa 1, 3 und 7 Tagen), damit Vokabeln hängen bleiben.",
|
||||||
|
"courseTodayPlanStepReviewDue": "Jetzt kurz wiederholen",
|
||||||
|
"courseTodayPlanStepBlock": "Weiter im aktuellen Block",
|
||||||
|
"courseTodayPlanStepIntensive": "Intensive Wiederholung",
|
||||||
|
"courseTodayPlanStepContinue": "Als Nächstes auf deinem Lernpfad",
|
||||||
|
"courseTodayPlanStepPractice": "Frei üben (optional)",
|
||||||
|
"courseTodayPlanOpen": "Lektion öffnen",
|
||||||
|
"courseTodayPlanTrainer": "Im Trainer üben",
|
||||||
|
"courseTodayPlanEmpty": "Gerade ist keine gestaffelte Wiederholung fällig und es gibt keinen klaren nächsten Block-Schritt. Wähle unten eine Lektion oder nutze die freie Vertiefung mit dem Trainer.",
|
||||||
"courseFlowReviewStat": "Fällige Wiederholung: {count}",
|
"courseFlowReviewStat": "Fällige Wiederholung: {count}",
|
||||||
"courseFlowBlockStat": "Aktiver Block: {block}",
|
"courseFlowBlockStat": "Aktiver Block: {block}",
|
||||||
"courseFlowReviewTitle": "Fällige Wiederholung",
|
"courseFlowReviewTitle": "Fällige Wiederholung",
|
||||||
@@ -700,10 +710,20 @@
|
|||||||
"reviewBadgeScheduleInDays": "nächste Welle in {count} Tagen",
|
"reviewBadgeScheduleInDays": "nächste Welle in {count} Tagen",
|
||||||
"reviewBadgeScheduleToday": "Welle heute vorgesehen",
|
"reviewBadgeScheduleToday": "Welle heute vorgesehen",
|
||||||
"reviewBadgeScheduleOverdue": "Welle überfällig (seit {count} Tagen)",
|
"reviewBadgeScheduleOverdue": "Welle überfällig (seit {count} Tagen)",
|
||||||
"reviewStageDay1": "Tag 1",
|
"reviewBadgeLineAllDone": "Alle Kurz-Wiederholungen erledigt (3×)",
|
||||||
"reviewStageDay3": "Tag 3",
|
"reviewBadgeLineDue": "Kurz wiederholen: Schritt {step} von 3 · jetzt dran",
|
||||||
"reviewStageDay7": "Tag 7",
|
"reviewBadgeLineScheduled": "Kurz wiederholen: Schritt {step} von 3 · nächster Termin {when}",
|
||||||
"reviewStageCompleted": "Review abgeschlossen",
|
"reviewWhenFriendlyTomorrow": "morgen",
|
||||||
|
"reviewWhenFriendlyInDays": "in {count} Tagen",
|
||||||
|
"reviewWhenFriendlyToday": "heute",
|
||||||
|
"reviewWhenFriendlyOverdue": "überfällig (vor {count} Tag(en))",
|
||||||
|
"reviewWhenFriendlySoon": "bald",
|
||||||
|
"reviewBadgeTooltipDone": "Die drei empfohlenen Kurz-Wiederholungen nach diesem Lektionsende hast du absolviert. Üben im Trainer geht trotzdem weiter.",
|
||||||
|
"reviewBadgeTooltipActive": "Nach Lektionsende empfiehlt der Kurs drei kurze Wiederholungen im Abstand von etwa 1, 3 und 7 Tagen, damit Vokabeln im Gedächtnis bleiben. Das Badge zeigt, welcher Schritt (1–3) gerade dran ist bzw. wann der nächste Termin ist.",
|
||||||
|
"reviewStageDay1": "Schritt 1 von 3 (~1 Tag)",
|
||||||
|
"reviewStageDay3": "Schritt 2 von 3 (~3 Tage)",
|
||||||
|
"reviewStageDay7": "Schritt 3 von 3 (~7 Tage)",
|
||||||
|
"reviewStageCompleted": "Alle Kurz-Wiederholungen erledigt",
|
||||||
"phaseQuickstart": "Schnellstart",
|
"phaseQuickstart": "Schnellstart",
|
||||||
"phaseDailyLife": "Alltag",
|
"phaseDailyLife": "Alltag",
|
||||||
"phaseStabilization": "Stabilisierung",
|
"phaseStabilization": "Stabilisierung",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"selectCourse": "Course",
|
"selectCourse": "Course",
|
||||||
"selectLesson": "Lesson",
|
"selectLesson": "Lesson",
|
||||||
"reset": "Reset lesson for this user",
|
"reset": "Reset lesson for this user",
|
||||||
|
"confirmTitle": "Delete lesson progress",
|
||||||
"confirm": "Really delete progress for lesson “{lesson}” for {username}?",
|
"confirm": "Really delete progress for lesson “{lesson}” for {username}?",
|
||||||
"success": "Lesson progress was reset.",
|
"success": "Lesson progress was reset.",
|
||||||
"error": "Reset failed.",
|
"error": "Reset failed.",
|
||||||
@@ -50,6 +51,7 @@
|
|||||||
"throughLabel": "All lessons up to and including lesson number",
|
"throughLabel": "All lessons up to and including lesson number",
|
||||||
"hint": "Marks missing or open rows as completed, including target score and first review wave. Already completed lessons are left unchanged.",
|
"hint": "Marks missing or open rows as completed, including target score and first review wave. Already completed lessons are left unchanged.",
|
||||||
"submit": "Mark through here as completed",
|
"submit": "Mark through here as completed",
|
||||||
|
"confirmTitle": "Mark lessons complete",
|
||||||
"confirm": "Mark every lesson with number ≤ {n} for {username} in this course as completed?",
|
"confirm": "Mark every lesson with number ≤ {n} for {username} in this course as completed?",
|
||||||
"success": "{marked} lesson(s) newly marked complete ({unchanged} were already done).",
|
"success": "{marked} lesson(s) newly marked complete ({unchanged} were already done).",
|
||||||
"successNone": "No change: all affected lessons ({unchanged}) were already completed.",
|
"successNone": "No change: all affected lessons ({unchanged}) were already completed.",
|
||||||
|
|||||||
@@ -659,7 +659,17 @@
|
|||||||
"courseShareCodePlaceholder": "e.g. abc123def456",
|
"courseShareCodePlaceholder": "e.g. abc123def456",
|
||||||
"courseFlowEyebrow": "Daily flow",
|
"courseFlowEyebrow": "Daily flow",
|
||||||
"courseFlowTitle": "Best next step for today",
|
"courseFlowTitle": "Best next step for today",
|
||||||
"courseFlowIntro": "The order follows the concept: due reviews first, then the current block, then intensive review, and finally free practice.",
|
"courseFlowIntro": "Start with today’s suggested order at the top. Below that, the four areas in detail: due quick reviews, current block, intensive review, free practice.",
|
||||||
|
"courseTodayPlanTitle": "Suggested for today",
|
||||||
|
"courseTodayPlanIntro": "Practical order: first everything that is due for a quick review, then open lessons in your current block, then intensive review if shown. Quick reviews are three short revisit dates after you finish a lesson (typically about 1, 3 and 7 days apart) so vocabulary sticks.",
|
||||||
|
"courseTodayPlanStepReviewDue": "Quick review now",
|
||||||
|
"courseTodayPlanStepBlock": "Continue in your current block",
|
||||||
|
"courseTodayPlanStepIntensive": "Intensive review",
|
||||||
|
"courseTodayPlanStepContinue": "Next on your learning path",
|
||||||
|
"courseTodayPlanStepPractice": "Free practice (optional)",
|
||||||
|
"courseTodayPlanOpen": "Open lesson",
|
||||||
|
"courseTodayPlanTrainer": "Open trainer",
|
||||||
|
"courseTodayPlanEmpty": "Nothing scheduled as due right now and no clear next block step. Pick a lesson below or use free practice with the trainer.",
|
||||||
"courseFlowReviewStat": "Due review: {count}",
|
"courseFlowReviewStat": "Due review: {count}",
|
||||||
"courseFlowBlockStat": "Active block: {block}",
|
"courseFlowBlockStat": "Active block: {block}",
|
||||||
"courseFlowReviewTitle": "Due review",
|
"courseFlowReviewTitle": "Due review",
|
||||||
@@ -700,10 +710,20 @@
|
|||||||
"reviewBadgeScheduleInDays": "next wave in {count} days",
|
"reviewBadgeScheduleInDays": "next wave in {count} days",
|
||||||
"reviewBadgeScheduleToday": "wave slated for today",
|
"reviewBadgeScheduleToday": "wave slated for today",
|
||||||
"reviewBadgeScheduleOverdue": "wave overdue ({count} days)",
|
"reviewBadgeScheduleOverdue": "wave overdue ({count} days)",
|
||||||
"reviewStageDay1": "Day 1",
|
"reviewBadgeLineAllDone": "All quick reviews done (3×)",
|
||||||
"reviewStageDay3": "Day 3",
|
"reviewBadgeLineDue": "Quick review: step {step} of 3 · due now",
|
||||||
"reviewStageDay7": "Day 7",
|
"reviewBadgeLineScheduled": "Quick review: step {step} of 3 · next on {when}",
|
||||||
"reviewStageCompleted": "Review completed",
|
"reviewWhenFriendlyTomorrow": "tomorrow",
|
||||||
|
"reviewWhenFriendlyInDays": "in {count} days",
|
||||||
|
"reviewWhenFriendlyToday": "today",
|
||||||
|
"reviewWhenFriendlyOverdue": "overdue ({count} day(s) ago)",
|
||||||
|
"reviewWhenFriendlySoon": "soon",
|
||||||
|
"reviewBadgeTooltipDone": "You finished the three suggested quick reviews after this lesson. You can still keep practicing in the trainer.",
|
||||||
|
"reviewBadgeTooltipActive": "After you complete a lesson, the course suggests three short reviews about 1, 3 and 7 days apart so words stay in memory. The badge shows which step (1–3) is active or when the next date is.",
|
||||||
|
"reviewStageDay1": "Step 1 of 3 (~1 day)",
|
||||||
|
"reviewStageDay3": "Step 2 of 3 (~3 days)",
|
||||||
|
"reviewStageDay7": "Step 3 of 3 (~7 days)",
|
||||||
|
"reviewStageCompleted": "All quick reviews done",
|
||||||
"phaseQuickstart": "Quick start",
|
"phaseQuickstart": "Quick start",
|
||||||
"phaseDailyLife": "Daily life",
|
"phaseDailyLife": "Daily life",
|
||||||
"phaseStabilization": "Stabilization",
|
"phaseStabilization": "Stabilization",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"selectCourse": "Curso",
|
"selectCourse": "Curso",
|
||||||
"selectLesson": "Lección",
|
"selectLesson": "Lección",
|
||||||
"reset": "Restablecer lección para este usuario",
|
"reset": "Restablecer lección para este usuario",
|
||||||
|
"confirmTitle": "Eliminar progreso de la lección",
|
||||||
"confirm": "¿Borrar de verdad el progreso de la lección «{lesson}» para {username}?",
|
"confirm": "¿Borrar de verdad el progreso de la lección «{lesson}» para {username}?",
|
||||||
"success": "Se restableció el progreso de la lección.",
|
"success": "Se restableció el progreso de la lección.",
|
||||||
"error": "No se pudo restablecer.",
|
"error": "No se pudo restablecer.",
|
||||||
@@ -50,6 +51,7 @@
|
|||||||
"throughLabel": "Todas las lecciones hasta el número (incluido)",
|
"throughLabel": "Todas las lecciones hasta el número (incluido)",
|
||||||
"hint": "Marca filas faltantes o abiertas como completadas, con puntuación objetivo y primera ola de repaso. Las ya completadas no se cambian.",
|
"hint": "Marca filas faltantes o abiertas como completadas, con puntuación objetivo y primera ola de repaso. Las ya completadas no se cambian.",
|
||||||
"submit": "Marcar hasta aquí como completadas",
|
"submit": "Marcar hasta aquí como completadas",
|
||||||
|
"confirmTitle": "Marcar lecciones como completadas",
|
||||||
"confirm": "¿Marcar todas las lecciones con número ≤ {n} para {username} en este curso como completadas?",
|
"confirm": "¿Marcar todas las lecciones con número ≤ {n} para {username} en este curso como completadas?",
|
||||||
"success": "{marked} lección(es) marcadas como completadas ({unchanged} ya estaban hechas).",
|
"success": "{marked} lección(es) marcadas como completadas ({unchanged} ya estaban hechas).",
|
||||||
"successNone": "Sin cambios: todas las lecciones afectadas ({unchanged}) ya estaban completadas.",
|
"successNone": "Sin cambios: todas las lecciones afectadas ({unchanged}) ya estaban completadas.",
|
||||||
|
|||||||
@@ -657,7 +657,17 @@
|
|||||||
"courseShareCodePlaceholder": "p. ej. abc123def456",
|
"courseShareCodePlaceholder": "p. ej. abc123def456",
|
||||||
"courseFlowEyebrow": "Flujo del día",
|
"courseFlowEyebrow": "Flujo del día",
|
||||||
"courseFlowTitle": "La mejor continuación para hoy",
|
"courseFlowTitle": "La mejor continuación para hoy",
|
||||||
"courseFlowIntro": "El orden sigue el concepto: primero los repasos pendientes, luego el bloque actual, después la fase intensiva y al final la práctica libre.",
|
"courseFlowIntro": "Primero la sugerencia del día con orden concreto. Debajo, las cuatro zonas: repaso breve pendiente, bloque actual, fase intensiva, práctica libre.",
|
||||||
|
"courseTodayPlanTitle": "Sugerencia para hoy",
|
||||||
|
"courseTodayPlanIntro": "Orden práctico: primero todo lo marcado como repaso breve pendiente, luego las lecciones abiertas de tu bloque, después la fase intensiva si aparece. Los repasos breves son tres citas cortas tras terminar una lección (típicamente aprox. 1, 3 y 7 días) para fijar vocabulario.",
|
||||||
|
"courseTodayPlanStepReviewDue": "Repaso breve ahora",
|
||||||
|
"courseTodayPlanStepBlock": "Seguir en el bloque actual",
|
||||||
|
"courseTodayPlanStepIntensive": "Repaso intensivo",
|
||||||
|
"courseTodayPlanStepContinue": "Siguiente en tu ruta",
|
||||||
|
"courseTodayPlanStepPractice": "Práctica libre (opcional)",
|
||||||
|
"courseTodayPlanOpen": "Abrir lección",
|
||||||
|
"courseTodayPlanTrainer": "Abrir entrenador",
|
||||||
|
"courseTodayPlanEmpty": "Ahora no hay repaso escalonado pendiente ni un siguiente paso claro en el bloque. Elige una lección abajo o usa la práctica libre con el entrenador.",
|
||||||
"courseFlowReviewStat": "Repaso pendiente: {count}",
|
"courseFlowReviewStat": "Repaso pendiente: {count}",
|
||||||
"courseFlowBlockStat": "Bloque activo: {block}",
|
"courseFlowBlockStat": "Bloque activo: {block}",
|
||||||
"courseFlowReviewTitle": "Repaso pendiente",
|
"courseFlowReviewTitle": "Repaso pendiente",
|
||||||
@@ -698,10 +708,20 @@
|
|||||||
"reviewBadgeScheduleInDays": "siguiente ola en {count} días",
|
"reviewBadgeScheduleInDays": "siguiente ola en {count} días",
|
||||||
"reviewBadgeScheduleToday": "ola prevista hoy",
|
"reviewBadgeScheduleToday": "ola prevista hoy",
|
||||||
"reviewBadgeScheduleOverdue": "ola atrasada ({count} días)",
|
"reviewBadgeScheduleOverdue": "ola atrasada ({count} días)",
|
||||||
"reviewStageDay1": "Día 1",
|
"reviewBadgeLineAllDone": "Todos los repasos breves hechos (3×)",
|
||||||
"reviewStageDay3": "Día 3",
|
"reviewBadgeLineDue": "Repaso breve: paso {step} de 3 · toca ahora",
|
||||||
"reviewStageDay7": "Día 7",
|
"reviewBadgeLineScheduled": "Repaso breve: paso {step} de 3 · siguiente el {when}",
|
||||||
"reviewStageCompleted": "Repaso completado",
|
"reviewWhenFriendlyTomorrow": "mañana",
|
||||||
|
"reviewWhenFriendlyInDays": "en {count} días",
|
||||||
|
"reviewWhenFriendlyToday": "hoy",
|
||||||
|
"reviewWhenFriendlyOverdue": "atrasado (hace {count} día(s))",
|
||||||
|
"reviewWhenFriendlySoon": "pronto",
|
||||||
|
"reviewBadgeTooltipDone": "Completaste los tres repasos breves sugeridos tras esta lección. Puedes seguir practicando en el entrenador.",
|
||||||
|
"reviewBadgeTooltipActive": "Tras completar la lección, el curso propone tres repasos breves separados unos 1, 3 y 7 días para que el vocabulario quede fijo. La etiqueta indica qué paso (1–3) toca o cuándo es la siguiente cita.",
|
||||||
|
"reviewStageDay1": "Paso 1 de 3 (~1 día)",
|
||||||
|
"reviewStageDay3": "Paso 2 de 3 (~3 días)",
|
||||||
|
"reviewStageDay7": "Paso 3 de 3 (~7 días)",
|
||||||
|
"reviewStageCompleted": "Todos los repasos breves hechos",
|
||||||
"phaseQuickstart": "Inicio rápido",
|
"phaseQuickstart": "Inicio rápido",
|
||||||
"phaseDailyLife": "Vida diaria",
|
"phaseDailyLife": "Vida diaria",
|
||||||
"phaseStabilization": "Estabilización",
|
"phaseStabilization": "Estabilización",
|
||||||
|
|||||||
@@ -113,6 +113,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import apiClient from '@/utils/axios.js';
|
import apiClient from '@/utils/axios.js';
|
||||||
|
import { confirmAction } from '@/utils/feedback.js';
|
||||||
import AdminUserSearch from '@/components/admin/AdminUserSearch.vue';
|
import AdminUserSearch from '@/components/admin/AdminUserSearch.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -243,20 +244,23 @@ export default {
|
|||||||
this.loadingVocabCourseDetail = false;
|
this.loadingVocabCourseDetail = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
adminResetVocabLesson() {
|
async adminResetVocabLesson() {
|
||||||
if (!this.selected || !this.selectedVocabLessonId || this.vocabResetSubmitting) {
|
if (!this.selected || !this.selectedVocabLessonId || this.vocabResetSubmitting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const lesson = this.vocabCourseLessons.find((l) => String(l.id) === String(this.selectedVocabLessonId));
|
const lesson = this.vocabCourseLessons.find((l) => String(l.id) === String(this.selectedVocabLessonId));
|
||||||
const lessonLabel = lesson ? `${lesson.lessonNumber}. ${lesson.title}` : this.selectedVocabLessonId;
|
const lessonLabel = lesson ? `${lesson.lessonNumber}. ${lesson.title}` : this.selectedVocabLessonId;
|
||||||
const msg = this.$t('admin.vocabLessonReset.confirm', {
|
const confirmed = await confirmAction(this, {
|
||||||
lesson: lessonLabel,
|
title: this.$t('admin.vocabLessonReset.confirmTitle'),
|
||||||
username: this.selected.username
|
message: this.$t('admin.vocabLessonReset.confirm', {
|
||||||
|
lesson: lessonLabel,
|
||||||
|
username: this.selected.username
|
||||||
|
})
|
||||||
});
|
});
|
||||||
if (!window.confirm(msg)) {
|
if (!confirmed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.runAdminVocabReset();
|
await this.runAdminVocabReset();
|
||||||
},
|
},
|
||||||
async runAdminVocabReset() {
|
async runAdminVocabReset() {
|
||||||
this.vocabResetSubmitting = true;
|
this.vocabResetSubmitting = true;
|
||||||
@@ -272,19 +276,22 @@ export default {
|
|||||||
this.vocabResetSubmitting = false;
|
this.vocabResetSubmitting = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
adminMarkVocabLessonsThrough() {
|
async adminMarkVocabLessonsThrough() {
|
||||||
if (!this.selected || !this.selectedVocabCourseId || !this.canMarkVocabThrough || this.vocabMarkSubmitting) {
|
if (!this.selected || !this.selectedVocabCourseId || !this.canMarkVocabThrough || this.vocabMarkSubmitting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const n = Number(this.vocabMarkThroughNumber);
|
const n = Number(this.vocabMarkThroughNumber);
|
||||||
const msg = this.$t('admin.vocabLessonMarkComplete.confirm', {
|
const confirmed = await confirmAction(this, {
|
||||||
n,
|
title: this.$t('admin.vocabLessonMarkComplete.confirmTitle'),
|
||||||
username: this.selected.username
|
message: this.$t('admin.vocabLessonMarkComplete.confirm', {
|
||||||
|
n,
|
||||||
|
username: this.selected.username
|
||||||
|
})
|
||||||
});
|
});
|
||||||
if (!window.confirm(msg)) {
|
if (!confirmed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.runAdminVocabMarkThrough();
|
await this.runAdminVocabMarkThrough();
|
||||||
},
|
},
|
||||||
async runAdminVocabMarkThrough() {
|
async runAdminVocabMarkThrough() {
|
||||||
this.vocabMarkSubmitting = true;
|
this.vocabMarkSubmitting = true;
|
||||||
|
|||||||
@@ -51,6 +51,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="todayRecommendedSteps.length > 0" class="course-today-plan">
|
||||||
|
<h4 class="course-today-plan__title">{{ $t('socialnetwork.vocab.courses.courseTodayPlanTitle') }}</h4>
|
||||||
|
<p class="course-today-plan__intro">{{ $t('socialnetwork.vocab.courses.courseTodayPlanIntro') }}</p>
|
||||||
|
<ol class="course-today-plan__list">
|
||||||
|
<li v-for="(step, idx) in todayRecommendedSteps" :key="`${step.type}-${step.lesson.id}-${idx}`" class="course-today-plan__item">
|
||||||
|
<div class="course-today-plan__item-main">
|
||||||
|
<span class="course-today-plan__step-label">{{ todayPlanStepLabel(step.type) }}</span>
|
||||||
|
<span class="course-today-plan__lesson-title">{{ step.lesson.title }}</span>
|
||||||
|
<span class="course-today-plan__lesson-meta">#{{ step.lesson.lessonNumber }}</span>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="course-today-plan__action" @click="openTodayPlanStep(step)">
|
||||||
|
{{ step.type === 'practice' ? $t('socialnetwork.vocab.courses.courseTodayPlanTrainer') : $t('socialnetwork.vocab.courses.courseTodayPlanOpen') }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
<div v-else class="course-today-plan course-today-plan--empty">
|
||||||
|
<h4 class="course-today-plan__title">{{ $t('socialnetwork.vocab.courses.courseTodayPlanTitle') }}</h4>
|
||||||
|
<p class="course-today-plan__intro">{{ $t('socialnetwork.vocab.courses.courseTodayPlanEmpty') }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="course-flow__grid">
|
<div class="course-flow__grid">
|
||||||
<article class="course-flow-card">
|
<article class="course-flow-card">
|
||||||
<div class="course-flow-card__top">
|
<div class="course-flow-card__top">
|
||||||
@@ -177,6 +198,7 @@
|
|||||||
v-if="getReviewBadgeLabel(getLessonProgress(lesson.id, lesson))"
|
v-if="getReviewBadgeLabel(getLessonProgress(lesson.id, lesson))"
|
||||||
class="review-badge"
|
class="review-badge"
|
||||||
:class="getReviewBadgeClass(getLessonProgress(lesson.id, lesson))"
|
:class="getReviewBadgeClass(getLessonProgress(lesson.id, lesson))"
|
||||||
|
:title="getReviewBadgeTooltip(getLessonProgress(lesson.id, lesson))"
|
||||||
>
|
>
|
||||||
{{ getReviewBadgeLabel(getLessonProgress(lesson.id, lesson)) }}
|
{{ getReviewBadgeLabel(getLessonProgress(lesson.id, lesson)) }}
|
||||||
</span>
|
</span>
|
||||||
@@ -372,6 +394,32 @@ export default {
|
|||||||
})
|
})
|
||||||
.slice(0, 4);
|
.slice(0, 4);
|
||||||
},
|
},
|
||||||
|
todayRecommendedSteps() {
|
||||||
|
const out = [];
|
||||||
|
const seen = new Set();
|
||||||
|
const push = (type, lesson) => {
|
||||||
|
if (!lesson?.id || seen.has(lesson.id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
seen.add(lesson.id);
|
||||||
|
out.push({ type, lesson });
|
||||||
|
};
|
||||||
|
this.dueReviewLessons.forEach((l) => push('review_due', l));
|
||||||
|
this.currentBlockLessons.slice(0, 3).forEach((l) => push('block', l));
|
||||||
|
if (this.nextIntensiveReviewLesson) {
|
||||||
|
push('intensive', this.nextIntensiveReviewLesson);
|
||||||
|
}
|
||||||
|
if (out.length === 0 && this.currentLesson) {
|
||||||
|
const p = this.getLessonProgress(this.currentLesson.id, this.currentLesson);
|
||||||
|
if (!p?.completed) {
|
||||||
|
push('continue', this.currentLesson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out.length === 0 && this.freePracticeLessons.length > 0) {
|
||||||
|
push('practice', this.freePracticeLessons[0]);
|
||||||
|
}
|
||||||
|
return out.slice(0, 8);
|
||||||
|
},
|
||||||
isLessonNumberValid() {
|
isLessonNumberValid() {
|
||||||
return Number(this.newLesson.lessonNumber) > 0;
|
return Number(this.newLesson.lessonNumber) > 0;
|
||||||
},
|
},
|
||||||
@@ -502,7 +550,7 @@ export default {
|
|||||||
}
|
}
|
||||||
return this.$t('socialnetwork.vocab.courses.reviewDueSinceDays', { count: diffDays });
|
return this.$t('socialnetwork.vocab.courses.reviewDueSinceDays', { count: diffDays });
|
||||||
},
|
},
|
||||||
formatReviewBadgeSchedule(reviewNextDueAt) {
|
formatReviewWhenFriendly(reviewNextDueAt) {
|
||||||
if (!reviewNextDueAt) {
|
if (!reviewNextDueAt) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -514,15 +562,15 @@ export default {
|
|||||||
if (diffMs > 0) {
|
if (diffMs > 0) {
|
||||||
const untilDays = Math.ceil(diffMs / (24 * 60 * 60 * 1000));
|
const untilDays = Math.ceil(diffMs / (24 * 60 * 60 * 1000));
|
||||||
if (untilDays <= 1) {
|
if (untilDays <= 1) {
|
||||||
return this.$t('socialnetwork.vocab.courses.reviewBadgeScheduleTomorrow');
|
return this.$t('socialnetwork.vocab.courses.reviewWhenFriendlyTomorrow');
|
||||||
}
|
}
|
||||||
return this.$t('socialnetwork.vocab.courses.reviewBadgeScheduleInDays', { count: untilDays });
|
return this.$t('socialnetwork.vocab.courses.reviewWhenFriendlyInDays', { count: untilDays });
|
||||||
}
|
}
|
||||||
const diffDays = Math.floor((Date.now() - dueTimestamp) / (24 * 60 * 60 * 1000));
|
const diffDays = Math.floor((Date.now() - dueTimestamp) / (24 * 60 * 60 * 1000));
|
||||||
if (diffDays <= 0) {
|
if (diffDays <= 0) {
|
||||||
return this.$t('socialnetwork.vocab.courses.reviewBadgeScheduleToday');
|
return this.$t('socialnetwork.vocab.courses.reviewWhenFriendlyToday');
|
||||||
}
|
}
|
||||||
return this.$t('socialnetwork.vocab.courses.reviewBadgeScheduleOverdue', { count: diffDays });
|
return this.$t('socialnetwork.vocab.courses.reviewWhenFriendlyOverdue', { count: diffDays });
|
||||||
},
|
},
|
||||||
canShowLessonTrainer(lesson) {
|
canShowLessonTrainer(lesson) {
|
||||||
const p = this.getLessonProgress(lesson.id, lesson);
|
const p = this.getLessonProgress(lesson.id, lesson);
|
||||||
@@ -537,31 +585,35 @@ export default {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
getReviewStageLabel(progress) {
|
|
||||||
const stage = Number(progress?.reviewStage || 0);
|
|
||||||
if (stage === 0) return this.$t('socialnetwork.vocab.courses.reviewStageDay1');
|
|
||||||
if (stage === 1) return this.$t('socialnetwork.vocab.courses.reviewStageDay3');
|
|
||||||
if (stage === 2) return this.$t('socialnetwork.vocab.courses.reviewStageDay7');
|
|
||||||
if (stage >= 3) return this.$t('socialnetwork.vocab.courses.reviewStageCompleted');
|
|
||||||
return '';
|
|
||||||
},
|
|
||||||
getReviewBadgeLabel(progress) {
|
getReviewBadgeLabel(progress) {
|
||||||
if (!progress?.completed) {
|
if (!progress?.completed) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
const stageLabel = this.getReviewStageLabel(progress);
|
if (progress.reviewCompleted) {
|
||||||
if (!stageLabel) {
|
return this.$t('socialnetwork.vocab.courses.reviewBadgeLineAllDone');
|
||||||
|
}
|
||||||
|
const stage = Number(progress.reviewStage ?? 0);
|
||||||
|
const step = Math.min(3, stage + 1);
|
||||||
|
if (progress.reviewDue) {
|
||||||
|
return this.$t('socialnetwork.vocab.courses.reviewBadgeLineDue', { step });
|
||||||
|
}
|
||||||
|
const when = this.formatReviewWhenFriendly(progress.reviewNextDueAt);
|
||||||
|
if (when) {
|
||||||
|
return this.$t('socialnetwork.vocab.courses.reviewBadgeLineScheduled', { step, when });
|
||||||
|
}
|
||||||
|
return this.$t('socialnetwork.vocab.courses.reviewBadgeLineScheduled', {
|
||||||
|
step,
|
||||||
|
when: this.$t('socialnetwork.vocab.courses.reviewWhenFriendlySoon')
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getReviewBadgeTooltip(progress) {
|
||||||
|
if (!progress?.completed) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (progress.reviewCompleted) {
|
if (progress.reviewCompleted) {
|
||||||
return stageLabel;
|
return this.$t('socialnetwork.vocab.courses.reviewBadgeTooltipDone');
|
||||||
}
|
}
|
||||||
if (progress.reviewDue) {
|
return this.$t('socialnetwork.vocab.courses.reviewBadgeTooltipActive');
|
||||||
const dueLabel = this.formatReviewDue(progress.reviewNextDueAt);
|
|
||||||
return `${stageLabel} · ${dueLabel}`;
|
|
||||||
}
|
|
||||||
const scheduleLabel = this.formatReviewBadgeSchedule(progress.reviewNextDueAt);
|
|
||||||
return scheduleLabel ? `${stageLabel} · ${scheduleLabel}` : stageLabel;
|
|
||||||
},
|
},
|
||||||
getReviewBadgeClass(progress) {
|
getReviewBadgeClass(progress) {
|
||||||
if (!progress?.completed) {
|
if (!progress?.completed) {
|
||||||
@@ -639,6 +691,26 @@ export default {
|
|||||||
openLesson(lessonId) {
|
openLesson(lessonId) {
|
||||||
this.$router.push(`/socialnetwork/vocab/courses/${this.courseId}/lessons/${lessonId}`);
|
this.$router.push(`/socialnetwork/vocab/courses/${this.courseId}/lessons/${lessonId}`);
|
||||||
},
|
},
|
||||||
|
todayPlanStepLabel(type) {
|
||||||
|
const key = {
|
||||||
|
review_due: 'courseTodayPlanStepReviewDue',
|
||||||
|
block: 'courseTodayPlanStepBlock',
|
||||||
|
intensive: 'courseTodayPlanStepIntensive',
|
||||||
|
continue: 'courseTodayPlanStepContinue',
|
||||||
|
practice: 'courseTodayPlanStepPractice'
|
||||||
|
}[type];
|
||||||
|
return key ? this.$t(`socialnetwork.vocab.courses.${key}`) : '';
|
||||||
|
},
|
||||||
|
openTodayPlanStep(step) {
|
||||||
|
if (!step?.lesson) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (step.type === 'practice') {
|
||||||
|
this.openLessonPractice(step.lesson);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.openLesson(step.lesson.id);
|
||||||
|
},
|
||||||
openLessonPractice(lesson) {
|
openLessonPractice(lesson) {
|
||||||
this.$refs.practiceDialog?.open?.({
|
this.$refs.practiceDialog?.open?.({
|
||||||
courseId: this.courseId,
|
courseId: this.courseId,
|
||||||
@@ -1259,6 +1331,96 @@ export default {
|
|||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.course-today-plan {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 16px 18px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(255, 248, 235, 0.75);
|
||||||
|
border: 1px solid rgba(212, 184, 150, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan--empty {
|
||||||
|
background: rgba(250, 250, 250, 0.85);
|
||||||
|
border-color: var(--color-border, #e0dcd6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan__title {
|
||||||
|
margin: 0 0 8px;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
font-weight: 650;
|
||||||
|
color: var(--color-text-primary, #3a322c);
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan__intro {
|
||||||
|
margin: 0 0 14px;
|
||||||
|
font-size: 0.88rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--color-text-secondary, #5c534c);
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan__list {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1.25rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan__item {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan__item-main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan__step-label {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #8a6d3b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan__lesson-title {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan__lesson-meta {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan__action {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--color-border-strong, #c9c2b8);
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-today-plan__action:hover {
|
||||||
|
border-color: #b8a896;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-badge[title] {
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.course-flow__grid {
|
.course-flow__grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
|||||||
Reference in New Issue
Block a user