- 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)
58 lines
1.5 KiB
JavaScript
58 lines
1.5 KiB
JavaScript
/**
|
|
* 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}`;
|
|
}
|