@atlashub/smartstack-cli 1.5.0 → 1.5.2
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/.documentation/agents.html +920 -916
- package/.documentation/apex.html +1022 -1018
- package/.documentation/business-analyse.html +1505 -1501
- package/.documentation/commands.html +684 -680
- package/.documentation/css/styles.css +2168 -2168
- package/.documentation/efcore.html +2509 -2505
- package/.documentation/gitflow.html +2622 -2618
- package/.documentation/hooks.html +417 -413
- package/.documentation/index.html +327 -323
- package/.documentation/init.html +565 -0
- package/.documentation/installation.html +548 -462
- package/.documentation/js/app.js +794 -794
- package/.documentation/ralph-loop.html +534 -530
- package/.documentation/test-web.html +517 -513
- package/config/default-config.json +86 -86
- package/config/settings.json +53 -53
- package/config/settings.local.example.json +16 -16
- package/dist/index.js +18 -8
- package/dist/index.js.map +1 -1
- package/package.json +88 -88
- package/templates/agents/action.md +36 -36
- package/templates/agents/efcore/conflicts.md +84 -84
- package/templates/agents/efcore/db-deploy.md +51 -51
- package/templates/agents/efcore/db-reset.md +59 -59
- package/templates/agents/efcore/db-seed.md +56 -56
- package/templates/agents/efcore/db-status.md +64 -64
- package/templates/agents/efcore/migration.md +85 -85
- package/templates/agents/efcore/rebase-snapshot.md +62 -62
- package/templates/agents/efcore/scan.md +90 -90
- package/templates/agents/efcore/squash.md +67 -67
- package/templates/agents/explore-codebase.md +65 -65
- package/templates/agents/explore-docs.md +97 -97
- package/templates/agents/fix-grammar.md +49 -49
- package/templates/agents/gitflow/abort.md +45 -45
- package/templates/agents/gitflow/cleanup.md +85 -85
- package/templates/agents/gitflow/commit.md +40 -40
- package/templates/agents/gitflow/exec.md +48 -48
- package/templates/agents/gitflow/finish.md +92 -92
- package/templates/agents/gitflow/init.md +139 -139
- package/templates/agents/gitflow/merge.md +62 -62
- package/templates/agents/gitflow/plan.md +42 -42
- package/templates/agents/gitflow/pr.md +78 -78
- package/templates/agents/gitflow/review.md +49 -49
- package/templates/agents/gitflow/start.md +61 -61
- package/templates/agents/gitflow/status.md +32 -32
- package/templates/agents/snipper.md +36 -36
- package/templates/agents/websearch.md +46 -46
- package/templates/commands/_resources/formatting-guide.md +124 -124
- package/templates/commands/ai-prompt.md +315 -315
- package/templates/commands/apex/1-analyze.md +100 -100
- package/templates/commands/apex/2-plan.md +145 -145
- package/templates/commands/apex/3-execute.md +171 -171
- package/templates/commands/apex/4-examine.md +116 -116
- package/templates/commands/apex/5-tasks.md +209 -209
- package/templates/commands/apex.md +76 -76
- package/templates/commands/application/create.md +362 -362
- package/templates/commands/application/templates-backend.md +463 -463
- package/templates/commands/application/templates-frontend.md +517 -517
- package/templates/commands/application/templates-i18n.md +478 -478
- package/templates/commands/application/templates-seed.md +362 -362
- package/templates/commands/application.md +303 -303
- package/templates/commands/business-analyse/0-orchestrate.md +640 -640
- package/templates/commands/business-analyse/1-init.md +269 -269
- package/templates/commands/business-analyse/2-discover.md +520 -520
- package/templates/commands/business-analyse/3-analyse.md +408 -408
- package/templates/commands/business-analyse/4-specify.md +598 -598
- package/templates/commands/business-analyse/5-validate.md +326 -326
- package/templates/commands/business-analyse/6-handoff.md +746 -746
- package/templates/commands/business-analyse/7-doc-html.md +602 -602
- package/templates/commands/business-analyse/bug.md +325 -325
- package/templates/commands/business-analyse/change-request.md +368 -368
- package/templates/commands/business-analyse/hotfix.md +200 -200
- package/templates/commands/business-analyse.md +640 -640
- package/templates/commands/controller/create.md +216 -216
- package/templates/commands/controller/postman-templates.md +528 -528
- package/templates/commands/controller/templates.md +600 -600
- package/templates/commands/controller.md +337 -337
- package/templates/commands/create/agent.md +138 -138
- package/templates/commands/create/command.md +166 -166
- package/templates/commands/create/hook.md +234 -234
- package/templates/commands/create/plugin.md +329 -329
- package/templates/commands/create/project.md +507 -507
- package/templates/commands/create/skill.md +199 -199
- package/templates/commands/create.md +220 -220
- package/templates/commands/debug.md +95 -95
- package/templates/commands/documentation/module.md +202 -202
- package/templates/commands/documentation/templates.md +432 -432
- package/templates/commands/documentation.md +190 -190
- package/templates/commands/efcore/_env-check.md +153 -153
- package/templates/commands/efcore/conflicts.md +186 -186
- package/templates/commands/efcore/db-deploy.md +193 -193
- package/templates/commands/efcore/db-reset.md +426 -426
- package/templates/commands/efcore/db-seed.md +326 -326
- package/templates/commands/efcore/db-status.md +226 -226
- package/templates/commands/efcore/migration.md +400 -400
- package/templates/commands/efcore/rebase-snapshot.md +264 -264
- package/templates/commands/efcore/scan.md +198 -198
- package/templates/commands/efcore/squash.md +298 -298
- package/templates/commands/efcore.md +224 -224
- package/templates/commands/epct.md +69 -69
- package/templates/commands/explain.md +186 -186
- package/templates/commands/explore.md +45 -45
- package/templates/commands/feature-full.md +267 -267
- package/templates/commands/gitflow/1-init.md +1038 -1038
- package/templates/commands/gitflow/10-start.md +768 -768
- package/templates/commands/gitflow/11-finish.md +457 -457
- package/templates/commands/gitflow/12-cleanup.md +276 -276
- package/templates/commands/gitflow/13-sync.md +216 -216
- package/templates/commands/gitflow/14-rebase.md +251 -251
- package/templates/commands/gitflow/2-status.md +277 -277
- package/templates/commands/gitflow/3-commit.md +344 -344
- package/templates/commands/gitflow/4-plan.md +145 -145
- package/templates/commands/gitflow/5-exec.md +147 -147
- package/templates/commands/gitflow/6-abort.md +344 -344
- package/templates/commands/gitflow/7-pull-request.md +453 -355
- package/templates/commands/gitflow/8-review.md +240 -176
- package/templates/commands/gitflow/9-merge.md +451 -365
- package/templates/commands/gitflow.md +128 -128
- package/templates/commands/implement.md +663 -663
- package/templates/commands/init.md +567 -562
- package/templates/commands/mcp-integration.md +330 -330
- package/templates/commands/notification.md +129 -129
- package/templates/commands/oneshot.md +57 -57
- package/templates/commands/quick-search.md +72 -72
- package/templates/commands/ralph-loop/cancel-ralph.md +18 -18
- package/templates/commands/ralph-loop/help.md +126 -126
- package/templates/commands/ralph-loop/ralph-loop.md +18 -18
- package/templates/commands/review.md +106 -106
- package/templates/commands/utils/test-web-config.md +160 -160
- package/templates/commands/utils/test-web.md +151 -151
- package/templates/commands/validate.md +233 -233
- package/templates/commands/workflow.md +193 -193
- package/templates/gitflow/config.json +138 -138
- package/templates/hooks/ef-migration-check.md +139 -139
- package/templates/hooks/hooks.json +25 -25
- package/templates/hooks/stop-hook.sh +177 -177
- package/templates/skills/ai-prompt/SKILL.md +778 -778
- package/templates/skills/application/SKILL.md +563 -563
- package/templates/skills/application/templates-backend.md +450 -450
- package/templates/skills/application/templates-frontend.md +531 -531
- package/templates/skills/application/templates-i18n.md +520 -520
- package/templates/skills/application/templates-seed.md +647 -647
- package/templates/skills/business-analyse/SKILL.md +191 -191
- package/templates/skills/business-analyse/questionnaire.md +283 -283
- package/templates/skills/business-analyse/templates-frd.md +477 -477
- package/templates/skills/business-analyse/templates-react.md +580 -580
- package/templates/skills/controller/SKILL.md +240 -240
- package/templates/skills/controller/postman-templates.md +614 -614
- package/templates/skills/controller/templates.md +1468 -1468
- package/templates/skills/documentation/SKILL.md +133 -133
- package/templates/skills/documentation/templates.md +476 -476
- package/templates/skills/feature-full/SKILL.md +838 -838
- package/templates/skills/notification/SKILL.md +555 -555
- package/templates/skills/ui-components/SKILL.md +870 -870
- package/templates/skills/workflow/SKILL.md +582 -582
- package/templates/test-web/api-health.json +38 -38
- package/templates/test-web/minimal.json +19 -19
- package/templates/test-web/npm-package.json +46 -46
- package/templates/test-web/seo-check.json +54 -54
|
@@ -1,432 +1,432 @@
|
|
|
1
|
-
# Templates de Documentation
|
|
2
|
-
|
|
3
|
-
## Template User Module
|
|
4
|
-
|
|
5
|
-
```tsx
|
|
6
|
-
// web/smartstack-web/src/pages/docs/user/{context}/{ModuleName}DocPage.tsx
|
|
7
|
-
|
|
8
|
-
import { Link } from 'react-router-dom';
|
|
9
|
-
import { useTranslation } from 'react-i18next';
|
|
10
|
-
import { ArrowRight, ChevronRight, CheckCircle, AlertTriangle } from 'lucide-react';
|
|
11
|
-
|
|
12
|
-
// MOCK DATA - Données fictives pour illustrer l'interface
|
|
13
|
-
const mockData = {
|
|
14
|
-
items: [
|
|
15
|
-
{ id: 1, name: 'Item 1', status: 'active', value: 125 },
|
|
16
|
-
{ id: 2, name: 'Item 2', status: 'pending', value: 89 },
|
|
17
|
-
],
|
|
18
|
-
stats: { total: 256, active: 180, pending: 52, warning: 24 },
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export function {ModuleName}DocPage() {
|
|
22
|
-
const { t } = useTranslation('docs');
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<div className="space-y-8">
|
|
26
|
-
{/* 1. BREADCRUMB */}
|
|
27
|
-
<div className="flex items-center gap-2 text-sm text-[var(--text-secondary)]">
|
|
28
|
-
<Link to="/docs" className="hover:text-[var(--color-primary-600)]">
|
|
29
|
-
{t('breadcrumb.documentation')}
|
|
30
|
-
</Link>
|
|
31
|
-
<span>/</span>
|
|
32
|
-
<Link to="/docs/user" className="hover:text-[var(--color-primary-600)]">
|
|
33
|
-
{t('breadcrumb.user')}
|
|
34
|
-
</Link>
|
|
35
|
-
<span>/</span>
|
|
36
|
-
<span>{t('breadcrumb.moduleName')}</span>
|
|
37
|
-
</div>
|
|
38
|
-
|
|
39
|
-
{/* 2. HEADER */}
|
|
40
|
-
<div>
|
|
41
|
-
<h1 className="text-3xl font-bold mb-4 flex items-center gap-3">
|
|
42
|
-
<IconName className="w-8 h-8 text-[var(--color-primary-600)]" />
|
|
43
|
-
{t('module.moduleName.title')}
|
|
44
|
-
</h1>
|
|
45
|
-
<p className="text-lg text-[var(--text-secondary)]">
|
|
46
|
-
{t('module.moduleName.subtitle')}
|
|
47
|
-
</p>
|
|
48
|
-
</div>
|
|
49
|
-
|
|
50
|
-
{/* 3. TABLE DES MATIÈRES */}
|
|
51
|
-
<div className="card p-4">
|
|
52
|
-
<h2 className="font-semibold mb-3">{t('common.tableOfContents')}</h2>
|
|
53
|
-
<nav className="grid grid-cols-2 md:grid-cols-3 gap-2">
|
|
54
|
-
{['introduction', 'access', 'overview', 'features', 'faq', 'api'].map((section) => (
|
|
55
|
-
<a key={section} href={`#${section}`} className="flex items-center gap-2 p-2 rounded hover:bg-[var(--bg-secondary)]">
|
|
56
|
-
<ChevronRight className="w-4 h-4 text-[var(--color-primary-600)]" />
|
|
57
|
-
{t(`module.moduleName.sections.${section}.title`)}
|
|
58
|
-
</a>
|
|
59
|
-
))}
|
|
60
|
-
</nav>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
{/* 4. SECTIONS NUMÉROTÉES */}
|
|
64
|
-
<section id="introduction" className="scroll-mt-4">
|
|
65
|
-
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
|
|
66
|
-
<span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">1</span>
|
|
67
|
-
{t('module.moduleName.sections.introduction.title')}
|
|
68
|
-
</h2>
|
|
69
|
-
<div className="card p-6">
|
|
70
|
-
{/* Contenu de la section */}
|
|
71
|
-
</div>
|
|
72
|
-
</section>
|
|
73
|
-
|
|
74
|
-
{/* 5. MAQUETTE UI AVEC MOCK DATA */}
|
|
75
|
-
<section id="overview" className="scroll-mt-4">
|
|
76
|
-
<div className="card p-6">
|
|
77
|
-
<div className="border-2 border-dashed border-[var(--border-color)] rounded-lg p-4">
|
|
78
|
-
<div className="text-xs text-[var(--text-tertiary)] mb-4 text-center">
|
|
79
|
-
{t('common.mockupPreview')}
|
|
80
|
-
</div>
|
|
81
|
-
{/* Stats Cards */}
|
|
82
|
-
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
83
|
-
<div className="p-4 rounded-lg bg-[var(--bg-secondary)] text-center">
|
|
84
|
-
<div className="text-2xl font-bold text-[var(--color-primary-600)]">{mockData.stats.total}</div>
|
|
85
|
-
<div className="text-sm text-[var(--text-secondary)]">{t('common.total')}</div>
|
|
86
|
-
</div>
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
</section>
|
|
91
|
-
|
|
92
|
-
{/* 6. FAQ */}
|
|
93
|
-
<section id="faq" className="scroll-mt-4">
|
|
94
|
-
<div className="space-y-4">
|
|
95
|
-
{[1, 2, 3].map((i) => (
|
|
96
|
-
<div key={i} className="card p-4">
|
|
97
|
-
<h3 className="font-medium mb-2">{t(`module.moduleName.faq.q${i}.question`)}</h3>
|
|
98
|
-
<p className="text-sm text-[var(--text-secondary)]">{t(`module.moduleName.faq.q${i}.answer`)}</p>
|
|
99
|
-
</div>
|
|
100
|
-
))}
|
|
101
|
-
</div>
|
|
102
|
-
</section>
|
|
103
|
-
|
|
104
|
-
{/* 7. NAVIGATION FOOTER */}
|
|
105
|
-
<div className="flex justify-between pt-6 border-t border-[var(--border-color)]">
|
|
106
|
-
<Link to="/docs/user/previous" className="flex items-center gap-2 text-[var(--text-secondary)] hover:text-[var(--color-primary-600)]">
|
|
107
|
-
<ArrowRight className="w-4 h-4 rotate-180" />
|
|
108
|
-
{t('nav.previous')}
|
|
109
|
-
</Link>
|
|
110
|
-
<Link to="/docs/user/next" className="flex items-center gap-2 text-[var(--color-primary-600)]">
|
|
111
|
-
{t('nav.next')}
|
|
112
|
-
<ArrowRight className="w-4 h-4" />
|
|
113
|
-
</Link>
|
|
114
|
-
</div>
|
|
115
|
-
</div>
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Template Developer Tool
|
|
121
|
-
|
|
122
|
-
```tsx
|
|
123
|
-
// web/smartstack-web/src/pages/docs/developer/tools/{ToolName}Page.tsx
|
|
124
|
-
|
|
125
|
-
import { Link } from 'react-router-dom';
|
|
126
|
-
import { useTranslation } from 'react-i18next';
|
|
127
|
-
import { Terminal, CheckCircle, Copy, ExternalLink } from 'lucide-react';
|
|
128
|
-
import { useState } from 'react';
|
|
129
|
-
|
|
130
|
-
function CodeBlock({ code, language = 'bash' }: { code: string; language?: string }) {
|
|
131
|
-
const [copied, setCopied] = useState(false);
|
|
132
|
-
const handleCopy = () => {
|
|
133
|
-
navigator.clipboard.writeText(code);
|
|
134
|
-
setCopied(true);
|
|
135
|
-
setTimeout(() => setCopied(false), 2000);
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
return (
|
|
139
|
-
<div className="relative group">
|
|
140
|
-
<pre className="bg-[var(--bg-tertiary)] p-4 rounded-lg overflow-x-auto text-sm font-mono">
|
|
141
|
-
<code>{code}</code>
|
|
142
|
-
</pre>
|
|
143
|
-
<button onClick={handleCopy} className="absolute top-2 right-2 p-2 rounded bg-[var(--bg-secondary)] opacity-0 group-hover:opacity-100">
|
|
144
|
-
{copied ? <CheckCircle className="w-4 h-4 text-green-500" /> : <Copy className="w-4 h-4" />}
|
|
145
|
-
</button>
|
|
146
|
-
</div>
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export function {ToolName}Page() {
|
|
151
|
-
const { t } = useTranslation('docs');
|
|
152
|
-
|
|
153
|
-
return (
|
|
154
|
-
<div className="space-y-8">
|
|
155
|
-
{/* Breadcrumb */}
|
|
156
|
-
<div className="flex items-center gap-2 text-sm text-[var(--text-secondary)]">
|
|
157
|
-
<Link to="/docs">Documentation</Link>
|
|
158
|
-
<span>/</span>
|
|
159
|
-
<Link to="/docs/developer">Developer</Link>
|
|
160
|
-
<span>/</span>
|
|
161
|
-
<Link to="/docs/developer/tools">Tools</Link>
|
|
162
|
-
<span>/</span>
|
|
163
|
-
<span>{t('developer.tools.toolName.title')}</span>
|
|
164
|
-
</div>
|
|
165
|
-
|
|
166
|
-
{/* Header avec badges */}
|
|
167
|
-
<div>
|
|
168
|
-
<h1 className="text-3xl font-bold mb-4 flex items-center gap-3">
|
|
169
|
-
<Terminal className="w-8 h-8 text-[var(--color-primary-600)]" />
|
|
170
|
-
{t('developer.tools.toolName.title')}
|
|
171
|
-
</h1>
|
|
172
|
-
<div className="flex gap-2 mt-4">
|
|
173
|
-
<span className="px-3 py-1 rounded-full bg-green-500/10 text-green-600 text-sm">Gratuit</span>
|
|
174
|
-
<span className="px-3 py-1 rounded-full bg-blue-500/10 text-blue-600 text-sm">.NET</span>
|
|
175
|
-
</div>
|
|
176
|
-
</div>
|
|
177
|
-
|
|
178
|
-
{/* Sections: Prérequis, Installation, Configuration, Usage, CI/CD */}
|
|
179
|
-
<section id="installation">
|
|
180
|
-
<h2 className="text-xl font-semibold mb-4">Installation</h2>
|
|
181
|
-
<CodeBlock code="dotnet add package ToolName" />
|
|
182
|
-
</section>
|
|
183
|
-
|
|
184
|
-
{/* Liens externes */}
|
|
185
|
-
<div className="card p-4 bg-blue-500/5 border border-blue-500/20">
|
|
186
|
-
<div className="flex items-center gap-2 mb-2">
|
|
187
|
-
<ExternalLink className="w-4 h-4 text-blue-600" />
|
|
188
|
-
<span className="font-medium">Ressources</span>
|
|
189
|
-
</div>
|
|
190
|
-
<div className="flex gap-4">
|
|
191
|
-
<a href="#" className="text-blue-600 hover:underline text-sm">Documentation officielle</a>
|
|
192
|
-
<a href="#" className="text-blue-600 hover:underline text-sm">GitHub</a>
|
|
193
|
-
</div>
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
## Template Database Schema (avec MCD en HTML)
|
|
201
|
-
|
|
202
|
-
```tsx
|
|
203
|
-
// web/smartstack-web/src/pages/docs/developer/database/{SchemaName}SchemaPage.tsx
|
|
204
|
-
|
|
205
|
-
import { Link } from 'react-router-dom';
|
|
206
|
-
import { Database, Table, Key, Link2, ArrowRight } from 'lucide-react';
|
|
207
|
-
|
|
208
|
-
const schemaData = {
|
|
209
|
-
name: 'schema_name',
|
|
210
|
-
tables: [
|
|
211
|
-
{
|
|
212
|
-
name: 'TableName',
|
|
213
|
-
columns: [
|
|
214
|
-
{ name: 'Id', type: 'UNIQUEIDENTIFIER', isPK: true, isFK: false, required: true, description: 'Identifiant unique' },
|
|
215
|
-
{ name: 'ForeignId', type: 'UNIQUEIDENTIFIER', isPK: false, isFK: true, fkTable: 'OtherTable', required: true, description: 'Référence vers OtherTable' },
|
|
216
|
-
],
|
|
217
|
-
relations: [
|
|
218
|
-
{ type: '1:N', target: 'ChildTable', description: 'Une entrée a plusieurs enfants' },
|
|
219
|
-
]
|
|
220
|
-
},
|
|
221
|
-
]
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
// Composant pour afficher une table dans le diagramme MCD
|
|
225
|
-
function McdTableCard({ table, schema }: { table: typeof schemaData.tables[0]; schema: string }) {
|
|
226
|
-
return (
|
|
227
|
-
<div className="card p-4 min-w-[200px]">
|
|
228
|
-
<div className="flex items-center gap-2 mb-3 pb-2 border-b border-[var(--border-color)]">
|
|
229
|
-
<Table className="w-4 h-4 text-[var(--color-primary-600)]" />
|
|
230
|
-
<span className="font-semibold">{schema}.{table.name}</span>
|
|
231
|
-
</div>
|
|
232
|
-
<div className="space-y-1 text-sm">
|
|
233
|
-
{table.columns.map((col) => (
|
|
234
|
-
<div key={col.name} className="flex items-center gap-2">
|
|
235
|
-
{col.isPK && <Key className="w-3 h-3 text-amber-500" />}
|
|
236
|
-
{col.isFK && <Link2 className="w-3 h-3 text-blue-500" />}
|
|
237
|
-
{!col.isPK && !col.isFK && <span className="w-3" />}
|
|
238
|
-
<span className={`font-mono text-xs ${col.isPK ? 'font-bold' : ''}`}>
|
|
239
|
-
{col.name}
|
|
240
|
-
</span>
|
|
241
|
-
{col.required && <span className="text-red-500">*</span>}
|
|
242
|
-
</div>
|
|
243
|
-
))}
|
|
244
|
-
</div>
|
|
245
|
-
</div>
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Composant pour afficher une relation entre tables
|
|
250
|
-
function McdRelation({ from, to, type, description }: { from: string; to: string; type: string; description: string }) {
|
|
251
|
-
return (
|
|
252
|
-
<div className="flex items-center gap-4 py-2">
|
|
253
|
-
<span className="font-mono text-sm bg-[var(--bg-secondary)] px-2 py-1 rounded">{from}</span>
|
|
254
|
-
<div className="flex items-center gap-2">
|
|
255
|
-
<div className="w-8 h-0.5 bg-[var(--border-color)]" />
|
|
256
|
-
<span className="px-2 py-0.5 rounded bg-purple-500/10 text-purple-600 text-xs font-medium">{type}</span>
|
|
257
|
-
<ArrowRight className="w-4 h-4 text-[var(--text-tertiary)]" />
|
|
258
|
-
</div>
|
|
259
|
-
<span className="font-mono text-sm bg-[var(--bg-secondary)] px-2 py-1 rounded">{to}</span>
|
|
260
|
-
<span className="text-sm text-[var(--text-secondary)]">{description}</span>
|
|
261
|
-
</div>
|
|
262
|
-
);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
export function {SchemaName}SchemaPage() {
|
|
266
|
-
return (
|
|
267
|
-
<div className="space-y-8">
|
|
268
|
-
{/* Section MCD - Diagramme HTML */}
|
|
269
|
-
<section id="mcd">
|
|
270
|
-
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
|
|
271
|
-
<span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">1</span>
|
|
272
|
-
Modèle Conceptuel de Données (MCD)
|
|
273
|
-
</h2>
|
|
274
|
-
<div className="card p-6">
|
|
275
|
-
{/* Diagramme visuel des tables */}
|
|
276
|
-
<div className="flex flex-wrap gap-6 justify-center mb-8">
|
|
277
|
-
{schemaData.tables.map((table) => (
|
|
278
|
-
<McdTableCard key={table.name} table={table} schema={schemaData.name} />
|
|
279
|
-
))}
|
|
280
|
-
</div>
|
|
281
|
-
|
|
282
|
-
{/* Relations entre tables */}
|
|
283
|
-
<div className="border-t border-[var(--border-color)] pt-4">
|
|
284
|
-
<h4 className="font-medium mb-3 text-sm text-[var(--text-secondary)]">Relations</h4>
|
|
285
|
-
<div className="space-y-2">
|
|
286
|
-
{schemaData.tables.flatMap((table) =>
|
|
287
|
-
table.relations.map((rel, idx) => (
|
|
288
|
-
<McdRelation
|
|
289
|
-
key={`${table.name}-${idx}`}
|
|
290
|
-
from={table.name}
|
|
291
|
-
to={rel.target}
|
|
292
|
-
type={rel.type}
|
|
293
|
-
description={rel.description}
|
|
294
|
-
/>
|
|
295
|
-
))
|
|
296
|
-
)}
|
|
297
|
-
</div>
|
|
298
|
-
</div>
|
|
299
|
-
|
|
300
|
-
{/* Légende */}
|
|
301
|
-
<div className="mt-6 pt-4 border-t border-[var(--border-color)] flex flex-wrap gap-4 text-xs text-[var(--text-secondary)]">
|
|
302
|
-
<div className="flex items-center gap-1">
|
|
303
|
-
<Key className="w-3 h-3 text-amber-500" /> PK = Clé primaire
|
|
304
|
-
</div>
|
|
305
|
-
<div className="flex items-center gap-1">
|
|
306
|
-
<Link2 className="w-3 h-3 text-blue-500" /> FK = Clé étrangère
|
|
307
|
-
</div>
|
|
308
|
-
<div className="flex items-center gap-1">
|
|
309
|
-
<span className="text-red-500">*</span> = Obligatoire
|
|
310
|
-
</div>
|
|
311
|
-
</div>
|
|
312
|
-
</div>
|
|
313
|
-
</section>
|
|
314
|
-
|
|
315
|
-
{/* Section Tables détaillées */}
|
|
316
|
-
<section id="tables">
|
|
317
|
-
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
|
|
318
|
-
<span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">2</span>
|
|
319
|
-
Tables détaillées
|
|
320
|
-
</h2>
|
|
321
|
-
{schemaData.tables.map((table) => (
|
|
322
|
-
<div key={table.name} className="card p-6 mb-4">
|
|
323
|
-
<h3 className="font-semibold flex items-center gap-2 mb-4">
|
|
324
|
-
<Table className="w-5 h-5 text-[var(--color-primary-600)]" />
|
|
325
|
-
{schemaData.name}.{table.name}
|
|
326
|
-
</h3>
|
|
327
|
-
<div className="overflow-x-auto">
|
|
328
|
-
<table className="w-full text-sm">
|
|
329
|
-
<thead>
|
|
330
|
-
<tr className="bg-[var(--bg-secondary)]">
|
|
331
|
-
<th className="text-left py-2 px-3 rounded-tl-lg">Colonne</th>
|
|
332
|
-
<th className="text-left py-2 px-3">Type SQL</th>
|
|
333
|
-
<th className="text-left py-2 px-3">Clés</th>
|
|
334
|
-
<th className="text-left py-2 px-3 rounded-tr-lg">Description</th>
|
|
335
|
-
</tr>
|
|
336
|
-
</thead>
|
|
337
|
-
<tbody>
|
|
338
|
-
{table.columns.map((col, idx) => (
|
|
339
|
-
<tr key={col.name} className={idx % 2 === 1 ? 'bg-[var(--bg-secondary)]/50' : ''}>
|
|
340
|
-
<td className="py-2 px-3 font-mono text-sm">
|
|
341
|
-
{col.name}
|
|
342
|
-
{col.required && <span className="text-red-500 ml-1">*</span>}
|
|
343
|
-
</td>
|
|
344
|
-
<td className="py-2 px-3 text-[var(--text-secondary)]">{col.type}</td>
|
|
345
|
-
<td className="py-2 px-3">
|
|
346
|
-
{col.isPK && (
|
|
347
|
-
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded bg-amber-500/10 text-amber-600 text-xs mr-1">
|
|
348
|
-
<Key className="w-3 h-3" /> PK
|
|
349
|
-
</span>
|
|
350
|
-
)}
|
|
351
|
-
{col.isFK && (
|
|
352
|
-
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded bg-blue-500/10 text-blue-600 text-xs">
|
|
353
|
-
<Link2 className="w-3 h-3" /> FK
|
|
354
|
-
</span>
|
|
355
|
-
)}
|
|
356
|
-
</td>
|
|
357
|
-
<td className="py-2 px-3 text-[var(--text-secondary)]">{col.description}</td>
|
|
358
|
-
</tr>
|
|
359
|
-
))}
|
|
360
|
-
</tbody>
|
|
361
|
-
</table>
|
|
362
|
-
</div>
|
|
363
|
-
|
|
364
|
-
{/* Relations de cette table */}
|
|
365
|
-
{table.relations.length > 0 && (
|
|
366
|
-
<div className="mt-4 pt-4 border-t border-[var(--border-color)]">
|
|
367
|
-
<h4 className="font-medium mb-2 text-sm">Relations</h4>
|
|
368
|
-
<div className="flex flex-wrap gap-2">
|
|
369
|
-
{table.relations.map((rel, idx) => (
|
|
370
|
-
<div key={idx} className="flex items-center gap-2 px-3 py-1 rounded-lg bg-[var(--bg-secondary)] text-sm">
|
|
371
|
-
<span className="font-mono text-[var(--color-primary-600)]">{rel.type}</span>
|
|
372
|
-
<ArrowRight className="w-4 h-4 text-[var(--text-tertiary)]" />
|
|
373
|
-
<span>{rel.target}</span>
|
|
374
|
-
</div>
|
|
375
|
-
))}
|
|
376
|
-
</div>
|
|
377
|
-
</div>
|
|
378
|
-
)}
|
|
379
|
-
</div>
|
|
380
|
-
))}
|
|
381
|
-
</section>
|
|
382
|
-
</div>
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
## Patterns Réutilisables
|
|
388
|
-
|
|
389
|
-
### Stats Cards
|
|
390
|
-
```tsx
|
|
391
|
-
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
392
|
-
<div className="p-4 rounded-lg bg-[var(--bg-secondary)] text-center">
|
|
393
|
-
<div className="text-2xl font-bold text-[var(--color-primary-600)]">{value}</div>
|
|
394
|
-
<div className="text-sm text-[var(--text-secondary)]">{label}</div>
|
|
395
|
-
</div>
|
|
396
|
-
</div>
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### Badges de statut
|
|
400
|
-
```tsx
|
|
401
|
-
const statusColors = {
|
|
402
|
-
active: 'bg-green-500/10 text-green-600',
|
|
403
|
-
pending: 'bg-yellow-500/10 text-yellow-600',
|
|
404
|
-
error: 'bg-red-500/10 text-red-600',
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
<span className={`px-2 py-1 rounded text-xs ${statusColors[status]}`}>{status}</span>
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
### Section numérotée
|
|
411
|
-
```tsx
|
|
412
|
-
<section id="section-id" className="scroll-mt-4">
|
|
413
|
-
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
|
|
414
|
-
<span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">
|
|
415
|
-
{number}
|
|
416
|
-
</span>
|
|
417
|
-
{title}
|
|
418
|
-
</h2>
|
|
419
|
-
<div className="card p-6">{children}</div>
|
|
420
|
-
</section>
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
### Alert/Info Box
|
|
424
|
-
```tsx
|
|
425
|
-
<div className="p-4 rounded-lg bg-amber-500/10 border border-amber-500/20 flex items-start gap-3">
|
|
426
|
-
<AlertTriangle className="w-5 h-5 text-amber-600 flex-shrink-0" />
|
|
427
|
-
<div>
|
|
428
|
-
<div className="font-medium text-amber-600">Attention</div>
|
|
429
|
-
<p className="text-sm text-[var(--text-secondary)]">{message}</p>
|
|
430
|
-
</div>
|
|
431
|
-
</div>
|
|
432
|
-
```
|
|
1
|
+
# Templates de Documentation
|
|
2
|
+
|
|
3
|
+
## Template User Module
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
// web/smartstack-web/src/pages/docs/user/{context}/{ModuleName}DocPage.tsx
|
|
7
|
+
|
|
8
|
+
import { Link } from 'react-router-dom';
|
|
9
|
+
import { useTranslation } from 'react-i18next';
|
|
10
|
+
import { ArrowRight, ChevronRight, CheckCircle, AlertTriangle } from 'lucide-react';
|
|
11
|
+
|
|
12
|
+
// MOCK DATA - Données fictives pour illustrer l'interface
|
|
13
|
+
const mockData = {
|
|
14
|
+
items: [
|
|
15
|
+
{ id: 1, name: 'Item 1', status: 'active', value: 125 },
|
|
16
|
+
{ id: 2, name: 'Item 2', status: 'pending', value: 89 },
|
|
17
|
+
],
|
|
18
|
+
stats: { total: 256, active: 180, pending: 52, warning: 24 },
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export function {ModuleName}DocPage() {
|
|
22
|
+
const { t } = useTranslation('docs');
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div className="space-y-8">
|
|
26
|
+
{/* 1. BREADCRUMB */}
|
|
27
|
+
<div className="flex items-center gap-2 text-sm text-[var(--text-secondary)]">
|
|
28
|
+
<Link to="/docs" className="hover:text-[var(--color-primary-600)]">
|
|
29
|
+
{t('breadcrumb.documentation')}
|
|
30
|
+
</Link>
|
|
31
|
+
<span>/</span>
|
|
32
|
+
<Link to="/docs/user" className="hover:text-[var(--color-primary-600)]">
|
|
33
|
+
{t('breadcrumb.user')}
|
|
34
|
+
</Link>
|
|
35
|
+
<span>/</span>
|
|
36
|
+
<span>{t('breadcrumb.moduleName')}</span>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
{/* 2. HEADER */}
|
|
40
|
+
<div>
|
|
41
|
+
<h1 className="text-3xl font-bold mb-4 flex items-center gap-3">
|
|
42
|
+
<IconName className="w-8 h-8 text-[var(--color-primary-600)]" />
|
|
43
|
+
{t('module.moduleName.title')}
|
|
44
|
+
</h1>
|
|
45
|
+
<p className="text-lg text-[var(--text-secondary)]">
|
|
46
|
+
{t('module.moduleName.subtitle')}
|
|
47
|
+
</p>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
{/* 3. TABLE DES MATIÈRES */}
|
|
51
|
+
<div className="card p-4">
|
|
52
|
+
<h2 className="font-semibold mb-3">{t('common.tableOfContents')}</h2>
|
|
53
|
+
<nav className="grid grid-cols-2 md:grid-cols-3 gap-2">
|
|
54
|
+
{['introduction', 'access', 'overview', 'features', 'faq', 'api'].map((section) => (
|
|
55
|
+
<a key={section} href={`#${section}`} className="flex items-center gap-2 p-2 rounded hover:bg-[var(--bg-secondary)]">
|
|
56
|
+
<ChevronRight className="w-4 h-4 text-[var(--color-primary-600)]" />
|
|
57
|
+
{t(`module.moduleName.sections.${section}.title`)}
|
|
58
|
+
</a>
|
|
59
|
+
))}
|
|
60
|
+
</nav>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
{/* 4. SECTIONS NUMÉROTÉES */}
|
|
64
|
+
<section id="introduction" className="scroll-mt-4">
|
|
65
|
+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
|
|
66
|
+
<span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">1</span>
|
|
67
|
+
{t('module.moduleName.sections.introduction.title')}
|
|
68
|
+
</h2>
|
|
69
|
+
<div className="card p-6">
|
|
70
|
+
{/* Contenu de la section */}
|
|
71
|
+
</div>
|
|
72
|
+
</section>
|
|
73
|
+
|
|
74
|
+
{/* 5. MAQUETTE UI AVEC MOCK DATA */}
|
|
75
|
+
<section id="overview" className="scroll-mt-4">
|
|
76
|
+
<div className="card p-6">
|
|
77
|
+
<div className="border-2 border-dashed border-[var(--border-color)] rounded-lg p-4">
|
|
78
|
+
<div className="text-xs text-[var(--text-tertiary)] mb-4 text-center">
|
|
79
|
+
{t('common.mockupPreview')}
|
|
80
|
+
</div>
|
|
81
|
+
{/* Stats Cards */}
|
|
82
|
+
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
83
|
+
<div className="p-4 rounded-lg bg-[var(--bg-secondary)] text-center">
|
|
84
|
+
<div className="text-2xl font-bold text-[var(--color-primary-600)]">{mockData.stats.total}</div>
|
|
85
|
+
<div className="text-sm text-[var(--text-secondary)]">{t('common.total')}</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</section>
|
|
91
|
+
|
|
92
|
+
{/* 6. FAQ */}
|
|
93
|
+
<section id="faq" className="scroll-mt-4">
|
|
94
|
+
<div className="space-y-4">
|
|
95
|
+
{[1, 2, 3].map((i) => (
|
|
96
|
+
<div key={i} className="card p-4">
|
|
97
|
+
<h3 className="font-medium mb-2">{t(`module.moduleName.faq.q${i}.question`)}</h3>
|
|
98
|
+
<p className="text-sm text-[var(--text-secondary)]">{t(`module.moduleName.faq.q${i}.answer`)}</p>
|
|
99
|
+
</div>
|
|
100
|
+
))}
|
|
101
|
+
</div>
|
|
102
|
+
</section>
|
|
103
|
+
|
|
104
|
+
{/* 7. NAVIGATION FOOTER */}
|
|
105
|
+
<div className="flex justify-between pt-6 border-t border-[var(--border-color)]">
|
|
106
|
+
<Link to="/docs/user/previous" className="flex items-center gap-2 text-[var(--text-secondary)] hover:text-[var(--color-primary-600)]">
|
|
107
|
+
<ArrowRight className="w-4 h-4 rotate-180" />
|
|
108
|
+
{t('nav.previous')}
|
|
109
|
+
</Link>
|
|
110
|
+
<Link to="/docs/user/next" className="flex items-center gap-2 text-[var(--color-primary-600)]">
|
|
111
|
+
{t('nav.next')}
|
|
112
|
+
<ArrowRight className="w-4 h-4" />
|
|
113
|
+
</Link>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Template Developer Tool
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
// web/smartstack-web/src/pages/docs/developer/tools/{ToolName}Page.tsx
|
|
124
|
+
|
|
125
|
+
import { Link } from 'react-router-dom';
|
|
126
|
+
import { useTranslation } from 'react-i18next';
|
|
127
|
+
import { Terminal, CheckCircle, Copy, ExternalLink } from 'lucide-react';
|
|
128
|
+
import { useState } from 'react';
|
|
129
|
+
|
|
130
|
+
function CodeBlock({ code, language = 'bash' }: { code: string; language?: string }) {
|
|
131
|
+
const [copied, setCopied] = useState(false);
|
|
132
|
+
const handleCopy = () => {
|
|
133
|
+
navigator.clipboard.writeText(code);
|
|
134
|
+
setCopied(true);
|
|
135
|
+
setTimeout(() => setCopied(false), 2000);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<div className="relative group">
|
|
140
|
+
<pre className="bg-[var(--bg-tertiary)] p-4 rounded-lg overflow-x-auto text-sm font-mono">
|
|
141
|
+
<code>{code}</code>
|
|
142
|
+
</pre>
|
|
143
|
+
<button onClick={handleCopy} className="absolute top-2 right-2 p-2 rounded bg-[var(--bg-secondary)] opacity-0 group-hover:opacity-100">
|
|
144
|
+
{copied ? <CheckCircle className="w-4 h-4 text-green-500" /> : <Copy className="w-4 h-4" />}
|
|
145
|
+
</button>
|
|
146
|
+
</div>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function {ToolName}Page() {
|
|
151
|
+
const { t } = useTranslation('docs');
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<div className="space-y-8">
|
|
155
|
+
{/* Breadcrumb */}
|
|
156
|
+
<div className="flex items-center gap-2 text-sm text-[var(--text-secondary)]">
|
|
157
|
+
<Link to="/docs">Documentation</Link>
|
|
158
|
+
<span>/</span>
|
|
159
|
+
<Link to="/docs/developer">Developer</Link>
|
|
160
|
+
<span>/</span>
|
|
161
|
+
<Link to="/docs/developer/tools">Tools</Link>
|
|
162
|
+
<span>/</span>
|
|
163
|
+
<span>{t('developer.tools.toolName.title')}</span>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
{/* Header avec badges */}
|
|
167
|
+
<div>
|
|
168
|
+
<h1 className="text-3xl font-bold mb-4 flex items-center gap-3">
|
|
169
|
+
<Terminal className="w-8 h-8 text-[var(--color-primary-600)]" />
|
|
170
|
+
{t('developer.tools.toolName.title')}
|
|
171
|
+
</h1>
|
|
172
|
+
<div className="flex gap-2 mt-4">
|
|
173
|
+
<span className="px-3 py-1 rounded-full bg-green-500/10 text-green-600 text-sm">Gratuit</span>
|
|
174
|
+
<span className="px-3 py-1 rounded-full bg-blue-500/10 text-blue-600 text-sm">.NET</span>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
{/* Sections: Prérequis, Installation, Configuration, Usage, CI/CD */}
|
|
179
|
+
<section id="installation">
|
|
180
|
+
<h2 className="text-xl font-semibold mb-4">Installation</h2>
|
|
181
|
+
<CodeBlock code="dotnet add package ToolName" />
|
|
182
|
+
</section>
|
|
183
|
+
|
|
184
|
+
{/* Liens externes */}
|
|
185
|
+
<div className="card p-4 bg-blue-500/5 border border-blue-500/20">
|
|
186
|
+
<div className="flex items-center gap-2 mb-2">
|
|
187
|
+
<ExternalLink className="w-4 h-4 text-blue-600" />
|
|
188
|
+
<span className="font-medium">Ressources</span>
|
|
189
|
+
</div>
|
|
190
|
+
<div className="flex gap-4">
|
|
191
|
+
<a href="#" className="text-blue-600 hover:underline text-sm">Documentation officielle</a>
|
|
192
|
+
<a href="#" className="text-blue-600 hover:underline text-sm">GitHub</a>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Template Database Schema (avec MCD en HTML)
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
// web/smartstack-web/src/pages/docs/developer/database/{SchemaName}SchemaPage.tsx
|
|
204
|
+
|
|
205
|
+
import { Link } from 'react-router-dom';
|
|
206
|
+
import { Database, Table, Key, Link2, ArrowRight } from 'lucide-react';
|
|
207
|
+
|
|
208
|
+
const schemaData = {
|
|
209
|
+
name: 'schema_name',
|
|
210
|
+
tables: [
|
|
211
|
+
{
|
|
212
|
+
name: 'TableName',
|
|
213
|
+
columns: [
|
|
214
|
+
{ name: 'Id', type: 'UNIQUEIDENTIFIER', isPK: true, isFK: false, required: true, description: 'Identifiant unique' },
|
|
215
|
+
{ name: 'ForeignId', type: 'UNIQUEIDENTIFIER', isPK: false, isFK: true, fkTable: 'OtherTable', required: true, description: 'Référence vers OtherTable' },
|
|
216
|
+
],
|
|
217
|
+
relations: [
|
|
218
|
+
{ type: '1:N', target: 'ChildTable', description: 'Une entrée a plusieurs enfants' },
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
]
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
// Composant pour afficher une table dans le diagramme MCD
|
|
225
|
+
function McdTableCard({ table, schema }: { table: typeof schemaData.tables[0]; schema: string }) {
|
|
226
|
+
return (
|
|
227
|
+
<div className="card p-4 min-w-[200px]">
|
|
228
|
+
<div className="flex items-center gap-2 mb-3 pb-2 border-b border-[var(--border-color)]">
|
|
229
|
+
<Table className="w-4 h-4 text-[var(--color-primary-600)]" />
|
|
230
|
+
<span className="font-semibold">{schema}.{table.name}</span>
|
|
231
|
+
</div>
|
|
232
|
+
<div className="space-y-1 text-sm">
|
|
233
|
+
{table.columns.map((col) => (
|
|
234
|
+
<div key={col.name} className="flex items-center gap-2">
|
|
235
|
+
{col.isPK && <Key className="w-3 h-3 text-amber-500" />}
|
|
236
|
+
{col.isFK && <Link2 className="w-3 h-3 text-blue-500" />}
|
|
237
|
+
{!col.isPK && !col.isFK && <span className="w-3" />}
|
|
238
|
+
<span className={`font-mono text-xs ${col.isPK ? 'font-bold' : ''}`}>
|
|
239
|
+
{col.name}
|
|
240
|
+
</span>
|
|
241
|
+
{col.required && <span className="text-red-500">*</span>}
|
|
242
|
+
</div>
|
|
243
|
+
))}
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Composant pour afficher une relation entre tables
|
|
250
|
+
function McdRelation({ from, to, type, description }: { from: string; to: string; type: string; description: string }) {
|
|
251
|
+
return (
|
|
252
|
+
<div className="flex items-center gap-4 py-2">
|
|
253
|
+
<span className="font-mono text-sm bg-[var(--bg-secondary)] px-2 py-1 rounded">{from}</span>
|
|
254
|
+
<div className="flex items-center gap-2">
|
|
255
|
+
<div className="w-8 h-0.5 bg-[var(--border-color)]" />
|
|
256
|
+
<span className="px-2 py-0.5 rounded bg-purple-500/10 text-purple-600 text-xs font-medium">{type}</span>
|
|
257
|
+
<ArrowRight className="w-4 h-4 text-[var(--text-tertiary)]" />
|
|
258
|
+
</div>
|
|
259
|
+
<span className="font-mono text-sm bg-[var(--bg-secondary)] px-2 py-1 rounded">{to}</span>
|
|
260
|
+
<span className="text-sm text-[var(--text-secondary)]">{description}</span>
|
|
261
|
+
</div>
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function {SchemaName}SchemaPage() {
|
|
266
|
+
return (
|
|
267
|
+
<div className="space-y-8">
|
|
268
|
+
{/* Section MCD - Diagramme HTML */}
|
|
269
|
+
<section id="mcd">
|
|
270
|
+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
|
|
271
|
+
<span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">1</span>
|
|
272
|
+
Modèle Conceptuel de Données (MCD)
|
|
273
|
+
</h2>
|
|
274
|
+
<div className="card p-6">
|
|
275
|
+
{/* Diagramme visuel des tables */}
|
|
276
|
+
<div className="flex flex-wrap gap-6 justify-center mb-8">
|
|
277
|
+
{schemaData.tables.map((table) => (
|
|
278
|
+
<McdTableCard key={table.name} table={table} schema={schemaData.name} />
|
|
279
|
+
))}
|
|
280
|
+
</div>
|
|
281
|
+
|
|
282
|
+
{/* Relations entre tables */}
|
|
283
|
+
<div className="border-t border-[var(--border-color)] pt-4">
|
|
284
|
+
<h4 className="font-medium mb-3 text-sm text-[var(--text-secondary)]">Relations</h4>
|
|
285
|
+
<div className="space-y-2">
|
|
286
|
+
{schemaData.tables.flatMap((table) =>
|
|
287
|
+
table.relations.map((rel, idx) => (
|
|
288
|
+
<McdRelation
|
|
289
|
+
key={`${table.name}-${idx}`}
|
|
290
|
+
from={table.name}
|
|
291
|
+
to={rel.target}
|
|
292
|
+
type={rel.type}
|
|
293
|
+
description={rel.description}
|
|
294
|
+
/>
|
|
295
|
+
))
|
|
296
|
+
)}
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
|
|
300
|
+
{/* Légende */}
|
|
301
|
+
<div className="mt-6 pt-4 border-t border-[var(--border-color)] flex flex-wrap gap-4 text-xs text-[var(--text-secondary)]">
|
|
302
|
+
<div className="flex items-center gap-1">
|
|
303
|
+
<Key className="w-3 h-3 text-amber-500" /> PK = Clé primaire
|
|
304
|
+
</div>
|
|
305
|
+
<div className="flex items-center gap-1">
|
|
306
|
+
<Link2 className="w-3 h-3 text-blue-500" /> FK = Clé étrangère
|
|
307
|
+
</div>
|
|
308
|
+
<div className="flex items-center gap-1">
|
|
309
|
+
<span className="text-red-500">*</span> = Obligatoire
|
|
310
|
+
</div>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
</section>
|
|
314
|
+
|
|
315
|
+
{/* Section Tables détaillées */}
|
|
316
|
+
<section id="tables">
|
|
317
|
+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
|
|
318
|
+
<span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">2</span>
|
|
319
|
+
Tables détaillées
|
|
320
|
+
</h2>
|
|
321
|
+
{schemaData.tables.map((table) => (
|
|
322
|
+
<div key={table.name} className="card p-6 mb-4">
|
|
323
|
+
<h3 className="font-semibold flex items-center gap-2 mb-4">
|
|
324
|
+
<Table className="w-5 h-5 text-[var(--color-primary-600)]" />
|
|
325
|
+
{schemaData.name}.{table.name}
|
|
326
|
+
</h3>
|
|
327
|
+
<div className="overflow-x-auto">
|
|
328
|
+
<table className="w-full text-sm">
|
|
329
|
+
<thead>
|
|
330
|
+
<tr className="bg-[var(--bg-secondary)]">
|
|
331
|
+
<th className="text-left py-2 px-3 rounded-tl-lg">Colonne</th>
|
|
332
|
+
<th className="text-left py-2 px-3">Type SQL</th>
|
|
333
|
+
<th className="text-left py-2 px-3">Clés</th>
|
|
334
|
+
<th className="text-left py-2 px-3 rounded-tr-lg">Description</th>
|
|
335
|
+
</tr>
|
|
336
|
+
</thead>
|
|
337
|
+
<tbody>
|
|
338
|
+
{table.columns.map((col, idx) => (
|
|
339
|
+
<tr key={col.name} className={idx % 2 === 1 ? 'bg-[var(--bg-secondary)]/50' : ''}>
|
|
340
|
+
<td className="py-2 px-3 font-mono text-sm">
|
|
341
|
+
{col.name}
|
|
342
|
+
{col.required && <span className="text-red-500 ml-1">*</span>}
|
|
343
|
+
</td>
|
|
344
|
+
<td className="py-2 px-3 text-[var(--text-secondary)]">{col.type}</td>
|
|
345
|
+
<td className="py-2 px-3">
|
|
346
|
+
{col.isPK && (
|
|
347
|
+
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded bg-amber-500/10 text-amber-600 text-xs mr-1">
|
|
348
|
+
<Key className="w-3 h-3" /> PK
|
|
349
|
+
</span>
|
|
350
|
+
)}
|
|
351
|
+
{col.isFK && (
|
|
352
|
+
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded bg-blue-500/10 text-blue-600 text-xs">
|
|
353
|
+
<Link2 className="w-3 h-3" /> FK
|
|
354
|
+
</span>
|
|
355
|
+
)}
|
|
356
|
+
</td>
|
|
357
|
+
<td className="py-2 px-3 text-[var(--text-secondary)]">{col.description}</td>
|
|
358
|
+
</tr>
|
|
359
|
+
))}
|
|
360
|
+
</tbody>
|
|
361
|
+
</table>
|
|
362
|
+
</div>
|
|
363
|
+
|
|
364
|
+
{/* Relations de cette table */}
|
|
365
|
+
{table.relations.length > 0 && (
|
|
366
|
+
<div className="mt-4 pt-4 border-t border-[var(--border-color)]">
|
|
367
|
+
<h4 className="font-medium mb-2 text-sm">Relations</h4>
|
|
368
|
+
<div className="flex flex-wrap gap-2">
|
|
369
|
+
{table.relations.map((rel, idx) => (
|
|
370
|
+
<div key={idx} className="flex items-center gap-2 px-3 py-1 rounded-lg bg-[var(--bg-secondary)] text-sm">
|
|
371
|
+
<span className="font-mono text-[var(--color-primary-600)]">{rel.type}</span>
|
|
372
|
+
<ArrowRight className="w-4 h-4 text-[var(--text-tertiary)]" />
|
|
373
|
+
<span>{rel.target}</span>
|
|
374
|
+
</div>
|
|
375
|
+
))}
|
|
376
|
+
</div>
|
|
377
|
+
</div>
|
|
378
|
+
)}
|
|
379
|
+
</div>
|
|
380
|
+
))}
|
|
381
|
+
</section>
|
|
382
|
+
</div>
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Patterns Réutilisables
|
|
388
|
+
|
|
389
|
+
### Stats Cards
|
|
390
|
+
```tsx
|
|
391
|
+
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
392
|
+
<div className="p-4 rounded-lg bg-[var(--bg-secondary)] text-center">
|
|
393
|
+
<div className="text-2xl font-bold text-[var(--color-primary-600)]">{value}</div>
|
|
394
|
+
<div className="text-sm text-[var(--text-secondary)]">{label}</div>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Badges de statut
|
|
400
|
+
```tsx
|
|
401
|
+
const statusColors = {
|
|
402
|
+
active: 'bg-green-500/10 text-green-600',
|
|
403
|
+
pending: 'bg-yellow-500/10 text-yellow-600',
|
|
404
|
+
error: 'bg-red-500/10 text-red-600',
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
<span className={`px-2 py-1 rounded text-xs ${statusColors[status]}`}>{status}</span>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Section numérotée
|
|
411
|
+
```tsx
|
|
412
|
+
<section id="section-id" className="scroll-mt-4">
|
|
413
|
+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
|
|
414
|
+
<span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">
|
|
415
|
+
{number}
|
|
416
|
+
</span>
|
|
417
|
+
{title}
|
|
418
|
+
</h2>
|
|
419
|
+
<div className="card p-6">{children}</div>
|
|
420
|
+
</section>
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Alert/Info Box
|
|
424
|
+
```tsx
|
|
425
|
+
<div className="p-4 rounded-lg bg-amber-500/10 border border-amber-500/20 flex items-start gap-3">
|
|
426
|
+
<AlertTriangle className="w-5 h-5 text-amber-600 flex-shrink-0" />
|
|
427
|
+
<div>
|
|
428
|
+
<div className="font-medium text-amber-600">Attention</div>
|
|
429
|
+
<p className="text-sm text-[var(--text-secondary)]">{message}</p>
|
|
430
|
+
</div>
|
|
431
|
+
</div>
|
|
432
|
+
```
|