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:
57
src/helpers/router.js
Normal file
57
src/helpers/router.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* URL Router for Code Crispies
|
||||
* Handles hash-based routing for shareable lesson links
|
||||
* Format: #module-id/lesson-index (e.g., #flexbox/2)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parse current URL hash into module and lesson info
|
||||
* @returns {{ moduleId: string, lessonIndex: number } | null}
|
||||
*/
|
||||
export function parseHash() {
|
||||
const hash = window.location.hash.slice(1); // Remove '#'
|
||||
if (!hash) return null;
|
||||
|
||||
const parts = hash.split("/");
|
||||
if (parts.length !== 2) return null;
|
||||
|
||||
const moduleId = parts[0];
|
||||
const lessonIndex = parseInt(parts[1], 10);
|
||||
|
||||
if (!moduleId || isNaN(lessonIndex) || lessonIndex < 0) return null;
|
||||
|
||||
return { moduleId, lessonIndex };
|
||||
}
|
||||
|
||||
/**
|
||||
* Update URL hash with history entry (for navigation)
|
||||
* @param {string} moduleId
|
||||
* @param {number} lessonIndex
|
||||
*/
|
||||
export function updateHash(moduleId, lessonIndex) {
|
||||
const newHash = `#${moduleId}/${lessonIndex}`;
|
||||
if (window.location.hash !== newHash) {
|
||||
history.pushState(null, "", newHash);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace URL hash without history entry (for invalid URL fallbacks)
|
||||
* @param {string} moduleId
|
||||
* @param {number} lessonIndex
|
||||
*/
|
||||
export function replaceHash(moduleId, lessonIndex) {
|
||||
const newHash = `#${moduleId}/${lessonIndex}`;
|
||||
history.replaceState(null, "", newHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build full shareable URL for current lesson
|
||||
* @param {string} moduleId
|
||||
* @param {number} lessonIndex
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getShareableUrl(moduleId, lessonIndex) {
|
||||
const base = window.location.origin + window.location.pathname;
|
||||
return `${base}#${moduleId}/${lessonIndex}`;
|
||||
}
|
||||
Reference in New Issue
Block a user