first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 22:04:35 +03:00
commit 763b147cc3
199 changed files with 29356 additions and 0 deletions

View File

@@ -0,0 +1,277 @@
<script setup lang="ts">
import type { Home, Setting, MainMenu } from "~/types";
interface Props {
home?: Home | null;
setting?: Setting | null;
menu?: MainMenu | null;
}
defineProps<Props>();
const config = useRuntimeConfig()
const apiUrl = computed(() => config.public.BASE_API_URL || 'http://127.0.0.1:8000')
// Helper function to get full image URL
const getImageUrl = (imagePath: string | null | undefined) => {
if (!imagePath) return '/assets/images/about3.jpg'
if (imagePath.startsWith('http')) return imagePath
return `${apiUrl.value}${imagePath}`
}
// Current active section tracking
const route = useRoute()
// Initialize currentSection based on route hash (works on both server and client)
const initializeCurrentSection = () => {
if (route.hash) {
return route.hash.replace('#', '')
}
return 'home'
}
const currentSection = ref(initializeCurrentSection())
// Handle hash navigation for menu items
const handleHashNavigation = (event: Event, hash: string) => {
const route = useRoute()
// If we're not on the home page, navigate to home first
if (route.path !== '/') {
event.preventDefault()
navigateTo('/' + hash)
return
}
// On home page, handle smooth scroll
event.preventDefault()
if (import.meta.client) {
const targetId = hash.replace('#', '')
// Handle home section - scroll to top
if (targetId === 'home') {
currentSection.value = 'home'
window.scrollTo({
top: 0,
behavior: 'smooth'
})
window.history.pushState(null, '', '/')
return
}
// Handle other sections
const targetElement = document.getElementById(targetId)
if (targetElement) {
// Update current section
currentSection.value = targetId
// Smooth scroll to element
targetElement.scrollIntoView({
behavior: 'smooth',
block: 'start'
})
// Update URL hash without page jump
window.history.pushState(null, '', hash)
}
}
}
// Check if menu item is active
const isMenuActive = (path: string) => {
// Extract hash from path (e.g., "/#about" -> "about")
const pathHash = path.includes('#') ? path.split('#')[1] : ''
if (import.meta.server) {
// Server-side: URL hash kontrolü
if (path === '/') {
// Home is active only if there's no hash
return route.path === '/' && !route.hash
}
// Other sections: check if route hash matches
const routeHash = route.hash.replace('#', '')
return routeHash === pathHash
}
// Client-side: currentSection state kullan
if (path === '/') {
return currentSection.value === '' || currentSection.value === 'home'
}
return currentSection.value === pathHash
}
// Update current section based on scroll
const updateCurrentSection = () => {
if (import.meta.client) {
const sections = ['home', 'about', 'service', 'resume', 'project-gallery', 'contact']
const scrollPosition = window.scrollY + 100
for (const section of sections) {
const element = document.getElementById(section)
if (element) {
const { offsetTop, offsetHeight } = element
if (scrollPosition >= offsetTop && scrollPosition < offsetTop + offsetHeight) {
currentSection.value = section
return
}
}
}
// Default to home if no section matched
if (scrollPosition < 100) {
currentSection.value = 'home'
}
}
}
// Reinitialize menu on mount and route change
onMounted(() => {
// Add scroll listener
window.addEventListener('scroll', updateCurrentSection)
// Wait for DOM to be fully ready
nextTick(() => {
setTimeout(() => {
initializeMenu()
reinitWow()
updateCurrentSection()
}, 100)
})
})
onBeforeUnmount(() => {
if (import.meta.client) {
window.removeEventListener('scroll', updateCurrentSection)
}
})
watch(() => route.path, () => {
nextTick(() => {
setTimeout(() => {
initializeMenu()
reinitWow()
updateCurrentSection()
}, 100)
})
})
// Also watch for hash changes
watch(() => route.hash, (newHash) => {
if (newHash) {
currentSection.value = newHash.replace('#', '')
} else {
currentSection.value = 'home'
}
nextTick(() => {
setTimeout(() => {
initializeMenu()
}, 100)
})
})
const initializeMenu = () => {
if (import.meta.client && (window as any).$) {
// Disable jQuery onePageNav plugin completely - we handle everything with Vue
const $mainmenu = (window as any).$('#mainmenu-area')
if ($mainmenu.length) {
// Remove any existing onePageNav bindings
$mainmenu.off('click.onePageNav')
// Don't initialize onePageNav at all - Vue handles everything
}
}
}
const reinitWow = () => {
if (import.meta.client && (window as any).WOW) {
// Only reinitialize WOW for menu items, not profile area
const menuItems = document.querySelectorAll('#mainmenu-area li a.wow')
menuItems.forEach((item) => {
item.classList.remove('animated', 'fadeInUp')
// Force reflow
void (item as HTMLElement).offsetWidth
item.classList.add('animated', 'fadeInUp')
})
}
}
</script>
<template>
<div class="side-menu-wrapper">
<div class="menu-toogle-icon">
<div id="nav-icon3">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
<div class="side-menu">
<div class="heading-area">
<a href="/" class="profile-photo">
<img :src="getImageUrl(home?.image)" :alt="home?.name || 'Profile'">
</a>
<div class="name">
{{ home?.name || 'Atahan Deniz' }}
</div>
</div>
<ul id="mainmenu-area">
<li :class="{ current: isMenuActive('/') }">
<NuxtLink to="/" @click="handleHashNavigation($event, '#home')" class="wow fadeInUp" data-wow-delay="0.4s">
<i class="fas fa-home"></i> {{ menu?.home || 'Anasayfa' }}
</NuxtLink>
</li>
<li :class="{ current: isMenuActive('/#about') }">
<NuxtLink to="/#about" @click="handleHashNavigation($event, '#about')" class="wow fadeInUp" data-wow-delay="0.4s">
<i class="fas fa-user"></i> {{ menu?.about || 'Hakkımda' }}
</NuxtLink>
</li>
<li :class="{ current: isMenuActive('/#service') }">
<NuxtLink to="/#service" @click="handleHashNavigation($event, '#service')" class="wow fadeInUp" data-wow-delay="0.4s">
<i class="fas fa-briefcase"></i> {{ menu?.services || 'Hizmetlerim' }}
</NuxtLink>
</li>
<li :class="{ current: isMenuActive('/#resume') }">
<NuxtLink to="/#resume" @click="handleHashNavigation($event, '#resume')" class="wow fadeInUp" data-wow-delay="0.4s">
<i class="fas fa-file-alt"></i> {{ menu?.resume || 'Becerilerim' }}
</NuxtLink>
</li>
<li :class="{ current: isMenuActive('/#project-gallery') }">
<NuxtLink to="/#project-gallery" @click="handleHashNavigation($event, '#project-gallery')" class="wow fadeInUp" data-wow-delay="0.4s">
<i class="fas fa-layer-group"></i> {{ menu?.portfolio || 'Portfolio' }}
</NuxtLink>
</li>
<li :class="{ current: isMenuActive('/#contact') }">
<NuxtLink to="/#contact" @click="handleHashNavigation($event, '#contact')" class="wow fadeInUp" data-wow-delay="0.4s">
<i class="fas fa-check-square"></i> {{ menu?.contact || 'İletişim' }}
</NuxtLink>
</li>
</ul>
</div>
</div>
</template>
<style scoped>
/* Ensure menu items are always visible */
#mainmenu-area li {
opacity: 1 !important;
visibility: visible !important;
}
#mainmenu-area li a {
opacity: 1 !important;
visibility: visible !important;
}
/* Ensure profile photo and name are always visible */
.heading-area .profile-photo,
.heading-area .profile-photo img,
.heading-area .name {
opacity: 1 !important;
visibility: visible !important;
}
</style>