mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-05 08:42:02 +00:00
Added loading skeletons for carousels
This commit is contained in:
parent
f258866e07
commit
edf97c74fa
@ -3,6 +3,7 @@ import { Carousel } from 'primereact/carousel';
|
||||
import { parseEvent } from '@/utils/nostr';
|
||||
import { useNostr } from '@/hooks/useNostr';
|
||||
import CourseTemplate from '@/components/content/carousels/templates/CourseTemplate';
|
||||
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
||||
|
||||
const responsiveOptions = [
|
||||
{
|
||||
@ -22,38 +23,38 @@ const responsiveOptions = [
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
export default function CoursesCarousel() {
|
||||
const [processedCourses, setProcessedCourses] = useState([]);
|
||||
const [courses, setCourses] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const { fetchCourses } = useNostr();
|
||||
|
||||
useEffect(() => {
|
||||
const fetch = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const courses = await fetchCourses();
|
||||
console.log('courses:', courses);
|
||||
setCourses(courses);
|
||||
const fetchedCourses = await fetchCourses();
|
||||
if (fetchedCourses && fetchedCourses.length > 0) {
|
||||
const processed = fetchedCourses.map(course => parseEvent(course));
|
||||
setProcessedCourses(processed);
|
||||
} else {
|
||||
console.log('No courses fetched or empty array returned');
|
||||
}
|
||||
setLoading(false);
|
||||
} catch (error) {
|
||||
console.error('Error fetching courses:', error);
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
};
|
||||
fetch();
|
||||
}, [fetchCourses]);
|
||||
|
||||
useEffect(() => {
|
||||
const processCourses = courses.map(course => {
|
||||
const { id, content, title, summary, image, published_at } = parseEvent(course);
|
||||
return { id, content, title, summary, image, published_at };
|
||||
}
|
||||
);
|
||||
setProcessedCourses(processCourses);
|
||||
}, [courses]);
|
||||
}, [fetchCourses]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className="ml-[6%] mt-4">courses</h2>
|
||||
<Carousel value={[...processedCourses, ...processedCourses]} numVisible={2} itemTemplate={CourseTemplate} responsiveOptions={responsiveOptions} />
|
||||
<h2 className="ml-[6%] mt-4">Courses</h2>
|
||||
<Carousel value={loading ? [{}, {}, {}] : [...processedCourses, ...processedCourses]}
|
||||
numVisible={2}
|
||||
itemTemplate={loading ? TemplateSkeleton : CourseTemplate}
|
||||
responsiveOptions={responsiveOptions} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import { useNostr } from '@/hooks/useNostr';
|
||||
import { useImageProxy } from '@/hooks/useImageProxy';
|
||||
import { parseEvent } from '@/utils/nostr';
|
||||
import ResourceTemplate from '@/components/content/carousels/templates/ResourceTemplate';
|
||||
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
||||
|
||||
const responsiveOptions = [
|
||||
{
|
||||
@ -26,36 +27,36 @@ const responsiveOptions = [
|
||||
|
||||
export default function ResourcesCarousel() {
|
||||
const [processedResources, setProcessedResources] = useState([]);
|
||||
const [resources, setResources] = useState([]);
|
||||
const router = useRouter();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const { fetchResources } = useNostr();
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
|
||||
useEffect(() => {
|
||||
const fetch = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const resources = await fetchResources();
|
||||
console.log('resources:', resources);
|
||||
setResources(resources);
|
||||
const fetchedResources = await fetchResources();
|
||||
if (fetchedResources && fetchedResources.length > 0) {
|
||||
const processed = fetchedResources.map(resource => parseEvent(resource));
|
||||
setProcessedResources(processed);
|
||||
} else {
|
||||
console.log('No resources fetched or empty array returned');
|
||||
}
|
||||
setLoading(false);
|
||||
} catch (error) {
|
||||
console.error('Error fetching resources:', error);
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
fetch();
|
||||
}, [fetchResources]);
|
||||
|
||||
useEffect(() => {
|
||||
const processResources = resources.map(resource => {
|
||||
const { id, content, title, summary, image, published_at } = parseEvent(resource);
|
||||
return { id, content, title, summary, image, published_at };
|
||||
});
|
||||
setProcessedResources(processResources);
|
||||
}, [resources]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className="ml-[6%] mt-4">resources</h2>
|
||||
<Carousel value={[...processedResources, ...processedResources]} numVisible={2} itemTemplate={ResourceTemplate} responsiveOptions={responsiveOptions} />
|
||||
<h2 className="ml-[6%] mt-4">Resources</h2>
|
||||
<Carousel value={loading ? [{}, {}, {}] : [...processedResources, ...processedResources]}
|
||||
numVisible={2}
|
||||
itemTemplate={loading ? TemplateSkeleton : ResourceTemplate}
|
||||
responsiveOptions={responsiveOptions} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import { useNostr } from '@/hooks/useNostr';
|
||||
import { useImageProxy } from '@/hooks/useImageProxy';
|
||||
import { parseEvent } from '@/utils/nostr';
|
||||
import WorkshopTemplate from '@/components/content/carousels/templates/WorkshopTemplate';
|
||||
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
||||
|
||||
const responsiveOptions = [
|
||||
{
|
||||
@ -26,36 +27,36 @@ const responsiveOptions = [
|
||||
|
||||
export default function WorkshopsCarousel() {
|
||||
const [processedWorkshops, setProcessedWorkshops] = useState([]);
|
||||
const [workshops, setWorkshops] = useState([]);
|
||||
const router = useRouter();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const { fetchWorkshops } = useNostr();
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
|
||||
useEffect(() => {
|
||||
const fetch = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const workshops = await fetchWorkshops();
|
||||
console.log('workshops:', workshops);
|
||||
setWorkshops(workshops);
|
||||
const fetchedWorkshops = await fetchWorkshops();
|
||||
if (fetchedWorkshops && fetchedWorkshops.length > 0) {
|
||||
const processed = fetchedWorkshops.map(workshop => parseEvent(workshop));
|
||||
setProcessedWorkshops(processed);
|
||||
} else {
|
||||
console.log('No workshops fetched or empty array returned');
|
||||
}
|
||||
setLoading(false);
|
||||
} catch (error) {
|
||||
console.error('Error fetching workshops:', error);
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
fetch();
|
||||
}, [fetchWorkshops]);
|
||||
|
||||
useEffect(() => {
|
||||
const processWorkshops = workshops.map(workshop => {
|
||||
const { id, content, title, summary, image, published_at } = parseEvent(workshop);
|
||||
return { id, content, title, summary, image, published_at };
|
||||
});
|
||||
setProcessedWorkshops(processWorkshops);
|
||||
}, [workshops]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className="ml-[6%] mt-4">workshops</h2>
|
||||
<Carousel value={[...processedWorkshops, ...processedWorkshops]} numVisible={2} itemTemplate={WorkshopTemplate} responsiveOptions={responsiveOptions} />
|
||||
<h2 className="ml-[6%] mt-4">Workshops</h2>
|
||||
<Carousel value={loading ? [{}, {}, {}] : [...processedWorkshops, ...processedWorkshops]}
|
||||
numVisible={2}
|
||||
itemTemplate={loading ? TemplateSkeleton : WorkshopTemplate}
|
||||
responsiveOptions={responsiveOptions} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
import { Skeleton } from "primereact/skeleton";
|
||||
|
||||
const TemplateSkeleton = () => {
|
||||
return (
|
||||
<div className="flex flex-col items-start mx-auto px-4 mt-8 rounded-md">
|
||||
{/* Image Skeleton */}
|
||||
{/* <div className="w-full" style={{ paddingBottom: "56.25%" }}> */}
|
||||
<Skeleton width="100%" height="18rem"></Skeleton>
|
||||
{/* </div> */}
|
||||
|
||||
{/* Title Skeleton */}
|
||||
<Skeleton width="70%" className="mt-4 mb-2" height="2rem"></Skeleton>
|
||||
|
||||
{/* Summary Skeleton */}
|
||||
<Skeleton width="90%" className="mb-2" height="1rem"></Skeleton>
|
||||
<Skeleton width="90%" className="mb-4" height="1rem"></Skeleton>
|
||||
|
||||
{/* Date and Zap Amount Skeleton */}
|
||||
<div className="flex justify-between w-full">
|
||||
<Skeleton width="30%" height="1rem"></Skeleton>
|
||||
<Skeleton width="5%" height="1rem"></Skeleton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TemplateSkeleton;
|
@ -40,7 +40,7 @@ const CourseTemplate = (course) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-col items-center mx-auto px-4 cursor-pointer mt-8 rounded-md"
|
||||
className="flex flex-col items-center mx-auto px-4 mt-8 rounded-md"
|
||||
>
|
||||
<div
|
||||
onClick={() => router.push(`/details/${course.id}`)}
|
||||
@ -65,8 +65,8 @@ const CourseTemplate = (course) => {
|
||||
<p className="text-xs text-gray-400">
|
||||
{formatTimestampToHowLongAgo(course.published_at)}
|
||||
</p>
|
||||
<p className="text-xs">
|
||||
<i className="pi pi-bolt"></i> {zapAmount}
|
||||
<p className="text-xs cursor-pointer">
|
||||
<i className="pi pi-bolt text-yellow-300"></i> {zapAmount}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -40,7 +40,7 @@ const ResourceTemplate = (resource) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-col items-center mx-auto px-4 cursor-pointer mt-8 rounded-md"
|
||||
className="flex flex-col items-center mx-auto px-4 mt-8 rounded-md"
|
||||
>
|
||||
{/* Wrap the image in a div with a relative class with a padding-bottom of 56.25% representing the aspect ratio of 16:9 */}
|
||||
<div
|
||||
@ -66,8 +66,8 @@ const ResourceTemplate = (resource) => {
|
||||
<p className="text-xs text-gray-400">
|
||||
{formatTimestampToHowLongAgo(resource.published_at)}
|
||||
</p>
|
||||
<p className="text-xs">
|
||||
<i className="pi pi-bolt"></i> {zapAmount}
|
||||
<p className="text-xs cursor-pointer">
|
||||
<i className="pi pi-bolt text-yellow-300"></i> {zapAmount}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -40,7 +40,7 @@ const WorkshopTemplate = (workshop) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-col items-center mx-auto px-4 cursor-pointer mt-8 rounded-md"
|
||||
className="flex flex-col items-center mx-auto px-4 mt-8 rounded-md"
|
||||
>
|
||||
<div
|
||||
onClick={() => router.push(`/details/${workshop.id}`)}
|
||||
@ -65,8 +65,8 @@ const WorkshopTemplate = (workshop) => {
|
||||
<p className="text-xs text-gray-400">
|
||||
{formatTimestampToHowLongAgo(workshop.published_at)}
|
||||
</p>
|
||||
<p className="text-xs">
|
||||
<i className="pi pi-bolt"></i> {zapAmount}
|
||||
<p className="text-xs cursor-pointer">
|
||||
<i className="pi pi-bolt text-yellow-300"></i> {zapAmount}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user