251 lines
8.1 KiB
Vue
251 lines
8.1 KiB
Vue
<template>
|
|
<nav class="bg-white border-b border-gray-200 sticky top-0 z-50">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="flex justify-between items-center h-16">
|
|
<!-- Logo/Titre -->
|
|
<div class="flex items-center">
|
|
<router-link to="/" class="text-2xl font-bold text-black transition-colors" style="color: black; --hover-color: #6b7280;" onmouseover="this.style.color='#6b7280'" onmouseout="this.style.color='black'">
|
|
Patois Franco-Provençal
|
|
</router-link>
|
|
</div>
|
|
|
|
<!-- Navigation principale -->
|
|
<div class="hidden md:flex items-center space-x-8">
|
|
<router-link
|
|
to="/"
|
|
class="nav-link"
|
|
:class="{ 'active': $route.name === 'Home' }"
|
|
>
|
|
<div class="flex items-center space-x-2">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
|
|
</svg>
|
|
<span>Accueil</span>
|
|
</div>
|
|
</router-link>
|
|
<router-link
|
|
to="/textes"
|
|
class="nav-link"
|
|
:class="{ 'active': $route.name === 'Texts' }"
|
|
>
|
|
<div class="flex items-center space-x-2">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.746 0 3.332.477 4.5 1.253v13C20.832 18.477 19.246 18 17.5 18c-1.746 0-3.332.477-4.5 1.253"/>
|
|
</svg>
|
|
<span>Textes</span>
|
|
</div>
|
|
</router-link>
|
|
<template v-if="!useDropdown">
|
|
<router-link
|
|
v-for="category in dynamicCategories"
|
|
:key="category.id"
|
|
:to="getCategoryLink(category)"
|
|
class="nav-link"
|
|
:class="{ 'active': isCategoryActive(category) }"
|
|
>
|
|
<span>{{ category.name }}</span>
|
|
</router-link>
|
|
</template>
|
|
<div v-else class="relative group">
|
|
<button
|
|
class="nav-link"
|
|
:class="{ 'active': isBlogActive }"
|
|
type="button"
|
|
>
|
|
Blog
|
|
</button>
|
|
<div class="absolute left-0 mt-2 w-56 bg-white border border-gray-200 rounded-lg shadow-lg py-2 hidden group-hover:block">
|
|
<router-link
|
|
v-for="category in categories"
|
|
:key="category.id"
|
|
:to="getCategoryLink(category)"
|
|
class="dropdown-link"
|
|
>
|
|
{{ category.name }}
|
|
</router-link>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Barre de recherche -->
|
|
<div class="relative">
|
|
<input
|
|
v-model="searchQuery"
|
|
@keyup.enter="performSearch"
|
|
type="text"
|
|
placeholder="Rechercher..."
|
|
class="w-64 px-4 py-2 pl-10 pr-4 text-sm border border-gray-300 rounded-full focus:outline-none focus:border-black focus:ring-1 focus:ring-black"
|
|
/>
|
|
<div class="absolute inset-y-0 left-0 pl-3 flex items-center">
|
|
<svg class="h-4 w-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Menu mobile -->
|
|
<div class="md:hidden">
|
|
<button
|
|
@click="mobileMenuOpen = !mobileMenuOpen"
|
|
class="text-black focus:outline-none" style="color: black; --hover-color: #6b7280;" onmouseover="this.style.color='#6b7280'" onmouseout="this.style.color='black'"
|
|
>
|
|
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Menu mobile déplié -->
|
|
<div v-if="mobileMenuOpen" class="md:hidden border-t border-gray-200 pt-4 pb-4">
|
|
<div class="flex flex-col space-y-4">
|
|
<router-link to="/" class="nav-link-mobile">Accueil</router-link>
|
|
<router-link to="/textes" class="nav-link-mobile">Textes</router-link>
|
|
<div v-if="categories.length" class="pt-2 border-t border-gray-200">
|
|
<div class="text-xs uppercase tracking-wide text-gray-500 mb-2">Blog</div>
|
|
<router-link
|
|
v-for="category in categories"
|
|
:key="category.id"
|
|
:to="getCategoryLink(category)"
|
|
class="nav-link-mobile"
|
|
>
|
|
{{ category.name }}
|
|
</router-link>
|
|
</div>
|
|
<div class="pt-2">
|
|
<input
|
|
v-model="searchQuery"
|
|
@keyup.enter="performSearch"
|
|
type="text"
|
|
placeholder="Rechercher..."
|
|
class="w-full px-4 py-2 text-sm border border-gray-300 rounded-full focus:outline-none focus:border-black"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
</template>
|
|
|
|
<script>
|
|
import { ref, computed, onMounted } from 'vue'
|
|
import { useRouter, useRoute } from 'vue-router'
|
|
import { wordpressService } from '../services/wordpressService.js'
|
|
|
|
export default {
|
|
name: 'NavigationBar',
|
|
setup() {
|
|
const router = useRouter()
|
|
const route = useRoute()
|
|
const searchQuery = ref('')
|
|
const mobileMenuOpen = ref(false)
|
|
const categories = ref([])
|
|
const categoriesLoading = ref(false)
|
|
|
|
const performSearch = () => {
|
|
if (searchQuery.value.trim()) {
|
|
router.push({
|
|
name: 'Texts',
|
|
query: { search: searchQuery.value.trim() }
|
|
})
|
|
mobileMenuOpen.value = false
|
|
}
|
|
}
|
|
|
|
const loadCategories = async () => {
|
|
categoriesLoading.value = true
|
|
try {
|
|
categories.value = await wordpressService.getCategories()
|
|
} catch (error) {
|
|
console.error('Erreur lors du chargement des catégories:', error)
|
|
} finally {
|
|
categoriesLoading.value = false
|
|
}
|
|
}
|
|
|
|
const dynamicCategories = computed(() => {
|
|
return categories.value.slice(0, 4)
|
|
})
|
|
|
|
const useDropdown = computed(() => {
|
|
return categories.value.length > 4
|
|
})
|
|
|
|
const getCategoryLink = (category) => {
|
|
return category.slug === 'actualites' ? '/actualites' : `/blog/${category.slug}`
|
|
}
|
|
|
|
const isCategoryActive = (category) => {
|
|
if (category.slug === 'actualites') {
|
|
return route.name === 'News' || route.name === 'NewsArticle'
|
|
}
|
|
|
|
return route.name === 'BlogCategory' && route.params.slug === category.slug
|
|
}
|
|
|
|
const isBlogActive = computed(() => {
|
|
return route.name === 'News' || route.name === 'BlogCategory' || route.name === 'NewsArticle'
|
|
})
|
|
|
|
onMounted(() => {
|
|
loadCategories()
|
|
})
|
|
|
|
return {
|
|
searchQuery,
|
|
mobileMenuOpen,
|
|
categories,
|
|
categoriesLoading,
|
|
dynamicCategories,
|
|
useDropdown,
|
|
isBlogActive,
|
|
getCategoryLink,
|
|
isCategoryActive,
|
|
performSearch
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.nav-link {
|
|
font-weight: 500;
|
|
transition: color 0.2s;
|
|
padding-bottom: 0.25rem;
|
|
color: #6b7280;
|
|
}
|
|
|
|
.nav-link:hover {
|
|
color: black;
|
|
}
|
|
|
|
.nav-link.active {
|
|
color: black;
|
|
border-bottom: 2px solid black;
|
|
}
|
|
|
|
.nav-link-mobile {
|
|
font-weight: 500;
|
|
transition: color 0.2s;
|
|
padding-top: 0.5rem;
|
|
padding-bottom: 0.5rem;
|
|
color: #6b7280;
|
|
}
|
|
|
|
.nav-link-mobile:hover {
|
|
color: black;
|
|
}
|
|
|
|
.dropdown-link {
|
|
display: block;
|
|
padding: 0.5rem 1rem;
|
|
color: #374151;
|
|
transition: color 0.2s, background-color 0.2s;
|
|
}
|
|
|
|
.dropdown-link:hover {
|
|
color: black;
|
|
background-color: #f9fafb;
|
|
}
|
|
</style>
|