first commit
This commit is contained in:
13
app/pages/auth/login.vue
Normal file
13
app/pages/auth/login.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<LoginComponent />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
13
app/pages/auth/register.vue
Normal file
13
app/pages/auth/register.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<RegisterComponent />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
401
app/pages/index.vue
Normal file
401
app/pages/index.vue
Normal file
@@ -0,0 +1,401 @@
|
||||
<script setup lang="ts">
|
||||
import { storeToRefs } from "pinia";
|
||||
import type { Banner } from "~~/types/banner";
|
||||
import type { PostResponse } from "~~/types/post";
|
||||
|
||||
import { useSettingStore } from '~/stores/setting';
|
||||
import { useBannerStore } from '~/stores/banner';
|
||||
|
||||
const _settings = useSettingStore();
|
||||
const { settings } = storeToRefs(_settings);
|
||||
|
||||
const _bannerStore = useBannerStore();
|
||||
const { banner } = storeToRefs(_bannerStore);
|
||||
|
||||
// API base URL — goreceli image path'ini tam URL'e donustur
|
||||
const config = useRuntimeConfig();
|
||||
const apiBase = (config.public.BASE_API_URL as string) || 'http://127.0.0.1:8080';
|
||||
|
||||
// Banner'dan gelen ilk banner'in resim URL'si (tam URL)
|
||||
const bannerImageUrl = computed(() => {
|
||||
const img = banner.value?.[0]?.image;
|
||||
if (!img) return undefined;
|
||||
if (img.startsWith('http')) return img;
|
||||
return `${apiBase.replace(/\/$/, '')}${img}`;
|
||||
});
|
||||
|
||||
// Resim path'ini tam URL'e donustur
|
||||
const imgUrl = (path: string) => {
|
||||
if (!path) return '';
|
||||
if (path.startsWith('http')) return path;
|
||||
return `${apiBase.replace(/\/$/, '')}${path}`;
|
||||
};
|
||||
|
||||
// Tarihi gg.aa.yyyy formatina cevir
|
||||
const formatDate = (dateStr?: string) => {
|
||||
if (!dateStr) return '';
|
||||
return new Date(dateStr).toLocaleDateString('tr-TR', {
|
||||
day: '2-digit', month: 'long', year: 'numeric'
|
||||
});
|
||||
};
|
||||
|
||||
const breadcrumbs = [
|
||||
{ label: 'Home', href: '#' },
|
||||
{ label: 'Blog' }
|
||||
]
|
||||
|
||||
useSeoMeta({
|
||||
title: 'Blog',
|
||||
description: 'En son haberler ve makaleler',
|
||||
})
|
||||
|
||||
// Postlari API'dan cek
|
||||
const route = useRoute();
|
||||
const page = computed(() => Number(route.query.page) || 1);
|
||||
|
||||
const { data: postsData, refresh } = await useFetch<PostResponse>(() => `${apiBase}/api/v1/posts?page=${page.value}`);
|
||||
const posts = computed(() => postsData.value?.data ?? []);
|
||||
const postMeta = computed(() => postsData.value?.meta);
|
||||
|
||||
// Sayfa degistirme fonksiyonu
|
||||
const changePage = (newPage: number) => {
|
||||
if (newPage < 1 || (postMeta.value && newPage > Math.ceil(postMeta.value.total / postMeta.value.per_page))) return;
|
||||
navigateTo({ query: { ...route.query, page: newPage } });
|
||||
};
|
||||
|
||||
// Toplam sayfa sayisi
|
||||
const totalPages = computed(() => {
|
||||
if (!postMeta.value) return 1;
|
||||
return Math.ceil(postMeta.value.total / postMeta.value.per_page);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<PageTitle title="Blog" subtitle="Our Latest News" :breadcrumbs="breadcrumbs" :image="bannerImageUrl"
|
||||
:color="banner?.[0]?.color" imageType="background" />
|
||||
<!-- Content
|
||||
============================================= -->
|
||||
<section id="content">
|
||||
<div class="content-wrap">
|
||||
<div class="container">
|
||||
<div class="row gx-5 col-mb-80">
|
||||
<!-- Post Content
|
||||
============================================= -->
|
||||
<main class="postcontent col-lg-9">
|
||||
<!-- Postlar API'dan geliyor -->
|
||||
<div id="posts" class="row gutter-40">
|
||||
|
||||
<div v-for="post in posts" :key="post.ID" class="entry col-12">
|
||||
<div class="grid-inner row g-0">
|
||||
<!-- Sol: Post resmi -->
|
||||
<div class="col-md-4">
|
||||
<div class="entry-image">
|
||||
<NuxtLink :to="`/blog/${post.slug}`">
|
||||
<img :src="imgUrl(post.images_min || post.images)" :alt="post.title"
|
||||
style="width:100%; height:200px; object-fit:cover;" />
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Sag: Post icerigi -->
|
||||
<div class="col-md-8 ps-md-4">
|
||||
<div class="entry-title title-sm">
|
||||
<h2>
|
||||
<NuxtLink :to="`/blog/${post.slug}`">{{ post.title }}</NuxtLink>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="entry-meta">
|
||||
<ul>
|
||||
<li><i class="uil uil-schedule" /> {{ formatDate(post.UpdatedAt || post.CreatedAt) }}
|
||||
<span v-if="post.UpdatedAt && post.UpdatedAt !== post.CreatedAt"
|
||||
style="font-size: 0.8em; opacity: 0.8;">
|
||||
(Güncellendi)
|
||||
</span>
|
||||
</li>
|
||||
<li v-if="post.categories?.length">
|
||||
<i class="uil uil-folder-open" />
|
||||
<template v-for="(cat, ci) in post.categories" :key="cat.ID">
|
||||
<NuxtLink :to="`/kategori/${cat.slug}`">{{ cat.title }}</NuxtLink>
|
||||
<span v-if="ci < post.categories.length - 1">, </span>
|
||||
</template>
|
||||
</li>
|
||||
<li v-if="post.tags?.length">
|
||||
<i class="uil uil-tag" />
|
||||
<template v-for="(tag, ti) in post.tags" :key="tag.ID">
|
||||
<span>{{ tag.name }}</span>
|
||||
<span v-if="ti < post.tags.length - 1">, </span>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="entry-content">
|
||||
<p>{{ post.content.substring(0, 150) }}{{ post.content.length > 150 ? '...' : '' }}</p>
|
||||
<NuxtLink :to="`/blog/${post.slug}`" class="more-link">Devamını Oku</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Post bulunamadiysa -->
|
||||
<div v-if="!posts.length" class="col-12 text-center py-5">
|
||||
<p>Henüz gönderi bulunamadı.</p>
|
||||
</div>
|
||||
|
||||
</div><!-- #posts end -->
|
||||
|
||||
<!-- Pager
|
||||
============================================= -->
|
||||
<div v-if="totalPages > 1" class="d-flex justify-content-between mt-5">
|
||||
<button class="btn btn-outline-secondary" :disabled="page <= 1" @click="changePage(page - 1)">
|
||||
← Daha Eski
|
||||
</button>
|
||||
<div class="align-self-center">
|
||||
Sayfa {{ page }} / {{ totalPages }}
|
||||
</div>
|
||||
<button class="btn btn-outline-dark" :disabled="page >= totalPages" @click="changePage(page + 1)">
|
||||
Daha Yeni →
|
||||
</button>
|
||||
</div>
|
||||
<!-- .pager end -->
|
||||
|
||||
</main><!-- .postcontent end -->
|
||||
|
||||
<!-- Sidebar
|
||||
============================================= -->
|
||||
<aside class="sidebar col-lg-3">
|
||||
<div class="sidebar-widgets-wrap">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="widget">
|
||||
|
||||
<ul id="canvas-tab" class="nav canvas-tabs tabs nav-tabs size-sm mb-3" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="canvas-tab-1" class="nav-link active" data-bs-toggle="pill" data-bs-target="#tab-1"
|
||||
type="button" role="tab" aria-controls="canvas-tab-1" aria-selected="true">Popular</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="canvas-tab-2" class="nav-link" data-bs-toggle="pill" data-bs-target="#tab-2"
|
||||
type="button" role="tab" aria-controls="canvas-tab-2" aria-selected="false">Recents</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="canvas-tab-3" class="nav-link uil uil-comments-alt" data-bs-toggle="pill"
|
||||
data-bs-target="#tab-3" type="button" role="tab" aria-controls="canvas-tab-3"
|
||||
aria-selected="false" />
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="canvas-TabContent" class="tab-content">
|
||||
|
||||
<div id="tab-1" class="tab-pane show active" role="tabpanel" aria-labelledby="canvas-tab-1"
|
||||
tabindex="0">
|
||||
<div id="popular-post-list-sidebar" class="posts-sm row col-mb-30">
|
||||
<div class="entry col-12">
|
||||
<div class="grid-inner row g-0">
|
||||
<div class="col-auto">
|
||||
<div class="entry-image">
|
||||
<a href="#"><img class="rounded-circle" src="/images/magazine/small/3.jpg"
|
||||
alt="Image"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col ps-3">
|
||||
<div class="entry-title">
|
||||
<h4><a href="#">Lorem ipsum dolor sit amet, consectetur</a></h4>
|
||||
</div>
|
||||
<div class="entry-meta">
|
||||
<ul>
|
||||
<li><i class="uil uil-comments-alt" /> 35 Comments</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="entry col-12">
|
||||
<div class="grid-inner row g-0">
|
||||
<div class="col-auto">
|
||||
<div class="entry-image">
|
||||
<a href="#"><img class="rounded-circle" src="/images/magazine/small/2.jpg"
|
||||
alt="Image"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col ps-3">
|
||||
<div class="entry-title">
|
||||
<h4><a href="#">Elit Assumenda vel amet dolorum quasi</a></h4>
|
||||
</div>
|
||||
<div class="entry-meta">
|
||||
<ul>
|
||||
<li><i class="uil uil-comments-alt" /> 24 Comments</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="entry col-12">
|
||||
<div class="grid-inner row g-0">
|
||||
<div class="col-auto">
|
||||
<div class="entry-image">
|
||||
<a href="#"><img class="rounded-circle" src="/images/magazine/small/1.jpg"
|
||||
alt="Image"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col ps-3">
|
||||
<div class="entry-title">
|
||||
<h4><a href="#">Debitis nihil placeat, illum est nisi</a></h4>
|
||||
</div>
|
||||
<div class="entry-meta">
|
||||
<ul>
|
||||
<li><i class="uil uil-comments-alt" /> 19 Comments</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab-2" class="tab-pane" role="tabpanel" aria-labelledby="canvas-tab-2" tabindex="0">
|
||||
<div id="recent-post-list-sidebar" class="posts-sm row col-mb-30">
|
||||
<div class="entry col-12">
|
||||
<div class="grid-inner row g-0">
|
||||
<div class="col-auto">
|
||||
<div class="entry-image">
|
||||
<a href="#"><img class="rounded-circle" src="/images/magazine/small/1.jpg"
|
||||
alt="Image"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col ps-3">
|
||||
<div class="entry-title">
|
||||
<h4><a href="#">Lorem ipsum dolor sit amet, consectetur</a></h4>
|
||||
</div>
|
||||
<div class="entry-meta">
|
||||
<ul>
|
||||
<li>10th July 2021</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="entry col-12">
|
||||
<div class="grid-inner row g-0">
|
||||
<div class="col-auto">
|
||||
<div class="entry-image">
|
||||
<a href="#"><img class="rounded-circle" src="/images/magazine/small/2.jpg"
|
||||
alt="Image"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col ps-3">
|
||||
<div class="entry-title">
|
||||
<h4><a href="#">Elit Assumenda vel amet dolorum quasi</a></h4>
|
||||
</div>
|
||||
<div class="entry-meta">
|
||||
<ul>
|
||||
<li>10th July 2021</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="entry col-12">
|
||||
<div class="grid-inner row g-0">
|
||||
<div class="col-auto">
|
||||
<div class="entry-image">
|
||||
<a href="#"><img class="rounded-circle" src="/images/magazine/small/3.jpg"
|
||||
alt="Image"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col ps-3">
|
||||
<div class="entry-title">
|
||||
<h4><a href="#">Debitis nihil placeat, illum est nisi</a></h4>
|
||||
</div>
|
||||
<div class="entry-meta">
|
||||
<ul>
|
||||
<li>10th July 2021</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab-3" class="tab-pane" role="tabpanel" aria-labelledby="canvas-tab-3" tabindex="0">
|
||||
<div id="recent-comments-list-sidebar" class="posts-sm row col-mb-30">
|
||||
<div class="entry col-12">
|
||||
<div class="grid-inner row g-0">
|
||||
<div class="col-auto">
|
||||
<div class="entry-image">
|
||||
<a href="#"><img class="rounded-circle" src="/images/icons/avatar.jpg"
|
||||
alt="User Avatar"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col ps-3">
|
||||
<strong>John Doe:</strong> Veritatis recusandae sunt repellat distinctio...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="entry col-12">
|
||||
<div class="grid-inner row g-0">
|
||||
<div class="col-auto">
|
||||
<div class="entry-image">
|
||||
<a href="#"><img class="rounded-circle" src="/images/icons/avatar.jpg"
|
||||
alt="User Avatar"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col ps-3">
|
||||
<strong>Mary Jane:</strong> Possimus libero, earum officia architecto maiores....
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="entry col-12">
|
||||
<div class="grid-inner row g-0">
|
||||
<div class="col-auto">
|
||||
<div class="entry-image">
|
||||
<a href="#"><img class="rounded-circle" src="/images/icons/avatar.jpg"
|
||||
alt="User Avatar"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col ps-3">
|
||||
<strong>Site Admin:</strong> Deleniti magni labore laboriosam odio...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="widget">
|
||||
<h4>Tag Cloud</h4>
|
||||
<div class="tagcloud">
|
||||
<a href="#">general</a>
|
||||
<a href="#">videos</a>
|
||||
<a href="#">music</a>
|
||||
<a href="#">media</a>
|
||||
<a href="#">photography</a>
|
||||
<a href="#">parallax</a>
|
||||
<a href="#">ecommerce</a>
|
||||
<a href="#">terms</a>
|
||||
<a href="#">coupons</a>
|
||||
<a href="#">modern</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</aside><!-- .sidebar end -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section><!-- #content end -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user