mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-03 07:42:03 +00:00
useCourseData into reusable hooks
This commit is contained in:
parent
045418397c
commit
51cd1e4d97
@ -1,9 +1,13 @@
|
||||
import useCourseDecryption from '../encryption/useCourseDecryption';
|
||||
import useCourseTabs from './useCourseTabs';
|
||||
import useCoursePayment from './useCoursePayment';
|
||||
import useCourseData from './useCourseData';
|
||||
import useLessons from './useLessons';
|
||||
|
||||
export {
|
||||
useCourseDecryption,
|
||||
useCourseTabs,
|
||||
useCoursePayment
|
||||
useCoursePayment,
|
||||
useCourseData,
|
||||
useLessons
|
||||
};
|
79
src/hooks/courses/useCourseData.js
Normal file
79
src/hooks/courses/useCourseData.js
Normal file
@ -0,0 +1,79 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { parseCourseEvent } from '@/utils/nostr';
|
||||
import { nip19 } from 'nostr-tools';
|
||||
import { useToast } from '../useToast';
|
||||
|
||||
/**
|
||||
* Hook to fetch and manage course data
|
||||
* @param {Object} ndk - NDK instance for Nostr data fetching
|
||||
* @param {Function} fetchAuthor - Function to fetch author data
|
||||
* @param {Object} router - Next.js router instance
|
||||
* @returns {Object} Course data and related state
|
||||
*/
|
||||
const useCourseData = (ndk, fetchAuthor, router) => {
|
||||
const [course, setCourse] = useState(null);
|
||||
const [lessonIds, setLessonIds] = useState([]);
|
||||
const [paidCourse, setPaidCourse] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const { showToast } = useToast();
|
||||
|
||||
useEffect(() => {
|
||||
if (!router.isReady) return;
|
||||
|
||||
const { slug } = router.query;
|
||||
|
||||
const fetchCourseId = async () => {
|
||||
if (slug.includes('naddr')) {
|
||||
const { data } = nip19.decode(slug);
|
||||
if (!data?.identifier) {
|
||||
showToast('error', 'Error', 'Resource not found');
|
||||
return null;
|
||||
}
|
||||
return data.identifier;
|
||||
} else {
|
||||
return slug;
|
||||
}
|
||||
};
|
||||
|
||||
const fetchCourse = async courseId => {
|
||||
try {
|
||||
await ndk.connect();
|
||||
const event = await ndk.fetchEvent({ '#d': [courseId] });
|
||||
if (!event) return null;
|
||||
|
||||
const author = await fetchAuthor(event.pubkey);
|
||||
const lessonIds = event.tags.filter(tag => tag[0] === 'a').map(tag => tag[1].split(':')[2]);
|
||||
|
||||
const parsedCourse = { ...parseCourseEvent(event), author };
|
||||
return { parsedCourse, lessonIds };
|
||||
} catch (error) {
|
||||
console.error('Error fetching event:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const initializeCourse = async () => {
|
||||
setLoading(true);
|
||||
const id = await fetchCourseId();
|
||||
if (!id) {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const courseData = await fetchCourse(id);
|
||||
if (courseData) {
|
||||
const { parsedCourse, lessonIds } = courseData;
|
||||
setCourse(parsedCourse);
|
||||
setLessonIds(lessonIds);
|
||||
setPaidCourse(parsedCourse.price && parsedCourse.price > 0);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
initializeCourse();
|
||||
}, [router.isReady, router.query, ndk, fetchAuthor, showToast]);
|
||||
|
||||
return { course, lessonIds, paidCourse, loading };
|
||||
};
|
||||
|
||||
export default useCourseData;
|
61
src/hooks/courses/useLessons.js
Normal file
61
src/hooks/courses/useLessons.js
Normal file
@ -0,0 +1,61 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { parseEvent } from '@/utils/nostr';
|
||||
|
||||
/**
|
||||
* Hook to fetch and manage lesson data for a course
|
||||
* @param {Object} ndk - NDK instance for Nostr data fetching
|
||||
* @param {Function} fetchAuthor - Function to fetch author data
|
||||
* @param {Array} lessonIds - Array of lesson IDs to fetch
|
||||
* @param {String} pubkey - Public key of the course author
|
||||
* @returns {Object} Lesson data and state
|
||||
*/
|
||||
const useLessons = (ndk, fetchAuthor, lessonIds, pubkey) => {
|
||||
const [lessons, setLessons] = useState([]);
|
||||
const [uniqueLessons, setUniqueLessons] = useState([]);
|
||||
|
||||
// Fetch lessons when IDs or pubkey change
|
||||
useEffect(() => {
|
||||
if (lessonIds.length > 0 && pubkey) {
|
||||
const fetchLessons = async () => {
|
||||
try {
|
||||
await ndk.connect();
|
||||
|
||||
// Create a single filter with all lesson IDs to avoid multiple calls
|
||||
const filter = {
|
||||
'#d': lessonIds,
|
||||
kinds: [30023, 30402],
|
||||
authors: [pubkey],
|
||||
};
|
||||
|
||||
const events = await ndk.fetchEvents(filter);
|
||||
const newLessons = [];
|
||||
|
||||
// Process events
|
||||
for (const event of events) {
|
||||
const author = await fetchAuthor(event.pubkey);
|
||||
const parsedLesson = { ...parseEvent(event), author };
|
||||
newLessons.push(parsedLesson);
|
||||
}
|
||||
|
||||
setLessons(newLessons);
|
||||
} catch (error) {
|
||||
console.error('Error fetching events:', error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchLessons();
|
||||
}
|
||||
}, [lessonIds, ndk, fetchAuthor, pubkey]);
|
||||
|
||||
// Deduplicate lessons
|
||||
useEffect(() => {
|
||||
const newUniqueLessons = Array.from(
|
||||
new Map(lessons.map(lesson => [lesson.id, lesson])).values()
|
||||
);
|
||||
setUniqueLessons(newUniqueLessons);
|
||||
}, [lessons]);
|
||||
|
||||
return { lessons, uniqueLessons, setLessons };
|
||||
};
|
||||
|
||||
export default useLessons;
|
Loading…
x
Reference in New Issue
Block a user