0

I have a Laravel 10(php 8.1) project in which i have install vue 3 for making a dynamic component.

Component Detail: I have created a component for showing team members of a company with a category bar where they can be categorize(this all functionality is working fine before implementing vue3-carousel).

Trying to achieve: the issue i'm getting is where I try to implement dynamic pagination for members.

I tried to implement multiple plugins of vue (vue-awesome-paginate, vue3-pagination,v-pagination-3 ) but they all don't work out. Now i tried to implement vue3-carousel it is working but the problem is that the data is not showing in it.team members and it's category bar image.

Project dependencies: Laravel 10.10 Vue ^3.2.36 vue3-carousel ^0.3.1

This below is my whole code

TeamMember.vue:

<template>
    <div>
        <!-- Category Section -->
        <div class="isotop_nav" id="categories-container">
            <ul>
                <li>
                    <!-- Use Vue data properties and methods -->
                    <a href="#" :class="{ 'active': selectedCategory === null }"
                        @click.prevent="handleCategoryClick(null)">
                        All
                    </a>
                </li>
                <!-- Loop through categories and generate links -->
                <li v-for="category in categories" :key="category.id">
                    <!-- Use Vue data properties and methods -->
                    <a href="#" :class="{ 'active': selectedCategory === category.name }"
                        @click.prevent="handleCategoryClick(category.name)">
                        {{ category . name }}
                    </a>
                </li>
            </ul>
        </div>

        <!-- Team Section -->
        <div class="leadership_list onTeam_sec">
            <carousel :items-to-show="3">
                <div class="row justify-content-center" id="filtered-team-members">
                    <!-- Use Vue data properties and methods -->
                    <slide v-for="member in members" :key="member.id" class="col-xxl-3 col-xl-3 col-lg-4 col-md-4 category-item">
                        <div :data-category="member.category ? member.category.name : ''">
                            <div class="leadership_list_info">
                                <span>
                                    <!-- Use Vue data properties -->
                                    <img :src="`/uploads/${member.profile_picture}`" alt="leadership profile" />
                                </span>
                                <a href="#"><strong>{{ member . name }}</strong></a>
                                <p>{{ member . role }}</p>
                                <div class="contactSocial_infoList">
                                    <ul>
                                        <!-- Use Vue data properties -->
                                        <li v-if="member.twitter_link">
                                            <a :href="member.twitter_link" target="_blank" class="s_tw">
                                                <i class="fa-brands fa-twitter"></i>
                                            </a>
                                        </li>
                                        <li v-if="member.salesforce_link">
                                            <a :href="member.salesforce_link" target="_blank" class="s_inst">
                                                <i class="fa-brands fa-salesforce"></i>
                                            </a>
                                        </li>
                                        <li v-if="member.linkedIn_link">
                                            <a :href="member.linkedIn_link" target="_blank" class="s_link">
                                                <i class="fa-brands fa-linkedin"></i>
                                            </a>
                                        </li>
                                    </ul>
                                </div>
                            </div>
                        </div>
                    </slide>
                </div>
                <!-- <Page :total="pageInfo" :current="pageInfo.current_page"  :page-size="parseInt(pageInfo.total)" v-if="pageInfo"/> -->
                <p v-if="members.length === 0">No team members found.</p>
                <template #addons>
                    <navigation />
                    <pagination />
                </template>
            </carousel>
        </div>
    </div>
</template>


<script>
    import axios from "axios";
    import 'vue3-carousel/dist/carousel.css'
    import { Carousel, Slide, Pagination, Navigation } from 'vue3-carousel'
    // import ViewUIPlus from 'view-ui-plus'
    // import 'view-ui-plus/dist/styles/viewuiplus.css'


    export default {
        data() {
            return {
                members: [],
                categories: [],
                selectedCategory: null,
                // currentPage: 1,
                // itemsPerPage: 3,  // Adjust as needed
                // totalItems: 0,
                // total: 3,
                // pageInfo: null,
            };
        },
        components: {
            // VueAwesomePagination,
            Carousel,
            Slide,
            Pagination,
            Navigation,
            // ViewUIPlus
        },
        mounted() {
            // Fetch initial team members (all members)
            //
            this.fetchCategories();
            // this.filterTeamMembers();
        },
        methods: {

            // function to fetch categories
            fetchCategories() {
                // axios.get(`/our-team/categories`)
                axios.get(`/our-team/categories`)
                    .then(response => {
                        console.log('API Response for categories:', response.data);
                        this.categories = response.data.categories;
                        // this.members = response.data.members;
                        this.members = Object.entries(response.data.members).map(([key, value]) => value);
                        console.log(this.members);
                        // this.pageInfo = response.data.members;
                        // console.log(this.pageInfo);
                        this.selectedCategory = null;
                    })
                    .catch(error => {
                        console.error('Error fetching categories:', error);
                    });
            },

            // Function to fetch and display filtered team members
            filterTeamMembers(member) {
                axios.get(`/our-team/${member || 'all'}`)
                    .then(response => {
                        console.log('API Response:', response.data);
                        // this.members = response.data.members;
                        this.members = Object.values(response.data.members);
                        this.totalItems = response.data.total;
                    })
                    .catch(error => {
                        console.error('Error fetching team members:', error);
                    });
            },

            handleCategoryClick(category) {
                // Set the selected category
                this.selectedCategory = category;
                this.currentPage = 1;
                // Filter team members based on the selected category
                this.filterTeamMembers(category);
            },

                // handlePaginationChange(newPage) {
                // this.currentPage = newPage;
                // this.filterTeamMembers(this.selectedCategory);
                // },


        // handlePaginationChange(newPage) {
        //     this.currentPage = newPage;
        //     this.filterTeamMembers(this.selectedCategory);
        //     console.log(this.filterTeamMembers(this.selectedCategory));
        // },

        // nextPage() {
        //     if (this.currentPage * this.itemsPerPage < this.totalItems) {
        //         this.currentPage++;
        //         this.filterTeamMembers(this.selectedCategory);
        //     }
        // },

        // prevPage() {
        //     if (this.currentPage > 1) {
        //         this.currentPage--;
        //         this.filterTeamMembers(this.selectedCategory);
        //     }
        // },

        },

    }
</script>

Routes:

Route::get('/our-team/categories', [TeamMemberContentController::class, 'getTeam'])->name('team');
Route::get('/our-team/{member?}', [TeamMemberContentController::class, 'filterByCategory'])->name('team-members.filter');

TeamMemberContentController.php

<?php

namespace App\Http\Controllers;

use Log;
use App\Models\Category;
use App\Models\TeamMember;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\TeamCategory;
use Illuminate\Support\Facades\View;

class TeamMemberContentController extends Controller
{
    public function index(Request $request, $category = null)
    {
        // $members = TeamMember::all();
        $members = TeamMember::where('status', 'opened')->orderBy('order_column')->get();
        $categories = TeamCategory::all();
        $selectedCategory = null;

        // $categories = TeamCategory::all();
        // $selectedCategory = null;

        if ($category && $category !== 'all') {
            $selectedCategory = TeamCategory::where('name', 'like', $category)->first();
            if ($selectedCategory) {
                $members = $selectedCategory->teamMembers()->where('status', 'opened')->orderBy('order_column')->get();
            } else {
                $members = TeamMember::where('status', 'opened')->orderBy('order_column')->get();
            }
        }


        if ($request->ajax()) {
            try {
                $view = View::make('components.team-members', compact('members', 'categories', 'selectedCategory'))->render();
                return response()->json(['html' => $view]);
            } catch (\Exception $e) {
                return response()->json(['error' => $e->getMessage()], 500);
            }
        }

        return view('our-team.our-team', compact(
            'members',
            'categories',
            'selectedCategory'
        ));
    }


    public function filterByCategory(Request $request, $category)
    {
        // Log::info('Received category:', ['category' => $category]);
        if ($category === 'all') {
            // If the category is 'all', return all team members
            $members = TeamMember::where('status', 'opened')->orderBy('order_column')->paginate(3);
        } else {
            // If it's a specific category, filter by that category
            $categoryModel = TeamCategory::where('name', 'like', $category)->first();

            if (!$categoryModel) {
                // Handle the case when the category is not found
                return response()->json([
                    'members' => []
                ]);
            }

            // $members = $categoryModel->teamMembers;
            $members = $categoryModel->teamMembers()->where('status', 'opened')->orderBy('order_column')->get();
        }

        if ($request->ajax()) {
            return response()->json([
                'members' => $members,
                // 'categories' => $categories,
                // 'selectedCategory' => $selectedCategory,
            ]);
        }

        return view('our-team.our-team', compact('members', 'categories'));
    }


    public function getTeam(Request $request, $category = null)
    {
        $membersQuery = TeamMember::where('status', 'opened')->orderBy('order_column');
        $categories = TeamCategory::all();
        $selectedCategory = null;

        if ($category && $category !== 'all') {
            $selectedCategory = TeamCategory::where('name', 'like', $category)->first();
            if ($selectedCategory) {
                $membersQuery->where('team_category_id', $selectedCategory->id);
            }
        }

        $members = $membersQuery->get();

        if ($request->ajax()) {
            return response()->json(['members' => $members, 'categories' => $categories, 'selectedCategory' => $selectedCategory]);
        }

        return view('our-team.our-team', compact('members', 'categories', 'selectedCategory'));
    }
}

vite.congfig.js

import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import vue from "@vitejs/plugin-vue";

export default defineConfig({
    plugins: [
        laravel({
            input: [
                "resources/sass/app.scss",
                "resources/js/app.js",
                "resources/css/app.css",
            ],
            // input: ["resources/js/app.js"],
            refresh: true,
        }),
        vue({
            compilerOptions: {
                isCustomElement: (tag) => tag.startsWith("carousel"),
            },
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    resolve: {
        alias: {
            vue: "vue/dist/vue.esm-bundler.js",
        },
    },
});

and this below is the response data format image : response data image

Kindly let me know how to resolve the issue or there's alternative way(plugins) of achieving dynamic pagination.

Tried: I tried to achieve dynamic pagination for the component but it's not worked out.

Expect: I want to achieve dynamic pagination for the members which will work when i tried to filter through category bar it.

2 Answers 2

0

You might try inertia, it makes working with vue so much easier laravel inertia vue pagination

Sign up to request clarification or add additional context in comments.

2 Comments

thanks @Ivar for the suggestion. Does it work well in laravel too. because i have a laravel project and vue is installed in it with vite.config.js file.
Yes inertia laravel and vue are a very good combination. Im not familiar with vite
0

The vue3-carousel starts working when i moved or removed or moved the div tag between the carousel and slide tag it starts working fine. I don't know the exact reason, when i was trying different things it worked out.

I think it may be due to fact that slide tag is it's direct child and it requirement for the plugin structure. Now the update code below

        <div class="leadership_list onTeam_sec">
        <div  id="filtered-team-members">
        <carousel :items-to-show="3" :items="members"  class="row justify-content-center">
                <!-- Use Vue data properties and methods -->
                <!-- console members data -->


                <slide v-for="(member) in members" :key="member.id" class="col-xxl-3 col-xl-3 col-lg-4 col-md-4 category-item">
                    <div :data-category="member.category ? member.category.name : ''" >
                        <div class="leadership_list_info">
                            <span>
                                <img :src="`/uploads/${member.profile_picture}`" alt="leadership profile" />
                            </span>
                            <a href="#"><strong>{{ member.name }}</strong></a>
                            <p>{{ member . role }}</p>
                            <div class="contactSocial_infoList">
                                <ul>
                                    <!-- Use Vue data properties -->
                                    <li v-if="member.twitter_link">
                                        <a :href="member.twitter_link" target="_blank" class="s_tw">
                                            <i class="fa-brands fa-twitter"></i>
                                        </a>
                                    </li>
                                    <li v-if="member.salesforce_link">
                                        <a :href="member.salesforce_link" target="_blank" class="s_inst">
                                            <i class="fa-brands fa-salesforce"></i>
                                        </a>
                                    </li>
                                    <li v-if="member.linkedIn_link">
                                        <a :href="member.linkedIn_link" target="_blank" class="s_link">
                                            <i class="fa-brands fa-linkedin"></i>
                                        </a>
                                    </li>
                                </ul>
                            </div>
                        </div>
                    </div>
                </slide>
                <!-- <Page :total="pageInfo" :current="pageInfo.current_page"  :page-size="parseInt(pageInfo.total)" v-if="pageInfo"/> -->
                <!-- <p v-if="members.length === 0">No team members found.</p> -->
                <template #addons>
                    <navigation />
                    <pagination />
                </template>
            </carousel>
        </div>

Let me know if anyone knows the reason. As far as for me it worked out.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.