diff --git a/src/components/NavigationBar.vue b/src/components/NavigationBar.vue index 4a44f42..64c7a1e 100644 --- a/src/components/NavigationBar.vue +++ b/src/components/NavigationBar.vue @@ -36,15 +36,15 @@
- + - Au Hasard + Actualités
@@ -83,7 +83,7 @@
Accueil Textes - Au Hasard + Actualités
.nav-link { - @apply font-medium transition-colors duration-200 pb-1; + font-weight: 500; + transition: color 0.2s; + padding-bottom: 0.25rem; color: #6b7280; } @@ -140,11 +142,15 @@ export default { } .nav-link.active { - @apply text-black border-b-2 border-black; + color: black; + border-bottom: 2px solid black; } .nav-link-mobile { - @apply font-medium transition-colors duration-200 py-2; + font-weight: 500; + transition: color 0.2s; + padding-top: 0.5rem; + padding-bottom: 0.5rem; color: #6b7280; } diff --git a/src/router/index.js b/src/router/index.js index f3e67cd..4273483 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -2,6 +2,8 @@ import Home from '../views/Home.vue' import Texts from '../views/Texts.vue' import TextReader from '../views/TextReader.vue' +import News from '../views/News.vue' +import NewsArticle from '../views/NewsArticle.vue' import { textService } from '../services/textService.js' const routes = [ @@ -22,17 +24,15 @@ const routes = [ props: true }, { - path: '/au-hasard', - name: 'Random', - beforeEnter: async (to, from, next) => { - try { - const randomText = await textService.getRandomText() - next(`/texte/${randomText.id}`) - } catch (error) { - console.error('Erreur lors de la redirection vers un texte aléatoire:', error) - next('/textes') - } - } + path: '/actualites', + name: 'News', + component: News + }, + { + path: '/actualite/:id', + name: 'NewsArticle', + component: NewsArticle, + props: true } ] diff --git a/src/services/wordpressService.js b/src/services/wordpressService.js new file mode 100644 index 0000000..2481f41 --- /dev/null +++ b/src/services/wordpressService.js @@ -0,0 +1,96 @@ +const API_BASE_URL = 'https://admin-afpl.federation-ouest-francoprovencal.fr/wp-json/wp/v2' +const ACTUALITES_CATEGORY_ID = 3 + +/** + * Service pour interagir avec l'API WordPress (Headless CMS) + */ +export const wordpressService = { + /** + * Récupère tous les posts de la catégorie "actualites" + * @param {number} perPage - Nombre de posts par page (défaut: 10) + * @param {number} page - Numéro de page (défaut: 1) + * @returns {Promise} - { posts: Array, totalPages: number, total: number } + */ + async getNews(perPage = 10, page = 1) { + try { + const response = await fetch( + `${API_BASE_URL}/posts?categories=${ACTUALITES_CATEGORY_ID}&per_page=${perPage}&page=${page}&_embed` + ) + + if (!response.ok) { + throw new Error(`Erreur HTTP: ${response.status}`) + } + + const posts = await response.json() + const totalPages = parseInt(response.headers.get('X-WP-TotalPages') || '1') + const total = parseInt(response.headers.get('X-WP-Total') || '0') + + return { + posts: posts.map(post => this.formatPost(post)), + totalPages, + total + } + } catch (error) { + console.error('Erreur lors de la récupération des actualités:', error) + throw error + } + }, + + /** + * Récupère un post spécifique par son ID + * @param {number} id - ID du post + * @returns {Promise} - Post formaté + */ + async getNewsById(id) { + try { + const response = await fetch(`${API_BASE_URL}/posts/${id}?_embed`) + + if (!response.ok) { + throw new Error(`Erreur HTTP: ${response.status}`) + } + + const post = await response.json() + return this.formatPost(post) + } catch (error) { + console.error(`Erreur lors de la récupération du post ${id}:`, error) + throw error + } + }, + + /** + * Formate un post WordPress pour l'utilisation dans l'application + * @param {Object} post - Post brut de l'API WordPress + * @returns {Object} - Post formaté + */ + formatPost(post) { + return { + id: post.id, + title: post.title.rendered, + content: post.content.rendered, + excerpt: post.excerpt.rendered, + date: post.date, + modified: post.modified, + slug: post.slug, + link: post.link, + author: post._embedded?.author?.[0]?.name || 'Auteur inconnu', + featuredImage: post._embedded?.['wp:featuredmedia']?.[0]?.source_url || null, + featuredImageAlt: post._embedded?.['wp:featuredmedia']?.[0]?.alt_text || '', + categories: post._embedded?.['wp:term']?.[0]?.map(cat => cat.name) || [], + tags: post._embedded?.['wp:term']?.[1]?.map(tag => tag.name) || [] + } + }, + + /** + * Formate une date pour l'affichage + * @param {string} dateString - Date au format ISO + * @returns {string} - Date formatée en français + */ + formatDate(dateString) { + const date = new Date(dateString) + return date.toLocaleDateString('fr-FR', { + year: 'numeric', + month: 'long', + day: 'numeric' + }) + } +} diff --git a/src/style.css b/src/style.css index 6dc4374..5e14008 100644 --- a/src/style.css +++ b/src/style.css @@ -2,6 +2,9 @@ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); @theme { + --font-sans: 'Inter', system-ui, sans-serif; + + /* Ajouter les couleurs personnalisées si nécessaire */ --color-gray-custom: #6b7280; --color-gray-custom-light: #9ca3af; } @@ -9,25 +12,50 @@ @layer base { body { font-family: 'Inter', sans-serif; - @apply bg-white text-black leading-relaxed; + background-color: white; + color: black; + line-height: 1.625; } } @layer components { .btn-primary { - @apply bg-black text-white px-6 py-3 rounded-full hover:bg-gray-800 transition-colors duration-200 font-medium; + background-color: black; + color: white; + padding: 0.75rem 1.5rem; + border-radius: 9999px; + font-weight: 500; + transition: background-color 0.2s; + } + + .btn-primary:hover { + background-color: #1f2937; } .btn-secondary { - @apply border-2 border-black text-black px-6 py-3 rounded-full hover:bg-black hover:text-white transition-all duration-200 font-medium; + border: 2px solid black; + color: black; + padding: 0.75rem 1.5rem; + border-radius: 9999px; + font-weight: 500; + transition: all 0.2s; + } + + .btn-secondary:hover { + background-color: black; + color: white; } .text-patois { - @apply font-medium text-lg leading-relaxed; + font-weight: 500; + font-size: 1.125rem; + line-height: 1.625; } .text-french { - @apply font-normal text-lg leading-relaxed; + font-weight: 400; + font-size: 1.125rem; + line-height: 1.625; color: var(--color-gray-custom); } } diff --git a/src/views/Home.vue b/src/views/Home.vue index 77476a7..d1a28ab 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -15,9 +15,6 @@ Explorer les textes - - Texte au hasard - diff --git a/src/views/News.vue b/src/views/News.vue new file mode 100644 index 0000000..63ee321 --- /dev/null +++ b/src/views/News.vue @@ -0,0 +1,243 @@ + + + + + diff --git a/src/views/NewsArticle.vue b/src/views/NewsArticle.vue new file mode 100644 index 0000000..a198b17 --- /dev/null +++ b/src/views/NewsArticle.vue @@ -0,0 +1,324 @@ + + + + +