samre-cli 1.0.1 → 1.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "samre-cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "CLI officiel d'injection automatique du SDK Samré dans les applications mobiles (Flutter, React Native)",
5
5
  "main": "bin/samre.js",
6
6
  "bin": {
@@ -1,4 +1,4 @@
1
- // Modèle complet pour lib/samre_sdk.dart
1
+ // Modèle complet pour lib/samre_sdk.dart (Version 100% autonome sans dépendance au Navigator)
2
2
 
3
3
  export function generateFlutterSdkCode({ apiUrl, apiKey, appId, appName, dureeJours }) {
4
4
  return `// =================================================================
@@ -33,6 +33,7 @@ class SamreOverlay extends StatefulWidget {
33
33
  class _SamreOverlayState extends State<SamreOverlay> {
34
34
  int _secondsRemaining = SamreConfig.requiredDurationSeconds;
35
35
  bool _canSubmit = false;
36
+ bool _showValidationDialog = false;
36
37
  Timer? _timer;
37
38
 
38
39
  @override
@@ -62,69 +63,91 @@ class _SamreOverlayState extends State<SamreOverlay> {
62
63
  super.dispose();
63
64
  }
64
65
 
65
- void _openValidationDialog() {
66
- showDialog(
67
- context: context,
68
- barrierDismissible: false,
69
- builder: (ctx) => const SamreValidationDialog(),
70
- );
66
+ void _openDialog() {
67
+ setState(() => _showValidationDialog = true);
68
+ }
69
+
70
+ void _closeDialog() {
71
+ setState(() => _showValidationDialog = false);
71
72
  }
72
73
 
73
74
  @override
74
75
  Widget build(BuildContext context) {
75
- return Stack(
76
- children: [
77
- widget.child,
78
- Positioned(
79
- bottom: 24,
80
- right: 20,
81
- child: Material(
82
- elevation: 8,
83
- borderRadius: BorderRadius.circular(24),
84
- color: _canSubmit ? const Color(0xFF2563EB) : Colors.black.withOpacity(0.75),
85
- child: InkWell(
76
+ return Directionality(
77
+ textDirection: TextDirection.ltr,
78
+ child: Stack(
79
+ children: [
80
+ widget.child,
81
+
82
+ // ── Bouton Flottant en Bas à Droite ──────────────────────────────
83
+ Positioned(
84
+ bottom: 24,
85
+ right: 20,
86
+ child: Material(
87
+ elevation: 8,
86
88
  borderRadius: BorderRadius.circular(24),
87
- onTap: _canSubmit ? _openValidationDialog : null,
88
- child: Padding(
89
- padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
90
- child: Row(
91
- mainAxisSize: MainAxisSize.min,
92
- children: [
93
- Icon(
94
- _canSubmit ? Icons.verified_user : Icons.timer_outlined,
95
- color: Colors.white,
96
- size: 18,
97
- ),
98
- const SizedBox(width: 8),
99
- Text(
100
- _canSubmit ? 'Valider Journée' : 'Test en cours (\${_secondsRemaining}s)',
101
- style: const TextStyle(
89
+ color: _canSubmit ? const Color(0xFF2563EB) : Colors.black.withOpacity(0.75),
90
+ child: InkWell(
91
+ borderRadius: BorderRadius.circular(24),
92
+ onTap: _canSubmit ? _openDialog : null,
93
+ child: Padding(
94
+ padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
95
+ child: Row(
96
+ mainAxisSize: MainAxisSize.min,
97
+ children: [
98
+ Icon(
99
+ _canSubmit ? Icons.verified_user : Icons.timer_outlined,
102
100
  color: Colors.white,
103
- fontWeight: FontWeight.bold,
104
- fontSize: 12,
105
- decoration: TextDecoration.none,
101
+ size: 18,
102
+ ),
103
+ const SizedBox(width: 8),
104
+ Text(
105
+ _canSubmit ? 'Valider Journée' : 'Test en cours (\${_secondsRemaining}s)',
106
+ style: const TextStyle(
107
+ color: Colors.white,
108
+ fontWeight: FontWeight.bold,
109
+ fontSize: 12,
110
+ decoration: TextDecoration.none,
111
+ ),
106
112
  ),
107
- ),
108
- ],
113
+ ],
114
+ ),
109
115
  ),
110
116
  ),
111
117
  ),
112
118
  ),
113
- ),
114
- ],
119
+
120
+ // ── Fenêtre Modale de Validation (Indépendante du Navigator) ─────
121
+ if (_showValidationDialog)
122
+ Positioned.fill(
123
+ child: Container(
124
+ color: Colors.black.withOpacity(0.75),
125
+ alignment: Alignment.center,
126
+ padding: const EdgeInsets.symmetric(horizontal: 20),
127
+ child: Material(
128
+ color: Colors.transparent,
129
+ child: SamreValidationCard(
130
+ onClose: _closeDialog,
131
+ ),
132
+ ),
133
+ ),
134
+ ),
135
+ ],
136
+ ),
115
137
  );
116
138
  }
117
139
  }
118
140
 
119
- /// Boîte de dialogue de validation du code quotidien par le panéliste
120
- class SamreValidationDialog extends StatefulWidget {
121
- const SamreValidationDialog({Key? key}) : super(key: key);
141
+ /// Carte de dialogue de validation du code quotidien
142
+ class SamreValidationCard extends StatefulWidget {
143
+ final VoidCallback onClose;
144
+ const SamreValidationCard({Key? key, required this.onClose}) : super(key: key);
122
145
 
123
146
  @override
124
- State<SamreValidationDialog> createState() => _SamreValidationDialogState();
147
+ State<SamreValidationCard> createState() => _SamreValidationCardState();
125
148
  }
126
149
 
127
- class _SamreValidationDialogState extends State<SamreValidationDialog> {
150
+ class _SamreValidationCardState extends State<SamreValidationCard> {
128
151
  final _panelisteCtrl = TextEditingController();
129
152
  final _codeCtrl = TextEditingController();
130
153
  bool _loading = false;
@@ -200,103 +223,136 @@ class _SamreValidationDialogState extends State<SamreValidationDialog> {
200
223
 
201
224
  @override
202
225
  Widget build(BuildContext context) {
203
- return AlertDialog(
204
- backgroundColor: const Color(0xFF0F172A),
205
- shape: RoundedRectangleBorder(
206
- borderRadius: BorderRadius.circular(20),
207
- side: const BorderSide(color: Color(0xFF334155)),
208
- ),
209
- title: Row(
210
- children: [
211
- Container(
212
- padding: const EdgeInsets.all(8),
213
- decoration: BoxDecoration(
214
- color: const Color(0xFF2563EB).withOpacity(0.2),
215
- borderRadius: BorderRadius.circular(10),
216
- ),
217
- child: const Icon(Icons.verified, color: Color(0xFF60A5FA), size: 22),
218
- ),
219
- const SizedBox(width: 12),
220
- const Expanded(
221
- child: Text(
222
- 'Validation Samré',
223
- style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold),
224
- ),
226
+ return Container(
227
+ constraints: const BoxConstraints(maxWidth: 420),
228
+ decoration: BoxDecoration(
229
+ color: const Color(0xFF0F172A),
230
+ borderRadius: BorderRadius.circular(24),
231
+ border: Border.all(color: const Color(0xFF334155), width: 1.5),
232
+ boxShadow: [
233
+ BoxShadow(
234
+ color: Colors.black.withOpacity(0.5),
235
+ blurRadius: 25,
236
+ spreadRadius: 5,
225
237
  ),
226
238
  ],
227
239
  ),
228
- content: SingleChildScrollView(
229
- child: Column(
230
- mainAxisSize: MainAxisSize.min,
231
- crossAxisAlignment: CrossAxisAlignment.stretch,
232
- children: [
233
- const Text(
234
- 'Saisissez vos identifiants fournis par la plateforme Samré pour enregistrer votre journée.',
235
- style: TextStyle(color: Color(0xFF94A3B8), fontSize: 13),
236
- ),
237
- const SizedBox(height: 16),
238
- TextField(
239
- controller: _panelisteCtrl,
240
- style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w600),
241
- decoration: InputDecoration(
242
- labelText: 'Identifiant Panéliste',
243
- labelStyle: const TextStyle(color: Color(0xFF94A3B8)),
244
- hintText: 'Ex: TST-7A8B9C',
245
- hintStyle: const TextStyle(color: Color(0xFF475569)),
246
- filled: true,
247
- fillColor: const Color(0xFF1E293B),
248
- border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
249
- ),
250
- ),
251
- const SizedBox(height: 12),
252
- TextField(
253
- controller: _codeCtrl,
254
- textCapitalization: TextCapitalization.characters,
255
- style: const TextStyle(color: Colors.white, letterSpacing: 2, fontWeight: FontWeight.bold),
256
- decoration: InputDecoration(
257
- labelText: 'Code Unique du Jour',
258
- labelStyle: const TextStyle(color: Color(0xFF94A3B8)),
259
- hintText: 'Ex: 7K9P-4MX2',
260
- hintStyle: const TextStyle(color: Color(0xFF475569), letterSpacing: 0),
261
- filled: true,
262
- fillColor: const Color(0xFF1E293B),
263
- border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
264
- ),
265
- ),
266
- if (_message != null) ...[
267
- const SizedBox(height: 14),
240
+ padding: const EdgeInsets.all(22),
241
+ child: Column(
242
+ mainAxisSize: MainAxisSize.min,
243
+ crossAxisAlignment: CrossAxisAlignment.stretch,
244
+ children: [
245
+ // Titre
246
+ Row(
247
+ children: [
268
248
  Container(
269
- padding: const EdgeInsets.all(12),
249
+ padding: const EdgeInsets.all(8),
270
250
  decoration: BoxDecoration(
271
- color: _success ? const Color(0xFF065F46).withOpacity(0.3) : const Color(0xFF991B1B).withOpacity(0.3),
251
+ color: const Color(0xFF2563EB).withOpacity(0.2),
272
252
  borderRadius: BorderRadius.circular(10),
273
- border: Border.all(color: _success ? const Color(0xFF10B981) : const Color(0xFFEF4444)),
274
253
  ),
254
+ child: const Icon(Icons.verified, color: Color(0xFF60A5FA), size: 22),
255
+ ),
256
+ const SizedBox(width: 12),
257
+ const Expanded(
275
258
  child: Text(
276
- _message!,
277
- style: TextStyle(color: _success ? const Color(0xFF34D399) : const Color(0xFFF87171), fontSize: 12, fontWeight: FontWeight.w600),
259
+ 'Validation Samré',
260
+ style: TextStyle(
261
+ color: Colors.white,
262
+ fontSize: 18,
263
+ fontWeight: FontWeight.bold,
264
+ ),
278
265
  ),
279
266
  ),
267
+ IconButton(
268
+ icon: const Icon(Icons.close, color: Color(0xFF94A3B8), size: 20),
269
+ onPressed: widget.onClose,
270
+ ),
280
271
  ],
272
+ ),
273
+ const SizedBox(height: 12),
274
+ const Text(
275
+ 'Saisissez vos identifiants pour enregistrer votre journée de test.',
276
+ style: TextStyle(color: Color(0xFF94A3B8), fontSize: 13),
277
+ ),
278
+ const SizedBox(height: 16),
279
+ TextField(
280
+ controller: _panelisteCtrl,
281
+ style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w600),
282
+ decoration: InputDecoration(
283
+ labelText: 'Identifiant Panéliste',
284
+ labelStyle: const TextStyle(color: Color(0xFF94A3B8)),
285
+ hintText: 'Ex: TST-7A8B9C',
286
+ hintStyle: const TextStyle(color: Color(0xFF475569)),
287
+ filled: true,
288
+ fillColor: const Color(0xFF1E293B),
289
+ border: OutlineInputBorder(
290
+ borderRadius: BorderRadius.circular(12),
291
+ borderSide: const BorderSide(color: Color(0xFF334155)),
292
+ ),
293
+ ),
294
+ ),
295
+ const SizedBox(height: 12),
296
+ TextField(
297
+ controller: _codeCtrl,
298
+ textCapitalization: TextCapitalization.characters,
299
+ style: const TextStyle(color: Colors.white, letterSpacing: 2, fontWeight: FontWeight.bold),
300
+ decoration: InputDecoration(
301
+ labelText: 'Code Unique du Jour',
302
+ labelStyle: const TextStyle(color: Color(0xFF94A3B8)),
303
+ hintText: 'Ex: 7K9P-4MX2',
304
+ hintStyle: const TextStyle(color: Color(0xFF475569), letterSpacing: 0),
305
+ filled: true,
306
+ fillColor: const Color(0xFF1E293B),
307
+ border: OutlineInputBorder(
308
+ borderRadius: BorderRadius.circular(12),
309
+ borderSide: const BorderSide(color: Color(0xFF334155)),
310
+ ),
311
+ ),
312
+ ),
313
+ if (_message != null) ...[
314
+ const SizedBox(height: 14),
315
+ Container(
316
+ padding: const EdgeInsets.all(12),
317
+ decoration: BoxDecoration(
318
+ color: _success ? const Color(0xFF065F46).withOpacity(0.3) : const Color(0xFF991B1B).withOpacity(0.3),
319
+ borderRadius: BorderRadius.circular(10),
320
+ border: Border.all(color: _success ? const Color(0xFF10B981) : const Color(0xFFEF4444)),
321
+ ),
322
+ child: Text(
323
+ _message!,
324
+ style: TextStyle(
325
+ color: _success ? const Color(0xFF34D399) : const Color(0xFFF87171),
326
+ fontSize: 12,
327
+ fontWeight: FontWeight.w600,
328
+ ),
329
+ ),
330
+ ),
281
331
  ],
282
- ),
283
- ),
284
- actions: [
285
- TextButton(
286
- onPressed: () => Navigator.pop(context),
287
- child: const Text('Fermer', style: TextStyle(color: Color(0xFF94A3B8))),
288
- ),
289
- ElevatedButton(
290
- onPressed: _loading ? null : _verify,
291
- style: ElevatedButton.styleFrom(
292
- backgroundColor: const Color(0xFF2563EB),
293
- shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
332
+ const SizedBox(height: 18),
333
+ Row(
334
+ mainAxisAlignment: MainAxisAlignment.end,
335
+ children: [
336
+ TextButton(
337
+ onPressed: widget.onClose,
338
+ child: const Text('Fermer', style: TextStyle(color: Color(0xFF94A3B8))),
339
+ ),
340
+ const SizedBox(width: 8),
341
+ ElevatedButton(
342
+ onPressed: _loading ? null : _verify,
343
+ style: ElevatedButton.styleFrom(
344
+ backgroundColor: const Color(0xFF2563EB),
345
+ padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
346
+ shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
347
+ ),
348
+ child: _loading
349
+ ? const SizedBox(width: 16, height: 16, child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2))
350
+ : const Text('Valider', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
351
+ ),
352
+ ],
294
353
  ),
295
- child: _loading
296
- ? const SizedBox(width: 16, height: 16, child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2))
297
- : const Text('Valider', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
298
- ),
299
- ],
354
+ ],
355
+ ),
300
356
  );
301
357
  }
302
358
  }