57 lines
1.4 KiB
TypeScript
57 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
|
|
|
const STORAGE_KEY = "digital-course-video-completed";
|
|
|
|
function loadCompleted(): Set<string> {
|
|
if (typeof window === "undefined") return new Set();
|
|
try {
|
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
if (!raw) return new Set();
|
|
const arr = JSON.parse(raw) as string[];
|
|
return new Set(Array.isArray(arr) ? arr : []);
|
|
} catch {
|
|
return new Set();
|
|
}
|
|
}
|
|
|
|
function saveCompleted(ids: Set<string>) {
|
|
if (typeof window === "undefined") return;
|
|
try {
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify([...ids]));
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
export function useVideoProgress() {
|
|
const [completed, setCompleted] = useState<Set<string>>(() => new Set());
|
|
|
|
useEffect(() => {
|
|
setCompleted(loadCompleted());
|
|
}, []);
|
|
|
|
const markCompleted = useCallback((lessonId: string) => {
|
|
setCompleted((prev) => {
|
|
const next = new Set(prev);
|
|
next.add(lessonId);
|
|
saveCompleted(next);
|
|
return next;
|
|
});
|
|
}, []);
|
|
|
|
const isCompleted = useCallback(
|
|
(lessonId: string) => completed.has(lessonId),
|
|
[completed]
|
|
);
|
|
|
|
const isPartCompleted = useCallback(
|
|
(lessonIds: string[]) =>
|
|
lessonIds.length > 0 && lessonIds.every((id) => completed.has(id)),
|
|
[completed]
|
|
);
|
|
|
|
return { completed, markCompleted, isCompleted, isPartCompleted };
|
|
}
|