mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-05-20 08:52:03 +00:00
Nostr queries working for courses resources and workshops
This commit is contained in:
parent
ff6b6bbc2c
commit
9a1694dc74
@ -4,7 +4,8 @@ import { parseCourseEvent } from '@/utils/nostr';
|
|||||||
import { useNostr } from '@/hooks/useNostr';
|
import { useNostr } from '@/hooks/useNostr';
|
||||||
import CourseTemplate from '@/components/content/carousels/templates/CourseTemplate';
|
import CourseTemplate from '@/components/content/carousels/templates/CourseTemplate';
|
||||||
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
||||||
import { useNostrQueries } from '@/hooks/useNostrQueries';
|
// import { useNostrQueries } from '@/hooks/useNostrQueries';
|
||||||
|
import { useCoursesQuery } from '@/hooks/nostrQueries/useCoursesQuery';
|
||||||
|
|
||||||
const responsiveOptions = [
|
const responsiveOptions = [
|
||||||
{
|
{
|
||||||
@ -27,17 +28,8 @@ const responsiveOptions = [
|
|||||||
export default function CoursesCarousel() {
|
export default function CoursesCarousel() {
|
||||||
const [processedCourses, setProcessedCourses] = useState([]);
|
const [processedCourses, setProcessedCourses] = useState([]);
|
||||||
const { fetchZapsForEvents } = useNostr();
|
const { fetchZapsForEvents } = useNostr();
|
||||||
const { courses, coursesError, zapsForEvents, refetchZapsForEvents } = useNostrQueries()
|
// const { courses, coursesError, zapsForEvents, refetchZapsForEvents } = useNostrQueries()
|
||||||
|
const { courses, coursesError, refetchCourses } = useCoursesQuery()
|
||||||
useEffect(() => {
|
|
||||||
if (courses && courses.length > 0) {
|
|
||||||
refetchZapsForEvents(courses);
|
|
||||||
}
|
|
||||||
}, [courses]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log('zapsForEvents:', zapsForEvents);
|
|
||||||
}, [zapsForEvents]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetch = async () => {
|
const fetch = async () => {
|
||||||
|
@ -5,6 +5,7 @@ import { parseEvent } from '@/utils/nostr';
|
|||||||
import ResourceTemplate from '@/components/content/carousels/templates/ResourceTemplate';
|
import ResourceTemplate from '@/components/content/carousels/templates/ResourceTemplate';
|
||||||
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
||||||
import { useNostrQueries } from '@/hooks/useNostrQueries';
|
import { useNostrQueries } from '@/hooks/useNostrQueries';
|
||||||
|
import { useResourcesQuery } from '@/hooks/useResourcesQuery';
|
||||||
|
|
||||||
const responsiveOptions = [
|
const responsiveOptions = [
|
||||||
{
|
{
|
||||||
@ -27,7 +28,8 @@ const responsiveOptions = [
|
|||||||
export default function ResourcesCarousel() {
|
export default function ResourcesCarousel() {
|
||||||
const [processedResources, setProcessedResources] = useState([]);
|
const [processedResources, setProcessedResources] = useState([]);
|
||||||
const { fetchZapsForEvents } = useNostr();
|
const { fetchZapsForEvents } = useNostr();
|
||||||
const { resources, resourcesError, refetchResources } = useNostrQueries()
|
// const { resources, resourcesError, refetchResources } = useNostrQueries()
|
||||||
|
const { resources, resourcesError, refetchResources } = useResourcesQuery()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetch = async () => {
|
const fetch = async () => {
|
||||||
|
@ -6,7 +6,8 @@ import { useNostr } from '@/hooks/useNostr';
|
|||||||
import { parseEvent } from '@/utils/nostr';
|
import { parseEvent } from '@/utils/nostr';
|
||||||
import WorkshopTemplate from '@/components/content/carousels/templates/WorkshopTemplate';
|
import WorkshopTemplate from '@/components/content/carousels/templates/WorkshopTemplate';
|
||||||
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
||||||
import { useNostrQueries } from '@/hooks/useNostrQueries';
|
// import { useNostrQueries } from '@/hooks/useNostrQueries';
|
||||||
|
import { useWorkshopsQuery } from '@/hooks/nostrQueries/useWorkshopsQuery';
|
||||||
|
|
||||||
const responsiveOptions = [
|
const responsiveOptions = [
|
||||||
{
|
{
|
||||||
@ -29,7 +30,8 @@ const responsiveOptions = [
|
|||||||
export default function WorkshopsCarousel() {
|
export default function WorkshopsCarousel() {
|
||||||
const [processedWorkshops, setProcessedWorkshops] = useState([])
|
const [processedWorkshops, setProcessedWorkshops] = useState([])
|
||||||
|
|
||||||
const { workshops, workshopsError } = useNostrQueries()
|
// const { workshops, workshopsError } = useNostrQueries()
|
||||||
|
const { workshops, workshopsError, refetchWorkshops } = useWorkshopsQuery()
|
||||||
const { fetchZapsForEvents } = useNostr()
|
const { fetchZapsForEvents } = useNostr()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
61
src/hooks/nostrQueries/useCoursesQuery.js
Normal file
61
src/hooks/nostrQueries/useCoursesQuery.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { useNostr } from '@/hooks/useNostr';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
const AUTHOR_PUBKEY = process.env.NEXT_PUBLIC_AUTHOR_PUBKEY
|
||||||
|
|
||||||
|
export function useCoursesQuery() {
|
||||||
|
const [isClient, setIsClient] = useState(false);
|
||||||
|
const { subscribe } = useNostr();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsClient(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchCourses = async () => {
|
||||||
|
const filter = [{ kinds: [30004], authors: [AUTHOR_PUBKEY] }];
|
||||||
|
// Do we need required tags for courses? community instead?
|
||||||
|
// const hasRequiredTags = (tags) => {
|
||||||
|
// const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||||
|
// const hasCourse = tags.some(([tag, value]) => tag === "t" && value === "course");
|
||||||
|
// return hasPlebDevs && hasCourse;
|
||||||
|
// };
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let courses = [];
|
||||||
|
const subscription = subscribe(
|
||||||
|
filter,
|
||||||
|
{
|
||||||
|
onevent: (event) => {
|
||||||
|
// if (hasRequiredTags(event.tags)) {
|
||||||
|
// courses.push(event);
|
||||||
|
// }
|
||||||
|
courses.push(event);
|
||||||
|
},
|
||||||
|
onerror: (error) => {
|
||||||
|
console.error('Error fetching courses:', error);
|
||||||
|
reject(error);
|
||||||
|
},
|
||||||
|
onclose: () => {
|
||||||
|
resolve(courses);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
subscription?.close();
|
||||||
|
resolve(courses);
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: courses, isLoading: coursesLoading, error: coursesError, refetch: refetchCourses } = useQuery({
|
||||||
|
queryKey: ['courses', isClient],
|
||||||
|
queryFn: fetchCourses,
|
||||||
|
staleTime: 1000 * 60 * 10, // 10 minutes
|
||||||
|
cacheTime: 1000 * 60 * 60, // 1 hour
|
||||||
|
enabled: isClient,
|
||||||
|
})
|
||||||
|
|
||||||
|
return { courses, coursesLoading, coursesError, refetchCourses }
|
||||||
|
}
|
61
src/hooks/nostrQueries/useResourcesQuery.js
Normal file
61
src/hooks/nostrQueries/useResourcesQuery.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { useNostr } from '@/hooks/useNostr';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
const AUTHOR_PUBKEY = process.env.NEXT_PUBLIC_AUTHOR_PUBKEY
|
||||||
|
|
||||||
|
export function useResourcesQuery() {
|
||||||
|
const [isClient, setIsClient] = useState(false);
|
||||||
|
const { subscribe } = useNostr();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsClient(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchResources = async () => {
|
||||||
|
console.log('fetching resources');
|
||||||
|
const filter = [{ kinds: [30023, 30402], authors: [AUTHOR_PUBKEY] }];
|
||||||
|
const hasRequiredTags = (tags) => {
|
||||||
|
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||||
|
const hasResource = tags.some(([tag, value]) => tag === "t" && value === "resource");
|
||||||
|
return hasPlebDevs && hasResource;
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let resources = [];
|
||||||
|
const subscription = subscribe(
|
||||||
|
filter,
|
||||||
|
{
|
||||||
|
onevent: (event) => {
|
||||||
|
if (hasRequiredTags(event.tags)) {
|
||||||
|
resources.push(event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onerror: (error) => {
|
||||||
|
console.error('Error fetching resources:', error);
|
||||||
|
reject(error);
|
||||||
|
},
|
||||||
|
onclose: () => {
|
||||||
|
resolve(resources);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set a timeout to resolve the promise after collecting events
|
||||||
|
setTimeout(() => {
|
||||||
|
subscription?.close();
|
||||||
|
resolve(resources);
|
||||||
|
}, 2000); // Adjust the timeout value as needed
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: resources, isLoading: resourcesLoading, error: resourcesError, refetch: refetchResources } = useQuery({
|
||||||
|
queryKey: ['resources', isClient],
|
||||||
|
queryFn: fetchResources,
|
||||||
|
staleTime: 1000 * 60 * 10, // 10 minutes
|
||||||
|
cacheTime: 1000 * 60 * 60, // 1 hour
|
||||||
|
enabled: isClient,
|
||||||
|
})
|
||||||
|
|
||||||
|
return { resources, resourcesLoading, resourcesError, refetchResources }
|
||||||
|
}
|
61
src/hooks/nostrQueries/useWorkshopsQuery.js
Normal file
61
src/hooks/nostrQueries/useWorkshopsQuery.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { useNostr } from '@/hooks/useNostr';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
const AUTHOR_PUBKEY = process.env.NEXT_PUBLIC_AUTHOR_PUBKEY
|
||||||
|
|
||||||
|
export function useWorkshopsQuery() {
|
||||||
|
const [isClient, setIsClient] = useState(false);
|
||||||
|
const { subscribe } = useNostr();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsClient(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchWorkshops = async () => {
|
||||||
|
console.log('fetching workshops');
|
||||||
|
const filter = [{ kinds: [30023, 30402], authors: [AUTHOR_PUBKEY] }];
|
||||||
|
const hasRequiredTags = (tags) => {
|
||||||
|
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||||
|
const hasWorkshop = tags.some(([tag, value]) => tag === "t" && value === "workshop");
|
||||||
|
return hasPlebDevs && hasWorkshop;
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let resources = [];
|
||||||
|
const subscription = subscribe(
|
||||||
|
filter,
|
||||||
|
{
|
||||||
|
onevent: (event) => {
|
||||||
|
if (hasRequiredTags(event.tags)) {
|
||||||
|
resources.push(event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onerror: (error) => {
|
||||||
|
console.error('Error fetching resources:', error);
|
||||||
|
reject(error);
|
||||||
|
},
|
||||||
|
onclose: () => {
|
||||||
|
resolve(resources);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set a timeout to resolve the promise after collecting events
|
||||||
|
setTimeout(() => {
|
||||||
|
subscription?.close();
|
||||||
|
resolve(resources);
|
||||||
|
}, 2000); // Adjust the timeout value as needed
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: workshops, isLoading: workshopsLoading, error: workshopsError, refetch: refetchWorkshops } = useQuery({
|
||||||
|
queryKey: ['workshops', isClient],
|
||||||
|
queryFn: fetchWorkshops,
|
||||||
|
staleTime: 1000 * 60 * 10, // 10 minutes
|
||||||
|
cacheTime: 1000 * 60 * 60, // 1 hour
|
||||||
|
enabled: isClient,
|
||||||
|
})
|
||||||
|
|
||||||
|
return { workshops, workshopsLoading, workshopsError, refetchWorkshops }
|
||||||
|
}
|
@ -1,164 +0,0 @@
|
|||||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
||||||
import { useState, useEffect, useCallback } from 'react'
|
|
||||||
import { useNostr } from '@/hooks/useNostr'
|
|
||||||
|
|
||||||
const AUTHOR_PUBKEY = process.env.NEXT_PUBLIC_AUTHOR_PUBKEY
|
|
||||||
|
|
||||||
export function useNostrQueries() {
|
|
||||||
const [isClient, setIsClient] = useState(false)
|
|
||||||
|
|
||||||
const { subscribe, fetchZapsForEvent, fetchZapsForEvents } = useNostr()
|
|
||||||
const queryClient = useQueryClient()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setIsClient(true)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const fetchWorkshops = async () => {
|
|
||||||
const filter = [{ kinds: [30023, 30402], authors: [AUTHOR_PUBKEY] }]
|
|
||||||
const hasRequiredTags = (tags) => {
|
|
||||||
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs")
|
|
||||||
const hasWorkshop = tags.some(([tag, value]) => tag === "t" && value === "workshop")
|
|
||||||
return hasPlebDevs && hasWorkshop
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
let workshops = []
|
|
||||||
const subscription = subscribe(filter,
|
|
||||||
{
|
|
||||||
onevent: (event) => {
|
|
||||||
if (hasRequiredTags(event.tags)) {
|
|
||||||
workshops.push(event)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onerror: (error) => {
|
|
||||||
console.error('Error fetching workshops:', error)
|
|
||||||
reject(error);
|
|
||||||
},
|
|
||||||
onclose: () => {
|
|
||||||
resolve(workshops)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Set a timeout to resolve the promise after collecting events
|
|
||||||
setTimeout(() => {
|
|
||||||
subscription?.close()
|
|
||||||
resolve(workshops)
|
|
||||||
}, 2000) // Adjust the timeout value as needed
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchResources = async () => {
|
|
||||||
console.log('fetching resources');
|
|
||||||
const filter = [{ kinds: [30023, 30402], authors: [AUTHOR_PUBKEY] }];
|
|
||||||
const hasRequiredTags = (tags) => {
|
|
||||||
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
|
||||||
const hasResource = tags.some(([tag, value]) => tag === "t" && value === "resource");
|
|
||||||
return hasPlebDevs && hasResource;
|
|
||||||
};
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let resources = [];
|
|
||||||
const subscription = subscribe(
|
|
||||||
filter,
|
|
||||||
{
|
|
||||||
onevent: (event) => {
|
|
||||||
if (hasRequiredTags(event.tags)) {
|
|
||||||
resources.push(event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onerror: (error) => {
|
|
||||||
console.error('Error fetching resources:', error);
|
|
||||||
reject(error);
|
|
||||||
},
|
|
||||||
onclose: () => {
|
|
||||||
resolve(resources);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set a timeout to resolve the promise after collecting events
|
|
||||||
setTimeout(() => {
|
|
||||||
subscription?.close();
|
|
||||||
resolve(resources);
|
|
||||||
}, 2000); // Adjust the timeout value as needed
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchCourses = async () => {
|
|
||||||
const filter = [{ kinds: [30004], authors: [AUTHOR_PUBKEY] }];
|
|
||||||
// Do we need required tags for courses? community instead?
|
|
||||||
// const hasRequiredTags = (tags) => {
|
|
||||||
// const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
|
||||||
// const hasCourse = tags.some(([tag, value]) => tag === "t" && value === "course");
|
|
||||||
// return hasPlebDevs && hasCourse;
|
|
||||||
// };
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let courses = [];
|
|
||||||
const subscription = subscribe(
|
|
||||||
filter,
|
|
||||||
{
|
|
||||||
onevent: (event) => {
|
|
||||||
// if (hasRequiredTags(event.tags)) {
|
|
||||||
// courses.push(event);
|
|
||||||
// }
|
|
||||||
courses.push(event);
|
|
||||||
},
|
|
||||||
onerror: (error) => {
|
|
||||||
console.error('Error fetching courses:', error);
|
|
||||||
reject(error);
|
|
||||||
},
|
|
||||||
onclose: () => {
|
|
||||||
resolve(courses);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
subscription?.close();
|
|
||||||
resolve(courses);
|
|
||||||
}, 2000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data: workshops, isLoading: workshopsLoading, error: workshopsError, refetch: refetchWorkshops } = useQuery({
|
|
||||||
queryKey: ['workshops', isClient],
|
|
||||||
queryFn: fetchWorkshops,
|
|
||||||
staleTime: 1000 * 60 * 10, // 10 minutes
|
|
||||||
cacheTime: 1000 * 60 * 60, // 1 hour
|
|
||||||
enabled: isClient,
|
|
||||||
})
|
|
||||||
|
|
||||||
const { data: resources, isLoading: resourcesLoading, error: resourcesError, refetch: refetchResources } = useQuery({
|
|
||||||
queryKey: ['resources', isClient],
|
|
||||||
queryFn: fetchResources,
|
|
||||||
staleTime: 1000 * 60 * 10, // 10 minutes
|
|
||||||
cacheTime: 1000 * 60 * 60, // 1 hour
|
|
||||||
enabled: isClient,
|
|
||||||
})
|
|
||||||
|
|
||||||
const { data: courses, isLoading: coursesLoading, error: coursesError, refetch: refetchCourses } = useQuery({
|
|
||||||
queryKey: ['courses', isClient],
|
|
||||||
queryFn: fetchCourses,
|
|
||||||
staleTime: 1000 * 60 * 10, // 10 minutes
|
|
||||||
cacheTime: 1000 * 60 * 60, // 1 hour
|
|
||||||
enabled: isClient,
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
workshops,
|
|
||||||
workshopsLoading,
|
|
||||||
workshopsError,
|
|
||||||
resources,
|
|
||||||
resourcesLoading,
|
|
||||||
resourcesError,
|
|
||||||
courses,
|
|
||||||
coursesLoading,
|
|
||||||
coursesError,
|
|
||||||
refetchCourses,
|
|
||||||
refetchResources,
|
|
||||||
refetchWorkshops,
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,9 +19,9 @@ export default function Home() {
|
|||||||
</Head>
|
</Head>
|
||||||
<main>
|
<main>
|
||||||
<HeroBanner />
|
<HeroBanner />
|
||||||
{/* <CoursesCarousel /> */}
|
<CoursesCarousel />
|
||||||
<WorkshopsCarousel />
|
<WorkshopsCarousel />
|
||||||
{/* <ResourcesCarousel /> */}
|
<ResourcesCarousel />
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user