feat: add shareable lesson links with URL routing

- Add share button with SVG link icon in lesson title row
- Create share dialog with copy URL functionality
- Implement URL hash-based routing for lesson navigation
- Support browser back/forward navigation
- Add i18n translations for share dialog in all languages
- Position share button between title and completion badge
- Add RTL support for title row layout

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
2026-01-14 21:35:49 +01:00
parent a4563638a0
commit 0f14568d2c
5 changed files with 364 additions and 53 deletions

View File

@@ -99,6 +99,13 @@ const translations = {
dontShowAgain: "Don't show this again",
reset: "Reset",
// Share dialog
shareDialogTitle: "Share Lesson",
shareDialogText: "Copy this URL to share the current lesson:",
shareTitle: "Share lesson",
copyUrl: "Copy",
urlCopied: "URL copied to clipboard!",
// Dynamic content
loadingFallbackText: "Could not load lesson. Please select one from the menu or check the help.",
completed: "Completed",
@@ -207,6 +214,13 @@ const translations = {
dontShowAgain: "Nicht mehr anzeigen",
reset: "Zurücksetzen",
// Share dialog
shareDialogTitle: "Lektion teilen",
shareDialogText: "Kopiere diese URL, um die aktuelle Lektion zu teilen:",
shareTitle: "Lektion teilen",
copyUrl: "Kopieren",
urlCopied: "URL in die Zwischenablage kopiert!",
// Dynamic content
loadingFallbackText: "Lektion konnte nicht geladen werden. Bitte wähle eine aus dem Menü oder prüfe die Hilfe.",
completed: "Erledigt",
@@ -315,6 +329,13 @@ const translations = {
dontShowAgain: "Nie pokazuj ponownie",
reset: "Resetuj",
// Share dialog
shareDialogTitle: "Udostępnij lekcję",
shareDialogText: "Skopiuj ten URL, aby udostępnić bieżącą lekcję:",
shareTitle: "Udostępnij lekcję",
copyUrl: "Kopiuj",
urlCopied: "URL skopiowany do schowka!",
// Dynamic content
loadingFallbackText: "Nie można załadować lekcji. Wybierz jedną z menu lub sprawdź pomoc.",
completed: "Ukończono",
@@ -424,6 +445,13 @@ const translations = {
dontShowAgain: "No mostrar de nuevo",
reset: "Reiniciar",
// Share dialog
shareDialogTitle: "Compartir lección",
shareDialogText: "Copia esta URL para compartir la lección actual:",
shareTitle: "Compartir lección",
copyUrl: "Copiar",
urlCopied: "¡URL copiada al portapapeles!",
// Dynamic content
loadingFallbackText: "No se pudo cargar la lección. Selecciona una del menú o consulta la ayuda.",
completed: "Completado",
@@ -531,6 +559,13 @@ const translations = {
dontShowAgain: "لا تظهر هذا مرة أخرى",
reset: "إعادة تعيين",
// Share dialog
shareDialogTitle: "مشاركة الدرس",
shareDialogText: "انسخ هذا الرابط لمشاركة الدرس الحالي:",
shareTitle: "مشاركة الدرس",
copyUrl: "نسخ",
urlCopied: "تم نسخ الرابط إلى الحافظة!",
// Dynamic content
loadingFallbackText: "تعذر تحميل الدرس. اختر واحدًا من القائمة أو تحقق من المساعدة.",
completed: "مكتمل",
@@ -639,6 +674,13 @@ const translations = {
dontShowAgain: "Більше не показувати",
reset: "Скинути",
// Share dialog
shareDialogTitle: "Поділитися уроком",
shareDialogText: "Скопіюйте цю URL-адресу, щоб поділитися поточним уроком:",
shareTitle: "Поділитися уроком",
copyUrl: "Копіювати",
urlCopied: "URL-адресу скопійовано до буфера обміну!",
// Dynamic content
loadingFallbackText: "Не вдалося завантажити урок. Виберіть один з меню або перевірте допомогу.",
completed: "Завершено",