afkaar-gen 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -0
- package/SKILL.md +80 -0
- package/bin/interactive.js +10 -0
- package/interactive.html +575 -0
- package/package.json +42 -0
- package/references/architecture.md +185 -0
- package/references/figma-mode.md +57 -0
- package/references/inspiration-mode.md +71 -0
- package/references/integrations.md +111 -0
- package/references/iteration-mode.md +60 -0
- package/references/questions.md +198 -0
- package/references/security-checklist.md +218 -0
- package/references/seo-guide.md +183 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Architecture du site PHP flat-file généré
|
|
2
|
+
|
|
3
|
+
## Structure des répertoires
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
/
|
|
7
|
+
├── config.php # Constantes, credentials (jamais versionné)
|
|
8
|
+
├── index.php # Front controller / routeur
|
|
9
|
+
├── .htaccess # Rewrite, sécurité, cache, compression
|
|
10
|
+
├── robots.txt # Règles robots
|
|
11
|
+
├── core/
|
|
12
|
+
│ ├── functions.php # JSON r/w, CSRF, SEO, upload, helpers
|
|
13
|
+
│ └── lead-handler.php # Traitement formulaire contact + anti-spam
|
|
14
|
+
├── data/
|
|
15
|
+
│ ├── settings.json # Coordonnées, équipe, stats, clients, avis
|
|
16
|
+
│ ├── services.json # Services (slug, titre, contenu, SEO)
|
|
17
|
+
│ ├── references.json # Portfolio clients
|
|
18
|
+
│ ├── posts.json # Articles de blog
|
|
19
|
+
│ ├── leads.json # Soumissions formulaire contact
|
|
20
|
+
│ ├── seo.json # SEO global + par page
|
|
21
|
+
│ └── login-limits.json # Anti brute-force (IP → tentatives)
|
|
22
|
+
├── admin/ # Panneau d'administration (optionnel)
|
|
23
|
+
│ ├── inc/
|
|
24
|
+
│ │ ├── auth.php # Authentification + session + brute-force
|
|
25
|
+
│ │ ├── layout-top.php # Début HTML admin
|
|
26
|
+
│ │ └── layout-bottom.php# Fin HTML admin
|
|
27
|
+
│ ├── index.php # Dashboard
|
|
28
|
+
│ ├── login.php # Page connexion
|
|
29
|
+
│ ├── logout.php # Déconnexion
|
|
30
|
+
│ ├── services.php # CRUD services
|
|
31
|
+
│ ├── references.php # CRUD références
|
|
32
|
+
│ ├── posts.php # CRUD blog
|
|
33
|
+
│ ├── leads.php # Gestion leads + export CSV
|
|
34
|
+
│ ├── seo.php # Réglages SEO
|
|
35
|
+
│ └── settings.php # Paramètres site + mot de passe
|
|
36
|
+
├── templates/
|
|
37
|
+
│ ├── layout/
|
|
38
|
+
│ │ ├── header.php # <head>, nav, JSON-LD global
|
|
39
|
+
│ │ └── footer.php # Footer, scripts
|
|
40
|
+
│ └── pages/
|
|
41
|
+
│ ├── home.php # Page accueil
|
|
42
|
+
│ ├── service.php # Page service détail
|
|
43
|
+
│ ├── references.php # Liste références
|
|
44
|
+
│ ├── reference.php # Détail référence
|
|
45
|
+
│ ├── blog.php # Liste articles
|
|
46
|
+
│ ├── post.php # Article détail
|
|
47
|
+
│ ├── contact.php # Page contact + formulaire
|
|
48
|
+
│ └── 404.php # Page erreur 404
|
|
49
|
+
└── assets/
|
|
50
|
+
├── css/
|
|
51
|
+
│ ├── style.css # Styles site public
|
|
52
|
+
│ └── admin.css # Styles admin panel
|
|
53
|
+
├── js/
|
|
54
|
+
│ ├── main.js # JS site public
|
|
55
|
+
│ └── admin-editor.js # JS admin
|
|
56
|
+
├── img/ # Images du site (logo, icônes, OG)
|
|
57
|
+
└── uploads/ # Uploads utilisateur (images)
|
|
58
|
+
└── .htaccess # Bloque PHP dans uploads
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Routeur (index.php)
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
URI → parse_url() → rtrim('/', '/')
|
|
65
|
+
├── /sitemap.xml → génère sitemap XML dynamique
|
|
66
|
+
├── /contact/send (POST)→ core/lead-handler.php
|
|
67
|
+
├── / → template home.php
|
|
68
|
+
├── /contact → template contact.php
|
|
69
|
+
├── /references → template references.php
|
|
70
|
+
├── /blog → template blog.php
|
|
71
|
+
├── /blog/{slug} → template post.php
|
|
72
|
+
├── /services/{slug} → template service.php
|
|
73
|
+
├── /references/{slug} → template reference.php
|
|
74
|
+
└── autre → template 404.php + http_response_code(404)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Chaque page charge les données JSON nécessaires, les filtre (actifs seulement), les trie, puis include le template correspondant.
|
|
78
|
+
|
|
79
|
+
## Stockage JSON
|
|
80
|
+
|
|
81
|
+
- `json_read(nom)` : verrouillage partagé (`LOCK_SH`), retourne array
|
|
82
|
+
- `json_write(nom, data)` : écriture atomique (`.tmp` + `rename` + `LOCK_EX`)
|
|
83
|
+
- `json_path(nom)` : `DATA_DIR . '/' . basename(nom) . '.json'`
|
|
84
|
+
|
|
85
|
+
### Schémas JSON
|
|
86
|
+
|
|
87
|
+
**services.json** :
|
|
88
|
+
```json
|
|
89
|
+
[{
|
|
90
|
+
"id": "svc-xxx", "slug": "mon-service", "title": "Mon Service",
|
|
91
|
+
"icon": "code|growth|brand|compass|formation",
|
|
92
|
+
"order": 1, "active": true,
|
|
93
|
+
"excerpt": "Accroche courte...",
|
|
94
|
+
"points": ["Point 1", "Point 2", "Point 3"],
|
|
95
|
+
"content": "<p>HTML...</p>",
|
|
96
|
+
"seo_title": "", "seo_description": ""
|
|
97
|
+
}]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**leads.json** :
|
|
101
|
+
```json
|
|
102
|
+
[{
|
|
103
|
+
"id": "abc12345", "date": "2026-07-22 14:30:00",
|
|
104
|
+
"name": "Nom", "email": "email@exemple.com",
|
|
105
|
+
"phone": "+216 XX XXX XXX",
|
|
106
|
+
"project_type": "Site web", "goal": "Vendre en ligne",
|
|
107
|
+
"message": "Bonjour...",
|
|
108
|
+
"ip": "192.168.1.1", "status": "new"
|
|
109
|
+
}]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**settings.json** : phone, email, address, map_url, facebook, instagram, linkedin, stats[], tags[], clients[], team[], ceo_name, ceo_role, ceo_message, google_reviews_url, google_place_id, reviews[]
|
|
113
|
+
|
|
114
|
+
## .htaccess
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
Options -Indexes
|
|
118
|
+
RewriteEngine On
|
|
119
|
+
RewriteBase /
|
|
120
|
+
|
|
121
|
+
# HTTPS forcé
|
|
122
|
+
RewriteCond %{HTTPS} off
|
|
123
|
+
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
|
124
|
+
|
|
125
|
+
# Bloquer dossiers sensibles
|
|
126
|
+
RewriteRule ^data/ - [F,L]
|
|
127
|
+
RewriteRule ^core/ - [F,L]
|
|
128
|
+
RewriteRule ^templates/ - [F,L]
|
|
129
|
+
|
|
130
|
+
# Fichiers réels servis directement
|
|
131
|
+
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
|
132
|
+
RewriteCond %{REQUEST_FILENAME} -d
|
|
133
|
+
RewriteRule ^ - [L]
|
|
134
|
+
|
|
135
|
+
# Tout le reste vers routeur
|
|
136
|
+
RewriteRule ^ index.php [L]
|
|
137
|
+
|
|
138
|
+
# En-têtes sécurité
|
|
139
|
+
Header always set X-Content-Type-Options "nosniff"
|
|
140
|
+
Header always set X-Frame-Options "DENY"
|
|
141
|
+
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
|
142
|
+
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
|
143
|
+
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()"
|
|
144
|
+
|
|
145
|
+
# Cache assets
|
|
146
|
+
ExpiresByType image/webp "access plus 1 month"
|
|
147
|
+
ExpiresByType image/png "access plus 1 month"
|
|
148
|
+
ExpiresByType image/jpeg "access plus 1 month"
|
|
149
|
+
ExpiresByType text/css "access plus 1 month"
|
|
150
|
+
ExpiresByType application/javascript "access plus 1 month"
|
|
151
|
+
ExpiresByType font/woff2 "access plus 1 year"
|
|
152
|
+
|
|
153
|
+
# Compression
|
|
154
|
+
AddOutputFilterByType DEFLATE text/html text/css application/javascript image/svg+xml
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Fichier uploads/.htaccess
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
<FilesMatch "\.(?i:php|phtml|phar)$">
|
|
161
|
+
Require all denied
|
|
162
|
+
</FilesMatch>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## config.php
|
|
166
|
+
|
|
167
|
+
```php
|
|
168
|
+
<?php declare(strict_types=1);
|
|
169
|
+
define('APP_NAME', "Mon Site");
|
|
170
|
+
define('APP_URL', 'https://monsite.tn');
|
|
171
|
+
define('APP_ROOT', __DIR__);
|
|
172
|
+
define('DATA_DIR', APP_ROOT . '/data');
|
|
173
|
+
define('UPLOADS_DIR', APP_ROOT . '/assets/uploads');
|
|
174
|
+
define('UPLOADS_URL', '/assets/uploads');
|
|
175
|
+
define('MAIL_TO', 'contact@monsite.tn');
|
|
176
|
+
define('MAIL_FROM', 'no-reply@monsite.tn');
|
|
177
|
+
define('MAIL_ENABLED', true);
|
|
178
|
+
define('SESSION_NAME', 'monsite_admin');
|
|
179
|
+
define('CSRF_KEY', '_monsite_csrf');
|
|
180
|
+
// GOOGLE_API_KEY définie ici, JAMAIS dans data/settings.json
|
|
181
|
+
error_reporting(E_ALL);
|
|
182
|
+
ini_set('display_errors', '0');
|
|
183
|
+
date_default_timezone_set('Africa/Tunis');
|
|
184
|
+
require_once APP_ROOT . '/core/functions.php';
|
|
185
|
+
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Mode Figma
|
|
2
|
+
|
|
3
|
+
## Déclenchement
|
|
4
|
+
|
|
5
|
+
Automatique si l'utilisateur mentionne "Figma" ou partage un lien Figma.
|
|
6
|
+
|
|
7
|
+
## Approche recommandée : Screenshot
|
|
8
|
+
|
|
9
|
+
**Pour les non-techniciens** : demander une capture d'écran de la maquette.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
🎨 Vous avez une maquette Figma — parfait !
|
|
13
|
+
|
|
14
|
+
Pour que je puisse m'en inspirer, le plus simple est de :
|
|
15
|
+
1. Faire une capture d'écran de votre maquette (ou exporter en PNG depuis Figma)
|
|
16
|
+
2. M'envoyer l'image (je l'analyserai visuellement)
|
|
17
|
+
|
|
18
|
+
Pas de screenshot ? Pas de souci, décrivez-moi simplement votre design :
|
|
19
|
+
- Layout (une colonne, deux colonnes, grille ?)
|
|
20
|
+
- Ambiance (sombre, clair, coloré ?)
|
|
21
|
+
- Éléments importants
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Approche API (si token fourni)
|
|
25
|
+
|
|
26
|
+
Si l'utilisateur a un Personal Access Token Figma :
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Pour une extraction automatique depuis Figma, j'ai besoin :
|
|
30
|
+
1. De votre PERSONAL ACCESS TOKEN Figma
|
|
31
|
+
→ Settings → Account → Personal Access Tokens → créer un token
|
|
32
|
+
2. De l'ID du fichier (dans l'URL : figma.com/file/ID/nom)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Endpoints utilisés** :
|
|
36
|
+
|
|
37
|
+
```http
|
|
38
|
+
GET https://api.figma.com/v1/files/{file_key}/styles
|
|
39
|
+
→ Récupère les styles de couleurs, textes, effets
|
|
40
|
+
|
|
41
|
+
GET https://api.figma.com/v1/files/{file_key}
|
|
42
|
+
→ Récupère la structure complète du fichier
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Ce qui est extrait** :
|
|
46
|
+
- Noms des frames → sections du site
|
|
47
|
+
- Couleurs (fills) → palette
|
|
48
|
+
- Styles de texte → polices, tailles, graisses
|
|
49
|
+
- Grilles et layouts
|
|
50
|
+
|
|
51
|
+
## Ce qui n'est PAS extrait
|
|
52
|
+
- Images (pas de téléchargement automatique)
|
|
53
|
+
- Composants complexes
|
|
54
|
+
- Prototypes / interactions
|
|
55
|
+
|
|
56
|
+
## Fallback
|
|
57
|
+
Si aucune des deux méthodes ne fonctionne → mode questionnaire classique avec description verbale.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Mode inspiration URL
|
|
2
|
+
|
|
3
|
+
## Déclenchement
|
|
4
|
+
|
|
5
|
+
Automatique si le message de l'utilisateur contient une URL (`http://` ou `https://`).
|
|
6
|
+
|
|
7
|
+
## Flux
|
|
8
|
+
|
|
9
|
+
1. L'agent utilise `webfetch` pour récupérer la page
|
|
10
|
+
2. Extraction des informations suivantes :
|
|
11
|
+
|
|
12
|
+
### Couleurs
|
|
13
|
+
- Chercher les variables CSS `--primary`, `--accent`, `--ink`, etc.
|
|
14
|
+
- Chercher les styles inline dominants
|
|
15
|
+
- Chercher les couleurs dans les classes CSS répétées
|
|
16
|
+
|
|
17
|
+
### Sections
|
|
18
|
+
Analyser le DOM pour détecter les sections :
|
|
19
|
+
```html
|
|
20
|
+
<section id="services"> → section "Services"
|
|
21
|
+
<section class="hero"> → section "Hero"
|
|
22
|
+
<footer> → section "Footer"
|
|
23
|
+
<nav> → Navigation
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Contenu extrait
|
|
27
|
+
- Titres de page (h1, h2)
|
|
28
|
+
- Texte des services (si listés)
|
|
29
|
+
- Liens de navigation → structure du site
|
|
30
|
+
- Polices (Google Fonts link tags → `href`)
|
|
31
|
+
- Images de fond / héros
|
|
32
|
+
|
|
33
|
+
### SEO
|
|
34
|
+
- Balise title
|
|
35
|
+
- Meta description
|
|
36
|
+
- Open Graph tags
|
|
37
|
+
- JSON-LD (Organization, Service, etc.)
|
|
38
|
+
- GTM ID (si présent)
|
|
39
|
+
|
|
40
|
+
## Résumé présenté à l'utilisateur
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
🌐 J'ai analysé {URL} — voici ce que j'en retire :
|
|
44
|
+
|
|
45
|
+
🎨 Palette couleurs :
|
|
46
|
+
Principal : #... Secondaire : #...
|
|
47
|
+
|
|
48
|
+
📄 Sections détectées :
|
|
49
|
+
✓ Hero ✓ Services ✓ Portfolio ✓ Contact
|
|
50
|
+
|
|
51
|
+
🔤 Police : Montserrat
|
|
52
|
+
|
|
53
|
+
🛠️ Services listés : (3)
|
|
54
|
+
- Dev Web
|
|
55
|
+
- Marketing
|
|
56
|
+
- Branding
|
|
57
|
+
|
|
58
|
+
SEO présent : ✓ GTM ✓ OG tags ✓ JSON-LD
|
|
59
|
+
|
|
60
|
+
Souhaitez-vous repartir de cette base ou changer des éléments ?
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Après validation
|
|
64
|
+
|
|
65
|
+
L'agent pré-remplit le questionnaire avec les données extraites, et ne pose que les questions manquantes.
|
|
66
|
+
|
|
67
|
+
## Limites
|
|
68
|
+
|
|
69
|
+
- Si le site est en JS lourd (React, Vue, SPA) → le fetch peut ne pas capturer le rendu final. L'agent mentionne : "Le site semble utiliser JavaScript pour l'affichage — j'ai extrait ce que j'ai pu, mais certaines informations peuvent être manquantes."
|
|
70
|
+
- Si le site n'est pas accessible (bloqué, login) → l'agent bascule en mode questionnaire seul.
|
|
71
|
+
- Les images ne sont pas extraites (respect copyright).
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Guide des intégrations
|
|
2
|
+
|
|
3
|
+
## WhatsApp Business API (notification leads)
|
|
4
|
+
|
|
5
|
+
Dans `lead-handler.php`, après enregistrement du lead :
|
|
6
|
+
```php
|
|
7
|
+
// Envoi WhatsApp via API (exemple avec CallMeBot ou WATI)
|
|
8
|
+
$whatsapp_enabled = !empty($settings['whatsapp_api_key'] ?? '');
|
|
9
|
+
if ($whatsapp_enabled) {
|
|
10
|
+
$api = 'https://api.callmebot.com/whatsapp.php?phone=' . urlencode($settings['whatsapp_phone'] ?? '')
|
|
11
|
+
. '&text=' . urlencode("Nouveau lead : $name - $email - $phone")
|
|
12
|
+
. '&apikey=' . urlencode($settings['whatsapp_api_key'] ?? '');
|
|
13
|
+
@file_get_contents($api);
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Credentials** : stockés dans `data/settings.json` UNIQUEMENT si l'utilisateur les remplit via l'admin. Sinon, clé API dans `config.php`.
|
|
18
|
+
|
|
19
|
+
## Calendly / Réservation
|
|
20
|
+
|
|
21
|
+
Dans la page contact, ajouter un iframe ou un lien :
|
|
22
|
+
```php
|
|
23
|
+
<?php if (!empty($settings['calendly_url'])): ?>
|
|
24
|
+
<div class="calendly-inline-widget"
|
|
25
|
+
data-url="<?= e($settings['calendly_url']) ?>"
|
|
26
|
+
style="min-width:320px;height:700px;"></div>
|
|
27
|
+
<script src="https://assets.calendly.com/assets/external/widget.js" async></script>
|
|
28
|
+
<?php endif; ?>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Google Analytics + GTM
|
|
32
|
+
|
|
33
|
+
Configuré via `data/seo.json` → `global.gtm_id`.
|
|
34
|
+
GTM installé dans `header.php` avec noscript fallback.
|
|
35
|
+
|
|
36
|
+
## Facebook Pixel
|
|
37
|
+
|
|
38
|
+
Dans `assets/js/main.js` ou `header.php` :
|
|
39
|
+
```html
|
|
40
|
+
<script>
|
|
41
|
+
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
|
|
42
|
+
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
|
|
43
|
+
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
|
|
44
|
+
n.queue=[];t=b.createElement(e);t.async=!0;
|
|
45
|
+
t.src=v;s=b.getElementsByTagName(e)[0];
|
|
46
|
+
s.parentNode.insertBefore(t,s)}(window,document,'script',
|
|
47
|
+
'https://connect.facebook.net/en_US/fbevents.js');
|
|
48
|
+
fbq('init', 'PIXEL_ID');
|
|
49
|
+
fbq('track', 'PageView');
|
|
50
|
+
</script>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Pixel ID** dans `data/settings.json` → champ `facebook_pixel`.
|
|
54
|
+
|
|
55
|
+
## Newsletter (Mailchimp / Brevo / Sendinblue)
|
|
56
|
+
|
|
57
|
+
Dans `lead-handler.php`, option d'abonnement :
|
|
58
|
+
```php
|
|
59
|
+
if (!empty($_POST['newsletter'])) {
|
|
60
|
+
$api_key = $settings['newsletter_api_key'] ?? '';
|
|
61
|
+
$list_id = $settings['newsletter_list_id'] ?? '';
|
|
62
|
+
if ($api_key && $list_id) {
|
|
63
|
+
// Appel API Brevo/Mailchimp pour ajouter le contact
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Paiement en ligne (Stripe / Paymee / D17)
|
|
69
|
+
|
|
70
|
+
Pas de génération complète de e-commerce, seulement :
|
|
71
|
+
- Bouton "Payer en ligne" redirigeant vers la plateforme
|
|
72
|
+
- Page de confirmation simple
|
|
73
|
+
- Les credentials de paiement sont dans `config.php` uniquement
|
|
74
|
+
|
|
75
|
+
## Google Sheets (sauvegarde leads)
|
|
76
|
+
|
|
77
|
+
Dans `lead-handler.php` :
|
|
78
|
+
```php
|
|
79
|
+
$webhook_url = $settings['google_sheets_webhook'] ?? '';
|
|
80
|
+
if ($webhook_url) {
|
|
81
|
+
$data = json_encode(['name' => $name, 'email' => $email, ...]);
|
|
82
|
+
@file_get_contents($webhook_url, false, stream_context_create([
|
|
83
|
+
'http' => ['method' => 'POST', 'header' => 'Content-Type: application/json', 'content' => $data]
|
|
84
|
+
]));
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Slack / Discord / Telegram (notifications)
|
|
89
|
+
|
|
90
|
+
Webhook simple :
|
|
91
|
+
```php
|
|
92
|
+
$webhook = $settings['slack_webhook'] ?? '';
|
|
93
|
+
if ($webhook) {
|
|
94
|
+
$msg = json_encode(['text' => "Nouveau lead : $name - $email"]);
|
|
95
|
+
@file_get_contents($webhook, false, stream_context_create([
|
|
96
|
+
'http' => ['method' => 'POST', 'header' => 'Content-Type: application/json', 'content' => $msg]
|
|
97
|
+
]));
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Configuration dans l'admin
|
|
102
|
+
|
|
103
|
+
Dans `admin/settings.php`, section "Intégrations" :
|
|
104
|
+
- whatsapp_phone, whatsapp_api_key
|
|
105
|
+
- calendly_url
|
|
106
|
+
- facebook_pixel
|
|
107
|
+
- newsletter_api_key, newsletter_list_id
|
|
108
|
+
- slack_webhook
|
|
109
|
+
- google_sheets_webhook
|
|
110
|
+
|
|
111
|
+
**Règle** : les clés API sensibles sont stockées en clair dans `data/settings.json` uniquement si l'utilisateur les remplit via l'admin. Pour un niveau de sécurité supérieur, les déplacer dans `config.php` en constantes. Le README généré mentionne cette alternative.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Mode itération (modifier un site existant)
|
|
2
|
+
|
|
3
|
+
## Déclenchement
|
|
4
|
+
|
|
5
|
+
L'utilisateur dit : "ajoute...", "modifie...", "change...", "supprime...",
|
|
6
|
+
"j'ai déjà un site généré, je veux..."
|
|
7
|
+
|
|
8
|
+
## Flux
|
|
9
|
+
|
|
10
|
+
1. Vérifier que le dossier du site existe (demander le chemin si nécessaire)
|
|
11
|
+
2. Lire la structure existante (data/ + config.php)
|
|
12
|
+
3. Analyser la demande de modification
|
|
13
|
+
4. Appliquer uniquement les changements nécessaires :
|
|
14
|
+
|
|
15
|
+
### Exemples
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
User : "Ajoute un service 'Conseil IA'"
|
|
19
|
+
→ Lire data/services.json
|
|
20
|
+
→ Ajouter le nouveau service dans le tableau
|
|
21
|
+
→ Réécrire services.json
|
|
22
|
+
→ Le template service.php n'est pas modifié (il est déjà générique)
|
|
23
|
+
|
|
24
|
+
User : "Change la couleur principale en vert"
|
|
25
|
+
→ Lire assets/css/style.css
|
|
26
|
+
→ Remplacer la variable --primary
|
|
27
|
+
→ Réécrire style.css
|
|
28
|
+
|
|
29
|
+
User : "Ajoute une section FAQ sur l'accueil"
|
|
30
|
+
→ Lire data/settings.json (vérifier si FAQ déjà dans les sections)
|
|
31
|
+
→ Lire templates/pages/home.php
|
|
32
|
+
→ Ajouter la section FAQ dans le template
|
|
33
|
+
→ Ajouter le JSON-LD FAQPage dans index.php (pageSchemas)
|
|
34
|
+
|
|
35
|
+
User : "Supprime le blog"
|
|
36
|
+
→ Lire data/posts.json → vider le tableau
|
|
37
|
+
→ Optionnel : désactiver la route /blog dans les variables du site
|
|
38
|
+
→ Les fichiers templates restent (pas de casse)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Règles
|
|
42
|
+
|
|
43
|
+
- **Ne jamais regénérer un fichier qui n'a pas besoin de changement**
|
|
44
|
+
- **Ne jamais réécrire `data/users.json`** (préserver le mot de passe admin)
|
|
45
|
+
- **Ne jamais modifier `data/leads.json`** (préserver les messages reçus)
|
|
46
|
+
- **Préserver `config.php`** si des credentials y ont été ajoutés
|
|
47
|
+
- Si la modification impacte le questionnaire, le reposer partiellement (ex: nouveau service → demande les détails du service uniquement)
|
|
48
|
+
- Si la modification casse quelque chose (ex: suppression d'un service qui a des références associées) → prévenir l'utilisateur avant d'agir
|
|
49
|
+
|
|
50
|
+
## Validation après itération
|
|
51
|
+
|
|
52
|
+
- `php -l` sur les fichiers modifiés
|
|
53
|
+
- Vérifier que les données JSON sont toujours valides (`json_decode !== null`)
|
|
54
|
+
- Afficher un diff des changements :
|
|
55
|
+
```
|
|
56
|
+
Modifications appliquées :
|
|
57
|
+
📄 data/services.json → +1 service "Conseil IA"
|
|
58
|
+
🎨 assets/css/style.css → --primary: #... → #...
|
|
59
|
+
🖼️ templates/pages/home.php → nouvelle section FAQ
|
|
60
|
+
```
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Questionnaire — 4 étapes, version sélections
|
|
2
|
+
|
|
3
|
+
L'agent propose des choix, l'utilisateur sélectionne. Chaque question a une suggestion par défaut pour accélérer.
|
|
4
|
+
|
|
5
|
+
## Étape 1 : Identité
|
|
6
|
+
|
|
7
|
+
**Q1 — Nom de l'entreprise**
|
|
8
|
+
```
|
|
9
|
+
Suggestions :
|
|
10
|
+
A) Utiliser votre nom/prénom ────────── "Mon nom"
|
|
11
|
+
B) Un nom d'agence ──────────────────── "Mon Agence Digitale"
|
|
12
|
+
C) Un nom de marque ─────────────────── "MaMarque"
|
|
13
|
+
D) Autre (vous dites)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Q2 — Domaine (URL)**
|
|
17
|
+
```
|
|
18
|
+
Suggestions :
|
|
19
|
+
A) nomprenom.tn ──────── si réponse A à Q1
|
|
20
|
+
B) monagence.tn ──────── si réponse B à Q1
|
|
21
|
+
C) mamark.tn ─────────── si réponse C à Q1
|
|
22
|
+
D) Autre (vous dites)
|
|
23
|
+
E) Je ne sais pas encore → on mettra un placeholder
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Q3 — Logo**
|
|
27
|
+
```
|
|
28
|
+
Suggestions :
|
|
29
|
+
A) Je l'envoie en image (base64)
|
|
30
|
+
B) Je le décris, vous le créez (nom + style)
|
|
31
|
+
C) Pas de logo pour l'instant → placeholder généré
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Q4 — Couleurs et style**
|
|
35
|
+
```
|
|
36
|
+
Palettes suggérées (choisir une lettre) :
|
|
37
|
+
A) Bleu marine + Orange (#1a237e / #ff6f00) — Pro & dynamique
|
|
38
|
+
B) Vert sombre + Beige (#1b5e20 / #f5f0e8) — Nature & sérénité
|
|
39
|
+
C) Violet + Rose (#6a1b9a / #ec407a) — Créatif & moderne
|
|
40
|
+
D) Noir + Blanc + Or (#14131c / #f5c518) — Luxe & sobre
|
|
41
|
+
E) Rouge + Gris (#c62828 / #424242) — Puissant & technique
|
|
42
|
+
F) Bleu clair + Blanc (#1976d2 / #ffffff) — Tech & épuré
|
|
43
|
+
G) Personnalisé (vous donnez vos couleurs)
|
|
44
|
+
|
|
45
|
+
Style visuel :
|
|
46
|
+
A) Professionnel & sobre ── lignes nettes, espace, sérieux
|
|
47
|
+
B) Moderne & dynamique ──── animations, audacieux
|
|
48
|
+
C) Créatif & coloré ─────── original, qui se démarque
|
|
49
|
+
D) Minimaliste ──────────── beaucoup d'espace blanc, épuré
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Étape 2 : Contenu
|
|
53
|
+
|
|
54
|
+
**Q5 — Sections de la page d'accueil**
|
|
55
|
+
```
|
|
56
|
+
Choisissez les sections voulues (lettres) :
|
|
57
|
+
A) Hero ──────── Grande bannière avec titre + CTA
|
|
58
|
+
B) À propos ──── Présentation de l'entreprise
|
|
59
|
+
C) Services ──── Vos offres en carte
|
|
60
|
+
D) Réalisations ─ Portfolio / projets déjà faits
|
|
61
|
+
E) Équipe ────── Les membres de l'équipe
|
|
62
|
+
F) Témoignages ─ Avis clients
|
|
63
|
+
G) Chiffres ──── Stats marquantes
|
|
64
|
+
H) FAQ ───────── Questions fréquentes
|
|
65
|
+
I) Blog ──────── Derniers articles
|
|
66
|
+
J) Contact ───── Formulaire + coordonnées
|
|
67
|
+
K) Clients ───── Bande logos des marques clients
|
|
68
|
+
L) Marque ────── Bandeau défilant de tags/services
|
|
69
|
+
|
|
70
|
+
Suggestion par défaut : A, B, C, D, F, J, K
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Q6 — Services proposés**
|
|
74
|
+
```
|
|
75
|
+
Pour chaque service, l'agent demande : nom + 3 points clés.
|
|
76
|
+
Suggestions de services courants :
|
|
77
|
+
A) Développement Web ─── Sites vitrine, e-commerce
|
|
78
|
+
B) Marketing Digital ──── Réseaux sociaux, publicité
|
|
79
|
+
C) Branding & Design ──── Logo, charte graphique
|
|
80
|
+
D) Stratégie & Conseil ── Audit, conseil
|
|
81
|
+
E) Formation ──────────── Ateliers, coaching
|
|
82
|
+
F) Autre (vous décrivez)
|
|
83
|
+
|
|
84
|
+
→ L'agent pose ensuite 1 question par service ajouté
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Q7 — Pages supplémentaires**
|
|
88
|
+
```
|
|
89
|
+
En plus de l'accueil, quelles pages ?
|
|
90
|
+
A) Mentions légales
|
|
91
|
+
B) FAQ dédiée
|
|
92
|
+
C) Recrutement
|
|
93
|
+
D) Galerie photos
|
|
94
|
+
E) CGV / CGU
|
|
95
|
+
F) Aucune
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Q8 — Réseaux sociaux**
|
|
99
|
+
```
|
|
100
|
+
A) Facebook
|
|
101
|
+
B) Instagram
|
|
102
|
+
C) LinkedIn
|
|
103
|
+
D) TikTok
|
|
104
|
+
E) YouTube
|
|
105
|
+
F) WhatsApp
|
|
106
|
+
G) Aucun
|
|
107
|
+
H) Tous
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Étape 3 : Technique
|
|
111
|
+
|
|
112
|
+
**Q9 — Blog**
|
|
113
|
+
```
|
|
114
|
+
A) Oui, avec zone d'admin (j'écris moi-même)
|
|
115
|
+
B) Oui, sans admin (vous gérez)
|
|
116
|
+
C) Non, pas de blog
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Q10 — Administration**
|
|
120
|
+
```
|
|
121
|
+
A) Oui, admin complet (dashboard, CRUD services/références/leads)
|
|
122
|
+
B) Non, vous gérez tout
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Q11 — Intégrations**
|
|
126
|
+
```
|
|
127
|
+
A) WhatsApp ────── Notification à chaque lead
|
|
128
|
+
B) Calendly ────── Prise de rendez-vous en ligne
|
|
129
|
+
C) Google Analytics ── Déjà inclus
|
|
130
|
+
D) Facebook Pixel ──── Suivi publicitaire
|
|
131
|
+
E) Newsletter ──── Mailchimp / Brevo
|
|
132
|
+
F) Paiement ────── Stripe / Paymee
|
|
133
|
+
G) Slack/Discord ─ Notifications équipe
|
|
134
|
+
H) Aucune
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Q12 — Autres fonctionnalités**
|
|
138
|
+
```
|
|
139
|
+
A) Calculateur de devis en ligne
|
|
140
|
+
B) Chat en direct
|
|
141
|
+
C) Espace client privé
|
|
142
|
+
D) Système de réservation
|
|
143
|
+
E) Forum / communauté
|
|
144
|
+
F) Rien de plus
|
|
145
|
+
G) Autre (vous dites)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Q13 — Site d'inspiration**
|
|
149
|
+
```
|
|
150
|
+
A) Oui, je donne une URL
|
|
151
|
+
B) Oui, j'ai une capture d'écran / maquette
|
|
152
|
+
C) Non, on part de zéro
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Étape 4 : Finalisation
|
|
156
|
+
|
|
157
|
+
**Q14 — Maquette / Design**
|
|
158
|
+
```
|
|
159
|
+
A) Lien Figma (je peux extraire si token dispo, sinon screenshot)
|
|
160
|
+
B) Capture d'écran / image (base64)
|
|
161
|
+
C) Pas de maquette, confiance à vos propositions
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Q15 — Coordonnées (demander à la fin)**
|
|
165
|
+
```
|
|
166
|
+
L'agent demande successivement :
|
|
167
|
+
Téléphone : suggestion A) +216 XX XXX XXX / B) Autre
|
|
168
|
+
Email : suggestion A) contact@mondomaine.tn / B) Autre
|
|
169
|
+
Adresse : texte libre ou "Pas d'adresse physique"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Q16 — Hébergement**
|
|
173
|
+
```
|
|
174
|
+
A) Je ne sais pas encore → configuration par défaut
|
|
175
|
+
B) Hébergement mutualisé (Hostinger, OVH, GoDaddy...)
|
|
176
|
+
C) VPS / serveur dédié
|
|
177
|
+
D) Autre
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Q17 — Langue du site**
|
|
181
|
+
```
|
|
182
|
+
A) Français
|
|
183
|
+
B) Anglais
|
|
184
|
+
C) Arabe
|
|
185
|
+
D) Français + Anglais (bilingue)
|
|
186
|
+
E) Français + Arabe
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Règles d'or pour l'agent
|
|
190
|
+
|
|
191
|
+
- **Toujours donner des suggestions avec lettres** (A/B/C/D) — l'utilisateur répond par une lettre
|
|
192
|
+
- **Question suivante après réponse** — pas d'attente, enchaîner
|
|
193
|
+
- **Si réponse libre hors suggestions** → l'accepter et continuer
|
|
194
|
+
- **Si "je sais pas"** → prendre l'option par défaut (marquée ★)
|
|
195
|
+
- **Si l'utilisateur donne une URL** → mode inspiration URL, pré-remplir 70%
|
|
196
|
+
- **Regrouper 3-4 questions par message**, pas 1 par 1
|
|
197
|
+
- **Pas de jargon** : pas de "slug", "JSON", "SEO" — dire "adresse de la page", "texte pour Google"
|
|
198
|
+
- **Pour les services** : poser les détails un par un, immédiatement après l'ajout
|