Files
atahan/app/pages/portfolio/index.vue
Beyhan Oğur 763b147cc3 first commit
2026-04-26 22:04:35 +03:00

223 lines
7.7 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import MainMenuArea from "~/components/home/MainMenuArea.vue";
import type {Home, Setting, Category, PortfolioCategory, MainMenu, OpenClose} from "~/types";
// jQuery ve Magnific Popup için window tipini genişlet
interface WindowWithJQuery extends Window {
$?: any;
}
declare const window: WindowWithJQuery;
const config = useRuntimeConfig()
const apiUrl = computed(() => config.public.BASE_API_URL || 'http://127.0.0.1:8000')
const {data: openClose} = await useFetch<OpenClose>(`${apiUrl.value}/api/v1/open-close/`)
const {data: setting} = await useFetch<Setting>(`${apiUrl.value}/api/v1/settings/`)
const {data: home} = await useFetch<Home>(`${apiUrl.value}/api/v1/home/`)
const {data: menu} = await useFetch<MainMenu>(`${apiUrl.value}/api/v1/main-menu/`)
const {data: categories} = await useFetch<Category[]>(`${apiUrl.value}/api/v1/categories/`)
// Tüm portfolioları toplama
const allPortfolios = computed(() => {
if (!categories.value) return []
const portfolios: PortfolioCategory[] = []
categories.value.forEach(category => {
category.portfolio_categories.forEach(portfolio => {
if (!portfolios.find(p => p.id === portfolio.id)) {
portfolios.push(portfolio)
}
})
})
return portfolios
})
// Seçili kategori
const selectedCategory = ref<number | null>(null)
// Filtrelenmiş portfoliolar
const filteredPortfolios = computed(() => {
if (!selectedCategory.value || !categories.value) return allPortfolios.value
const category = categories.value.find(c => c.id === selectedCategory.value)
return category ? category.portfolio_categories : []
})
// Pagination
const currentPage = ref(1)
const itemsPerPage = 8
const totalPages = computed(() => Math.ceil(filteredPortfolios.value.length / itemsPerPage))
const paginatedPortfolios = computed(() => {
const start = (currentPage.value - 1) * itemsPerPage
const end = start + itemsPerPage
return filteredPortfolios.value.slice(start, end)
})
// Kategori seçme
const selectCategory = (categoryId: number | null) => {
selectedCategory.value = categoryId
currentPage.value = 1
}
// Sayfa değiştirme
const changePage = (page: number) => {
if (page >= 1 && page <= totalPages.value) {
currentPage.value = page
}
}
// Magnific Popup'ı başlat
const initMagnificPopup = () => {
if (typeof window !== 'undefined' && window.$) {
window.$('.img-popup').magnificPopup({
type: 'image',
gallery: {
enabled: false
}
})
}
}
// Component mount olduğunda ve sayfa değiştiğinde popup'ı yeniden başlat
onMounted(() => {
// jQuery ve Magnific Popup'ın yüklenmesi için biraz bekliyoruz
setTimeout(() => {
initMagnificPopup()
}, 100)
})
// Sayfa veya kategori değiştiğinde popup'ı yeniden başlat
watch([currentPage, selectedCategory], () => {
nextTick(() => {
setTimeout(() => {
initMagnificPopup()
}, 100)
})
})
</script>
<template >
<div v-if="openClose?.site_active">
<main-menu-area :home="home" :setting="setting" :menu="menu"/>
<!-- Main Content Area Start -->
<div class="main-content">
<div class="main-content-inner">
<!-- Portfolios Area Start -->
<section class="portfolios-page">
<div class="container">
<div class="row">
<div class="col-lg-8">
<div class="row">
<div v-for="portfolio in paginatedPortfolios" :key="portfolio.id" class="col-lg-6 col-md-6">
<div class="gallery-item-content">
<div class="item-thumbnail">
<img :src="`${apiUrl}${portfolio.image}`" :alt="portfolio.url">
<div class="content-overlay">
<div class="content">
<div class="links">
<a :href="portfolio.url" target="_blank" class="link"><i class="fas fa-link"></i></a>
<a class="img-popup image-preview"
:href="`${apiUrl}${portfolio.image}`">
<i class="fas fa-eye"></i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 d-flex justify-content-center">
<nav v-if="totalPages > 1" aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item" :class="{ disabled: currentPage === 1 }">
<a class="page-link" href="#" @click.prevent="changePage(currentPage - 1)" aria-label="Previous">
<span aria-hidden="true"><i class="fas fa-angle-double-left"></i></span>
</a>
</li>
<li v-for="page in totalPages" :key="page" class="page-item">
<a class="page-link" :class="{ active: currentPage === page }" href="#" @click.prevent="changePage(page)">{{ page }}</a>
</li>
<li class="page-item" :class="{ disabled: currentPage === totalPages }">
<a class="page-link" href="#" @click.prevent="changePage(currentPage + 1)" aria-label="Next">
<span aria-hidden="true"><i class="fas fa-angle-double-right"></i></span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="categori-widget">
<h4 class="title">
Kategoriler
</h4>
<ul class="cat-list">
<li>
<a href="#" @click.prevent="selectCategory(null)" :class="{ active: selectedCategory === null }">
<p>
All
</p>
<span class="count">
{{ allPortfolios.length }}
</span>
</a>
</li>
<li v-for="category in categories" :key="category.id">
<a href="#" @click.prevent="selectCategory(category.id)" :class="{ active: selectedCategory === category.id }">
<p>
{{ category.title }}
</p>
<span class="count">
{{ category.portfolio_categories.length }}
</span>
</a>
</li>
</ul>
</div>
<!-- <div class="latest-post-widget">
<h4 class="title">
Latest Projects
</h4>
<ul class="post-list">
<li v-for="project in latestProjects" :key="project.id">
<div class="post">
<div class="post-img">
<img :src="`${apiUrl}${project.image}`" alt="">
</div>
<div class="post-details">
<a :href="project.url" target="_blank" class="post-title">
{{ project.url }}
</a>
</div>
</div>
</li>
</ul>
</div>-->
</div>
</div>
</div>
</section>
<!-- Portfolios Area End -->
</div>
</div>
<!-- Main Content Area End -->
<!-- Back to Top Start -->
<div class="bottomtotop">
<i class="fas fa-chevron-right"></i>
</div>
<!-- Back to Top End -->
</div>
</template>
<style scoped>
</style>