@atlashub/smartstack-cli 1.14.1 → 1.14.3
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/gitflow.html +330 -162
- package/dist/index.js +183 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/skills/_shared.md +29 -6
- package/templates/skills/apex/SKILL.md +56 -0
- package/templates/skills/apex/steps/step-01-analyze.md +22 -5
- package/templates/skills/apex/steps/step-04-validate.md +32 -6
- package/templates/skills/ui-components/SKILL.md +167 -5
package/package.json
CHANGED
|
@@ -109,9 +109,32 @@ if (entity.UserType == UserType.System || entity.UserType == UserType.LocalAdmin
|
|
|
109
109
|
|
|
110
110
|
## MCP Tools References
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
|
115
|
-
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
112
|
+
### Outils Core
|
|
113
|
+
|
|
114
|
+
| Tool | Usage | Step APEX |
|
|
115
|
+
|------|-------|-----------|
|
|
116
|
+
| `mcp__smartstack__validate_conventions` | Valider conventions SmartStack (tables, migrations, services, namespaces, entities, tenants, controllers) | step-04-validate |
|
|
117
|
+
| `mcp__smartstack__scaffold_extension` | Génération code (feature, entity, service, controller, component, dto, validator, repository) | step-03-execute |
|
|
118
|
+
| `mcp__smartstack__check_migrations` | Analyser migrations EF Core (conflits, ordre, ModelSnapshot) | step-04-validate |
|
|
119
|
+
| `mcp__smartstack__api_docs` | Documentation API depuis Swagger/OpenAPI ou controllers | step-01-analyze |
|
|
120
|
+
| `mcp__smartstack__suggest_migration` | Suggérer nom migration ({context}_v{version}_{sequence}_{Description}) | step-03-execute |
|
|
121
|
+
| `mcp__smartstack__generate_permissions` | Générer permissions RBAC depuis NavRoute | step-03-execute |
|
|
122
|
+
|
|
123
|
+
### Outils Tests
|
|
124
|
+
|
|
125
|
+
| Tool | Usage | Step APEX |
|
|
126
|
+
|------|-------|-----------|
|
|
127
|
+
| `mcp__smartstack__scaffold_tests` | Générer tests unitaires/intégration/sécurité | step-07-tests |
|
|
128
|
+
| `mcp__smartstack__analyze_test_coverage` | Analyser couverture de tests du projet | step-07-tests |
|
|
129
|
+
| `mcp__smartstack__validate_test_conventions` | Valider conventions de nommage des tests | step-07-tests |
|
|
130
|
+
| `mcp__smartstack__suggest_test_scenarios` | Suggérer scénarios de test basés sur le code | step-07-tests |
|
|
131
|
+
|
|
132
|
+
### Outils Frontend
|
|
133
|
+
|
|
134
|
+
| Tool | Usage | Step APEX |
|
|
135
|
+
|------|-------|-----------|
|
|
136
|
+
| `mcp__smartstack__scaffold_api_client` | Générer client TypeScript avec NavRoute | step-03-execute |
|
|
137
|
+
| `mcp__smartstack__scaffold_routes` | Générer React Router depuis NavRoute backend | step-03-execute |
|
|
138
|
+
| `mcp__smartstack__validate_frontend_routes` | Valider synchronisation routes frontend/backend | step-04-validate |
|
|
139
|
+
| `mcp__smartstack__scaffold_frontend_extension` | Générer infrastructure extension frontend | step-03-execute |
|
|
140
|
+
| `mcp__smartstack__analyze_extension_points` | Analyser points d'extension dans les pages React | step-01-analyze |
|
|
@@ -225,6 +225,62 @@ When provided, step-00 will:
|
|
|
225
225
|
- **Use parallel agents** for independent exploration tasks (unless economy_mode)
|
|
226
226
|
</execution_rules>
|
|
227
227
|
|
|
228
|
+
<mcp_requirements>
|
|
229
|
+
**SmartStack MCP Integration:**
|
|
230
|
+
|
|
231
|
+
APEX est fortement couplé au développement SmartStack via les outils MCP.
|
|
232
|
+
Référence complète dans `_shared.md` section "MCP Tools References".
|
|
233
|
+
|
|
234
|
+
### Outils obligatoires (chaque exécution APEX)
|
|
235
|
+
|
|
236
|
+
| Tool | Quand | Step |
|
|
237
|
+
|------|-------|------|
|
|
238
|
+
| `mcp__smartstack__api_docs` | Analyse contexte API existant | step-01-analyze |
|
|
239
|
+
| `mcp__smartstack__validate_conventions` | Validation finale du code généré | step-04-validate |
|
|
240
|
+
|
|
241
|
+
### Outils conditionnels (step-03-execute)
|
|
242
|
+
|
|
243
|
+
| Tool | Condition |
|
|
244
|
+
|------|-----------|
|
|
245
|
+
| `mcp__smartstack__scaffold_extension` | Génération entités/services/controllers |
|
|
246
|
+
| `mcp__smartstack__suggest_migration` | Création nouvelle migration EF Core |
|
|
247
|
+
| `mcp__smartstack__generate_permissions` | Génération permissions RBAC |
|
|
248
|
+
| `mcp__smartstack__scaffold_api_client` | Génération client TypeScript |
|
|
249
|
+
| `mcp__smartstack__scaffold_routes` | Génération routes React Router |
|
|
250
|
+
|
|
251
|
+
### Outils conditionnels (step-04-validate)
|
|
252
|
+
|
|
253
|
+
| Tool | Condition |
|
|
254
|
+
|------|-----------|
|
|
255
|
+
| `mcp__smartstack__check_migrations` | Si modifications EF Core détectées |
|
|
256
|
+
| `mcp__smartstack__validate_frontend_routes` | Si code frontend généré |
|
|
257
|
+
|
|
258
|
+
### Outils tests (step-07-tests, si `-t`)
|
|
259
|
+
|
|
260
|
+
| Tool | Usage |
|
|
261
|
+
|------|-------|
|
|
262
|
+
| `mcp__smartstack__scaffold_tests` | Générer tests unitaires/intégration |
|
|
263
|
+
| `mcp__smartstack__suggest_test_scenarios` | Suggérer scénarios de test |
|
|
264
|
+
| `mcp__smartstack__analyze_test_coverage` | Analyser couverture existante |
|
|
265
|
+
|
|
266
|
+
### Outils analyse (step-01-analyze)
|
|
267
|
+
|
|
268
|
+
| Tool | Usage |
|
|
269
|
+
|------|-------|
|
|
270
|
+
| `mcp__smartstack__analyze_extension_points` | Identifier points d'extension React |
|
|
271
|
+
|
|
272
|
+
### Vérification MCP (step-00)
|
|
273
|
+
|
|
274
|
+
Au démarrage, vérifier la disponibilité du MCP SmartStack :
|
|
275
|
+
- Si disponible : utiliser les outils MCP pour génération et validation
|
|
276
|
+
- Si indisponible : avertir l'utilisateur, continuer en mode dégradé (outils manuels)
|
|
277
|
+
|
|
278
|
+
### Mode économie (`-e`)
|
|
279
|
+
|
|
280
|
+
En mode économie, les outils MCP restent disponibles mais les subagents sont désactivés.
|
|
281
|
+
Privilégier les outils MCP (`scaffold_*`) pour la génération plutôt que l'écriture manuelle.
|
|
282
|
+
</mcp_requirements>
|
|
283
|
+
|
|
228
284
|
<success_criteria>
|
|
229
285
|
|
|
230
286
|
- Each step loaded progressively
|
|
@@ -50,7 +50,24 @@ From the task description, identify:
|
|
|
50
50
|
|
|
51
51
|
These keywords guide exploration - NOT planning.
|
|
52
52
|
|
|
53
|
-
### 2.
|
|
53
|
+
### 2. SmartStack MCP Context (if available)
|
|
54
|
+
|
|
55
|
+
**Use MCP tools for SmartStack-specific context:**
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
mcp__smartstack__api_docs:
|
|
59
|
+
format: "markdown"
|
|
60
|
+
# Récupère la documentation API existante
|
|
61
|
+
# Identifie les endpoints, DTOs, et patterns utilisés
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This provides:
|
|
65
|
+
- Existing API endpoints and their structure
|
|
66
|
+
- DTOs and request/response models
|
|
67
|
+
- Controller patterns and conventions
|
|
68
|
+
- NavRoute hierarchy
|
|
69
|
+
|
|
70
|
+
### 3. Explore Codebase
|
|
54
71
|
|
|
55
72
|
**If `{economy_mode}` = true:**
|
|
56
73
|
|
|
@@ -98,7 +115,7 @@ Find:
|
|
|
98
115
|
3. Known pitfalls or gotchas
|
|
99
116
|
```
|
|
100
117
|
|
|
101
|
-
###
|
|
118
|
+
### 4. Synthesize Findings
|
|
102
119
|
|
|
103
120
|
Combine results into structured context:
|
|
104
121
|
|
|
@@ -140,7 +157,7 @@ Combine results into structured context:
|
|
|
140
157
|
- Use httpOnly cookies for tokens
|
|
141
158
|
```
|
|
142
159
|
|
|
143
|
-
###
|
|
160
|
+
### 5. Infer Acceptance Criteria
|
|
144
161
|
|
|
145
162
|
Based on task and context, infer success criteria:
|
|
146
163
|
|
|
@@ -156,7 +173,7 @@ Based on "{task_description}" and existing patterns:
|
|
|
156
173
|
_These will be refined in the planning step._
|
|
157
174
|
```
|
|
158
175
|
|
|
159
|
-
###
|
|
176
|
+
### 6. Save Output (if save_mode)
|
|
160
177
|
|
|
161
178
|
**If `{save_mode}` = true:**
|
|
162
179
|
|
|
@@ -165,7 +182,7 @@ Write findings to `{output_dir}/01-analyze.md`:
|
|
|
165
182
|
- Add timestamp at the end
|
|
166
183
|
- Update 00-context.md Progress table: 01-analyze -> Complete
|
|
167
184
|
|
|
168
|
-
###
|
|
185
|
+
### 7. Present Context Summary
|
|
169
186
|
|
|
170
187
|
```
|
|
171
188
|
**Context Gathering Complete**
|
|
@@ -85,7 +85,33 @@ pnpm run test
|
|
|
85
85
|
3. Fix the root cause
|
|
86
86
|
4. Re-run until passing
|
|
87
87
|
|
|
88
|
-
### 3.
|
|
88
|
+
### 3. SmartStack Convention Validation (if MCP available)
|
|
89
|
+
|
|
90
|
+
**Use MCP to validate SmartStack conventions:**
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
mcp__smartstack__validate_conventions:
|
|
94
|
+
checks: ["all"]
|
|
95
|
+
# Valide: tables, migrations, services, namespaces, entities, tenants, controllers
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**If EF Core changes detected, also run:**
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
mcp__smartstack__check_migrations:
|
|
102
|
+
# Vérifie conflits, ordre chronologique, ModelSnapshot
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**MCP validation checks:**
|
|
106
|
+
- [ ] Table naming (domain prefixes: auth_, nav_, cfg_, etc.)
|
|
107
|
+
- [ ] Migration naming ({context}_v{version}_{sequence}_{Description})
|
|
108
|
+
- [ ] Service interfaces (I*Service pattern)
|
|
109
|
+
- [ ] Namespace structure (Domain → Application → Infrastructure → API)
|
|
110
|
+
- [ ] Entity conventions (base classes, soft delete, audit)
|
|
111
|
+
- [ ] Tenant isolation (ITenantEntity where required)
|
|
112
|
+
- [ ] Controller routes (NavRoute attributes)
|
|
113
|
+
|
|
114
|
+
### 4. Self-Audit Checklist
|
|
89
115
|
|
|
90
116
|
Verify each item:
|
|
91
117
|
|
|
@@ -109,14 +135,14 @@ Verify each item:
|
|
|
109
135
|
- [ ] Error handling consistent
|
|
110
136
|
- [ ] Naming conventions match
|
|
111
137
|
|
|
112
|
-
###
|
|
138
|
+
### 5. Format Code
|
|
113
139
|
|
|
114
140
|
If format command available:
|
|
115
141
|
```bash
|
|
116
142
|
pnpm run format
|
|
117
143
|
```
|
|
118
144
|
|
|
119
|
-
###
|
|
145
|
+
### 6. Final Verification
|
|
120
146
|
|
|
121
147
|
Re-run all checks:
|
|
122
148
|
```bash
|
|
@@ -125,7 +151,7 @@ pnpm run typecheck && pnpm run lint
|
|
|
125
151
|
|
|
126
152
|
Both MUST pass.
|
|
127
153
|
|
|
128
|
-
###
|
|
154
|
+
### 7. Present Validation Results
|
|
129
155
|
|
|
130
156
|
```
|
|
131
157
|
**Validation Complete**
|
|
@@ -144,7 +170,7 @@ Both MUST pass.
|
|
|
144
170
|
**Summary:** All checks passing, ready for next step.
|
|
145
171
|
```
|
|
146
172
|
|
|
147
|
-
###
|
|
173
|
+
### 8. Save Output (if save_mode)
|
|
148
174
|
|
|
149
175
|
**If `{save_mode}` = true:**
|
|
150
176
|
|
|
@@ -154,7 +180,7 @@ Write to `{output_dir}/04-validate.md`:
|
|
|
154
180
|
- Timestamp
|
|
155
181
|
- Update 00-context.md Progress table: 04-validate -> Complete
|
|
156
182
|
|
|
157
|
-
###
|
|
183
|
+
### 9. Determine Next Step
|
|
158
184
|
|
|
159
185
|
**Decision tree:**
|
|
160
186
|
|
|
@@ -70,12 +70,12 @@ import { EntityCard, ProviderCard, TemplateCard } from '@/components/ui/EntityCa
|
|
|
70
70
|
| `links` | `Array<{ icon, label, href?, onClick? }>` |
|
|
71
71
|
| `actions` | `Array<{ label, href?, onClick?, variant, icon?, disabled? }>` |
|
|
72
72
|
|
|
73
|
-
### Action Variants
|
|
73
|
+
### Action Variants (EntityCard)
|
|
74
74
|
| Variant | Style |
|
|
75
75
|
|---------|-------|
|
|
76
|
-
| `primary` | `bg-accent-
|
|
77
|
-
| `secondary` | `bg-
|
|
78
|
-
| `ghost` | `
|
|
76
|
+
| `primary` | `bg-[var(--color-accent-600)] text-white` |
|
|
77
|
+
| `secondary` | `bg-[var(--bg-secondary)] text-[var(--text-secondary)]` |
|
|
78
|
+
| `ghost` | `text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]` (NO border!) |
|
|
79
79
|
|
|
80
80
|
## RESPONSIVE GRID
|
|
81
81
|
|
|
@@ -159,12 +159,174 @@ const canExecute = hasPermission('module.action.execute');
|
|
|
159
159
|
| Catalogs | Cards with complex interactive states |
|
|
160
160
|
| Clickable grids | Cards with integrated forms |
|
|
161
161
|
|
|
162
|
+
## CRITICAL: CSS VARIABLES (NEVER HARDCODE COLORS)
|
|
163
|
+
|
|
164
|
+
**NEVER use hardcoded Tailwind colors.** ALWAYS use CSS variables for theme compliance.
|
|
165
|
+
|
|
166
|
+
### Status Colors
|
|
167
|
+
| Status | Background | Text | Border | Dot (solid) |
|
|
168
|
+
|--------|------------|------|--------|-------------|
|
|
169
|
+
| **Info** (Pending, Business) | `--info-bg` | `--info-text` | `--info-border` | `--info-dot` |
|
|
170
|
+
| **Success** (Active) | `--success-bg` | `--success-text` | `--success-border` | `--success-dot` |
|
|
171
|
+
| **Warning** (Suspended, Owner) | `--warning-bg` | `--warning-text` | `--warning-border` | `--warning-dot` |
|
|
172
|
+
| **Error** (Danger, Archive) | `--error-bg` | `--error-text` | `--error-border` | `--error-dot` |
|
|
173
|
+
| **Accent** (Personal, Primary) | `--accent-bg` | `--accent-text` | `--accent-border` | `--color-accent-500` |
|
|
174
|
+
|
|
175
|
+
### Badge Pattern
|
|
176
|
+
```tsx
|
|
177
|
+
// ✅ CORRECT - Uses CSS variables
|
|
178
|
+
<span className="px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--info-bg)] text-[var(--info-text)]">
|
|
179
|
+
Info Badge
|
|
180
|
+
</span>
|
|
181
|
+
|
|
182
|
+
// ❌ WRONG - Hardcoded Tailwind colors
|
|
183
|
+
<span className="bg-blue-500/10 text-blue-500">Info Badge</span>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Status Config Pattern
|
|
187
|
+
```tsx
|
|
188
|
+
// ✅ CORRECT
|
|
189
|
+
const STATUS_CONFIG = {
|
|
190
|
+
Pending: { bgColor: 'bg-[var(--info-bg)]', color: 'text-[var(--info-text)]', borderColor: 'border-[var(--info-border)]' },
|
|
191
|
+
Active: { bgColor: 'bg-[var(--success-bg)]', color: 'text-[var(--success-text)]', borderColor: 'border-[var(--success-border)]' },
|
|
192
|
+
Suspended: { bgColor: 'bg-[var(--warning-bg)]', color: 'text-[var(--warning-text)]', borderColor: 'border-[var(--warning-border)]' },
|
|
193
|
+
Archived: { bgColor: 'bg-[var(--bg-tertiary)]', color: 'text-[var(--text-tertiary)]', borderColor: 'border-[var(--border-color)]' }
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// ❌ WRONG - dark: variants are obsolete
|
|
197
|
+
const STATUS_CONFIG = {
|
|
198
|
+
Active: { bgColor: 'bg-emerald-50 dark:bg-emerald-900/20', ... }
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## BUTTON VARIANTS
|
|
203
|
+
|
|
204
|
+
### Action Buttons (Status changes)
|
|
205
|
+
```tsx
|
|
206
|
+
// Success action (Activate)
|
|
207
|
+
<button className="px-4 py-2 rounded-[var(--radius-button)] bg-[var(--success-dot)] text-white hover:opacity-90">
|
|
208
|
+
Activate
|
|
209
|
+
</button>
|
|
210
|
+
|
|
211
|
+
// Warning action (Suspend)
|
|
212
|
+
<button className="px-4 py-2 rounded-[var(--radius-button)] bg-[var(--warning-dot)] text-white hover:opacity-90">
|
|
213
|
+
Suspend
|
|
214
|
+
</button>
|
|
215
|
+
|
|
216
|
+
// Danger action (Archive/Delete)
|
|
217
|
+
<button className="px-4 py-2 rounded-[var(--radius-button)] bg-[var(--error-dot)] text-white hover:opacity-90">
|
|
218
|
+
Archive
|
|
219
|
+
</button>
|
|
220
|
+
|
|
221
|
+
// Primary action
|
|
222
|
+
<button className="px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]">
|
|
223
|
+
Save
|
|
224
|
+
</button>
|
|
225
|
+
|
|
226
|
+
// Ghost action (NO BORDER!)
|
|
227
|
+
<button className="px-4 py-2 rounded-[var(--radius-button)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)]">
|
|
228
|
+
Refresh
|
|
229
|
+
</button>
|
|
230
|
+
|
|
231
|
+
// Secondary action
|
|
232
|
+
<button className="px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]">
|
|
233
|
+
Cancel
|
|
234
|
+
</button>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Button Rules
|
|
238
|
+
| Variant | Background | Text | Border | Hover |
|
|
239
|
+
|---------|------------|------|--------|-------|
|
|
240
|
+
| **Primary** | `--color-accent-600` | `white` | none | `--color-accent-700` |
|
|
241
|
+
| **Success** | `--success-dot` | `white` | none | `opacity-90` |
|
|
242
|
+
| **Warning** | `--warning-dot` | `white` | none | `opacity-90` |
|
|
243
|
+
| **Danger** | `--error-dot` | `white` | none | `opacity-90` |
|
|
244
|
+
| **Secondary** | `--bg-secondary` | `--text-secondary` | none | `--bg-hover` |
|
|
245
|
+
| **Ghost** | transparent | `--text-secondary` | **NONE** | `--bg-hover` |
|
|
246
|
+
|
|
247
|
+
## DETAIL PAGE TEMPLATE
|
|
248
|
+
|
|
249
|
+
### Structure
|
|
250
|
+
```tsx
|
|
251
|
+
<div className="container mx-auto px-4 py-6 max-w-7xl space-y-6">
|
|
252
|
+
{/* Header */}
|
|
253
|
+
<div className="flex items-center gap-4">
|
|
254
|
+
<button onClick={() => navigate(-1)} className="p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)]">
|
|
255
|
+
<ArrowLeft className="w-5 h-5 text-[var(--text-secondary)]" />
|
|
256
|
+
</button>
|
|
257
|
+
<div className="flex-1">
|
|
258
|
+
<h1 className="text-xl sm:text-2xl font-bold text-[var(--text-primary)]">{title}</h1>
|
|
259
|
+
<p className="text-sm text-[var(--text-secondary)]">{subtitle}</p>
|
|
260
|
+
</div>
|
|
261
|
+
<div className="flex items-center gap-2">
|
|
262
|
+
{/* Status badges */}
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
|
|
266
|
+
{/* Pill Tabs */}
|
|
267
|
+
<div className="flex gap-1 p-1 bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]">
|
|
268
|
+
{tabs.map(tab => (
|
|
269
|
+
<button
|
|
270
|
+
key={tab.id}
|
|
271
|
+
className={`px-4 py-2 rounded-[var(--radius-button)] font-medium ${
|
|
272
|
+
activeTab === tab.id
|
|
273
|
+
? 'bg-[var(--color-accent-600)] text-white'
|
|
274
|
+
: 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'
|
|
275
|
+
}`}
|
|
276
|
+
>
|
|
277
|
+
{tab.label}
|
|
278
|
+
</button>
|
|
279
|
+
))}
|
|
280
|
+
</div>
|
|
281
|
+
|
|
282
|
+
{/* Tab Content */}
|
|
283
|
+
<div className="min-h-[400px]">{/* ... */}</div>
|
|
284
|
+
</div>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Info Card Pattern
|
|
288
|
+
```tsx
|
|
289
|
+
<div className="p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]">
|
|
290
|
+
<div className="flex items-center justify-between mb-4">
|
|
291
|
+
<h3 className="text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2">
|
|
292
|
+
<Icon className="w-5 h-5" />
|
|
293
|
+
{title}
|
|
294
|
+
</h3>
|
|
295
|
+
<button className="flex items-center gap-1 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]">
|
|
296
|
+
<Edit3 className="w-4 h-4" />
|
|
297
|
+
{t('common:edit')}
|
|
298
|
+
</button>
|
|
299
|
+
</div>
|
|
300
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
301
|
+
<div className="p-3 rounded-lg bg-[var(--bg-secondary)]">
|
|
302
|
+
<p className="text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1">{label}</p>
|
|
303
|
+
<p className="text-sm text-[var(--text-primary)] font-medium">{value}</p>
|
|
304
|
+
</div>
|
|
305
|
+
</div>
|
|
306
|
+
</div>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Error Display Pattern
|
|
310
|
+
```tsx
|
|
311
|
+
{error && (
|
|
312
|
+
<div className="p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]">
|
|
313
|
+
<div className="flex items-center gap-2 text-[var(--error-text)]">
|
|
314
|
+
<AlertTriangle className="w-5 h-5" />
|
|
315
|
+
<span>{error}</span>
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
318
|
+
)}
|
|
319
|
+
```
|
|
320
|
+
|
|
162
321
|
## ABSOLUTE RULES
|
|
163
322
|
|
|
164
323
|
| DO | DON'T |
|
|
165
324
|
|----|-------|
|
|
325
|
+
| CSS variables for ALL colors | Hardcoded Tailwind colors (`bg-blue-500`) |
|
|
326
|
+
| `--success-dot`, `--warning-dot`, `--error-dot` for action buttons | `bg-emerald-500`, `bg-amber-500`, `bg-red-500` |
|
|
327
|
+
| `--info-bg`, `--success-bg`, etc. for badges | `bg-blue-500/10 dark:bg-blue-900/20` |
|
|
328
|
+
| Ghost buttons WITHOUT border | `border border-[var(--border-color)]` on ghost |
|
|
166
329
|
| EntityCard for entities | Custom cards with manual divs |
|
|
167
|
-
| Distinct colored header | rounded-full for avatar (that's table) |
|
|
168
330
|
| Responsive grid 1→2→3→4 | Fixed non-responsive grid |
|
|
169
331
|
| h-full + flex-1 + mt-auto | Unaligned buttons in grid |
|
|
170
332
|
| Empty and loading states | Native HTML tooltip |
|