<template> <div class="container" ref="scrollContainer" @dragover.prevent="handleDragOverContainer" @drop.prevent="handleDrop" > <div class="card-container"> <div class="card"> <AddCourseCard /> </div> <div class="card" v-for="(element, index) in products" :key="index" :draggable="true" @dragstart="handleDragStart(index)" @dragover.prevent="handleDragOverCard(index)" @dragend="handleDragEnd" > <CoursesCard :title="element.title" :text="element.text" :imageSrc="element.imageSrc" :productId="element.id" /> </div> </div> </div> </template>
<script> import AddCourseCard from './AddCourseCard.vue' import CoursesCard from './CourseCard.vue' import { OfferService } from '../../service/index' import { GroupState } from '../../composition/groups' import Draggable from 'vuedraggable'
export default { name: 'Learning', components: { CoursesCard, AddCourseCard, draggable: Draggable, }, data() { return { products: [], pageNo: 1, // Initialize pageNo limit: 10, // Set your desired limit per page loading: false, isGroupAdmin: GroupState.state.isGroupAdmin, dragData: null, draggedIndex: null, dropTargetIndex: null, reachedEnd: false, // Flag to prevent multiple requests while loading dragOptions: { // Specify any options for Vue.Draggable here if needed group: 'cards', // Add a group to allow cards to be dragged between different lists animation: 200, // Animation duration when items are reordered }, dummyData: [ { title: 'Card 1', text: 'Some quick example text for Card 1', imageSrc: 'https://picsum.photos/1600/1176/?image=25', }, { title: 'Card 2', text: 'Some quick example text for Card 2', imageSrc: 'https://picsum.photos/1600/1176/?image=26', }, { title: 'Card 3', text: 'Some quick example text for Card 3', imageSrc: 'https://picsum.photos/1600/1176/?image=27', }, { title: 'Card 4', text: 'Some quick example text for Card 1', imageSrc: 'https://picsum.photos/1600/1176/?image=25', }, { title: 'Card 5', text: 'Some quick example text for Card 2', imageSrc: 'https://picsum.photos/1600/1176/?image=26', }, { title: 'Card 6', text: 'Some quick example text for Card 3', imageSrc: 'https://picsum.photos/1600/1176/?image=27', }, // Add more dummy data items as needed ], } }, mounted() { // Call the initial API request when the component is mounted
this.fetchAllProducts() const container = this.$refs.scrollContainer if (container) { container.addEventListener('scroll', this.handleScroll) } }, methods: { handleScroll() { const container = this.$refs.scrollContainer if (!container) return
// Calculate when to trigger fetching more data based on scroll position const scrollPosition = container.scrollTop + container.clientHeight const maxScroll = container.scrollHeight
if ( scrollPosition >= maxScroll - 100 && !this.loading && !this.reachedEnd ) { // You can adjust the threshold (100 in this example) to your needs this.fetchNextPage() } }, async fetchNextPage() { // Your existing code to fetch the next page of data // ...
if (this.pagesEnd) { this.reachedEnd = true // Set the flag to indicate the end of data } }, async fetchAllProducts() { if (!this.isGroupAdmin) { this.fetchDataFromAPIForGroup() } else { this.fetchDataFromAPI() } }, async fetchDataFromAPI() { if (this.loading) return // Prevent multiple requests while loading
this.loading = true try { const response = await OfferService.getOfferProductForUser({ pageNo: this.pageNo, limit: this.limit, })
// Append the new data to the existing products array this.products = [...this.products, ...response]
// Increment the pageNo for the next request this.pageNo++ } catch (error) { console.error('Error fetching data from API:', error) } finally { this.loading = false } }, async fetchDataFromAPIForGroup() { if (this.loading) return // Prevent multiple requests while loading
this.loading = true try { const response = await OfferService.getOfferProductForGroup({ pageNo: this.pageNo, limit: this.limit, })
// Append the new data to the existing products array this.products = [...this.products, ...response]
// Increment the pageNo for the next request this.pageNo++ } catch (error) { console.error('Error fetching data from API:', error) } finally { this.loading = false } },
handleDragStart(index) { this.draggedIndex = index }, handleDragOverCard(index) { this.dropTargetIndex = index }, handleDragOverContainer(event) { // Prevent the default behavior, which is to not allow dropping event.preventDefault() }, handleDrop() { if (this.draggedIndex !== null && this.dropTargetIndex !== null) { // Splice the dragged card out of the dummyData array const draggedCard = this.products.splice(this.draggedIndex, 1)[0]
// Insert the dragged card at the drop target index this.products.splice(this.dropTargetIndex, 0, draggedCard)
// Reset the dragged and drop target indices this.draggedIndex = null this.dropTargetIndex = null } },
// Handle drag over handleDragOver(index) { if (!this.dragData) return
// Prevent the default behavior, which is to not allow dropping event.preventDefault()
// Swap the positions of the dragged item and the drop target const temp = this.dummyData[index] this.dummyData[index] = this.dragData this.dragData = temp console.log(this.dummyData) },
// Handle drag end handleDragEnd() { this.dragData = null }, }, } </script>
<style scoped> .container { display: flex; justify-content: center; /* Added to enable scrolling */ overflow-y: auto; }
.card-container { display: flex; flex-wrap: wrap; gap: 10px; max-width: 1216px; margin: 0 auto; }
.card { flex: 0 0 calc(33.33% - 10px); max-width: calc(33.33% - 10px); margin-bottom: 20px; box-sizing: border-box; }
@media (max-width: 768px) { .card { flex: 0 0 calc(50% - 10px); max-width: calc(50% - 10px); } }
@media (max-width: 480px) { .card { flex: 0 0 100%; max-width: 100%; } } </style> |