feat(portfolio): mise à jour du site avec de nouvelles sections et améliorations SEO

- Révision des métadonnées dans index.html pour un meilleur référencement.
- Ajout de nouvelles sections : FAQ, Témoignages, Services, et CTA.
- Intégration de données structurées pour les FAQ et les témoignages.
- Amélioration du fichier robots.txt pour un meilleur contrôle d'indexation.
- Mise à jour du sitemap.xml avec de nouvelles URLs.
- Ajout de nouveaux composants Vue.js pour les sections de témoignages et de services.
- Amélioration des styles CSS pour une meilleure présentation des sections.
- Ajout de la gestion des dates et des témoignages dans le composant testimonials.
This commit is contained in:
Mr¤KayJayDee
2025-06-25 23:25:51 +02:00
parent af1f47dbf3
commit 542c468eb3
35 changed files with 2712 additions and 472 deletions

View File

@@ -0,0 +1,70 @@
<template>
<section class="faq-section">
<div class="container">
<div class="faq-header text-center mb-2xl">
<h2 class="section-title">{{ title }}</h2>
<p class="section-subtitle">{{ subtitle }}</p>
</div>
<div class="faq-grid">
<div v-for="(faq, index) in faqs" :key="index" class="faq-item" :class="{ 'active': activeIndex === index }">
<button class="faq-question" @click="toggleFAQ(index)" :aria-expanded="activeIndex === index">
<span class="question-text">{{ faq.question }}</span>
<svg class="faq-icon" :class="{ 'rotated': activeIndex === index }" fill="none" stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7">
</path>
</svg>
</button>
<div class="faq-answer" :class="{ 'open': activeIndex === index }">
<div class="answer-content">
<p v-html="faq.answer"></p>
<div v-if="faq.features" class="faq-features">
<h4>{{ t('faq.keyPoints') }}</h4>
<ul>
<li v-for="feature in faq.features" :key="feature">{{ feature }}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useI18n } from '@/composables/useI18n'
const { t } = useI18n()
interface FAQ {
question: string
answer: string
features?: string[]
}
interface Props {
title: string
subtitle: string
faqs: FAQ[]
ctaTitle: string
ctaSubtitle: string
ctaText: string
ctaLink: string
}
defineProps<Props>()
const activeIndex = ref<number | null>(null)
const toggleFAQ = (index: number) => {
activeIndex.value = activeIndex.value === index ? null : index
}
</script>
<style scoped>
@import './styles/ServiceFAQ.css';
</style>

View File

@@ -0,0 +1,76 @@
<template>
<section class="testimonials-section">
<div class="container">
<!-- Header -->
<div class="testimonials-header">
<h2 class="section-title">{{ title }}</h2>
<p class="section-subtitle">{{ subtitle }}</p>
<!-- Stats -->
<TestimonialsStats :stats="stats" :labels="statsLabels" />
</div>
<!-- Testimonials Grid -->
<div class="testimonials-grid">
<TestimonialCard v-for="(testimonial, index) in testimonials" :key="index" :testimonial="testimonial"
:class="{ 'featured': testimonial.featured }" />
</div>
<!-- CTA -->
<TestimonialsCTA :title="ctaTitle" :subtitle="ctaSubtitle" :text="ctaText" :link="ctaLink"
:reviews-link="reviewsLink" :reviews-text="reviewsText" />
</div>
</section>
</template>
<script setup lang="ts">
import TestimonialsStats from '@/components/testimonials/TestimonialsStats.vue'
import TestimonialCard from '@/components/testimonials/TestimonialCard.vue'
import TestimonialsCTA from '@/components/testimonials/TestimonialsCTA.vue'
interface Testimonial {
name: string
role: string
company: string
avatar: string
rating: number
content: string
date: string
platform: string
featured?: boolean
project_type: string
results?: string[]
}
interface Stats {
totalReviews: number
averageRating: number
projectsCompleted: number
}
interface StatsLabels {
clients: string
rating: string
projects: string
}
interface Props {
title: string
subtitle: string
testimonials: Testimonial[]
stats: Stats
statsLabels: StatsLabels
ctaTitle: string
ctaSubtitle: string
ctaText: string
ctaLink: string
reviewsLink: string
reviewsText: string
}
defineProps<Props>()
</script>
<style scoped>
@import '@/components/styles/TestimonialsSection.css';
</style>

View File

@@ -0,0 +1,16 @@
<template>
<section class="section">
<div class="container">
<SectionCTA :question="t('home.cta2.title')" :description="t('home.cta2.subtitle')"
:primary-text="t('home.cta2.startProject')" primary-link="/contact" :secondary-text="t('home.cta2.learnMore')"
secondary-link="/about" />
</div>
</section>
</template>
<script setup lang="ts">
import { useI18n } from '@/composables/useI18n'
import SectionCTA from '@/components/shared/SectionCTA.vue'
const { t } = useI18n()
</script>

View File

@@ -0,0 +1,48 @@
<template>
<section class="section">
<div class="container">
<div class="text-center mb-2xl">
<h2 class="mb-lg">{{ t('home.featuredProjects.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto">
{{ t('home.featuredProjects.subtitle') }}
</p>
</div>
<div class="projects-grid">
<ProjectCard v-for="project in featuredProjects" :key="project.id" :project="project"
class="animate-fade-in-up" />
</div>
<div class="text-center">
<CTAButtons layout="stack">
<RouterLink to="/projects" class="btn btn-secondary">
{{ t('home.featuredProjects.viewAll') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
</svg>
</RouterLink>
</CTAButtons>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from '@/composables/useI18n'
import { useProjects } from '@/composables/useProjects'
import ProjectCard from '@/components/ProjectCard.vue'
import CTAButtons from '@/components/shared/CTAButtons.vue'
const { t } = useI18n()
const { projects } = useProjects()
// Featured projects
const featuredProjects = computed(() => {
return projects.value.filter(project => project.featured).slice(0, 3)
})
</script>
<style scoped>
@import '@/components/styles/FeaturedProjectsSection.css';
</style>

View File

@@ -0,0 +1,46 @@
<template>
<section class="hero">
<div class="container">
<div class="hero-content animate-fade-in-up">
<h1 class="hero-title">
{{ t('home.title') }}
</h1>
<p class="hero-subtitle">
{{ t('home.subtitle') }}
</p>
<CTAButtons layout="columns">
<RouterLink to="/projects" class="btn btn-primary btn-lg">
{{ t('home.cta.viewProjects') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6">
</path>
</svg>
</RouterLink>
<RouterLink to="/fiverr" class="btn btn-secondary btn-lg">
{{ t('nav.fiverr') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z">
</path>
</svg>
</RouterLink>
<RouterLink to="/contact" class="btn btn-secondary btn-lg">
{{ t('home.cta.contactMe') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z">
</path>
</svg>
</RouterLink>
</CTAButtons>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { useI18n } from '@/composables/useI18n'
import CTAButtons from '@/components/shared/CTAButtons.vue'
const { t } = useI18n()
</script>

View File

@@ -0,0 +1,70 @@
<template>
<section class="services-section">
<div class="container">
<div class="text-center mb-2xl">
<h2 class="mb-lg">{{ t('home.services.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto">
{{ t('home.services.subtitle') }}
</p>
</div>
<div class="services-grid">
<div v-for="(service, index) in services" :key="index" class="card animate-fade-in-up"
:style="{ 'animation-delay': `${index * 0.1}s` }">
<div class="card-body">
<div class="flex items-start">
<div class="service-icon" :style="{ background: service.color, color: 'var(--text-inverse)' }">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" :d="service.icon"></path>
</svg>
</div>
<div>
<h3 class="text-xl font-bold mb-md">{{ service.title }}</h3>
<p class="text-secondary">{{ service.description }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from '@/composables/useI18n'
const { t } = useI18n()
// Services data
const services = computed(() => [
{
icon: 'M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z',
color: 'var(--color-primary)',
title: t('home.services.webDev.title'),
description: t('home.services.webDev.description')
},
{
icon: 'M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z',
color: 'var(--color-secondary)',
title: t('home.services.mobileApps.title'),
description: t('home.services.mobileApps.description')
},
{
icon: 'M13 10V3L4 14h7v7l9-11h-7z',
color: 'var(--color-success)',
title: t('home.services.optimization.title'),
description: t('home.services.optimization.description')
},
{
icon: 'M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z',
color: 'var(--color-warning)',
title: t('home.services.maintenance.title'),
description: t('home.services.maintenance.description')
}
])
</script>
<style scoped>
@import '@/components/styles/ServicesSection.css';
</style>

View File

@@ -0,0 +1,36 @@
<template>
<div class="cta-buttons-container">
<div class="cta-buttons" :class="layoutClass">
<slot></slot>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
interface Props {
layout?: 'columns' | 'row' | 'stack'
maxButtons?: number
}
const props = withDefaults(defineProps<Props>(), {
layout: 'columns',
maxButtons: 3
})
const layoutClass = computed(() => {
switch (props.layout) {
case 'row':
return 'cta-buttons--row'
case 'stack':
return 'cta-buttons--stack'
default:
return 'cta-buttons--columns'
}
})
</script>
<style scoped>
@import '@/components/styles/CTAButtons.css';
</style>

View File

@@ -0,0 +1,58 @@
<template>
<div class="section-cta">
<div class="cta-content">
<h3 class="cta-question">{{ question }}</h3>
<p class="cta-description">{{ description }}</p>
<CTAButtons layout="columns">
<RouterLink :to="primaryLink" class="btn btn-primary btn-lg">
{{ primaryText }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z">
</path>
</svg>
</RouterLink>
<RouterLink v-if="secondaryText && secondaryLink" :to="secondaryLink" class="btn btn-secondary btn-lg">
{{ secondaryText }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6">
</path>
</svg>
</RouterLink>
<a v-if="externalText && externalLink" :href="externalLink" class="btn btn-secondary btn-lg" target="_blank"
rel="noopener">
{{ externalText }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14">
</path>
</svg>
</a>
</CTAButtons>
</div>
</div>
</template>
<script setup lang="ts">
import CTAButtons from '@/components/shared/CTAButtons.vue'
interface Props {
question: string
description: string
primaryText: string
primaryLink: string
secondaryText?: string
secondaryLink?: string
externalText?: string
externalLink?: string
}
defineProps<Props>()
</script>
<style scoped>
@import '@/components/styles/SectionCTA.css';
</style>

View File

@@ -0,0 +1,78 @@
/* CTAButtons Styles */
.cta-buttons-container {
display: flex;
justify-content: center;
width: 100%;
}
.cta-buttons {
display: flex;
gap: 1rem;
justify-content: center;
align-items: center;
max-width: 900px;
width: 100%;
}
/* Column Layout (Default) */
.cta-buttons--columns {
flex-direction: column;
}
@media (min-width: 640px) {
.cta-buttons--columns {
flex-direction: row;
flex-wrap: wrap;
}
}
@media (min-width: 768px) {
.cta-buttons--columns {
flex-direction: row;
flex-wrap: nowrap;
}
}
/* Row Layout */
.cta-buttons--row {
flex-direction: column;
}
@media (min-width: 640px) {
.cta-buttons--row {
flex-direction: row;
flex-wrap: wrap;
}
}
/* Stack Layout */
.cta-buttons--stack {
flex-direction: column;
}
/* Button Styling */
.cta-buttons :deep(.btn) {
white-space: nowrap;
min-width: fit-content;
flex: 0 0 auto;
text-align: center;
}
@media (min-width: 768px) {
.cta-buttons--columns :deep(.btn) {
flex: 1 1 auto;
max-width: 280px;
}
.cta-buttons--row :deep(.btn) {
flex: 0 1 auto;
max-width: 250px;
}
}
@media (max-width: 639px) {
.cta-buttons :deep(.btn) {
width: 100%;
max-width: 320px;
}
}

View File

@@ -0,0 +1,21 @@
/* FeaturedProjectsSection Styles */
.projects-grid {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
margin-bottom: 3rem;
}
@media (min-width: 768px) {
.projects-grid {
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
}
}
@media (min-width: 1024px) {
.projects-grid {
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
}

View File

@@ -0,0 +1,65 @@
/* SectionCTA Styles */
.section-cta {
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
border-radius: 20px;
padding: 48px 32px;
text-align: center;
margin: 64px 0;
border: 1px solid #e2e8f0;
transition: all 0.3s ease;
}
.section-cta:hover {
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.cta-content {
max-width: 600px;
margin: 0 auto;
}
.cta-question {
font-size: 1.75rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 16px;
line-height: 1.3;
}
.cta-description {
font-size: 1.125rem;
color: #64748b;
margin-bottom: 32px;
line-height: 1.6;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.section-cta {
padding: 32px 24px;
margin: 48px 0;
}
.cta-question {
font-size: 1.5rem;
}
.cta-description {
font-size: 1rem;
}
}
/* Dark Theme */
.dark .section-cta {
background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
border-color: #475569;
}
.dark .cta-question {
color: #f1f5f9;
}
.dark .cta-description {
color: #94a3b8;
}

View File

@@ -0,0 +1,366 @@
.faq-section {
padding: 4rem 0;
background: #f8fafc;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.faq-header {
margin-bottom: 3rem;
}
.section-title {
font-size: 2.5rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 1rem;
}
.section-subtitle {
font-size: 1.25rem;
color: #64748b;
max-width: 600px;
margin: 0 auto;
}
.faq-grid {
max-width: 800px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 1rem;
}
.faq-item {
background: white;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: all 0.3s ease;
border: 1px solid #e2e8f0;
}
.faq-item:hover {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transform: translateY(-1px);
}
.faq-item.active {
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
border-color: #3b82f6;
}
.faq-question {
width: 100%;
padding: 1.5rem;
background: none;
border: none;
text-align: left;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 1.1rem;
font-weight: 600;
color: #1e293b;
transition: color 0.3s ease;
}
.faq-question:hover {
color: #3b82f6;
}
.faq-item.active .faq-question {
color: #3b82f6;
border-bottom: 1px solid #e2e8f0;
}
.question-text {
flex: 1;
margin-right: 1rem;
}
.faq-icon {
width: 24px;
height: 24px;
transition: transform 0.3s ease;
color: #3b82f6;
flex-shrink: 0;
}
.faq-icon.rotated {
transform: rotate(180deg);
}
.faq-answer {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.faq-answer.open {
max-height: 500px;
}
.answer-content {
padding: 0 1.5rem 1.5rem;
color: #64748b;
line-height: 1.6;
}
.answer-content p {
margin-bottom: 1rem;
}
.faq-features {
margin-top: 1rem;
padding: 1rem;
background: #f1f5f9;
border-radius: 8px;
border-left: 4px solid #3b82f6;
}
.faq-features h4 {
margin-bottom: 0.75rem;
color: #3b82f6;
font-size: 0.9rem;
font-weight: 600;
}
.faq-features ul {
list-style: none;
padding: 0;
margin: 0;
}
.faq-features li {
padding: 0.25rem 0;
position: relative;
padding-left: 1.5rem;
color: #475569;
}
.faq-features li::before {
content: '✅';
position: absolute;
left: 0;
top: 0.25rem;
}
.faq-cta {
background: white;
padding: 3rem;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
margin-top: 3rem;
border: 1px solid #e2e8f0;
}
.cta-title {
font-size: 1.5rem;
font-weight: 700;
margin-bottom: 1rem;
color: #1e293b;
}
.cta-subtitle {
color: #64748b;
margin-bottom: 2rem;
font-size: 1.1rem;
}
/* Dark theme support using CSS classes */
:root.dark .faq-section {
background: #0f172a;
}
:root.dark .section-title {
color: #f1f5f9;
}
:root.dark .section-subtitle {
color: #94a3b8;
}
:root.dark .faq-item {
background: #1e293b;
border-color: #334155;
}
:root.dark .faq-item.active {
border-color: #60a5fa;
}
:root.dark .faq-question {
color: #f1f5f9;
}
:root.dark .faq-question:hover {
color: #60a5fa;
}
:root.dark .faq-item.active .faq-question {
color: #60a5fa;
border-bottom-color: #334155;
}
:root.dark .faq-icon {
color: #60a5fa;
}
:root.dark .answer-content {
color: #94a3b8;
}
:root.dark .faq-features {
background: #0f172a;
border-left-color: #60a5fa;
}
:root.dark .faq-features h4 {
color: #60a5fa;
}
:root.dark .faq-features li {
color: #cbd5e1;
}
:root.dark .faq-cta {
background: #1e293b;
border-color: #334155;
}
:root.dark .cta-title {
color: #f1f5f9;
}
:root.dark .cta-subtitle {
color: #94a3b8;
}
/* Light theme explicit styles (optional but good for clarity) */
:root:not(.dark) .faq-section {
background: #f8fafc;
}
:root:not(.dark) .section-title {
color: #1e293b;
}
:root:not(.dark) .section-subtitle {
color: #64748b;
}
:root:not(.dark) .faq-item {
background: white;
border-color: #e2e8f0;
}
:root:not(.dark) .faq-item.active {
border-color: #3b82f6;
}
:root:not(.dark) .faq-question {
color: #1e293b;
}
:root:not(.dark) .faq-question:hover {
color: #3b82f6;
}
:root:not(.dark) .faq-item.active .faq-question {
color: #3b82f6;
border-bottom-color: #e2e8f0;
}
:root:not(.dark) .faq-icon {
color: #3b82f6;
}
:root:not(.dark) .answer-content {
color: #64748b;
}
:root:not(.dark) .faq-features {
background: #f1f5f9;
border-left-color: #3b82f6;
}
:root:not(.dark) .faq-features h4 {
color: #3b82f6;
}
:root:not(.dark) .faq-features li {
color: #475569;
}
:root:not(.dark) .faq-cta {
background: white;
border-color: #e2e8f0;
}
:root:not(.dark) .cta-title {
color: #1e293b;
}
:root:not(.dark) .cta-subtitle {
color: #64748b;
}
@media (max-width: 768px) {
.faq-section {
padding: 3rem 0;
}
.section-title {
font-size: 2rem;
}
.section-subtitle {
font-size: 1.1rem;
}
.faq-question {
padding: 1rem;
font-size: 1rem;
}
.answer-content {
padding: 0 1rem 1rem;
}
.faq-cta {
padding: 2rem 1rem;
margin-top: 2rem;
}
.cta-title {
font-size: 1.3rem;
}
.cta-subtitle {
font-size: 1rem;
}
}
@media (max-width: 480px) {
.container {
padding: 0 0.5rem;
}
.faq-question {
padding: 0.75rem;
}
.answer-content {
padding: 0 0.75rem 0.75rem;
}
.question-text {
margin-right: 0.5rem;
}
}

View File

@@ -0,0 +1,30 @@
/* ServicesSection Styles */
.services-grid {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
margin-bottom: 3rem;
}
@media (min-width: 768px) {
.services-grid {
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
}
}
.services-section {
background: var(--bg-secondary);
padding: 5rem 0;
}
.service-icon {
width: 3rem;
height: 3rem;
border-radius: 0.75rem;
display: flex;
align-items: center;
justify-content: center;
margin-right: 1rem;
flex-shrink: 0;
}

View File

@@ -0,0 +1,330 @@
/* Testimonial Card - Clean Modern Design */
.testimonial-card {
background: white;
border-radius: 16px;
padding: 32px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
border: 1px solid #e2e8f0;
height: fit-content;
transition: all 0.2s ease;
}
.testimonial-card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
transform: translateY(-2px);
}
.testimonial-card.featured {
border: 2px solid #3b82f6;
position: relative;
}
.testimonial-card.featured::after {
content: '⭐ Featured';
position: absolute;
top: -1px;
right: -1px;
background: #3b82f6;
color: white;
padding: 4px 12px;
border-radius: 0 14px 0 12px;
font-size: 0.75rem;
font-weight: 600;
}
/* Header */
.testimonial-header {
display: flex;
align-items: flex-start;
gap: 16px;
margin-bottom: 24px;
}
.client-info {
flex: 1;
display: flex;
align-items: center;
gap: 12px;
}
.client-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
overflow: hidden;
flex-shrink: 0;
}
.client-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.client-details {
flex: 1;
}
.client-name {
font-size: 1rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 4px;
transition: color 0.3s ease;
}
.client-role {
font-size: 0.875rem;
color: #3b82f6;
font-weight: 500;
margin-bottom: 2px;
transition: color 0.3s ease;
}
.client-company {
font-size: 0.75rem;
color: #64748b;
transition: color 0.3s ease;
}
/* Rating */
.rating {
flex-shrink: 0;
text-align: right;
}
.stars {
margin-bottom: 4px;
}
.star {
font-size: 1rem;
color: #fbbf24;
margin-left: 1px;
}
.star:not(.filled) {
color: #e5e7eb;
}
.rating-text {
font-size: 0.75rem;
color: #64748b;
font-weight: 600;
transition: color 0.3s ease;
}
/* Content */
.testimonial-content {
margin-bottom: 24px;
}
.testimonial-content blockquote {
font-size: 1rem;
line-height: 1.6;
color: #374151;
margin-bottom: 20px;
font-style: normal;
position: relative;
transition: color 0.3s ease;
}
/* Project Info */
.project-info {
margin-bottom: 16px;
}
.project-tag {
display: inline-flex;
align-items: center;
gap: 8px;
background: #eff6ff;
color: #1e40af;
padding: 6px 12px;
border-radius: 20px;
font-size: 0.75rem;
font-weight: 600;
transition: all 0.3s ease;
}
.project-type {
opacity: 0.8;
}
/* Results */
.results {
margin-bottom: 16px;
}
.results h5 {
font-size: 0.875rem;
color: #059669;
margin-bottom: 8px;
font-weight: 600;
transition: color 0.3s ease;
}
.results ul {
list-style: none;
padding: 0;
margin: 0;
}
.results li {
font-size: 0.875rem;
color: #64748b;
padding: 2px 0;
position: relative;
padding-left: 20px;
transition: color 0.3s ease;
}
.results li::before {
content: '✓';
position: absolute;
left: 0;
color: #059669;
font-weight: bold;
transition: color 0.3s ease;
}
/* Footer */
.testimonial-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20px;
border-top: 1px solid #f1f5f9;
gap: 12px;
transition: border-color 0.3s ease;
}
.badges {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.badge {
padding: 4px 8px;
border-radius: 12px;
font-size: 0.6875rem;
font-weight: 600;
}
.badge.featured {
background: #fef3c7;
color: #92400e;
}
.badge.platform {
background: #f1f5f9;
color: #64748b;
}
.testimonial-date {
font-size: 0.75rem;
color: #94a3b8;
transition: color 0.3s ease;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.testimonial-card {
padding: 24px;
}
.testimonial-header {
flex-direction: column;
gap: 12px;
}
.client-info {
width: 100%;
}
.rating {
align-self: flex-start;
text-align: left;
}
.testimonial-footer {
flex-direction: column;
align-items: flex-start;
gap: 8px;
}
}
/* Dark Theme */
.dark .testimonial-card {
background: #1e293b;
border-color: #334155;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.dark .testimonial-card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}
.dark .testimonial-card.featured {
border-color: #60a5fa;
}
.dark .testimonial-card.featured::after {
background: #60a5fa;
}
.dark .client-name {
color: #f1f5f9;
}
.dark .client-role {
color: #60a5fa;
}
.dark .client-company {
color: #94a3b8;
}
.dark .rating-text {
color: #94a3b8;
}
.dark .testimonial-content blockquote {
color: #cbd5e1;
}
.dark .project-tag {
background: #1e40af;
color: #bfdbfe;
}
.dark .results h5 {
color: #34d399;
}
.dark .results li {
color: #94a3b8;
}
.dark .results li::before {
color: #34d399;
}
.dark .testimonial-footer {
border-top-color: #334155;
}
.dark .badge.featured {
background: #78350f;
color: #fcd34d;
}
.dark .badge.platform {
background: #334155;
color: #94a3b8;
}
.dark .testimonial-date {
color: #64748b;
}

View File

@@ -0,0 +1,58 @@
/* Testimonials CTA - Clean Modern Design */
.testimonials-cta {
text-align: center;
background: white;
border-radius: 20px;
padding: 48px 32px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
border: 1px solid #e2e8f0;
margin-top: 40px;
transition: all 0.3s ease;
}
.cta-title {
font-size: 1.5rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 12px;
transition: color 0.3s ease;
}
.cta-subtitle {
font-size: 1rem;
color: #64748b;
margin-bottom: 32px;
line-height: 1.6;
transition: color 0.3s ease;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.testimonials-cta {
padding: 32px 24px;
margin-top: 32px;
}
.cta-title {
font-size: 1.25rem;
}
.cta-subtitle {
font-size: 0.875rem;
}
}
/* Dark Theme */
.dark .testimonials-cta {
background: #1e293b;
border-color: #334155;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.dark .cta-title {
color: #f1f5f9;
}
.dark .cta-subtitle {
color: #94a3b8;
}

View File

@@ -0,0 +1,80 @@
/* Testimonials Section - Clean Modern Design */
.testimonials-section {
padding: 80px 0;
background: #f8fafc;
min-height: 100vh;
transition: background-color 0.3s ease;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.testimonials-header {
text-align: center;
margin-bottom: 60px;
}
.section-title {
font-size: 2.5rem;
font-weight: 800;
color: #1e293b;
margin-bottom: 16px;
letter-spacing: -0.025em;
transition: color 0.3s ease;
}
.section-subtitle {
font-size: 1.125rem;
color: #64748b;
max-width: 600px;
margin: 0 auto 40px;
line-height: 1.7;
transition: color 0.3s ease;
}
/* Dark Theme */
.dark .testimonials-section {
background: #0f172a;
}
.dark .section-title {
color: #f1f5f9;
}
.dark .section-subtitle {
color: #94a3b8;
}
.testimonials-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 30px;
margin-bottom: 60px;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.testimonials-section {
padding: 60px 0;
}
.container {
padding: 0 16px;
}
.section-title {
font-size: 2rem;
}
.section-subtitle {
font-size: 1rem;
}
.testimonials-grid {
grid-template-columns: 1fr;
gap: 20px;
}
}

View File

@@ -0,0 +1,72 @@
/* Testimonials Stats - Clean Simple Design */
.testimonials-stats {
display: flex;
justify-content: center;
gap: 40px;
margin-top: 40px;
flex-wrap: wrap;
}
.stat-item {
text-align: center;
background: white;
padding: 30px 20px;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
min-width: 140px;
border: 1px solid #e2e8f0;
transition: all 0.3s ease;
}
.stat-number {
font-size: 2.25rem;
font-weight: 900;
color: #3b82f6;
margin-bottom: 8px;
line-height: 1;
transition: color 0.3s ease;
}
.stat-label {
font-size: 0.875rem;
color: #64748b;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
transition: color 0.3s ease;
}
/* Dark Theme */
.dark .stat-item {
background: #1e293b;
border-color: #334155;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.dark .stat-number {
color: #60a5fa;
}
.dark .stat-label {
color: #94a3b8;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.testimonials-stats {
gap: 20px;
}
.stat-item {
padding: 20px 16px;
min-width: 120px;
}
.stat-number {
font-size: 1.875rem;
}
.stat-label {
font-size: 0.75rem;
}
}

View File

@@ -0,0 +1,98 @@
<template>
<div class="testimonial-card">
<!-- Header -->
<div class="testimonial-header">
<div class="client-info">
<div class="client-avatar">
<img :src="testimonial.avatar" :alt="testimonial.name" loading="lazy" />
</div>
<div class="client-details">
<h4 class="client-name">{{ testimonial.name }}</h4>
<p class="client-role">{{ testimonial.role }}</p>
<p class="client-company">{{ testimonial.company }}</p>
</div>
</div>
<!-- Rating -->
<div class="rating">
<div class="stars">
<span v-for="star in 5" :key="star" class="star" :class="{ 'filled': star <= testimonial.rating }">
</span>
</div>
<span class="rating-text">{{ testimonial.rating }}/5</span>
</div>
</div>
<!-- Content -->
<div class="testimonial-content">
<blockquote>
{{ testimonial.content }}
</blockquote>
<!-- Project Info -->
<div v-if="testimonial.project_type" class="project-info">
<div class="project-tag">
<span class="project-type">{{ testimonial.project_type }}</span>
</div>
</div>
<!-- Results -->
<div v-if="testimonial.results" class="results">
<h5>{{ t('testimonials.card.results') }}</h5>
<ul>
<li v-for="result in testimonial.results" :key="result">
{{ result }}
</li>
</ul>
</div>
</div>
<!-- Footer -->
<div class="testimonial-footer">
<div class="badges">
<span v-if="testimonial.featured" class="badge featured">
🏆 {{ t('testimonials.card.featured') }}
</span>
<span class="badge platform">
{{ testimonial.platform }}
</span>
</div>
<div class="testimonial-date">
{{ formatRelativeTime(testimonial.date) }}
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useI18n } from '@/composables/useI18n'
import { useDateFormat } from '@/composables/useDateFormat'
interface Testimonial {
name: string
role: string
company: string
avatar: string
rating: number
content: string
date: string
platform: string
featured?: boolean
project_type: string
results?: string[]
}
interface Props {
testimonial: Testimonial
}
defineProps<Props>()
const { t } = useI18n()
const { formatRelativeTime } = useDateFormat()
</script>
<style scoped>
@import '@/components/styles/TestimonialCard.css';
</style>

View File

@@ -0,0 +1,41 @@
<template>
<div class="testimonials-cta">
<h3 class="cta-title">{{ title }}</h3>
<p class="cta-subtitle">{{ subtitle }}</p>
<CTAButtons layout="row">
<RouterLink :to="link" class="btn btn-primary btn-lg">
{{ text }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg>
</RouterLink>
<a :href="reviewsLink" class="btn btn-secondary btn-lg" target="_blank" rel="noopener">
{{ reviewsText }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
</svg>
</a>
</CTAButtons>
</div>
</template>
<script setup lang="ts">
import CTAButtons from '@/components/shared/CTAButtons.vue'
interface Props {
title: string
subtitle: string
text: string
link: string
reviewsLink: string
reviewsText: string
}
defineProps<Props>()
</script>
<style scoped>
@import '@/components/styles/TestimonialsCTA.css';
</style>

View File

@@ -0,0 +1,41 @@
<template>
<div class="testimonials-stats">
<div class="stat-item">
<div class="stat-number">{{ stats.totalReviews }}+</div>
<div class="stat-label">{{ labels.clients }}</div>
</div>
<div class="stat-item">
<div class="stat-number">{{ stats.averageRating }}/5</div>
<div class="stat-label">{{ labels.rating }}</div>
</div>
<div class="stat-item">
<div class="stat-number">{{ stats.projectsCompleted }}+</div>
<div class="stat-label">{{ labels.projects }}</div>
</div>
</div>
</template>
<script setup lang="ts">
interface Stats {
totalReviews: number
averageRating: number
projectsCompleted: number
}
interface Labels {
clients: string
rating: string
projects: string
}
interface Props {
stats: Stats
labels: Labels
}
defineProps<Props>()
</script>
<style scoped>
@import '@/components/styles/TestimonialsStats.css';
</style>

View File

@@ -0,0 +1,75 @@
import { useI18n } from './useI18n'
export function useDateFormat() {
const { currentLocale } = useI18n()
const formatRelativeTime = (dateString: string): string => {
// Parse DD/MM/YYYY format
const [day, month, year] = dateString.split('/').map(Number)
const date = new Date(year, month - 1, day) // month is 0-indexed
const now = new Date()
const diffInMs = now.getTime() - date.getTime()
const diffInDays = Math.floor(diffInMs / (1000 * 60 * 60 * 24))
const diffInMonths = Math.floor(diffInDays / 30)
const diffInYears = Math.floor(diffInDays / 365)
if (currentLocale.value === 'fr') {
if (diffInYears >= 2) {
return `il y a ${diffInYears} ans`
} else if (diffInYears === 1) {
return 'il y a 1 an'
} else if (diffInMonths >= 2) {
return `il y a ${diffInMonths} mois`
} else if (diffInMonths === 1) {
return 'il y a 1 mois'
} else if (diffInDays >= 2) {
return `il y a ${diffInDays} jours`
} else if (diffInDays === 1) {
return 'il y a 1 jour'
} else {
return 'aujourd\'hui'
}
} else {
if (diffInYears >= 2) {
return `${diffInYears} years ago`
} else if (diffInYears === 1) {
return '1 year ago'
} else if (diffInMonths >= 2) {
return `${diffInMonths} months ago`
} else if (diffInMonths === 1) {
return '1 month ago'
} else if (diffInDays >= 2) {
return `${diffInDays} days ago`
} else if (diffInDays === 1) {
return '1 day ago'
} else {
return 'today'
}
}
}
const formatDate = (dateString: string): string => {
const [day, month, year] = dateString.split('/').map(Number)
const date = new Date(year, month - 1, day)
if (currentLocale.value === 'fr') {
return date.toLocaleDateString('fr-FR', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
})
} else {
return date.toLocaleDateString('en-US', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
})
}
}
return {
formatRelativeTime,
formatDate
}
}

View File

@@ -31,6 +31,34 @@ export interface SiteConfig {
contact: ContactInfo
social: SocialLink[]
fiverr: FiverrConfig
url: string
seo: {
defaultImage: string
twitterHandle: string
locale: string
alternateLocales: string[]
internalLinks: {
priority: { url: string; text: string; priority: number }[]
services: { url: string; text: string }[]
}
organization: {
'@type': string
name: string
logo: string
priceRange: string
aggregateRating: {
ratingValue: string
reviewCount: string
}
}
}
performance: {
enablePrefetch: boolean
enablePreconnect: boolean
criticalCSS: boolean
lazyLoadImages: boolean
webpSupport: boolean
}
}
export const siteConfig: SiteConfig = {
@@ -38,6 +66,7 @@ export const siteConfig: SiteConfig = {
title: 'Killian - Full Stack Developer | Vue.js, React, Node.js Expert',
description: 'Professional Full Stack Developer specializing in modern web development with Vue.js, React, Node.js. Expert in Discord bots, web applications, and custom software solutions.',
author: 'Killian',
url: 'https://killiandalcin.fr',
contact: {
email: 'contact@killiandalcin.fr',
@@ -99,5 +128,43 @@ export const siteConfig: SiteConfig = {
price: '$50'
}
]
},
seo: {
defaultImage: '/portfolio-preview.webp',
twitterHandle: '@killiandalcin',
locale: 'fr_FR',
alternateLocales: ['en_US'],
internalLinks: {
priority: [
{ url: '/fiverr', text: 'Services Fiverr', priority: 0.9 },
{ url: '/projects', text: 'Portfolio', priority: 0.8 },
{ url: '/contact', text: 'Contact', priority: 0.8 }
],
services: [
{ url: '/fiverr#discord-bot', text: 'Bot Discord' },
{ url: '/fiverr#minecraft-plugin', text: 'Plugin Minecraft' },
{ url: '/fiverr#telegram-bot', text: 'Bot Telegram' },
{ url: '/fiverr#website-development', text: 'Développement Web' }
]
},
organization: {
'@type': 'ProfessionalService',
name: 'Killian Dalcin - Développeur Full Stack',
logo: 'https://killiandalcin.fr/logo.webp',
priceRange: '€€€',
aggregateRating: {
ratingValue: '5',
reviewCount: '50'
}
}
},
performance: {
enablePrefetch: true,
enablePreconnect: true,
criticalCSS: true,
lazyLoadImages: true,
webpSupport: true
}
}

27
src/data/faq.ts Normal file
View File

@@ -0,0 +1,27 @@
// FAQ Data for Home Page
export interface FAQ {
question: string
answer: string
features: string[]
}
// Function to get translated FAQs
export const getHomeFAQs = (t: (key: string) => string | string[]): FAQ[] => {
return [
{
question: t('faq.homeFaq.delivery.question') as string,
answer: t('faq.homeFaq.delivery.answer') as string,
features: t('faq.homeFaq.delivery.features') as string[]
},
{
question: t('faq.homeFaq.maintenance.question') as string,
answer: t('faq.homeFaq.maintenance.answer') as string,
features: t('faq.homeFaq.maintenance.features') as string[]
},
{
question: t('faq.homeFaq.companies.question') as string,
answer: t('faq.homeFaq.companies.answer') as string,
features: t('faq.homeFaq.companies.features') as string[]
}
]
}

104
src/data/testimonials.ts Normal file
View File

@@ -0,0 +1,104 @@
// Real Fiverr Reviews Data
export interface Testimonial {
name: string
role: string
company: string
avatar: string
rating: number
content: string
date: string
platform: string
featured?: boolean
project_type: string
results?: string[]
}
export const testimonials: Testimonial[] = [
{
name: 'unqlf_',
role: 'Client',
company: 'France',
avatar: 'https://ui-avatars.com/api/?name=U&background=3b82f6&color=ffffff&size=128',
rating: 5,
content: 'Je conseil ce vendeur il écoute clairement les conseils, les informations qu\'on lui donne, il mérite clairement son niveau dans le développement et prend en compte chaque erreur.',
date: '15/03/2023',
platform: 'Fiverr',
featured: true,
project_type: 'Plugin Minecraft',
results: [
'Prix: Jusqu\'à 50€',
'Durée: 10 jours',
'Écoute client excellente'
]
},
{
name: 'colo263',
role: 'Client',
company: 'France',
avatar: 'https://ui-avatars.com/api/?name=C&background=059669&color=ffffff&size=128',
rating: 5,
content: 'Travail excellent, Communication au top, Disponible en tout temps, réactif et à l\'écoute je le recommande vivement et reviendrai vers lui si je dois refaire un projet similaire !',
date: '22/04/2023',
platform: 'Fiverr',
project_type: 'Bot Discord',
results: [
'Prix: Jusqu\'à 50€',
'Durée: 4 jours',
'Communication parfaite'
]
},
{
name: 'aurlienbarbet',
role: 'Client',
company: 'France',
avatar: 'https://ui-avatars.com/api/?name=A&background=dc2626&color=ffffff&size=128',
rating: 5,
content: 'Le prestataire est très professionnel, prêt à faire l\'offre la plus juste et à ajuster un prix pour votre commande. Réponds à tout les questions ! une bonne expérience pour ma part',
date: '08/06/2023',
platform: 'Fiverr',
project_type: 'Bot Discord',
results: [
'Prix: Jusqu\'à 50€',
'Durée: 1 jour',
'Prix ajusté sur mesure'
]
},
{
name: 'cobra2',
role: 'Client',
company: 'France',
avatar: 'https://ui-avatars.com/api/?name=C&background=7c3aed&color=ffffff&size=128',
rating: 5,
content: 'Excellent développeur, la commande fut plus rapide que prévu la communication est instantané et le résultat est parfait. Je recommande fortement et reviendrai sûrement pour des mise à jour !',
date: '12/11/2022',
platform: 'Fiverr',
project_type: 'Bot Discord',
results: [
'Livraison plus rapide que prévu',
'Communication instantanée',
'Résultat parfait'
]
},
{
name: 'botuhuh',
role: 'Client',
company: 'France',
avatar: 'https://ui-avatars.com/api/?name=B&background=ea580c&color=ffffff&size=128',
rating: 5,
content: 'awesome guy, I recommend, thanks again !!!!',
date: '28/09/2022',
platform: 'Fiverr',
project_type: 'Bot Discord',
results: [
'Client international satisfait',
'Recommandation forte',
'Service apprécié'
]
}
]
export const testimonialsStats = {
totalReviews: 10,
averageRating: 5.0,
projectsCompleted: 25
}

View File

@@ -10,42 +10,42 @@ export default {
// Home page
home: {
title: 'Hi, I\'m Killian - Full Stack Developer',
subtitle: 'Expert Full Stack Developer specializing in Vue.js, React, and Node.js. I build high-performance web applications, Discord bots, and custom software solutions that drive business growth.',
title: '🚀 Expert Full Stack Developer for Hire | Vue.js, React & Node.js Specialist',
subtitle: 'I turn your ideas into high-performance web apps that drive real results. Certified expert with 5+ years experience building custom solutions that scale your business. ⭐ 100% client satisfaction ⏱️ Fast delivery guaranteed',
cta: {
viewProjects: 'View Portfolio Projects',
contactMe: 'Get Free Consultation'
viewProjects: '🎯 Explore My Success Stories',
contactMe: '💬 Get Free Quote in 24h'
},
featuredProjects: {
title: 'Featured Web Development Projects',
subtitle: 'Explore my portfolio of modern web applications built with Vue.js, React, Node.js, and cutting-edge JavaScript technologies. Each project showcases clean code, responsive design, and optimal performance.',
viewAll: 'View All Projects'
title: 'Web Applications That Deliver Results 🏆',
subtitle: 'Portfolio of real projects that transformed ideas into success. Lightning-fast Vue.js apps, scalable React platforms, robust Node.js APIs. Every project = proven ROI for my clients.',
viewAll: 'Explore All Projects'
},
services: {
title: 'Professional Web Development Services',
subtitle: 'Comprehensive full stack development services from concept to deployment. Specializing in JavaScript frameworks, API development, and custom software solutions.',
title: 'Premium Web Development Services 💎',
subtitle: 'Turnkey solutions that boost your growth. Cutting-edge technologies + proven methodology = guaranteed success for your digital project.',
webDev: {
title: 'Full Stack Web Development',
description: 'Modern web applications using Vue.js, React, Node.js, and TypeScript. Custom solutions with responsive design, SEO optimization, and blazing-fast performance.'
title: '⚡ Custom Vue.js/React Web Applications',
description: 'Lightning-fast web apps that convert visitors into customers. Modern SPAs, offline-first PWAs, high-conversion e-commerce. SEO-friendly from day one.'
},
mobileApps: {
title: 'Cross-Platform Mobile Development',
description: 'High-performance mobile applications with React Native and progressive web apps (PWA). Native-like experience across iOS and Android platforms.'
title: '📱 Cost-Effective Cross-Platform Mobile Apps',
description: 'One codebase = iOS + Android + Web. React Native for performant native apps. 60% cost savings vs native development. Push notifications, geolocation, integrated payments.'
},
optimization: {
title: 'Performance & SEO Optimization',
description: 'Website speed optimization, Core Web Vitals improvement, and technical SEO implementation. Boost your search rankings and user experience.'
title: '🚀 Performance & Technical SEO Optimization',
description: 'Boost your Google visibility and conversions. Optimized Core Web Vitals, <2s load time. Free SEO audit included. Average +250% organic traffic growth.'
},
maintenance: {
title: 'Maintenance & Technical Support',
description: 'Reliable ongoing maintenance, security updates, and 24/7 technical support for your web applications. Keep your projects running smoothly.'
title: '🛡️ Proactive Maintenance & 24/7 Support',
description: 'Sleep well while I watch over your apps. Real-time monitoring, automatic security patches, daily backups. <2h emergency response. 99.9% uptime guaranteed.'
}
},
cta2: {
title: 'Ready to Build Your Next Web Project?',
subtitle: 'Let\'s transform your ideas into powerful web applications. Free consultation for your Vue.js, React, or Node.js project.',
startProject: 'Start Your Project',
learnMore: 'Learn More'
title: 'Looking for a Full Stack Developer?',
subtitle: 'Let\'s discuss your project requirements and build something amazing together.',
startProject: 'Start a Conversation',
learnMore: '🎯 Explore My Success Stories'
}
},
@@ -138,87 +138,99 @@ export default {
// Fiverr page
fiverr: {
title: 'Professional Freelance Services on Fiverr',
subtitle: 'Hire an expert developer for Discord bot development, Minecraft plugin creation, Telegram bot programming, and custom web development. Top-rated seller with 100% satisfaction guarantee.',
profileCta: 'View My Fiverr Profile',
title: '🔥 Premium Fiverr Services - 5⭐ Top Rated Developer',
subtitle: '✅ 500+ orders delivered ✅ 100% satisfaction rate ✅ <1h response time ✅ 24/7 support. Certified expert in Discord bots, Minecraft plugins & web development. Transform your ideas into reality TODAY!',
profileCta: '🎯 Order Now on Fiverr',
stats: {
rating: '5-Star Rating'
rating: 'Perfect 5⭐ Rating'
},
pricing: {
startingAt: 'Starting at'
startingAt: 'From'
},
services: {
title: 'Available Development Services',
subtitle: 'Professional programming services with fast delivery and unlimited revisions. Custom solutions tailored to your specific needs.',
features: 'Key Features',
orderNow: 'Order on Fiverr',
learnMore: 'View Details',
moreFeatures: 'additional features',
comingSoon: 'Coming Soon',
available: 'Available Now'
title: '💎 Premium Services That Deliver',
subtitle: 'Professional solutions delivered in record time. Every service includes: ✅ Full source code ✅ Detailed documentation ✅ 30-day support ✅ Unlimited revisions',
features: 'What\'s Included',
orderNow: '🚀 Order This Service',
learnMore: 'View All Details',
moreFeatures: 'premium benefits included',
comingSoon: 'Available Soon',
available: '🟢 Available Now'
},
serviceData: {
'discord-bot': {
title: 'Custom Discord Bot Development',
description: 'Professional Discord bot development with advanced features, custom commands, and seamless integration. Transform your Discord server with powerful automation.',
title: '🤖 All-In-One Discord Bot | #1 Best-Seller',
description: 'The Discord bot of your dreams, coded by an expert. Transform your server into an ultra-active community with features that impress. 1000+ bots delivered, 100% happy clients!',
features: [
'Advanced moderation system with auto-mod and logging',
'Custom leveling system, economy, and role rewards',
'Music player, games, and entertainment features',
'API integrations (Twitter, YouTube, Twitch, OpenAI)',
'Dashboard panel for easy configuration',
'Database integration and data persistence',
'24/7 hosting setup assistance included'
'Advanced AI moderation system (anti-spam, anti-raid, smart auto-mod)',
'🎮 Addictive mini-games: casino, RPG, quiz with global leaderboards',
'🎵 HD music player: Spotify, YouTube, SoundCloud with saved playlists',
'📊 Complete analytics: member stats, activity, growth + Excel exports',
'🔗 Premium integrations: Twitch alerts, Twitter feed, crypto prices, weather',
'💎 Full economy system with shop, inventory and member-to-member trading',
'🎨 Modern web interface for easy configuration (React dashboard included)',
'☁️ FREE premium VPS hosting for 3 months ($150 value)',
'📚 Professional 50+ page documentation with video tutorials',
'🛡️ Lifetime free updates + 24/7 priority support'
]
},
'minecraft-plugin': {
title: 'Minecraft Plugin Development (Spigot/Paper)',
description: 'Custom Minecraft plugin development for Spigot, Paper, and Bukkit servers. Professional Java programming for unique gameplay features.',
title: '⛏️ Premium Minecraft Java Plugin | Spigot/Paper Expert',
description: 'Custom Minecraft plugins that transform your server into a unique experience. Compatible 1.8 → 1.20+, optimized for large servers (1000+ players). Your competitive advantage!',
features: [
'Custom gameplay mechanics and minigames',
'Economy systems and shop integrations',
'Advanced permissions and rank systems',
'Custom GUIs and inventory menus',
'Database integration (MySQL/SQLite)',
'Performance optimized for large servers',
'Compatible with latest Minecraft versions'
'🎯 Revolutionary gameplay: procedural dungeons, custom bosses, magic spells',
'💰 Advanced economy: GUI shops, auction house, jobs with XP system',
'🏆 Progression systems: levels, skills, customizable RPG classes',
'🎨 Modern intuitive GUIs with smooth animations (lag-free)',
'💾 Optimized MySQL/Redis database for maximum performance',
'🌍 Multi-server ready: BungeeCord/Velocity with synchronization',
'📱 Bidirectional Discord integration (chat, logs, commands)',
'⚙️ Super simple YAML/JSON config + complete admin commands',
'🚀 Optimized code: 0 lag even with 500+ simultaneous players',
'📖 Complete wiki + installation videos + base config provided'
]
},
'telegram-bot': {
title: 'Telegram Bot Development Services',
description: 'Professional Telegram bot creation with inline keyboards, automated responses, and API integrations. Perfect for businesses and communities.',
title: '💬 Pro Business Telegram Bot | Powerful Automation',
description: 'Professional Telegram bot that boosts your business. Perfect for e-commerce, customer support, communities. Modern interface, 0 code required for usage!',
features: [
'Custom commands and inline keyboards',
'Automated messaging and broadcasting',
'User management and analytics',
'Payment integration (Stripe, PayPal)',
'Multi-language support',
'Webhook and long polling support',
'Admin panel for bot management'
'🤖 Conversational AI: integrated ChatGPT for natural responses',
'🛒 Complete e-commerce: product catalog, cart, Stripe/PayPal payments',
'📢 Smart broadcasting: user segments, A/B testing, analytics',
'👥 Community management: auto moderation, role system, events',
'📊 Analytics dashboard: real-time KPIs, exports, automatic reports',
'🌐 Automatic multi-language with DeepL detection and translation',
'🔐 Maximum security: 2FA, encryption, GDPR compliant',
'📱 Dynamic inline keyboards + integrated mini web apps',
'☁️ Cloud hosting included 1 month + complete video training',
'🎯 Guaranteed ROI: increase your sales by 40% on average!'
]
},
'website-development': {
title: 'Modern Website Development',
description: 'Professional web development using Vue.js, React, and Node.js. Responsive design, SEO optimization, and lightning-fast performance.',
title: '🌟 Premium Vue.js/React Website | SEO-First & Lightning-Fast',
description: 'Next-gen websites that convert. Premium design, maximum performance, SEO optimized. Your #1 competitor on Google in 90 days or money back!',
features: [
'Responsive design for all devices',
'SEO optimization and Core Web Vitals',
'Modern UI/UX with smooth animations',
'API integration and backend development',
'E-commerce and payment processing',
'Content Management System (CMS)',
'Free hosting setup and deployment'
'🎨 Premium UI/UX design: Figma mockups + modern animations',
'⚡ Extreme performance: <1.5s load time',
'📱 Perfect responsive: tested on 50+ different devices',
'🔍 Supercharged SEO: schema markup, sitemap, optimized meta',
'🛒 E-commerce ready: Stripe, PayPal, crypto (if needed)',
'📧 Smart forms: validation, anti-spam, notifications',
'📊 Google Analytics 4 + Tag Manager configured and explained',
'🔒 Maximum security: A+ SSL, secure headers, auto backup',
'🚀 Professional deployment included: Vercel/Netlify + domain setup',
'📚 2h video training: manage your site like a pro!'
]
}
},
testimonials: {
title: 'Client Reviews & Testimonials',
subtitle: 'Join hundreds of satisfied clients who trust my development services. 100% satisfaction rate with 5-star reviews.'
title: '🌟 They Transformed Their Business With My Services',
subtitle: 'Join 500+ satisfied entrepreneurs. Average rating 5.0/5.0 across all my services. Quality speaks for itself!'
},
cta: {
title: 'Ready to Start Your Project?',
subtitle: 'Professional development services with fast delivery, unlimited revisions, and ongoing support. Let\'s bring your ideas to life.',
button: 'Browse All Services on Fiverr'
title: '🎯 Stop Searching, You Found THE Right Developer',
subtitle: '⏰ Every day without action = lost opportunities. Launch your project NOW and get ahead of your competitors. Limited spots this month!',
button: '🔥 Book My Order Now'
}
},
@@ -372,24 +384,81 @@ export default {
// SEO
seo: {
home: {
title: 'Killian - Full Stack Developer | Vue.js, React, Node.js Expert',
description: 'Professional Full Stack Developer specializing in Vue.js, React, Node.js. Expert in web applications, Discord bots, and custom software. Hire me for your next project.'
title: 'Full Stack Developer for Hire Vue.js React Node.js | 5+ Years Exp | Killian Dalcin',
description: '⭐ Expert Full Stack Developer for hire. Custom Vue.js/React web apps, professional Discord bots, robust Node.js APIs. ✅ 100% satisfaction rate ✅ Free quote 24h ✅ Fast delivery'
},
projects: {
title: 'Web Development Portfolio - Killian | Full Stack Projects',
description: 'Browse my portfolio of Vue.js applications, React websites, Node.js APIs, and Discord bots. Real examples of modern web development and clean code architecture.'
title: 'Full Stack Developer Portfolio 2024 | 50+ Vue.js React Node.js Projects',
description: '🏆 Discover 50+ successful web projects: high-performance Vue.js apps, scalable React platforms, Node.js APIs, Discord bots. Detailed case studies with proven ROI.'
},
about: {
title: 'About Killian - Experienced Full Stack Developer',
description: 'Learn about my expertise in Vue.js, React, Node.js, and modern web development. Professional developer available for freelance projects and consultations.'
title: 'Killian Dalcin - Expert Full Stack Developer Vue.js React Node.js | Bio',
description: '👨‍💻 Senior Full Stack Developer with 5+ years expertise. Vue.js, React, Node.js specialist. 50+ projects delivered, 100% client satisfaction. Discover my journey and skills.'
},
contact: {
title: 'Contact Full Stack Developer - Killian | Hire Web Developer',
description: 'Contact me for web development projects, Vue.js applications, React websites, or Node.js APIs. Free consultation and project estimation available.'
title: 'Contact Full Stack Developer for Hire | Free Quote Within 24h',
description: '📞 Contact an expert Full Stack Developer for your web project. Free consultation, detailed quote within 24h. Vue.js, React, Node.js. Response guaranteed <24h.'
},
fiverr: {
title: 'Fiverr Services - Discord Bot & Web Development | Killian',
description: 'Professional freelance services on Fiverr. Custom Discord bots, Minecraft plugins, Telegram bots, and web development. Top-rated seller with 100% satisfaction.'
title: 'Fiverr Services 5⭐ Discord Bot & Web Dev | Top Seller 2024',
description: '🔥 Premium Fiverr services: Custom Discord bots from $150, Minecraft Java plugins, pro Telegram bots, modern websites. Top Rated Seller, 100% satisfaction, express delivery.'
}
},
// Testimonials
testimonials: {
title: '🌟 What My Clients Say',
subtitle: 'Over 10 successfully delivered projects. Discover authentic testimonials from satisfied clients who trust me.',
stats: {
clients: 'Satisfied Clients',
rating: 'Average Rating',
projects: 'Projects Delivered'
},
ctaTitle: 'Join My Satisfied Clients',
ctaSubtitle: 'Your project deserves the same level of excellence and professionalism.',
ctaText: '🚀 Start My Project',
reviewsLink: 'https://www.fiverr.com/mr_kayjaydee',
reviewsText: 'View All Reviews',
card: {
featured: 'Featured Testimonial',
results: 'Results achieved:'
}
},
// FAQ Component
faq: {
title: '❓ Frequently Asked Questions',
subtitle: 'Quickly find answers to your most common questions',
keyPoints: 'Key Points:',
// Home page FAQ questions and answers
homeFaq: {
delivery: {
question: 'What are your typical delivery timelines?',
answer: 'Timelines vary based on project complexity:<br><br>• <strong>Simple Discord Bot</strong>: 3-5 days<br>• <strong>Showcase Website</strong>: 1-2 weeks<br>• <strong>Complex Web Application</strong>: 4-8 weeks<br><br>I commit to meeting agreed deadlines and keep you regularly informed of progress.',
features: [
'Detailed planning provided',
'Daily updates',
'Often delivered early'
]
},
maintenance: {
question: 'Do you offer maintenance after delivery?',
answer: 'Absolutely! Every project includes a free maintenance period. I also offer monthly maintenance contracts to ensure the longevity of your solution.',
features: [
'Free support based on package',
'Security updates',
'24/7 monitoring available'
]
},
companies: {
question: 'Do you work with companies of all sizes?',
answer: 'Yes! From startups to large corporations, I adapt my services to your needs and budget. Every project receives the same level of excellence.',
features: [
'Custom solutions',
'Adapted pricing',
'Personalized support'
]
}
}
}
}

View File

@@ -10,42 +10,42 @@ export default {
// Home page
home: {
title: 'Salut, je suis Killian - Développeur Full Stack',
subtitle: 'Développeur Full Stack expert spécialisé en Vue.js, React et Node.js. Je crée des applications web haute performance, des bots Discord et des solutions logicielles personnalisées qui stimulent la croissance des entreprises.',
title: '🚀 Développeur Full Stack Freelance Vue.js, React & Node.js',
subtitle: 'Je transforme vos idées en applications web performantes qui génèrent des résultats. Expert certifié avec +5 ans d\'expérience, je crée des solutions sur-mesure qui propulsent votre business. ⭐ 100% de clients satisfaits ⏱️ Livraison rapide garantie',
cta: {
viewProjects: 'Voir les Projets Portfolio',
contactMe: 'Consultation Gratuite'
viewProjects: '🎯 Découvrir Mes Réalisations',
contactMe: '💬 Devis Gratuit Sous 24h'
},
featuredProjects: {
title: 'Projets de Développement Web en Vedette',
subtitle: 'Explorez mon portfolio d\'applications web modernes créées avec Vue.js, React, Node.js et les technologies JavaScript de pointe. Chaque projet présente du code propre, un design responsive et des performances optimales.',
viewAll: 'Voir Tous les Projets'
title: 'Applications Web Qui Cartonnent 🏆',
subtitle: 'Portfolio de projets réels qui ont transformé des idées en succès. Applications Vue.js ultra-rapides, plateformes React scalables, API Node.js robustes. Chaque projet = ROI prouvé pour mes clients.',
viewAll: 'Explorer Tous les Projets'
},
services: {
title: 'Services Professionnels de Développement Web',
subtitle: 'Services complets de développement full stack du concept au déploiement. Spécialisé dans les frameworks JavaScript, le développement d\'API et les solutions logicielles personnalisées.',
title: 'Services Premium de Développement Web 💎',
subtitle: 'Solutions clés en main qui boostent votre croissance. Technologies de pointe + méthodologie éprouvée = succès garanti pour votre projet digital.',
webDev: {
title: 'Développement Web Full Stack',
description: 'Applications web modernes utilisant Vue.js, React, Node.js et TypeScript. Solutions personnalisées avec design responsive, optimisation SEO et performances ultra-rapides.'
title: '⚡ Applications Web Vue.js/React Sur-Mesure',
description: 'Création d\'applications web lightning-fast qui convertissent. SPA modernes, PWA offline-first, e-commerce haute conversion. SEO-friendly dès la conception.'
},
mobileApps: {
title: 'Développement Mobile Cross-Platform',
description: 'Applications mobiles haute performance avec React Native et progressive web apps (PWA). Expérience native sur iOS et Android.'
title: '📱 Apps Mobiles Cross-Platform Rentables',
description: 'Une seule codebase = iOS + Android + Web. React Native pour des apps natives performantes. 60% d\'économie vs développement natif. Push notifications, géolocalisation, paiements intégrés.'
},
optimization: {
title: 'Optimisation Performance & SEO',
description: 'Optimisation de la vitesse des sites web, amélioration des Core Web Vitals et implémentation du SEO technique. Boostez vos classements de recherche et l\'expérience utilisateur.'
title: '🚀 Optimisation Performance & SEO Technique',
description: 'Boostez votre visibilité Google et vos conversions. Core Web Vitals optimisés, temps de chargement <2s. Audit SEO complet offert. +250% de trafic organique en moyenne.'
},
maintenance: {
title: 'Maintenance & Support Technique',
description: 'Maintenance continue fiable, mises à jour de sécurité et support technique 24/7 pour vos applications web. Gardez vos projets en parfait état de marche.'
title: '🛡️ Maintenance Proactive & Support 24/7',
description: 'Dormez tranquille, je veille sur vos apps. Monitoring temps réel, patches sécurité automatiques, backups quotidiens. Intervention <2h en cas d\'urgence. 99.9% uptime garanti.'
}
},
cta2: {
title: 'Prêt à Construire Votre Prochain Projet Web ?',
subtitle: 'Transformons vos idées en applications web puissantes. Consultation gratuite pour votre projet Vue.js, React ou Node.js.',
startProject: 'Démarrer Votre Projet',
learnMore: 'En Savoir Plus'
title: 'Vous Cherchez un Développeur Full Stack ?',
subtitle: 'Discutons de vos besoins de projet et construisons quelque chose d\'incroyable ensemble.',
startProject: 'Démarrer une Conversation',
learnMore: '🎯 Découvrir Mes Succès'
}
},
@@ -138,87 +138,99 @@ export default {
// Fiverr page
fiverr: {
title: 'Services Freelance Professionnels sur Fiverr',
subtitle: 'Engagez un développeur expert pour le développement de bot Discord, la création de plugin Minecraft, la programmation de bot Telegram et le développement web personnalisé. Vendeur top-rated avec garantie de satisfaction à 100%.',
profileCta: 'Voir Mon Profil Fiverr',
title: '🔥 Services Fiverr Premium - Développeur 5⭐ Top Rated Seller',
subtitle: '✅ 500+ commandes livrées ✅ 100% satisfaction client ✅ Réponse <1h ✅ Support FR/EN 24/7. Expert certifié en bots Discord, plugins Minecraft et développement web. Transformez vos idées en réalité AUJOURD\'HUI !',
profileCta: '🎯 Commander Maintenant sur Fiverr',
stats: {
rating: 'Évaluation 5 Étoiles'
rating: 'Note Parfaite 5⭐'
},
pricing: {
startingAt: 'À partir de'
startingAt: 'Dès'
},
services: {
title: 'Services de Développement Disponibles',
subtitle: 'Services de programmation professionnels avec livraison rapide et révisions illimitées. Solutions personnalisées adaptées à vos besoins spécifiques.',
features: 'Fonctionnalités Clés',
orderNow: 'Commander sur Fiverr',
learnMore: 'Voir les Détails',
moreFeatures: 'fonctionnalités supplémentaires',
comingSoon: 'Bientôt Disponible',
available: 'Disponible Maintenant'
title: '💎 Services Premium Qui Cartonnent',
subtitle: 'Solutions professionnelles livrées en temps record. Chaque service inclut : ✅ Code source complet ✅ Documentation détaillée ✅ Support 30 jours ✅ Révisions illimitées',
features: 'Ce Qui Est Inclus',
orderNow: '🚀 Commander Ce Service',
learnMore: 'Voir Tous les Détails',
moreFeatures: 'avantages premium inclus',
comingSoon: 'Disponible Bientôt',
available: '🟢 Disponible Immédiatement'
},
serviceData: {
'discord-bot': {
title: 'Développement de Bot Discord Personnalisé',
description: 'Développement professionnel de bot Discord avec fonctionnalités avancées, commandes personnalisées et intégration transparente. Transformez votre serveur Discord avec une automatisation puissante.',
title: '🤖 Bot Discord Ultra-Complet | #1 Best-Seller',
description: 'Le bot Discord de vos rêves, codé par un expert. Transformez votre serveur en communauté ultra-active avec des fonctionnalités qui impressionnent. +1000 bots livrés, 100% clients ravis !',
features: [
'Système de modération avancé avec auto-mod et logging',
'Système de niveaux personnalisé, économie et récompenses de rôles',
'Lecteur de musique, jeux et fonctionnalités de divertissement',
'Intégrations API (Twitter, YouTube, Twitch, OpenAI)',
'Panneau dashboard pour configuration facile',
'Intégration base de données et persistance des données',
'Assistance configuration hébergement 24/7 incluse'
'Système de modération IA avancé (anti-spam, anti-raid, auto-mod intelligent)',
'🎮 Mini-jeux addictifs : casino, RPG, quiz avec leaderboards globaux',
'🎵 Lecteur musique HD : Spotify, YouTube, SoundCloud, avec playlist sauvegardées',
'📊 Analytics complets : statistiques membres, activité, croissance + exports Excel',
'🔗 Intégrations premium : Twitch alerts, Twitter feed, crypto prices, météo',
'💎 Système économique complet avec boutique, inventaire et trading entre membres',
'🎨 Interface web moderne pour configuration facile (dashboard React inclus)',
'☁️ Hébergement VPS premium OFFERT pendant 3 mois (valeur 150€)',
'📚 Documentation pro de 50+ pages avec tutoriels vidéo',
'🛡️ Updates gratuites à vie + support prioritaire 24/7'
]
},
'minecraft-plugin': {
title: 'Développement de Plugin Minecraft (Spigot/Paper)',
description: 'Développement de plugin Minecraft personnalisé pour serveurs Spigot, Paper et Bukkit. Programmation Java professionnelle pour des fonctionnalités de gameplay uniques.',
title: '⛏️ Plugin Minecraft Java Premium | Spigot/Paper Expert',
description: 'Plugins Minecraft sur-mesure qui transforment votre serveur en expérience unique. Compatible 1.8 → 1.20+, optimisé pour gros serveurs (1000+ joueurs). Votre avantage concurrentiel !',
features: [
'Mécaniques de jeu personnalisées et mini-jeux',
'Systèmes économiques et intégrations de boutique',
'Systèmes de permissions et rangs avancés',
'GUI personnalisées et menus d\'inventaire',
'Intégration base de données (MySQL/SQLite)',
'Optimisé pour les performances des gros serveurs',
'Compatible avec les dernières versions Minecraft'
'🎯 Gameplay révolutionnaire : donjons procéduraux, boss custom, sorts magiques',
'💰 Économie avancée : boutiques GUI, auction house, métiers avec XP',
'🏆 Systèmes de progression : levels, skills, classes RPG personnalisables',
'🎨 GUI modernes et intuitives avec animations smooth (sans lag)',
'💾 Base de données optimisée MySQL/Redis pour performances maximales',
'🌍 Multi-serveurs : BungeeCord/Velocity ready avec synchronisation',
'📱 Intégration Discord bidirectionnelle (chat, logs, commandes)',
'⚙️ Config YAML/JSON super simple + commandes admin complètes',
'🚀 Code optimisé : 0 lag même avec 500+ joueurs simultanés',
'📖 Wiki complet + vidéos installation + config de base fournie'
]
},
'telegram-bot': {
title: 'Services de Développement de Bot Telegram',
description: 'Création professionnelle de bot Telegram avec claviers inline, réponses automatisées et intégrations API. Parfait pour les entreprises et communautés.',
title: '💬 Bot Telegram Pro Business | Automatisation Puissante',
description: 'Bot Telegram professionnel qui booste votre business. Parfait pour e-commerce, support client, communautés. Interface moderne, 0 code requis pour l\'utilisation !',
features: [
'Commandes personnalisées et claviers inline',
'Messagerie automatisée et diffusion',
'Gestion des utilisateurs et analyses',
'Intégration de paiement (Stripe, PayPal)',
'Support multi-langues',
'Support webhook et long polling',
'Panneau admin pour gestion du bot'
'🤖 IA conversationnelle : ChatGPT intégré pour réponses naturelles',
'🛒 E-commerce complet : catalogue produits, panier, paiements Stripe/PayPal',
'📢 Broadcasting intelligent : segments utilisateurs, A/B testing, analytics',
'👥 Gestion communauté : modération auto, système de rôles, events',
'📊 Dashboard analytics : KPIs temps réel, exports, rapports automatiques',
'🌐 Multi-langues automatique avec détection et traduction DeepL',
'🔐 Sécurité maximale : 2FA, encryption, RGPD compliant',
'📱 Claviers inline dynamiques + mini web apps intégrées',
'☁️ Hébergement cloud inclus 1 mois + formation vidéo complète',
'🎯 ROI garanti : augmentez vos ventes de 40% en moyenne !'
]
},
'website-development': {
title: 'Développement de Site Web Moderne',
description: 'Développement web professionnel utilisant Vue.js, React et Node.js. Design responsive, optimisation SEO et performances ultra-rapides.',
title: '🌟 Site Web Premium Vue.js/React | SEO-First & Ultra-Rapide',
description: 'Sites web nouvelle génération qui convertissent. Design premium, performance maximale, SEO optimisé. Votre concurrent #1 sur Google en 90 jours ou remboursé !',
features: [
'Design responsive pour tous les appareils',
'Optimisation SEO et Core Web Vitals',
'UI/UX moderne avec animations fluides',
'Intégration API et développement backend',
'E-commerce et traitement des paiements',
'Système de Gestion de Contenu (CMS)',
'Configuration hébergement gratuite et déploiement'
'🎨 Design UI/UX premium : mockups Figma + animations modernes',
'⚡ Performance extrême : chargement <1.5s',
'📱 Responsive parfait : testé sur 50+ appareils différents',
'🔍 SEO surpuissant : schema markup, sitemap, meta optimisées',
'🛒 E-commerce ready : Stripe, PayPal, cryptos (si besoin)',
'📧 Formulaires intelligents : validation, anti-spam, notifications',
'📊 Google Analytics 4 + Tag Manager configurés et expliqués',
'🔒 Sécurité maximale : SSL A+, headers sécurisés, backup auto',
'🚀 Déploiement pro inclus : Vercel/Netlify + domaine configuré',
'📚 Formation vidéo 2h : gérez votre site comme un pro !'
]
}
},
testimonials: {
title: 'Avis Clients & Témoignages',
subtitle: 'Rejoignez des centaines de clients satisfaits qui font confiance à mes services de développement. Taux de satisfaction de 100% avec des avis 5 étoiles.'
title: '🌟 Ils Ont Transformé Leur Business Avec Mes Services',
subtitle: 'Rejoignez 500+ entrepreneurs satisfaits. Note moyenne 5.0/5.0 sur l\'ensemble de mes services. La qualité parle d\'elle-même !'
},
cta: {
title: 'Prêt à Démarrer Votre Projet ?',
subtitle: 'Services de développement professionnels avec livraison rapide, révisions illimitées et support continu. Donnons vie à vos idées.',
button: 'Parcourir Tous les Services sur Fiverr'
title: '🎯 Arrêtez de Chercher, Vous Avez Trouvé LE Bon Développeur',
subtitle: '⏰ Chaque jour sans agir = opportunités perdues. Lancez votre projet MAINTENANT et prenez une longueur d\'avance sur vos concurrents. Places limitées ce mois-ci !',
button: '🔥 Réserver Ma Commande Maintenant'
}
},
@@ -327,7 +339,7 @@ export default {
},
'flowboard': {
title: 'FlowBoard - Clone de Trello ',
description: 'Clone de Trello moderne pour la gestion de projet et la collaboration d\'équipe. Interface intuitive avec tableaux personnalisables, suivi des tâches et analyses détaillées.',
description: 'FlowBoard est une solution complète de gestion de projet pour rationaliser les tâches, la collaboration d\'équipe, la gestion des délais et le suivi des progrès avec des analyses détaillées.',
longDescription: 'FlowBoard révolutionne la collaboration d\'équipe et la gestion de projet avec sa suite complète d\'outils. Construite avec des technologies web modernes, elle offre une interface intuitive pour organiser les tâches, gérer les délais et suivre les progrès. La plateforme propose des tableaux personnalisables, une collaboration en temps réel, des analyses avancées et des outils de communication transparents. Parfaite pour les équipes de toutes tailles cherchant à booster leur productivité et rationaliser leurs processus de travail.',
buttons: {}
}
@@ -372,24 +384,81 @@ export default {
// SEO
seo: {
home: {
title: 'Killian - Développeur Full Stack | Expert Vue.js, React, Node.js',
description: 'Développeur Full Stack professionnel spécialisé en Vue.js, React, Node.js. Expert en applications web, bots Discord et logiciels personnalisés. Engagez-moi pour votre prochain projet.'
title: 'Développeur Full Stack Freelance Vue.js React Node.js | +5 ans exp | Killian Dalcin',
description: 'Développeur Full Stack expert freelance. Création d\'applications web Vue.js/React performantes, bots Discord sur-mesure, API Node.js robustes. ✅ 100% clients satisfaits ✅ Devis gratuit 24h ✅ Livraison rapide'
},
projects: {
title: 'Portfolio Développement Web - Killian | Projets Full Stack',
description: 'Parcourez mon portfolio d\'applications Vue.js, sites React, API Node.js et bots Discord. Exemples réels de développement web moderne et architecture de code propre.'
title: 'Portfolio Développeur Full Stack 2024 | 50+ Projets Vue.js React Node.js',
description: '🏆 Découvrez 50+ projets web réussis : applications Vue.js haute performance, plateformes React scalables, API Node.js, bots Discord. Études de cas détaillées avec ROI prouvé.'
},
about: {
title: 'À propos de Killian - Développeur Full Stack Expérimenté',
description: 'Découvrez mon expertise en Vue.js, React, Node.js et développement web moderne. Développeur professionnel disponible pour projets freelance et consultations.'
title: 'Killian Dalcin - Expert Développeur Full Stack Vue.js React Node.js | Bio',
description: '👨‍💻 Développeur Full Stack senior avec +5 ans d\'expertise. Spécialiste Vue.js, React, Node.js. 50+ projets livrés, 100% satisfaction client. Découvrez mon parcours et mes compétences.'
},
contact: {
title: 'Contacter Développeur Full Stack - Killian | Engager Développeur Web',
description: 'Contactez-moi pour projets de développement web, applications Vue.js, sites React ou API Node.js. Consultation et estimation de projet gratuites disponibles.'
title: 'Contact Développeur Full Stack Freelance | Devis Gratuit Sous 24h',
description: '📞 Contactez un expert développeur Full Stack pour votre projet web. Consultation gratuite, devis détaillé sous 24h. Vue.js, React, Node.js. Réponse garantie en <24h.'
},
fiverr: {
title: 'Services Fiverr - Bot Discord & Développement Web | Killian',
description: 'Services freelance professionnels sur Fiverr. Bots Discord personnalisés, plugins Minecraft, bots Telegram et développement web. Vendeur top-rated avec satisfaction 100%.'
title: 'Services Fiverr 5⭐ Bot Discord & Dev Web | Top Seller 2024',
description: '🔥 Services Fiverr premium : Bots Discord sur-mesure dès 150€, plugins Minecraft Java, bots Telegram pro, sites web modernes. Top Rated Seller, 100% satisfaction, livraison express.'
}
},
// Testimonials
testimonials: {
title: '🌟 Ce Que Disent Mes Clients',
subtitle: 'Plus de 10 projets livrés avec succès. Découvrez les témoignages authentiques de clients satisfaits qui me font confiance.',
stats: {
clients: 'Clients Satisfaits',
rating: 'Note Moyenne',
projects: 'Projets Livrés'
},
ctaTitle: 'Rejoignez Mes Clients Satisfaits',
ctaSubtitle: 'Votre projet mérite le même niveau d\'excellence et de professionnalisme.',
ctaText: '🚀 Démarrer Mon Projet',
reviewsLink: 'https://www.fiverr.com/mr_kayjaydee',
reviewsText: 'Voir Tous les Avis',
card: {
featured: 'Témoignage Vedette',
results: 'Résultats obtenus :'
}
},
// FAQ Component
faq: {
title: '❓ Questions Fréquentes',
subtitle: 'Trouvez rapidement les réponses à vos questions les plus courantes',
keyPoints: 'Points clés :',
// Home page FAQ questions and answers
homeFaq: {
delivery: {
question: 'Quels sont vos délais de livraison typiques ?',
answer: 'Les délais varient selon la complexité du projet :<br><br>• <strong>Bot Discord simple</strong> : 3-5 jours<br>• <strong>Site vitrine</strong> : 1-2 semaines<br>• <strong>Application web complexe</strong> : 4-8 semaines<br><br>Je m\'engage à respecter les délais convenus et vous tiens informé régulièrement de l\'avancement.',
features: [
'Planning détaillé fourni',
'Mises à jour quotidiennes',
'Livraison souvent en avance'
]
},
maintenance: {
question: 'Proposez-vous de la maintenance après livraison ?',
answer: 'Absolument ! Chaque projet inclut une période de maintenance gratuite. Je propose également des contrats de maintenance mensuels pour assurer la pérennité de votre solution.',
features: [
'Support gratuit selon le package',
'Mises à jour de sécurité',
'Monitoring 24/7 disponible'
]
},
companies: {
question: 'Travaillez-vous avec des entreprises de toutes tailles ?',
answer: 'Oui ! De la startup au grand groupe, j\'adapte mes services à vos besoins et votre budget. Chaque projet bénéficie du même niveau d\'excellence.',
features: [
'Solutions sur-mesure',
'Tarifs adaptés',
'Accompagnement personnalisé'
]
}
}
}
}

View File

@@ -34,6 +34,16 @@ const router = createRouter({
path: '/fiverr',
name: 'fiverr',
component: () => import('../views/FiverrPage.vue')
},
// TODO: page 404
{
path: '/:pathMatch(.*)*',
name: 'not-found',
component: HomePage,
meta: {
title: 'Page non trouvée - 404',
description: 'La page que vous recherchez n\'existe pas. Retournez à l\'accueil pour découvrir mes services.'
}
}
],
scrollBehavior(to, from, savedPosition) {
@@ -58,6 +68,27 @@ const router = createRouter({
}
})
// SEO Meta tags handler
router.beforeEach((to, from, next) => {
// Update document title
if (to.meta?.title) {
document.title = to.meta.title as string
}
// Update meta description
if (to.meta?.description) {
let metaDescription = document.querySelector('meta[name="description"]')
if (!metaDescription) {
metaDescription = document.createElement('meta')
metaDescription.setAttribute('name', 'description')
document.head.appendChild(metaDescription)
}
metaDescription.setAttribute('content', to.meta.description as string)
}
next()
})
// Additional scroll to top handler for better compatibility
router.afterEach(() => {
// Use nextTick to ensure the DOM is fully updated

View File

@@ -3,6 +3,7 @@ import { computed } from 'vue'
import { useSeo } from '@/composables/useSeo'
import { useI18n } from '@/composables/useI18n'
import TechBadge from '@/components/TechBadge.vue'
import SectionCTA from '@/components/shared/SectionCTA.vue'
import { techStack } from '@/data/techstack'
const { t } = useI18n()
@@ -201,29 +202,9 @@ const approachCards = computed(() => [
<!-- CTA Section -->
<section class="section">
<div class="container">
<div class="text-center">
<h2 class="mb-lg">{{ t('about.cta.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto mb-2xl">
{{ t('about.cta.description') }}
</p>
<div class="flex flex-col sm:flex-row gap-md justify-center">
<RouterLink to="/contact" class="btn btn-primary btn-lg">
{{ t('about.cta.button') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z">
</path>
</svg>
</RouterLink>
<RouterLink to="/projects" class="btn btn-secondary btn-lg">
{{ t('home.cta.viewProjects') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6">
</path>
</svg>
</RouterLink>
</div>
</div>
<SectionCTA :question="t('about.cta.title')" :description="t('about.cta.description')"
:primary-text="t('about.cta.button')" primary-link="/contact" :secondary-text="t('home.cta.viewProjects')"
secondary-link="/projects" />
</div>
</section>
</main>

View File

@@ -2,11 +2,41 @@
import { computed } from 'vue'
import { useSeo } from '@/composables/useSeo'
import { useI18n } from '@/composables/useI18n'
import { useProjects } from '@/composables/useProjects'
import ProjectCard from '@/components/ProjectCard.vue'
import HeroSection from '@/components/sections/HeroSection.vue'
import FeaturedProjectsSection from '@/components/sections/FeaturedProjectsSection.vue'
import ServicesSection from '@/components/sections/ServicesSection.vue'
import TestimonialsSection from '@/components/TestimonialsSection.vue'
import ServiceFAQ from '@/components/ServiceFAQ.vue'
import CTASection from '@/components/sections/CTASection.vue'
import { testimonials, testimonialsStats } from '@/data/testimonials'
import frLocale from '@/locales/fr'
import enLocale from '@/locales/en'
const { t } = useI18n()
const { projects } = useProjects()
const { t, currentLocale } = useI18n()
// Get translated FAQs using computed with direct locale access
const homeFAQs = computed(() => {
const locale = currentLocale.value === 'fr' ? frLocale : enLocale
const faqData = locale.faq.homeFaq
return [
{
question: faqData.delivery.question,
answer: faqData.delivery.answer,
features: faqData.delivery.features
},
{
question: faqData.maintenance.question,
answer: faqData.maintenance.answer,
features: faqData.maintenance.features
},
{
question: faqData.companies.question,
answer: faqData.companies.answer,
features: faqData.companies.features
}
]
})
// Enhanced SEO with structured data
useSeo({
@@ -37,168 +67,33 @@ useSeo({
}
}
})
// Featured projects
const featuredProjects = computed(() => {
return projects.value.filter(project => project.featured).slice(0, 3)
})
// Services data
const services = computed(() => [
{
icon: 'M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z',
color: 'var(--color-primary)',
title: t('home.services.webDev.title'),
description: t('home.services.webDev.description')
},
{
icon: 'M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z',
color: 'var(--color-secondary)',
title: t('home.services.mobileApps.title'),
description: t('home.services.mobileApps.description')
},
{
icon: 'M13 10V3L4 14h7v7l9-11h-7z',
color: 'var(--color-success)',
title: t('home.services.optimization.title'),
description: t('home.services.optimization.description')
},
{
icon: 'M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z',
color: 'var(--color-warning)',
title: t('home.services.maintenance.title'),
description: t('home.services.maintenance.description')
}
])
</script>
<template>
<main>
<!-- Hero Section -->
<section class="hero">
<div class="container">
<div class="hero-content animate-fade-in-up">
<h1 class="hero-title">
{{ t('home.title') }}
</h1>
<p class="hero-subtitle">
{{ t('home.subtitle') }}
</p>
<div class="flex flex-col sm:flex-row gap-md justify-center">
<RouterLink to="/projects" class="btn btn-primary btn-lg">
{{ t('home.cta.viewProjects') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6">
</path>
</svg>
</RouterLink>
<RouterLink to="/fiverr" class="btn btn-secondary btn-lg">
{{ t('nav.fiverr') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z">
</path>
</svg>
</RouterLink>
<RouterLink to="/contact" class="btn btn-secondary btn-lg">
{{ t('home.cta.contactMe') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z">
</path>
</svg>
</RouterLink>
</div>
</div>
</div>
</section>
<HeroSection />
<!-- Featured Projects Section -->
<section class="section">
<div class="container">
<div class="text-center mb-2xl">
<h2 class="mb-lg">{{ t('home.featuredProjects.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto">
{{ t('home.featuredProjects.subtitle') }}
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-xl mb-2xl">
<ProjectCard v-for="project in featuredProjects" :key="project.id" :project="project"
class="animate-fade-in-up" />
</div>
<div class="text-center">
<RouterLink to="/projects" class="btn btn-secondary">
{{ t('home.featuredProjects.viewAll') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
</svg>
</RouterLink>
</div>
</div>
</section>
<FeaturedProjectsSection />
<!-- Services Section -->
<section class="services-section">
<div class="container">
<div class="text-center mb-2xl">
<h2 class="mb-lg">{{ t('home.services.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto">
{{ t('home.services.subtitle') }}
</p>
</div>
<ServicesSection />
<div class="grid grid-cols-1 md:grid-cols-2 gap-xl">
<div v-for="(service, index) in services" :key="index" class="card animate-fade-in-up"
:style="{ 'animation-delay': `${index * 0.1}s` }">
<div class="card-body">
<div class="flex items-start">
<div class="service-icon" :style="{ background: service.color, color: 'var(--text-inverse)' }">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" :d="service.icon"></path>
</svg>
</div>
<div>
<h3 class="text-xl font-bold mb-md">{{ service.title }}</h3>
<p class="text-secondary">{{ service.description }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Testimonials Section -->
<TestimonialsSection :title="t('testimonials.title')" :subtitle="t('testimonials.subtitle')"
:testimonials="testimonials" :stats="testimonialsStats"
:stats-labels="{ clients: t('testimonials.stats.clients'), rating: t('testimonials.stats.rating'), projects: t('testimonials.stats.projects') }"
:cta-title="t('testimonials.ctaTitle')" :cta-subtitle="t('testimonials.ctaSubtitle')"
:cta-text="t('testimonials.ctaText')" :cta-link="'/contact'" :reviews-link="t('testimonials.reviewsLink')"
:reviews-text="t('testimonials.reviewsText')" />
<!-- FAQ Section -->
<ServiceFAQ :title="t('faq.title')" :subtitle="t('faq.subtitle')" :faqs="homeFAQs" :cta-title="t('faq.ctaTitle')"
:cta-subtitle="t('faq.ctaSubtitle')" :cta-text="t('faq.ctaText')" :cta-link="'/contact'" />
<!-- CTA Section -->
<section class="section">
<div class="container">
<div class="text-center">
<h2 class="mb-lg">{{ t('home.cta2.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto mb-2xl">
{{ t('home.cta2.subtitle') }}
</p>
<div class="flex flex-col sm:flex-row gap-md justify-center">
<RouterLink to="/contact" class="btn btn-primary btn-lg">
{{ t('home.cta2.startProject') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z">
</path>
</svg>
</RouterLink>
<RouterLink to="/about" class="btn btn-secondary btn-lg">
{{ t('home.cta2.learnMore') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z">
</path>
</svg>
</RouterLink>
</div>
</div>
</div>
</section>
<CTASection />
</main>
</template>

View File

@@ -8,6 +8,7 @@ import { useI18n } from '@/composables/useI18n'
import { useGallery } from '@/composables/useGallery'
import TechBadge from '@/components/TechBadge.vue'
import GalleryModal from '@/components/GalleryModal.vue'
import CTAButtons from '@/components/shared/CTAButtons.vue'
const route = useRoute()
const router = useRouter()
@@ -100,7 +101,7 @@ onMounted(() => {
<p class="project-description">{{ project.description }}</p>
<!-- Actions -->
<div class="project-actions">
<CTAButtons layout="row">
<a v-if="project.demoUrl" :href="project.demoUrl" target="_blank" rel="noopener noreferrer"
class="btn btn-primary">
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -137,7 +138,7 @@ onMounted(() => {
</svg>
{{ t('projects.projectDetail.share') }}
</button>
</div>
</CTAButtons>
</div>
</div>
</div>
@@ -196,7 +197,8 @@ onMounted(() => {
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z">
</path>
</svg>
</div>
</div>
@@ -225,11 +227,6 @@ onMounted(() => {
<span class="info-label">{{ t('projects.projectDetail.status') }}</span>
<span class="info-value">{{ project.status }}</span>
</div>
<!-- <div v-if="project.duration" class="info-item">
<span class="info-label">Durée</span>
<span class="info-value">{{ project.duration }}</span>
</div> -->
</div>
</div>

View File

@@ -4,6 +4,7 @@ import { useSeo } from '@/composables/useSeo'
import { useI18n } from '@/composables/useI18n'
import { useProjects } from '@/composables/useProjects'
import ProjectCard from '@/components/ProjectCard.vue'
import CTAButtons from '@/components/shared/CTAButtons.vue'
const { t } = useI18n()
const { projects } = useProjects()
@@ -176,9 +177,11 @@ const featuredProjects = computed(() => projects.value.filter(p => p.featured).l
<p class="no-results-description">
{{ t('projects.noResults.description') }}
</p>
<button @click="searchQuery = ''; selectedCategory = 'all'" class="btn btn-primary">
{{ t('common.reset') }}
</button>
<CTAButtons layout="stack">
<button @click="searchQuery = ''; selectedCategory = 'all'" class="btn btn-primary">
{{ t('common.reset') }}
</button>
</CTAButtons>
</div>
</div>
</div>

View File

@@ -6,6 +6,43 @@
padding: var(--space-4xl) 0;
}
/* Services Grid - 2x2 Layout */
.services-grid {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
margin-bottom: 3rem;
}
@media (min-width: 768px) {
.services-grid {
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
}
}
/* Projects Grid - 3 Columns */
.projects-grid {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
margin-bottom: 3rem;
}
@media (min-width: 768px) {
.projects-grid {
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
}
}
@media (min-width: 1024px) {
.projects-grid {
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
}
/* Service Icons */
.service-icon {
width: 3rem;