mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-04-19 10:51:20 +00:00
Merge pull request #42 from AustinKelsay/bugfix/carousel-cards-disappear-when-clicking-zap
Grid based layout for resource cards using tailwind instead of using primereact carousel component, this fixed the bug
This commit is contained in:
commit
e72da87b01
@ -1,34 +1,14 @@
|
|||||||
import React, { useState, useEffect, useCallback, useMemo } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Carousel } from 'primereact/carousel';
|
|
||||||
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
||||||
import { VideoTemplate } from '@/components/content/carousels/templates/VideoTemplate';
|
import { VideoTemplate } from '@/components/content/carousels/templates/VideoTemplate';
|
||||||
import { DocumentTemplate } from '@/components/content/carousels/templates/DocumentTemplate';
|
import { DocumentTemplate } from '@/components/content/carousels/templates/DocumentTemplate';
|
||||||
import { CourseTemplate } from '@/components/content/carousels/templates/CourseTemplate';
|
import { CourseTemplate } from '@/components/content/carousels/templates/CourseTemplate';
|
||||||
import { CombinedTemplate } from '@/components/content/carousels/templates/CombinedTemplate';
|
import { CombinedTemplate } from '@/components/content/carousels/templates/CombinedTemplate';
|
||||||
import debounce from 'lodash/debounce';
|
|
||||||
|
|
||||||
const responsiveOptions = [
|
|
||||||
{
|
|
||||||
breakpoint: '3000px',
|
|
||||||
numVisible: 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
breakpoint: '1462px',
|
|
||||||
numVisible: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
breakpoint: '575px',
|
|
||||||
numVisible: 1,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function GenericCarousel({items, selectedTopic, title}) {
|
export default function GenericCarousel({items, selectedTopic, title}) {
|
||||||
const [carousels, setCarousels] = useState([]);
|
|
||||||
const [lessons, setLessons] = useState([]);
|
const [lessons, setLessons] = useState([]);
|
||||||
|
|
||||||
const memoizedItems = useMemo(() => items, [items]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
axios.get('/api/lessons').then(res => {
|
axios.get('/api/lessons').then(res => {
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
@ -41,60 +21,51 @@ export default function GenericCarousel({items, selectedTopic, title}) {
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const getItemsPerCarousel = useCallback(() => {
|
const generateUniqueTemplateKey = (item, index, type) => {
|
||||||
const width = window.innerWidth;
|
if (!item) return `${type}-${index}`;
|
||||||
if (width <= 575) return 1;
|
const baseKey = item.id || item.d || `${type}-${index}`;
|
||||||
if (width <= 1462) return 2;
|
return `${type}-${baseKey}-${index}`;
|
||||||
return 3;
|
};
|
||||||
}, []);
|
|
||||||
|
|
||||||
const updateCarousels = useCallback(() => {
|
const renderItem = (item, index) => {
|
||||||
const itemsPerCarousel = getItemsPerCarousel();
|
if (!item) return <TemplateSkeleton key={generateUniqueTemplateKey(item, index, 'skeleton')} />;
|
||||||
const newCarousels = [];
|
|
||||||
for (let i = 0; i < memoizedItems.length; i += itemsPerCarousel) {
|
if (item.topics?.includes('video') && item.topics?.includes('document')) {
|
||||||
newCarousels.push(memoizedItems.slice(i, i + itemsPerCarousel));
|
return <CombinedTemplate
|
||||||
|
key={generateUniqueTemplateKey(item, index, 'combined')}
|
||||||
|
resource={item}
|
||||||
|
isLesson={lessons.includes(item?.d)}
|
||||||
|
/>;
|
||||||
|
} else if (item.type === 'document') {
|
||||||
|
return <DocumentTemplate
|
||||||
|
key={generateUniqueTemplateKey(item, index, 'document')}
|
||||||
|
document={item}
|
||||||
|
isLesson={lessons.includes(item?.d)}
|
||||||
|
/>;
|
||||||
|
} else if (item.type === 'video') {
|
||||||
|
return <VideoTemplate
|
||||||
|
key={generateUniqueTemplateKey(item, index, 'video')}
|
||||||
|
video={item}
|
||||||
|
isLesson={lessons.includes(item?.d)}
|
||||||
|
/>;
|
||||||
|
} else if (item.type === 'course') {
|
||||||
|
return <CourseTemplate
|
||||||
|
key={generateUniqueTemplateKey(item, index, 'course')}
|
||||||
|
course={item}
|
||||||
|
/>;
|
||||||
}
|
}
|
||||||
setCarousels(newCarousels);
|
return <TemplateSkeleton key={generateUniqueTemplateKey(item, index, 'fallback')} />;
|
||||||
}, [memoizedItems, getItemsPerCarousel]);
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
updateCarousels();
|
|
||||||
const debouncedHandleResize = debounce(updateCarousels, 250);
|
|
||||||
window.addEventListener('resize', debouncedHandleResize);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener('resize', debouncedHandleResize);
|
|
||||||
};
|
|
||||||
}, [updateCarousels, memoizedItems]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="w-full px-4 mb-4">
|
||||||
{carousels.map((carouselItems, index) => (
|
<div className="grid grid-cols-2 gap-4 max-w-full max-tab:grid-cols-1 lg:grid-cols-3">
|
||||||
<Carousel
|
{items.map((item, index) => (
|
||||||
key={index}
|
<div key={generateUniqueTemplateKey(item, index, 'container')} className="w-full min-w-0">
|
||||||
value={carouselItems}
|
{renderItem(item, index)}
|
||||||
itemTemplate={(item) => {
|
</div>
|
||||||
if (carouselItems.length > 0) {
|
))}
|
||||||
if (item.topics?.includes('video') && item.topics?.includes('document')) {
|
</div>
|
||||||
return <CombinedTemplate key={item.id} resource={item} isLesson={lessons.includes(item?.d)} />;
|
</div>
|
||||||
} else if (item.type === 'document') {
|
|
||||||
return <DocumentTemplate key={item.id} document={item} isLesson={lessons.includes(item?.d)} />;
|
|
||||||
} else if (item.type === 'video') {
|
|
||||||
return <VideoTemplate key={item.id} video={item} isLesson={lessons.includes(item?.d)} />;
|
|
||||||
} else if (item.type === 'course') {
|
|
||||||
return <CourseTemplate key={item.id} course={item} />;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return <TemplateSkeleton key={Math.random()} />;
|
|
||||||
}}
|
|
||||||
responsiveOptions={responsiveOptions}
|
|
||||||
className="mb-4"
|
|
||||||
pt={{
|
|
||||||
previousButton: { className: 'hidden' },
|
|
||||||
nextButton: { className: 'hidden' }
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user