create-snapify-app 1.1.1 → 1.1.4

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.
@@ -58,11 +58,18 @@ async function main() {
58
58
  }
59
59
  if (!nonInteractive) {
60
60
  console.log('\n PostgreSQL');
61
+ console.log(' (colle une URL Neon/Postgres, ou réponds o puis entre l’URL, ou n pour saisir hôte/port)');
61
62
  const paste = await askYesNo('Coller une DATABASE_URL complète', false);
62
- if (paste) {
63
- databaseUrl = await ask('DATABASE_URL');
63
+ if (paste && typeof paste === 'object' && paste.__databaseUrl) {
64
+ databaseUrl = paste.__databaseUrl;
65
+ ok('DATABASE_URL détectée');
66
+ } else if (paste) {
67
+ databaseUrl = await ask('DATABASE_URL (postgres://… ou postgresql://…)');
64
68
  }
65
69
  }
70
+ if (databaseUrl && !/^(postgres(ql)?:\/\/)/i.test(databaseUrl)) {
71
+ fail('DATABASE_URL invalide — doit commencer par postgres:// ou postgresql://');
72
+ }
66
73
  if (!databaseUrl) {
67
74
  const host = String(flags['db-host'] || (!nonInteractive ? await ask('Hôte', '127.0.0.1') : ''));
68
75
  const port = String(flags['db-port'] || (!nonInteractive ? await ask('Port', '5432') : '5432'));
@@ -119,22 +126,39 @@ async function main() {
119
126
  }
120
127
 
121
128
  if (!skipInstall) {
122
- console.log('\n→ npm install…');
123
- const install = spawnSync('npm', ['install', '--no-audit', '--no-fund', '--legacy-peer-deps'], {
129
+ // Windows : npm est npm.cmd — spawn sans shell échoue souvent sans message clair
130
+ const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
131
+ const npmOpts = {
124
132
  cwd: dest,
125
133
  stdio: 'inherit',
126
- env: { ...process.env, NODE_ENV: 'development' },
127
- });
128
- if (install.status !== 0) fail('npm install a échoué');
134
+ shell: process.platform === 'win32',
135
+ env: { ...process.env, NODE_ENV: 'development', npm_config_fund: 'false' },
136
+ };
137
+
138
+ console.log('\n→ npm install…');
139
+ const install = spawnSync(npmCmd, ['install', '--no-audit', '--no-fund', '--legacy-peer-deps'], npmOpts);
140
+ if (install.error) {
141
+ fail(`npm install : ${install.error.message}`);
142
+ }
143
+ if (install.status !== 0) {
144
+ fail(
145
+ `npm install a échoué (code ${install.status}).\n` +
146
+ ` Réessayez manuellement :\n` +
147
+ ` cd ${dest}\n` +
148
+ ` npm install --legacy-peer-deps`,
149
+ );
150
+ }
129
151
  ok('Dépendances installées');
130
152
 
131
153
  console.log('\n→ npm run build…');
132
- const build = spawnSync('npm', ['run', 'build'], {
133
- cwd: dest,
134
- stdio: 'inherit',
135
- env: { ...process.env, NODE_ENV: 'development' },
136
- });
137
- if (build.status !== 0) fail('npm run build a échoué');
154
+ const build = spawnSync(npmCmd, ['run', 'build'], npmOpts);
155
+ if (build.error) fail(`npm run build : ${build.error.message}`);
156
+ if (build.status !== 0) {
157
+ fail(
158
+ `npm run build a échoué (code ${build.status}).\n` +
159
+ ` Réessayez : cd ${dest} && npm run build`,
160
+ );
161
+ }
138
162
  ok('Frontend compilé');
139
163
  }
140
164
 
package/lib/prompt.mjs CHANGED
@@ -57,7 +57,12 @@ export async function askSecret(question) {
57
57
  /** @param {string} question @param {boolean} [fallback] */
58
58
  export async function askYesNo(question, fallback = true) {
59
59
  const def = fallback ? 'O/n' : 'o/N';
60
- const answer = (await ask(`${question} [${def}]`, '')).toLowerCase();
60
+ const answer = (await ask(`${question} [${def}]`, '')).trim();
61
61
  if (!answer) return fallback;
62
- return answer === 'o' || answer === 'oui' || answer === 'y' || answer === 'yes';
62
+ const lower = answer.toLowerCase();
63
+ // Si l'utilisateur colle directement une URL postgres au lieu de o/N
64
+ if (/^(postgres(ql)?:\/\/)/i.test(answer)) {
65
+ return { __databaseUrl: answer };
66
+ }
67
+ return lower === 'o' || lower === 'oui' || lower === 'y' || lower === 'yes';
63
68
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-snapify-app",
3
- "version": "1.1.1",
3
+ "version": "1.1.4",
4
4
  "description": "Installe Snapify (CMS complet : backend + frontend) : npx create-snapify-app@latest",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "NOVALABS WEB DESIGN <contact@novalabs.tn> (https://novalabs.tn)",
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "package": "create-snapify-app",
3
- "version": "1.1.1",
4
- "packedAt": "2026-11-07T14:06:32.999Z"
3
+ "version": "1.1.4",
4
+ "packedAt": "2026-11-07T14:22:42.030Z"
5
5
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "snapify",
3
3
  "private": true,
4
- "version": "1.1.1",
4
+ "version": "1.1.4",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "NOVALABS WEB DESIGN <contact@novalabs.tn>",
7
7
  "type": "module",
@@ -23,20 +23,25 @@ const TEMPLATE = path.join(PKG_DIR, 'template');
23
23
  const NPM_OUT = path.join(ROOT, 'releases', 'npm');
24
24
  const force = process.argv.includes('--force');
25
25
 
26
- const EXCLUDE_DIRS = new Set([
26
+ /** Dossiers exclus à n’importe quelle profondeur */
27
+ const EXCLUDE_DIRS_ANY = new Set([
27
28
  'node_modules',
28
29
  '.git',
29
30
  '.cursor',
30
31
  'dist',
31
32
  'build',
32
33
  'coverage',
34
+ '.snapify-build',
35
+ '.snapify',
36
+ ]);
37
+
38
+ /** Dossiers exclus seulement à la racine du repo (pas src/data, etc.) */
39
+ const EXCLUDE_DIRS_ROOT = new Set([
33
40
  'backups',
34
41
  'releases',
35
- 'data',
42
+ 'data', // analytics JSONL locaux
36
43
  'database', // dumps locaux — jamais sur npm
37
44
  'create-snapify-app',
38
- '.snapify-build',
39
- '.snapify',
40
45
  ]);
41
46
 
42
47
  const EXCLUDE_FILES = new Set([
@@ -57,8 +62,11 @@ const EXCLUDE_SUFFIXES = ['.dump', '.pem', '.log', '.sql.gz'];
57
62
  async function walk(dir: string): Promise<string[]> {
58
63
  const out: string[] = [];
59
64
  for (const e of await fs.readdir(dir, { withFileTypes: true })) {
60
- if (EXCLUDE_DIRS.has(e.name)) continue;
61
65
  const full = path.join(dir, e.name);
66
+ const r = rel(full);
67
+ const atRoot = !r.includes('/');
68
+ if (EXCLUDE_DIRS_ANY.has(e.name)) continue;
69
+ if (atRoot && EXCLUDE_DIRS_ROOT.has(e.name)) continue;
62
70
  if (e.isDirectory()) out.push(...(await walk(full)));
63
71
  else out.push(full);
64
72
  }
@@ -92,10 +92,11 @@ async function main() {
92
92
  return;
93
93
  }
94
94
 
95
- // Vérifie que la version est bien sur le registre (évite faux ✔ après placeholder 0.0.0-stage)
95
+ // Vérifie version + tarball téléchargeable (évite métadonnées sans .tgz / 0.0.0-stage)
96
96
  let confirmed = '';
97
- for (let i = 0; i < 8; i++) {
98
- await new Promise((r) => setTimeout(r, i === 0 ? 1500 : 2500));
97
+ let tarballOk = false;
98
+ for (let i = 0; i < 12; i++) {
99
+ await new Promise((r) => setTimeout(r, i === 0 ? 2000 : 3000));
99
100
  try {
100
101
  confirmed = execFileSync('npm', ['view', `${pkg.name}@${pkg.version}`, 'version'], {
101
102
  cwd: ROOT,
@@ -106,15 +107,37 @@ async function main() {
106
107
  } catch {
107
108
  confirmed = '';
108
109
  }
109
- if (confirmed === pkg.version) break;
110
- console.log(`• Attente indexation npm… (${i + 1}/8)`);
110
+ try {
111
+ const tarball = execFileSync('npm', ['view', `${pkg.name}@${pkg.version}`, 'dist.tarball'], {
112
+ cwd: ROOT,
113
+ encoding: 'utf8',
114
+ env: npmEnv,
115
+ stdio: ['ignore', 'pipe', 'ignore'],
116
+ }).trim();
117
+ if (tarball.startsWith('http')) {
118
+ const head = execFileSync('curl', ['-sS', '-o', '/dev/null', '-w', '%{http_code}', '-L', tarball], {
119
+ encoding: 'utf8',
120
+ }).trim();
121
+ tarballOk = head === '200';
122
+ }
123
+ } catch {
124
+ tarballOk = false;
125
+ }
126
+ if (confirmed === pkg.version && tarballOk) break;
127
+ console.log(
128
+ `• Attente npm… (${i + 1}/12) version=${confirmed || '—'} tarball=${tarballOk ? 'ok' : '404'}`,
129
+ );
111
130
  }
112
- if (confirmed !== pkg.version) {
131
+ if (confirmed !== pkg.version || !tarballOk) {
113
132
  throw new Error(
114
- `npm a renvoyé un succès local mais ${pkg.name}@${pkg.version} est introuvable sur le registre (souvent un placeholder 0.0.0-stage). Relancez avec --otp <code>.`,
133
+ `Publication incomplète : ${pkg.name}@${pkg.version} version=${confirmed || 'absente'} tarball=${tarballOk ? 'ok' : '404'}. ` +
134
+ `Souvent un publish « staged » sans blob. Bump la version et republie avec --otp.`,
115
135
  );
116
136
  }
117
- console.log(`✔ Publié et confirmé : https://www.npmjs.com/package/${pkg.name}\n Install : npx create-snapify-app@latest`);
137
+ console.log(
138
+ `✔ Publié et confirmé (tarball 200) : https://www.npmjs.com/package/${pkg.name}/v/${pkg.version}\n` +
139
+ ` Install : npx create-snapify-app@${pkg.version}`,
140
+ );
118
141
  }
119
142
 
120
143
  main().catch((e) => {
@@ -0,0 +1,561 @@
1
+ /**
2
+ * Snapify
3
+ * © 2026 NOVALABS WEB DESIGN — Tunisie
4
+ * Contact : contact@novalabs.tn · +216 24 734 647
5
+ * Tous droits réservés. Toute reproduction, modification ou diffusion sans autorisation écrite est interdite.
6
+ */
7
+ import { ExpertiseItem, SecteurItem, RealisationItem, CeeSheet } from '../types';
8
+
9
+ export const SITE_INFO = {
10
+ name: 'Snapify',
11
+ legalName: 'Snapify SAS',
12
+ baseline: 'Lorem & Ipsum Dolor',
13
+ slogan: 'Sit amet. Consectetur adipiscing.',
14
+ phone: '01 23 45 67 89',
15
+ phoneClean: '+33123456789',
16
+ contactEmail: 'contact@snapify.fr',
17
+ slaHours: '48 elit sed',
18
+ address: 'Do & Eiusmod tempor incididunt Ut',
19
+ rgeBadges: [
20
+ { name: 'LABORE Et+', desc: 'Dolore & magna aliqua enim ad' },
21
+ { name: 'MINIM Veniam QUIS', desc: 'Nostrud exercitation & ullamco laboris nisi aliquip' },
22
+ { name: 'EX Ea Commodo', desc: 'Consequat duis aute Irure In (reprehenderit voluptate)' }
23
+ ],
24
+ partnerEngineering: {
25
+ name: 'Velit Esse',
26
+ qualifications: [
27
+ 'CILLUM 1717 — Fugiat nulla pariatur excepteur',
28
+ 'SINT 1905 — Occaecat cupidatat non proident sunt culpa qui'
29
+ ]
30
+ },
31
+ insurance: {
32
+ name: 'OFFICIA Deserunt',
33
+ type: 'MOLLIT Anim & Id Est'
34
+ }
35
+ };
36
+
37
+ export const CEE_SHEETS: CeeSheet[] = [
38
+ {
39
+ id: 'hp-flottante',
40
+ name: 'Laborum curabitur pretium',
41
+ codeTertiaire: 'TINCIDUNT-LACUS-134',
42
+ codeIndustrie: 'NULLA-GRAVIDA-116',
43
+ description: 'Orci a odio nullam varius turpis et commodo pharetra est eros bibendum elit nec luctus magna felis.',
44
+ typicalSavings: '15% sollicitudin 25% mauris integer in mauris eu',
45
+ coverageEstimate: 'Nibh 80% euismod gravida duis AC'
46
+ },
47
+ {
48
+ id: 'bp-flottante',
49
+ name: 'Tellus et risus',
50
+ codeTertiaire: 'VULPUTATE-VEHICULA-145',
51
+ codeIndustrie: 'DONEC-LOBORTIS-115',
52
+ description: 'Risus a elit etiam tempor lorem ipsum dolor sit amet consectetur adipiscing elit sed do.',
53
+ typicalSavings: '8% eiusmod 14% tempor incididunt ut',
54
+ coverageEstimate: 'Labore et dolore MAGNA aliqua'
55
+ },
56
+ {
57
+ id: 'condenseur-he',
58
+ name: 'Enim ad minim',
59
+ codeTertiaire: 'VENIAM-QUIS-130',
60
+ codeIndustrie: 'NOSTRUD-EXERCITATION-113',
61
+ description: 'Ullamco laboris nisi-aliquip ex ea commodo CONSEQUAT duis aute irure in reprehenderit voluptate velit esse cillum.',
62
+ typicalSavings: '12% fugiat 20% nulla pariatur excepteur sint occaecat',
63
+ coverageEstimate: 'Cupidatat NON proident'
64
+ },
65
+ {
66
+ id: 'vev-vitesse',
67
+ name: 'Sunt culpa qui officia (DESERUNT)',
68
+ codeTertiaire: 'MOLLIT-ANIM-112',
69
+ codeIndustrie: 'ID-EST-102',
70
+ description: 'Laborum curabitur pretium tincidunt lacus nulla gravida orci a, odio nullam varius turpis et commodo pharetra est.',
71
+ typicalSavings: '20% eros 35% bibendum elit nec luctus',
72
+ coverageEstimate: 'Magna felis sollicitudin MAURIS'
73
+ },
74
+ {
75
+ id: 'fermeture-meubles',
76
+ name: 'Integer in mauris eu',
77
+ codeTertiaire: 'NIBH-EUISMOD-124 / 125',
78
+ codeIndustrie: '—',
79
+ description: 'Gravida duis ac tellus et risus vulputate vehicula donec lobortis risus a elit etiam tempor lorem ipsum.',
80
+ typicalSavings: '25% dolor 45% sit amet consectetur adipiscing elit',
81
+ coverageEstimate: 'Sed DO eiusmod tempor incididunt'
82
+ },
83
+ {
84
+ id: 'recup-chaleur-groupe',
85
+ name: 'Ut labore et dolore magna aliqua / ENIM',
86
+ codeTertiaire: 'AD-MINIM-139',
87
+ codeIndustrie: 'VENIAM-QUIS-103',
88
+ description: 'Nostrud exercitation ullamco laboris nisi aliquip ex ea commodo consequat duis aute irure in.',
89
+ typicalSavings: 'Reprehenderit voluptate 90% velit esse cillum fugiat nulla',
90
+ coverageEstimate: 'Pariatur EXCEPTEUR sint occaecat'
91
+ },
92
+ {
93
+ id: 'chaleur-fatale',
94
+ name: 'Cupidatat non proident sunt culpa',
95
+ codeTertiaire: '—',
96
+ codeIndustrie: 'QUI-OFFICIA-137',
97
+ description: 'Deserunt mollit anim id est laborum, curabitur, pretium tincidunt lacus nulla gravida orci a odio nullam.',
98
+ typicalSavings: 'Varius turpis et commodo pharetra est eros',
99
+ coverageEstimate: 'Bibendum ELIT nec & luctus MAGNA'
100
+ },
101
+ {
102
+ id: 'recup-eaux-grises',
103
+ name: 'Felis sollicitudin mauris integer in',
104
+ codeTertiaire: 'MAURIS-EU-154',
105
+ codeIndustrie: '—',
106
+ description: 'Nibh euismod gravida duis ac tellus et risus vulputate vehicula donec lobortis.',
107
+ typicalSavings: '30% risus 50% a elit etiam tempor',
108
+ coverageEstimate: 'Lorem IPSUM dolor'
109
+ },
110
+ {
111
+ id: 'pompe-a-chaleur',
112
+ name: 'Sit amet consectetur adipiscing/elit (sed do/eiusmod)',
113
+ codeTertiaire: 'TEMPOR-INCIDIDUNT-163',
114
+ codeIndustrie: 'UT-LABORE-117',
115
+ description: 'Et dolore magna aliqua enim ad MINIM veniam quis nostrud exercitation ullamco laboris.',
116
+ typicalSavings: 'Nisi 60% aliquip ex ea',
117
+ coverageEstimate: 'Commodo consequat & duis AUTE'
118
+ },
119
+ {
120
+ id: 'destratification',
121
+ name: 'Irure in reprehenderit voluptate velit',
122
+ codeTertiaire: 'ESSE-CILLUM-142',
123
+ codeIndustrie: 'FUGIAT-NULLA-116',
124
+ description: 'Pariatur excepteur sint occaecat cupidatat non proident sunt culpa qui officia deserunt mollit anim id est laborum curabitur pretium tincidunt.',
125
+ typicalSavings: '15% lacus 30% nulla gravida orci a odio',
126
+ coverageEstimate: 'NULLAM varius turpis et 18 commodo'
127
+ },
128
+ {
129
+ id: 'gtb-gtc',
130
+ name: 'Pharetra EST / EROS (Bibendum ELIT)',
131
+ codeTertiaire: 'NEC-LUCTUS-116',
132
+ codeIndustrie: 'MAGNA-FELIS-134',
133
+ description: 'Sollicitudin mauris integer in mauris eu nibh euismod, gravida duis, ac tellus et risus vulputate.',
134
+ typicalSavings: '15% vehicula 30% donec lobortis risus a',
135
+ coverageEstimate: 'Elit etiam tempor LOREM ipsum 2025/2030'
136
+ },
137
+ {
138
+ id: 'isolation-calorifugeage',
139
+ name: 'Dolor sit amet consectetur',
140
+ codeTertiaire: 'ADIPISCING-ELIT-106',
141
+ codeIndustrie: 'SED-DO-121',
142
+ description: 'Eiusmod tempor incididunt ut labore et (dolore, magna, aliqua) enim ad minim veniam quis nostrud exercitation.',
143
+ typicalSavings: 'Ullamco laboris nisi aliquip ex ea 80%',
144
+ coverageEstimate: 'Commodo consequat duis aute irure in reprehenderit'
145
+ },
146
+ {
147
+ id: 'toiture-terrasse',
148
+ name: 'Voluptate velit esse cillum',
149
+ codeTertiaire: 'FUGIAT-NULLA-107',
150
+ codeIndustrie: '—',
151
+ description: 'Pariatur excepteur sint occaecat cupidatat Non proident sunt culpa qui officia deserunt mollit anim.',
152
+ typicalSavings: '10% id 20% est laborum curabitur pretium tincidunt',
153
+ coverageEstimate: 'Lacus NULLA gravida orci'
154
+ }
155
+ ];
156
+
157
+ export const EXPERTISES: ExpertiseItem[] = [
158
+ {
159
+ slug: 'froid',
160
+ title: 'A odio & nullam',
161
+ shortDesc: 'Varius turpis et commodo pharetra, est eros bibendum, elit nec luctus magna felis sollicitudin.',
162
+ heroTitle: 'Mauris integer in mauris : eu nibh euismod gravida',
163
+ metaDesc: 'Duis ac tellus et risus, vulputate, vehicula, donec lobortis : risus a elit etiam tempor lorem ipsum.',
164
+ iconName: 'Snowflake',
165
+ solutions: [
166
+ {
167
+ title: 'Dolor sit amet',
168
+ description: 'Consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Enim ad minim veniam quis nostrud exercitation ullamco 80% laboris nisi.',
169
+ ceeFiches: 'ALIQUIP-EX-134 (Ea) · COMMODO-CONSEQUAT-116 (Duis)'
170
+ },
171
+ {
172
+ title: 'Aute irure in',
173
+ description: 'Reprehenderit voluptate velit esse cillum fugiat nulla pariatur excepteur sint occaecat cupidatat non proident sunt. Culpa qui officia deserunt mollit anim id est laborum curabitur 3%.',
174
+ ceeFiches: 'PRETIUM-TINCIDUNT-145 (Lacus) · NULLA-GRAVIDA-115 (Orci)'
175
+ },
176
+ {
177
+ title: 'A odio nullam',
178
+ description: 'Varius turpis et commodo pharetra est eros bibendum elit nec luctus magna felis sollicitudin MAURIS integer in mauris.',
179
+ ceeFiches: 'EU-NIBH-130 (Euismod) · GRAVIDA-DUIS-113 (Ac)'
180
+ },
181
+ {
182
+ title: 'Tellus et risus vulputate (VEHICULA)',
183
+ description: 'Donec lobortis risus a elit etiam tempor lorem ipsum dolor sit amet-consectetur adipiscing elit sed.',
184
+ ceeFiches: 'DO-EIUSMOD-112 (Tempor) · INCIDIDUNT-UT-102 (Labore)'
185
+ },
186
+ {
187
+ title: 'Et dolore magna aliqua',
188
+ description: 'Enim ad minim veniam quis nostrud exercitation ullamco laboris nisi aliquip ex ea commodo consequat.',
189
+ ceeFiches: 'DUIS-AUTE-124 (Irure) · IN-REPREHENDERIT-125 (Voluptate)'
190
+ }
191
+ ],
192
+ ceeList: ['VELIT-ESSE-134', 'CILLUM-FUGIAT-116', 'NULLA-PARIATUR-145', 'EXCEPTEUR-SINT-115', 'OCCAECAT-CUPIDATAT-130', 'NON-PROIDENT-113', 'SUNT-CULPA-112', 'QUI-OFFICIA-102', 'DESERUNT-MOLLIT-124', 'ANIM-ID-125']
193
+ },
194
+ {
195
+ slug: 'recuperation-de-chaleur',
196
+ title: 'Est laborum curabitur',
197
+ shortDesc: 'Pretium tincidunt lacus nulla gravida orci a, odio nullam varius turpis et commodo.',
198
+ heroTitle: 'Pharetra est eros : bibendum elit nec',
199
+ metaDesc: 'Luctus magna felis sollicitudin mauris integer in, mauris eu nibh euismod gravida duis ac tellus et risus vulputate vehicula donec lobortis.',
200
+ iconName: 'Flame',
201
+ solutions: [
202
+ {
203
+ title: 'Risus a elit / ETIAM',
204
+ description: 'Tempor lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua enim ad minim.',
205
+ ceeFiches: 'VENIAM-QUIS-139 (Nostrud) · EXERCITATION-ULLAMCO-103 (Laboris)'
206
+ },
207
+ {
208
+ title: 'Nisi aliquip ex',
209
+ description: 'Ea commodo consequat duis aute irure in, reprehenderit voluptate velit, esse cillum fugiat nulla pariatur excepteur.',
210
+ ceeFiches: 'SINT-OCCAECAT-137 (Cupidatat)'
211
+ },
212
+ {
213
+ title: 'Non proident sunt culpa qui',
214
+ description: 'Officia deserunt mollit anim id est laborum curabitur pretium tincidunt lacus nulla, gravida orci a odio.',
215
+ ceeFiches: 'NULLAM-VARIUS-154 (Turpis)'
216
+ }
217
+ ],
218
+ ceeList: ['ET-COMMODO-139', 'PHARETRA-EST-103', 'EROS-BIBENDUM-137', 'ELIT-NEC-154']
219
+ },
220
+ {
221
+ slug: 'chauffage-traitement-air',
222
+ title: 'Luctus & magna felis',
223
+ shortDesc: 'Sollicitudin mauris integer in mauris eu/nibh euismod gravida duis ac tellus et risus.',
224
+ heroTitle: 'Vulputate vehicula donec lobortis risus a elit',
225
+ metaDesc: 'Etiam tempor lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et.',
226
+ iconName: 'Wind',
227
+ solutions: [
228
+ {
229
+ title: 'Dolore magna aliqua enim/ad (minim veniam/quis)',
230
+ description: 'Nostrud exercitation ullamco laboris nisi. Aliquip ex ea commodo CONSEQUAT duis aute irure in reprehenderit voluptate velit esse cillum fugiat nulla pariatur excepteur.',
231
+ ceeFiches: 'SINT-OCCAECAT-163 (Cupidatat) · NON-PROIDENT-117 (Sunt)'
232
+ },
233
+ {
234
+ title: 'Culpa qui',
235
+ description: 'Officia deserunt mollit anim id est laborum curabitur pretium tincidunt lacus nulla gravida orci a odio nullam varius turpis. Et commodo pharetra est eros bibendum.',
236
+ ceeFiches: 'ELIT-NEC-142 (Luctus) · MAGNA-FELIS-116 (Sollicitudin)'
237
+ }
238
+ ],
239
+ ceeList: ['MAURIS-INTEGER-163', 'IN-MAURIS-117', 'EU-NIBH-142', 'EUISMOD-GRAVIDA-116']
240
+ },
241
+ {
242
+ slug: 'gtb-gtc',
243
+ title: 'Duis AC / TELLUS',
244
+ shortDesc: 'Et Risus vulputate Vehicula donec Lobortis/Risus a elit etiam tempor lorem ipsum dolor sit AMET.',
245
+ heroTitle: 'Consectetur ADIPISCING / ELIT sed do eiusmod tempor INCIDIDUNT',
246
+ metaDesc: 'Ut labore et dolore magna ALIQUA/ENIM ad minim veniam quis nostrud exercitation ullamco laboris nisi aliquip EX.',
247
+ iconName: 'Cpu',
248
+ solutions: [
249
+ {
250
+ title: 'EA / COMMODO consequat',
251
+ description: 'Duis aute, irure in reprehenderit voluptate velit esse cillum fugiat nulla pariatur excepteur sint OCCAECAT, cupidatat non proident sunt.',
252
+ ceeFiches: 'CULPA-QUI-116 (Officia) · DESERUNT-MOLLIT-134 (Anim)'
253
+ },
254
+ {
255
+ title: 'Id est laborum Curabitur PRETIUM',
256
+ description: 'Tincidunt lacus nulla gravida : orci a odio nullam varius turpis et commodo pharetra est eros bibendum elit > 290 nec (2025) luctus > 70 magna (2030).',
257
+ ceeFiches: 'FELIS-SOLLICITUDIN-116 (Mauris integer)'
258
+ }
259
+ ],
260
+ ceeList: ['IN-MAURIS-116', 'EU-NIBH-134']
261
+ },
262
+ {
263
+ slug: 'isolation-technique',
264
+ title: 'Euismod gravida',
265
+ shortDesc: 'Duis ac tellus et, risus vulputate vehicula donec lobortis risus a elit etiam.',
266
+ heroTitle: 'Tempor lorem ipsum dolor sit amet consectetur',
267
+ metaDesc: 'Adipiscing, elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua enim ad minim veniam.',
268
+ iconName: 'ShieldCheck',
269
+ solutions: [
270
+ {
271
+ title: 'Quis nostrud exercitation ullamco',
272
+ description: 'Laboris nisi aliquip ex ea commodo consequat duis aute, irure in reprehenderit. Voluptate velit esse cillum fugiat nulla pariatur excepteur sint.',
273
+ ceeFiches: 'OCCAECAT-CUPIDATAT-106 (Non) · PROIDENT-SUNT-121 (Culpa)'
274
+ },
275
+ {
276
+ title: 'Qui officia deserunt mollit',
277
+ description: 'Anim id est laborum curabitur pretium tincidunt lacus nulla gravida orci a odio nullam varius turpis et commodo.',
278
+ ceeFiches: 'PHARETRA-EST-107 (Eros)'
279
+ }
280
+ ],
281
+ ceeList: ['BIBENDUM-ELIT-106', 'NEC-LUCTUS-121', 'MAGNA-FELIS-107']
282
+ },
283
+ {
284
+ slug: 'reglementation-cee',
285
+ title: 'Sollicitudin & mauris INTEGER',
286
+ shortDesc: 'In mauris, eu NIBH euismod gravida duis ac tellus et risus Vulputate vehicula donec.',
287
+ heroTitle: 'Lobortis risus a ELIT',
288
+ metaDesc: 'Snapify etiam tempor lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor (INCIDIDUNT).',
289
+ iconName: 'FileCheck',
290
+ solutions: [
291
+ {
292
+ title: 'Ut labore & Et DOLORE',
293
+ description: 'Magna aliqua enim ad minim (-40% veniam 2030, -50% quis 2040, -60% nostrud 2050) exercitation ullamco laboris nisi 1 000 aliquip² ex ea. Commodo consequat duis aute irure in reprehenderit voluptate velit.',
294
+ ceeFiches: 'ESSE · Cillum fugiat'
295
+ },
296
+ {
297
+ title: 'Nulla PARIATUR (Excepteur Sint & Occaecat Cupidatat)',
298
+ description: 'Non proident sunt CULPA qui officia deserunt > 290 mollit anim id 1est laborum 2025, curabitur > 70 pretium tincidunt lacus 1nulla gravida 2030.',
299
+ ceeFiches: 'Orci A-ODIO-116 nullam'
300
+ },
301
+ {
302
+ title: 'Varius turpis et COMMODO pharetra Est eros Bibendum',
303
+ description: 'Elit nec, luctus magna felis sollicitudin mauris integer, in mauris eu nibh EUISMOD gravida duis ac tellus et risus vulputate.',
304
+ ceeFiches: 'Vehicula donec Lobortis & Risus'
305
+ }
306
+ ],
307
+ ceeList: ['A-ELIT-116', 'ETIAM-TEMPOR-134', 'LOREM-IPSUM-116', 'DOLOR-SIT-103', 'AMET-CONSECTETUR-139']
308
+ }
309
+ ];
310
+
311
+ export const SECTEURS: SecteurItem[] = [
312
+ {
313
+ slug: 'industrie',
314
+ title: 'Adipiscing',
315
+ shortDesc: 'Elit sed do, eiusmod, tempor incididunt, ut labore.',
316
+ heroTitle: 'Et dolore magna aliqua enim',
317
+ metaDesc: 'Ad minim, veniam quis nostrud exercitation, ullamco, laboris : nisi aliquip ex ea commodo consequat duis aute.',
318
+ image: '/images/photos/caravane-chameaux-desert.webp',
319
+ enjeux: [
320
+ 'Irure in reprehenderit voluptate velit esse cillum fugiat nulla pariatur excepteur sint occaecat cupidatat non.',
321
+ 'Proident sunt culpa qui officia deserunt mollit anim id est laborum curabitur pretium.',
322
+ 'Tincidunt lacus nulla gravida orci a odio nullam varius turpis et commodo.'
323
+ ],
324
+ solutions: [
325
+ { title: 'Pharetra est & eros', slug: 'froid' },
326
+ { title: 'Bibendum elit nec', slug: 'recuperation-de-chaleur' },
327
+ { title: 'Luctus magna', slug: 'isolation-technique' }
328
+ ],
329
+ typicalEquipments: ['Felis sollicitudin MAURIS3 / INTEGER2', 'In & mauris eu', 'Nibh euismod & gravida duis', 'Ac tellus et']
330
+ },
331
+ {
332
+ slug: 'tertiaire',
333
+ title: 'Risus',
334
+ shortDesc: 'Vulputate vehicula, donec, lobortis risus, a.',
335
+ heroTitle: 'Elit etiam tempor lorem ipsum',
336
+ metaDesc: 'Dolor sit, amet, consectetur, adipiscing : elit sed, DO, eiusmod tempor incididunt ut labore.',
337
+ image: '/images/photos/panorama-ville.jpg',
338
+ enjeux: [
339
+ 'Et dolore magna aliqua enim Ad Minim (veniam 2030 / 2040 / 2050 quis nostrud EXERCITATION).',
340
+ 'Ullamco laboris nisi aliquip ex ea Commodo CONSEQUAT (duis AUTE > 290 irure in > 70 reprehenderit).',
341
+ 'Voluptate velit esse cillum fugiat nulla pariatur excepteur sint occaecat cupidatat non proident sunt culpa.'
342
+ ],
343
+ solutions: [
344
+ { title: 'Qui officia & deserunt', slug: 'froid' },
345
+ { title: 'Mollit ANIM / ID', slug: 'gtb-gtc' },
346
+ { title: 'Est & laborum curabitur', slug: 'chauffage-traitement-air' }
347
+ ],
348
+ typicalEquipments: ['Pretium tincidunt & lacus nulla/gravida', 'Orci & A', 'Odio NULLAM', 'Varius turpis']
349
+ },
350
+ {
351
+ slug: 'residentiel-collectif',
352
+ title: 'Et commodo',
353
+ shortDesc: 'Pharetra est, eros bibendum elit nec luctus.',
354
+ heroTitle: 'Magna felis sollicitudin mauris integer',
355
+ metaDesc: 'In mauris, eu, nibh : euismod gravida duis ac tellus et risus vulputate vehicula donec.',
356
+ image: '/images/photos/ruelle-bleue-medina.jpg',
357
+ enjeux: [
358
+ 'Lobortis risus a elit etiam tempor lorem ipsum dolor sit amet.',
359
+ 'Consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et (dolore/magna).',
360
+ 'Aliqua enim ad MINIM veniam quis nostrud exercitation ullamco laboris nisi aliquip ex ea commodo.'
361
+ ],
362
+ solutions: [
363
+ { title: 'Consequat & duis aute', slug: 'chauffage-traitement-air' },
364
+ { title: 'Irure in', slug: 'isolation-technique' },
365
+ { title: 'Reprehenderit voluptate velit', slug: 'recuperation-de-chaleur' }
366
+ ],
367
+ typicalEquipments: ['Esse cillum & fugiat-nulla', 'Pariatur excepteur sint occaecat cupidatat non', 'Proident sunt culpa', 'Qui officia']
368
+ }
369
+ ];
370
+
371
+ export const REALISATIONS: RealisationItem[] = [
372
+ {
373
+ id: 'intermarche-trevenans',
374
+ slug: 'intermarche-trevenans',
375
+ client: 'Deserunt Mollit',
376
+ location: 'Anim',
377
+ department: '90',
378
+ sector: 'Tertiaire',
379
+ solution: 'Id Est Laborum & Curabitur Pretium Tincidunt',
380
+ shortDescription: 'Lacus nulla gravida orci a odio nullam varius turpis et commodo pharetra est eros bibendum.',
381
+ problem: 'Elit nec luctus magna felis sollicitudin mauris integer in mauris eu nibh euismod gravida-duis ac tellus et risus-vulputate vehicula donec lobortis.',
382
+ solutionDetail: 'Risus a elit etiam TEMPOR lorem ipsum dolor sit amet consectetur adipiscing elit sed, do eiusmod tempor incididunt ut labore et dolore magna ALIQUA.',
383
+ results: [
384
+ 'Enim ad minim veniam quis nostrud',
385
+ 'Exercitation ullamco laboris nisi aliquip ex',
386
+ 'Ea commodo consequat duis aute irure in reprehenderit voluptate velit'
387
+ ],
388
+ image: '/images/photos/panorama-ville.jpg',
389
+ ceeSheet: 'ESSE-CILLUM-134 & FUGIAT-NULLA-112',
390
+ metrics: [
391
+ { label: 'Pariatur', value: 'Excepteur sint' },
392
+ { label: 'Occaecat', value: 'Cupidatat (90)' },
393
+ { label: 'Non', value: 'PROIDENT Sunt & CULPA' },
394
+ { label: 'Qui OFFICIA', value: '100% deserunt' }
395
+ ]
396
+ },
397
+ {
398
+ id: 'colorcon-bazainville',
399
+ slug: 'colorcon-bazainville',
400
+ client: 'Mollit',
401
+ location: 'Anim',
402
+ department: '78',
403
+ sector: 'Industrie',
404
+ solution: 'Id est Laborum Curabitur & Pretium Tincidunt',
405
+ shortDescription: 'Lacus nulla gravida orci a odio nullam varius turpis et commodo pharetra est eros.',
406
+ problem: 'Bibendum elit nec luctus magna felis sollicitudin mauris integer in mauris eu nibh euismod gravida duis ac tellus et risus.',
407
+ solutionDetail: 'Vulputate vehicula donec lobortis risus a elit etiam tempor lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore.',
408
+ results: [
409
+ 'Magna aliqua enim ad minim veniam quis nostrud exercitation ullamco laboris nisi',
410
+ 'Aliquip ex ea commodo consequat Duis aute irure',
411
+ 'In reprehenderit voluptate velit esse cillum fugiat nulla pariatur'
412
+ ],
413
+ image: '/images/photos/caravane-chameaux-desert.webp',
414
+ ceeSheet: 'EXCEPTEUR-SINT-103 & OCCAECAT-CUPIDATAT-121',
415
+ metrics: [
416
+ { label: 'Non', value: 'Proident sunt' },
417
+ { label: 'Culpa', value: 'Qui (78)' },
418
+ { label: 'Officia', value: 'Deserunt mollit & Anim' },
419
+ { label: 'Id', value: 'Est Laborum Curabitur' }
420
+ ]
421
+ },
422
+ {
423
+ id: 'carrefour-market-idf',
424
+ slug: 'carrefour-market',
425
+ client: 'Pretium Tincidunt',
426
+ location: 'Lacus Nulla',
427
+ department: '75/92',
428
+ sector: 'Tertiaire',
429
+ solution: 'Gravida Orci A & Odio Nullam Varius',
430
+ shortDescription: 'Turpis et commodo pharetra est eros bibendum elit nec luctus magna felis sollicitudin mauris.',
431
+ problem: 'Integer in mauris eu nibh euismod gravida duis ac tellus et-risus vulputate vehicula donec lobortis risus a elit.',
432
+ solutionDetail: 'Etiam tempor lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod-tempor incididunt ut labore et dolore magna.',
433
+ results: [
434
+ 'Aliqua enim ad minim veniam quis nostrud exercitation',
435
+ 'Ullamco laboris nisi aliquip ex ea commodo consequat duis',
436
+ 'Aute irure in reprehenderit voluptate velit esse cillum FUGIAT'
437
+ ],
438
+ image: '/images/photos/sidi-bou-said-port.webp',
439
+ ceeSheet: 'NULLA-PARIATUR-130 & EXCEPTEUR-SINT-124',
440
+ metrics: [
441
+ { label: 'Occaecat', value: 'Cupidatat non' },
442
+ { label: 'Proident', value: 'Sunt-culpa-Qui' },
443
+ { label: 'Officia', value: 'Deserunt MOLLIT & Anim' },
444
+ { label: 'Id', value: 'EST laborum' }
445
+ ]
446
+ },
447
+ {
448
+ id: 'cedim-logistique',
449
+ slug: 'cedim',
450
+ client: 'CURABITUR',
451
+ location: 'Pretium Tincidunt',
452
+ department: 'France',
453
+ sector: 'Tertiaire',
454
+ solution: 'Lacus nulla Gravida Orci & A',
455
+ shortDescription: 'Odio nullam varius turpis et commodo pharetra est eros bibendum.',
456
+ problem: 'Elit nec luctus magna felis sollicitudin 10°Mauris integer in mauris eu nibh euismod gravida duis ac 12 tellus, et risus vulputate vehicula donec lobortis risus.',
457
+ solutionDetail: 'A elit etiam tempor lorem ipsum dolor sit amet consectetur adipiscing elit, sed do eiusmod TEMPOR incididunt ut labore et dolore.',
458
+ results: [
459
+ 'Magna aliqua enim 18°Ad minim veniam quis nostrud exercitation ullamco laboris nisi',
460
+ 'Aliquip ex ea commodo consequat duis aute irure',
461
+ 'In reprehenderit voluptate velit esse cillum fugiat nulla'
462
+ ],
463
+ image: '/images/photos/maison-campagne-collines.webp',
464
+ ceeSheet: 'PARIATUR-EXCEPTEUR-142 & SINT-OCCAECAT-116',
465
+ metrics: [
466
+ { label: 'Cupidatat', value: 'Non proident' },
467
+ { label: 'Sunt', value: '12 culpa qui' },
468
+ { label: 'Officia', value: 'Deserunt & MOLLIT' },
469
+ { label: 'Anim', value: 'Id EST laborum' }
470
+ ]
471
+ }
472
+ ];
473
+
474
+ export const METHODE_STEPS = [
475
+ {
476
+ num: '01',
477
+ title: 'Curabitur & pretium tincidunt lacus',
478
+ subtitle: 'Nulla gravida orci a odio nullam varius',
479
+ description: 'Turpis et commodo pharetra, est eros bibendum elit nec, luctus magna felis sollicitudin, mauris integer in mauris EU.',
480
+ deliverable: 'Nibh-euismod gravida duis'
481
+ },
482
+ {
483
+ num: '02',
484
+ title: 'Ac & tellus et-risus',
485
+ subtitle: 'Vulputate vehicula donec lobortis risus a',
486
+ description: 'Elit etiam tempor lorem ipsum dolor, sit amet consectetur, adipiscing elit sed do eiusmod (TEMPOR) incididunt ut labore et dolore magna aliqua ENIM.',
487
+ deliverable: 'Ad minim veniam, quis nostrud & exercitation ullamco laboris NISI'
488
+ },
489
+ {
490
+ num: '03',
491
+ title: 'Aliquip, ex & ea commodo consequat',
492
+ subtitle: 'Duis aute irure in',
493
+ description: 'Reprehenderit voluptate velit esse cillum fugiat nulla pariatur, excepteur sint occaecat cupidatat non proident sunt culpa, qui officia deserunt mollit anim.',
494
+ deliverable: 'Id-est laborum curabitur & pretium tincidunt lacus nulla gravida orci'
495
+ },
496
+ {
497
+ num: '04',
498
+ title: 'A ODIO, nullam & varius',
499
+ subtitle: 'Turpis et commodo pharetra est eros',
500
+ description: 'Bibendum elit nec luctus magna felis SOLLICITUDIN mauris integer in mauris eu, nibh euismod gravida duis ac tellus et risus vulputate.',
501
+ deliverable: 'Vehicula donec lobortis RISUS & a elit etiam'
502
+ }
503
+ ];
504
+
505
+ export const VOS_ENJEUX = [
506
+ {
507
+ icon: 'TrendingDown',
508
+ title: 'Tempor lorem ipsum dolor sit',
509
+ solutionText: 'Amet consectetur adipiscing elit sed do eiusmod (tempor, incididunt, ut) labore et dolore magna aliqua enim ad minim veniam.',
510
+ link: '/expertises/'
511
+ },
512
+ {
513
+ icon: 'ShieldAlert',
514
+ title: 'Quis nostrud exercitation ullamco',
515
+ solutionText: 'Laboris nisi, aliquip EX : ea commodo consequat duis aute irure in reprehenderit voluptate velit esse cillum fugiat nulla pariatur.',
516
+ link: '/expertises/reglementation-cee/'
517
+ },
518
+ {
519
+ icon: 'Wrench',
520
+ title: 'Excepteur sint occaecat cupidatat',
521
+ solutionText: 'Non proident sunt, culpa qui, officia deserunt mollit : anim id est laborum curabitur pretium tincidunt lacus.',
522
+ link: '/expertises/'
523
+ },
524
+ {
525
+ icon: 'BadgePercent',
526
+ title: 'Nulla gravida orci a odio nullam varius',
527
+ solutionText: 'Turpis et commodo pharetra est eros BIBENDUM elit Nec luctus Magna felis sollicitudin mauris integer in mauris eu nibh euismod gravida duis ac.',
528
+ link: '/expertises/reglementation-cee/'
529
+ }
530
+ ];
531
+
532
+ export const FAQ_HOME = [
533
+ {
534
+ question: 'Tellus et risus vulputate vehicula-donec ?',
535
+ answer: 'Snapify lobortis risus a elit etiam, tempor lorem ipsum (dolor sit, amet, consectetur, adipiscing) elit sed do eiusmod, tempor incididunt Ut.'
536
+ },
537
+ {
538
+ question: 'Labore et dolore magna aliqua enim Snapify ?',
539
+ answer: 'Ad 4 minim : veniam quis nostrud, exercitation ullamco laboris nisi-aliquip, ex ea commodo consequat duis, aute irure IN reprehenderit voluptate velit esse. Cillum fugiat nulla pariatur excepteur sint occaecat cupidatat.'
540
+ },
541
+ {
542
+ question: 'Non proident sunt-culpa qui officia deserunt mollit ANIM ?',
543
+ answer: 'Id est laborum curabitur pretium tincidunt lacus nulla gravida orci a odio nullam varius. Snapify turpis et commodo pharetra est EROS, bibendum elit nec luctus magna felis sollicitudin mauris integer. In mauris eu nibh euismod gravida duis ac.'
544
+ },
545
+ {
546
+ question: 'Tellus et risus-vulputate vehicula donec lobortis risus a ?',
547
+ answer: 'Elit etiam tempor lorem ipsum dolor sit 1 000 amet² consectetur adipiscing. Elit sed do eiusmod tempor incididunt ut labore 40 % et 2030, 50 % dolore 2040 magna 60 % aliqua 2050 enim ad minim veniam quis nostrud exercitation, ullamco laboris nisi aliquip ex ea commodo CONSEQUAT.'
548
+ },
549
+ {
550
+ question: 'Duis aute IRURE in-reprehenderit-voluptate velit esse cillum FUGIAT ?',
551
+ answer: 'Nulla pariatur excepteur sint occaecat cupidatat non proident sunt culpa 290 qui officia deserunt mollit anim id est laborum (CURABITUR) pretium tincidunt 1lacus nulla 2025. Gravida orci a odio 70 nullam varius 1turpis et 2030.'
552
+ },
553
+ {
554
+ question: 'Commodo pharetra est, eros bibendum elit : nec luctus magna Snapify ?',
555
+ answer: 'Felis-sollicitudin mauris integer in mauris eu nibh euismod gravida duis ac tellus. Et risus vulputate vehicula donec lobortis risus 48 a elit.'
556
+ },
557
+ {
558
+ question: 'Etiam tempor lorem ipsum-dolor ?',
559
+ answer: 'Sit amet consectetur adipiscing elit sed do eiusmod 48 tempor incididunt.'
560
+ }
561
+ ];