From d705c47fbce71ba54b8c0aab48abec7bfebc0f2b Mon Sep 17 00:00:00 2001 From: "Aboubacar M." Date: Mon, 16 Mar 2026 12:26:36 +0100 Subject: [PATCH] correction de bug formulaire de contact --- assets/css/main.css | 2 +- assets/data/services.json | 163 ++++++++ assets/js/pages/services-process.js | 32 ++ assets/js/pages/services.js | 205 ++++++--- assets/php/send_mail.php | 8 +- components/services/hero.html | 10 + index.html | 4 +- pages/services.html | 620 +--------------------------- 8 files changed, 379 insertions(+), 665 deletions(-) create mode 100644 assets/data/services.json create mode 100644 assets/js/pages/services-process.js create mode 100644 components/services/hero.html diff --git a/assets/css/main.css b/assets/css/main.css index f46ca77..374fc9a 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -2649,7 +2649,7 @@ footer { transform: translateY(-50%); z-index: 1; width: 0%; - transition: width 1s ease; + transition: width 5s ease; } .process-timeline.animated::after { diff --git a/assets/data/services.json b/assets/data/services.json new file mode 100644 index 0000000..4292e51 --- /dev/null +++ b/assets/data/services.json @@ -0,0 +1,163 @@ +[ + { + "id": "bots", + "nav": { + "label": "Bots Discord", + "icon": "code", + "stamp": null + }, + "visual": { + "accentFrom": "#8b3a62", + "accentTo": "#a64d79", + "stamp": null + }, + "title": "Bots Discord RP", + "description": "Des bots entièrement personnalisés pour animer et gérer vos serveurs Role Play. Nous développons des systèmes complets adaptés à votre univers et à vos mécaniques de jeu.", + "highlights": [ + { "value": "2-4", "label": "Semaines de dev" }, + { "value": "1 mois","label": "Support inclus" }, + { "value": "100%", "label": "Personnalisable" } + ], + "features": [ + { "icon": "dollar-sign", "title": "Économie virtuelle", "desc": "Monnaie, banque, transactions" }, + { "icon": "briefcase", "title": "Système de métiers", "desc": "Jobs, skills, progression" }, + { "icon": "shield", "title": "Combat & Stats", "desc": "PvP, PvE, attributs" }, + { "icon": "box", "title": "Inventaire avancé", "desc": "Items, crafting, échanges" }, + { "icon": "flag", "title": "Factions & Guildes", "desc": "Clans, territoires, guerres" }, + { "icon": "settings", "title": "Panel Admin", "desc": "Interface web de gestion" } + ], + "cta": [ + { "label": "Demander un devis", "href": "index.html#contact", "style": "primary", "icon": "message-circle" }, + { "label": "Voir nos réalisations","href": "realisations.html", "style": "secondary","icon": "eye" } + ] + }, + { + "id": "maps", + "nav": { + "label": "Maps Fortnite", + "icon": "map", + "stamp": { "type": "new", "text": "New" } + }, + "visual": { + "accentFrom": "#1a5e8b", + "accentTo": "#3a8bb5", + "stamp": { "type": "new", "text": "✦ New" } + }, + "title": "Maps Fortnite RP", + "description": "Des environnements immersifs créés sur mesure pour vos sessions Role Play. De la ville moderne au village médiéval, nous donnons vie à tous les univers.", + "highlights": [ + { "value": "3-6", "label": "Semaines de création" }, + { "value": "50+", "label": "Joueurs supportés" }, + { "value": "UEFN", "label": "Compatible" } + ], + "features": [ + { "icon": "home", "title": "Bâtiments détaillés", "desc": "Intérieurs accessibles et déco" }, + { "icon": "sun", "title": "Cycle jour/nuit", "desc": "Ambiance dynamique" }, + { "icon": "zap", "title": "Zones interactives", "desc": "Scripts et triggers" }, + { "icon": "cpu", "title": "Optimisation", "desc": "Performance garantie" }, + { "icon": "map-pin", "title": "Points d'intérêt", "desc": "Lieux uniques et mémorables" }, + { "icon": "edit-3", "title": "Modifications", "desc": "Ajustements post-livraison" } + ], + "cta": [ + { "label": "Demander un devis", "href": "index.html#contact", "style": "primary", "icon": "message-circle" }, + { "label": "Voir nos maps", "href": "realisations.html", "style": "secondary", "icon": "eye" } + ] + }, + { + "id": "graphisme", + "nav": { + "label": "Graphisme", + "icon": "image", + "stamp": null + }, + "visual": { + "accentFrom": "#8b5e3a", + "accentTo": "#b58a5a", + "stamp": null + }, + "title": "Créations Graphiques", + "description": "Une identité visuelle forte et cohérente pour vos projets. Du logo aux bannières, nous créons des visuels qui marquent les esprits et attirent votre communauté.", + "highlights": [ + { "value": "1-2", "label": "Semaines" }, + { "value": "∞", "label": "Révisions" }, + { "value": "HD", "label": "Qualité" } + ], + "features": [ + { "icon": "hexagon", "title": "Logo & Branding", "desc": "Identité visuelle complète" }, + { "icon": "layout", "title": "Bannières Discord", "desc": "Server banner, splash, icône" }, + { "icon": "smile", "title": "Emojis custom", "desc": "Pack emojis personnalisés" }, + { "icon": "grid", "title": "Icônes & Assets", "desc": "Items, skills, badges" }, + { "icon": "play-circle","title": "Animations", "desc": "GIFs et motion design" }, + { "icon": "book-open", "title": "Guide de style", "desc": "Charte graphique fournie" } + ], + "cta": [ + { "label": "Demander un devis", "href": "index.html#contact", "style": "primary", "icon": "message-circle" }, + { "label": "Voir nos créations", "href": "realisations.html", "style": "secondary", "icon": "eye" } + ] + }, + { + "id": "consulting", + "nav": { + "label": "Consulting", + "icon": "users", + "stamp": { "type": "free", "text": "Gratuit" } + }, + "visual": { + "accentFrom": "#3a8b5e", + "accentTo": "#5ab57a", + "stamp": { "type": "free", "text": "✓ Gratuit", "animated": true } + }, + "title": "Consulting & Accompagnement", + "titleStamp": { "type": "free", "text": "Gratuit" }, + "description": "Bénéficiez de notre expérience pour structurer, lancer et développer votre projet RP. Conseils stratégiques et accompagnement personnalisé.", + "highlights": [ + { "value": "50+", "label": "Projets accompagnés" }, + { "value": "3 ans", "label": "D'expérience" }, + { "value": "24/7", "label": "Support Discord" } + ], + "features": [ + { "icon": "search", "title": "Audit serveur", "desc": "Analyse de l'existant" }, + { "icon": "trending-up", "title": "Stratégie croissance","desc": "Plan de développement" }, + { "icon": "user-check", "title": "Formation staff", "desc": "Équipe modération" }, + { "icon": "heart", "title": "Expérience joueur", "desc": "Optimisation UX" }, + { "icon": "calendar", "title": "Planning events", "desc": "Calendrier d'animations" }, + { "icon": "dollar-sign", "title": "Monétisation", "desc": "Conseils revenus" } + ], + "cta": [ + { "label": "Prendre rendez-vous", "href": "index.html#contact", "style": "primary", "icon": "message-circle" } + ] + }, + { + "id": "pack", + "nav": { + "label": "Pack Complet", + "icon": "package", + "stamp": { "type": "popular", "text": "Populaire" } + }, + "visual": { + "accentFrom": "#8b3a8b", + "accentTo": "#b55ab5", + "stamp": { "type": "popular", "text": "★ Populaire", "animated": true } + }, + "title": "Pack Serveur Complet", + "titleStamp": { "type": "promo", "text": "-20%" }, + "description": "La solution tout-en-un pour lancer votre projet RP. Bot personnalisé, map Fortnite, identité visuelle et accompagnement : tout est inclus pour un lancement réussi.", + "highlights": [ + { "value": "-20%", "label": "VS services séparés" }, + { "value": "3 mois", "label": "Support inclus" }, + { "value": "Clé en main","label": "Prêt à lancer" } + ], + "features": [ + { "icon": "code", "title": "Bot Discord RP", "desc": "Système complet personnalisé" }, + { "icon": "map", "title": "Map Fortnite", "desc": "Environnement sur mesure" }, + { "icon": "image", "title": "Pack graphique", "desc": "Logo, bannières, emojis" }, + { "icon": "server", "title": "Config Discord", "desc": "Serveur prêt à l'emploi" }, + { "icon": "book", "title": "Documentation", "desc": "Guides et tutoriels" }, + { "icon": "headphones", "title": "Support 3 mois", "desc": "Accompagnement lancement" } + ], + "cta": [ + { "label": "Demander un devis pack", "href": "index.html#contact", "style": "primary", "icon": "message-circle" }, + { "label": "Voir nos packs livrés", "href": "realisations.html", "style": "secondary", "icon": "eye" } + ] + } +] diff --git a/assets/js/pages/services-process.js b/assets/js/pages/services-process.js new file mode 100644 index 0000000..ed72bf3 --- /dev/null +++ b/assets/js/pages/services-process.js @@ -0,0 +1,32 @@ +// Services page scripts (moved from inline in pages/services.html) +// Depends on ../main.js which initializes feather and other globals + +(function() { + document.addEventListener('DOMContentLoaded', () => { + // Timeline Animation + const timeline = document.getElementById('process-timeline'); + const steps = document.querySelectorAll('.process-step'); + + function animateTimeline() { + if (!timeline) return; + const timelineTop = timeline.getBoundingClientRect().top; + + if (timelineTop < window.innerHeight - 200) { + timeline.classList.add('animated'); + + // Animate steps sequentially + steps.forEach((step, index) => { + setTimeout(() => { + step.classList.add('active'); + }, index * 1000); + }); + } + } + + window.addEventListener('scroll', animateTimeline); + window.addEventListener('load', animateTimeline); + + + + }); +})(); diff --git a/assets/js/pages/services.js b/assets/js/pages/services.js index 494b7cd..577cc4c 100644 --- a/assets/js/pages/services.js +++ b/assets/js/pages/services.js @@ -1,57 +1,164 @@ -// Services page scripts (moved from inline in pages/services.html) -// Depends on ../main.js which initializes feather and other globals +/** + * OmégaKube — Services Tabs Renderer + * Charge assets/data/services.json et construit dynamiquement + * les onglets de navigation et leurs contenus. + * + * Dépend de main.js et services-process.js (déjà chargés avant ce script). + */ -(function() { - document.addEventListener('DOMContentLoaded', () => { - // Timeline Animation - const timeline = document.getElementById('process-timeline'); - const steps = document.querySelectorAll('.process-step'); +(function () { + 'use strict'; - function animateTimeline() { - if (!timeline) return; - const timelineTop = timeline.getBoundingClientRect().top; + /* ── Helpers ─────────────────────────────────────────────── */ - if (timelineTop < window.innerHeight - 200) { - timeline.classList.add('animated'); - - // Animate steps sequentially - steps.forEach((step, index) => { - setTimeout(() => { - step.classList.add('active'); - }, index * 400); - }); - } + function stampHtml(stamp, extraClass) { + if (!stamp) return ''; + const animated = stamp.animated ? ' service-stamp-animated' : ''; + const extra = extraClass ? ' ' + extraClass : ''; + return `${stamp.text}`; } - window.addEventListener('scroll', animateTimeline); - window.addEventListener('load', animateTimeline); - - // Service Tabs - const tabBtns = document.querySelectorAll('.service-tab-btn'); - const tabContents = document.querySelectorAll('.service-tab-content'); - - if (tabBtns.length && tabContents.length) { - tabBtns.forEach(btn => { - btn.addEventListener('click', () => { - const tabId = btn.dataset.tab; - - // Update buttons - tabBtns.forEach(b => b.classList.remove('active')); - btn.classList.add('active'); - - // Update content - tabContents.forEach(content => { - content.classList.remove('active'); - if (content.id === 'tab-' + tabId) { - content.classList.add('active'); - } - }); - - // Re-init feather icons for new content (safe if feather is loaded) - if (window.feather) window.feather.replace(); - }); - }); + function particlesHtml() { + return `
${'
'.repeat(6)}
`; } - }); + /* ── Rendu ───────────────────────────────────────────────── */ + + function renderNavBtn(service, isFirst) { + return ` + `; + } + + function renderVisual(service) { + const { accentFrom, accentTo, stamp } = service.visual; + return ` +
+ ${stampHtml(stamp, 'service-visual-stamp')} + ${particlesHtml()} +
+
+ +
+
+
`; + } + + function renderHighlights(highlights) { + return highlights.map(h => ` +
+
${h.value}
+
${h.label}
+
`).join(''); + } + + function renderFeatures(features, accentFrom, accentTo) { + return features.map(f => ` +
+
+ +
+
+

${f.title}

+

${f.desc}

+
+
`).join(''); + } + + function renderCtas(ctas) { + return ctas.map(c => ` + + + ${c.label} + `).join(''); + } + + function renderTabContent(service, isFirst) { + const { accentFrom, accentTo } = service.visual; + const titleStamp = service.titleStamp + ? ' ' + stampHtml({ ...service.titleStamp }, 'service-stamp-inline') + : ''; + + return ` +
+
+ ${renderVisual(service)} +
+
+

${service.title}${titleStamp}

+

${service.description}

+
+
+ ${renderHighlights(service.highlights)} +
+
+ ${renderFeatures(service.features, accentFrom, accentTo)} +
+
+ ${renderCtas(service.cta)} +
+
+
+
`; + } + + /* ── Logique des onglets ─────────────────────────────────── */ + + function initTabs() { + const tabBtns = document.querySelectorAll('.service-tab-btn'); + const tabContents = document.querySelectorAll('.service-tab-content'); + if (!tabBtns.length || !tabContents.length) return; + + tabBtns.forEach(btn => { + btn.addEventListener('click', () => { + const tabId = btn.dataset.tab; + + tabBtns.forEach(b => b.classList.remove('active')); + btn.classList.add('active'); + + tabContents.forEach(content => { + content.classList.remove('active'); + if (content.id === 'tab-' + tabId) content.classList.add('active'); + }); + + if (window.feather) window.feather.replace(); + }); + }); + } + + /* ── Init ────────────────────────────────────────────────── */ + + async function init() { + const navContainer = document.getElementById('service-tabs-nav'); + const contentContainer = document.getElementById('service-tabs-contents'); + if (!navContainer || !contentContainer) return; + + let services; + try { + const res = await fetch('../assets/data/services.json'); + if (!res.ok) throw new Error(`HTTP ${res.status}`); + services = await res.json(); + } catch (err) { + console.error('[services-tabs.js] Impossible de charger services.json :', err); + return; + } + + if (!Array.isArray(services) || services.length === 0) { + console.warn('[services-tabs.js] services.json est vide ou mal formé.'); + return; + } + + navContainer.innerHTML = services.map((s, i) => renderNavBtn(s, i === 0)).join(''); + contentContainer.innerHTML = services.map((s, i) => renderTabContent(s, i === 0)).join(''); + + if (window.feather) window.feather.replace(); + + initTabs(); + } + + document.addEventListener('DOMContentLoaded', init); + })(); diff --git a/assets/php/send_mail.php b/assets/php/send_mail.php index 8199809..5fa1a16 100644 --- a/assets/php/send_mail.php +++ b/assets/php/send_mail.php @@ -15,7 +15,7 @@ const ALLOWED_ORIGIN = '*'; // ou 'https://omegakube.com /* ── Anti-spam : limite par IP (optionnel, nécessite accès fichier) ── */ const RATE_LIMIT_ENABLED = true; -const RATE_LIMIT_MAX = 30; // max envois +const RATE_LIMIT_MAX = 3; // max envois const RATE_LIMIT_WINDOW = 3600; // par heure (secondes) const RATE_LIMIT_DIR = __DIR__ . '/.rate_limits/'; @@ -180,8 +180,8 @@ $emailBodyHtml = ' /* Boundary pour email multipart */ $boundary = '----=_Part_' . md5(uniqid('', true)); -$headers = "From: =?UTF-8?B?" . base64_encode($name) . "?= <{$email}>\r\n"; -$headers .= "Reply-To: {$email}\r\n"; +$headers = "From: " . RECIPIENT_NAME . " <" . RECIPIENT_EMAIL . ">\r\n"; +$headers .= "Reply-To: =?UTF-8?B?" . base64_encode($name) . "?= <{$email}>\r\n"; $headers .= "To: " . RECIPIENT_NAME . " <" . RECIPIENT_EMAIL . ">\r\n"; $headers .= "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: multipart/alternative; boundary=\"{$boundary}\"\r\n"; @@ -226,4 +226,4 @@ if ($sent) { } else { http_response_code(500); echo json_encode(['success' => false, 'message' => 'Une erreur est survenue lors de l\'envoi. Veuillez réessayer ou nous contacter directement par Discord.']); -} +} \ No newline at end of file diff --git a/components/services/hero.html b/components/services/hero.html new file mode 100644 index 0000000..6d7f907 --- /dev/null +++ b/components/services/hero.html @@ -0,0 +1,10 @@ + +
+
+
+ Ce que nous proposons +
+

Nos Services

+

Des solutions complètes et sur mesure pour donner vie à vos projets Role Play les plus ambitieux.

+
+
\ No newline at end of file diff --git a/index.html b/index.html index 10c3675..823e401 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@ -
+
@@ -19,7 +19,7 @@
-
+
diff --git a/pages/services.html b/pages/services.html index e178a80..a811991 100644 --- a/pages/services.html +++ b/pages/services.html @@ -9,41 +9,14 @@ - -
-
- - -
-
-
-
-
-
-
-
-
- - - - -
-
-
-
+ +
+
-
-
-
- Ce que nous proposons -
-

Nos Services

-

Des solutions complètes et sur mesure pour donner vie à vos projets Role Play les plus ambitieux.

-
-
+
@@ -105,583 +78,11 @@
- -
- - - - - -
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-

Bots Discord RP

-

Des bots entièrement personnalisés pour animer et gérer vos serveurs Role Play. Nous développons des systèmes complets adaptés à votre univers et à vos mécaniques de jeu.

-
- -
-
-
2-4
-
Semaines de dev
-
-
-
1 mois
-
Support inclus
-
-
-
100%
-
Personnalisable
-
-
- -
-
-
- -
-
-

Économie virtuelle

-

Monnaie, banque, transactions

-
-
-
-
- -
-
-

Système de métiers

-

Jobs, skills, progression

-
-
-
-
- -
-
-

Combat & Stats

-

PvP, PvE, attributs

-
-
-
-
- -
-
-

Inventaire avancé

-

Items, crafting, échanges

-
-
-
-
- -
-
-

Factions & Guildes

-

Clans, territoires, guerres

-
-
-
-
- -
-
-

Panel Admin

-

Interface web de gestion

-
-
-
- - -
-
-
- - -
-
-
- ✦ New -
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-

Maps Fortnite RP

-

Des environnements immersifs créés sur mesure pour vos sessions Role Play. De la ville moderne au village médiéval, nous donnons vie à tous les univers.

-
- -
-
-
3-6
-
Semaines de création
-
-
-
50+
-
Joueurs supportés
-
-
-
UEFN
-
Compatible
-
-
- -
-
-
- -
-
-

Bâtiments détaillés

-

Intérieurs accessibles et déco

-
-
-
-
- -
-
-

Cycle jour/nuit

-

Ambiance dynamique

-
-
-
-
- -
-
-

Zones interactives

-

Scripts et triggers

-
-
-
-
- -
-
-

Optimisation

-

Performance garantie

-
-
-
-
- -
-
-

Points d'intérêt

-

Lieux uniques et mémorables

-
-
-
-
- -
-
-

Modifications

-

Ajustements post-livraison

-
-
-
- - -
-
-
- - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-

Créations Graphiques

-

Une identité visuelle forte et cohérente pour vos projets. Du logo aux bannières, nous créons des visuels qui marquent les esprits et attirent votre communauté.

-
- -
-
-
1-2
-
Semaines
-
-
-
∞
-
Révisions
-
-
-
HD
-
Qualité
-
-
- -
-
-
- -
-
-

Logo & Branding

-

Identité visuelle complète

-
-
-
-
- -
-
-

Bannières Discord

-

Server banner, splash, icône

-
-
-
-
- -
-
-

Emojis custom

-

Pack emojis personnalisés

-
-
-
-
- -
-
-

Icônes & Assets

-

Items, skills, badges

-
-
-
-
- -
-
-

Animations

-

GIFs et motion design

-
-
-
-
- -
-
-

Guide de style

-

Charte graphique fournie

-
-
-
- - -
-
-
- - -
-
-
- ✓ Gratuit -
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-

Consulting & Accompagnement Gratuit

-

Bénéficiez de notre expérience pour structurer, lancer et développer votre projet RP. Conseils stratégiques et accompagnement personnalisé.

-
- -
-
-
50+
-
Projets accompagnés
-
-
-
3 ans
-
D'expérience
-
-
-
24/7
-
Support Discord
-
-
- -
-
-
- -
-
-

Audit serveur

-

Analyse de l'existant

-
-
-
-
- -
-
-

Stratégie croissance

-

Plan de développement

-
-
-
-
- -
-
-

Formation staff

-

Équipe modération

-
-
-
-
- -
-
-

Expérience joueur

-

Optimisation UX

-
-
-
-
- -
-
-

Planning events

-

Calendrier d'animations

-
-
-
-
- -
-
-

Monétisation

-

Conseils revenus

-
-
-
- - -
-
-
- - -
-
-
- ★ Populaire -
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-

Pack Serveur Complet -20%

-

La solution tout-en-un pour lancer votre projet RP. Bot personnalisé, map Fortnite, identité visuelle et accompagnement : tout est inclus pour un lancement réussi.

-
- -
-
-
-20%
-
VS services séparés
-
-
-
3 mois
-
Support inclus
-
-
-
Clé en main
-
Prêt à lancer
-
-
- -
-
-
- -
-
-

Bot Discord RP

-

Système complet personnalisé

-
-
-
-
- -
-
-

Map Fortnite

-

Environnement sur mesure

-
-
-
-
- -
-
-

Pack graphique

-

Logo, bannières, emojis

-
-
-
-
- -
-
-

Config Discord

-

Serveur prêt à l'emploi

-
-
-
-
- -
-
-

Documentation

-

Guides et tutoriels

-
-
-
-
- -
-
-

Support 3 mois

-

Accompagnement lancement

-
-
-
- - -
-
-
+ +
+ +
@@ -726,7 +127,7 @@

Contactez-nous pour un devis gratuit et personnalisé

- + Nous contacter @@ -736,6 +137,7 @@
+ - + \ No newline at end of file