@rsuci/shared-form-components 1.0.29 → 1.0.33

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.
Files changed (51) hide show
  1. package/dist/components/form-renderer/ConfirmationModal.d.ts +20 -0
  2. package/dist/components/form-renderer/ConfirmationModal.d.ts.map +1 -0
  3. package/dist/components/form-renderer/ConfirmationModal.js +79 -0
  4. package/dist/components/form-renderer/FormActions.d.ts +23 -0
  5. package/dist/components/form-renderer/FormActions.d.ts.map +1 -0
  6. package/dist/components/form-renderer/FormActions.js +116 -0
  7. package/dist/components/form-renderer/FormNavigationButtons.d.ts +23 -0
  8. package/dist/components/form-renderer/FormNavigationButtons.d.ts.map +1 -0
  9. package/dist/components/form-renderer/FormNavigationButtons.js +35 -0
  10. package/dist/components/form-renderer/FormProgress.d.ts +19 -0
  11. package/dist/components/form-renderer/FormProgress.d.ts.map +1 -0
  12. package/dist/components/form-renderer/FormProgress.js +26 -0
  13. package/dist/components/form-renderer/FormRenderer.d.ts +39 -0
  14. package/dist/components/form-renderer/FormRenderer.d.ts.map +1 -0
  15. package/dist/components/form-renderer/FormRenderer.js +113 -0
  16. package/dist/components/form-renderer/FormRendererContext.d.ts +109 -0
  17. package/dist/components/form-renderer/FormRendererContext.d.ts.map +1 -0
  18. package/dist/components/form-renderer/FormRendererContext.js +114 -0
  19. package/dist/components/form-renderer/GroupeInstanceTabs.d.ts +18 -0
  20. package/dist/components/form-renderer/GroupeInstanceTabs.d.ts.map +1 -0
  21. package/dist/components/form-renderer/GroupeInstanceTabs.js +174 -0
  22. package/dist/components/form-renderer/ValidationModal.d.ts +25 -0
  23. package/dist/components/form-renderer/ValidationModal.d.ts.map +1 -0
  24. package/dist/components/form-renderer/ValidationModal.js +37 -0
  25. package/dist/components/form-renderer/index.d.ts +19 -0
  26. package/dist/components/form-renderer/index.d.ts.map +1 -0
  27. package/dist/components/form-renderer/index.js +24 -0
  28. package/dist/hooks/useFormInstances.d.ts +87 -0
  29. package/dist/hooks/useFormInstances.d.ts.map +1 -0
  30. package/dist/hooks/useFormInstances.js +197 -0
  31. package/dist/hooks/useFormNavigation.d.ts +72 -0
  32. package/dist/hooks/useFormNavigation.d.ts.map +1 -0
  33. package/dist/hooks/useFormNavigation.js +147 -0
  34. package/dist/hooks/useFormRenderer.d.ts +87 -0
  35. package/dist/hooks/useFormRenderer.d.ts.map +1 -0
  36. package/dist/hooks/useFormRenderer.js +177 -0
  37. package/dist/hooks/useFormValidation.d.ts +50 -0
  38. package/dist/hooks/useFormValidation.d.ts.map +1 -0
  39. package/dist/hooks/useFormValidation.js +175 -0
  40. package/dist/index.d.ts +14 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +21 -0
  43. package/dist/lib/__tests__/date-functions.test.d.ts +5 -0
  44. package/dist/lib/__tests__/date-functions.test.d.ts.map +1 -0
  45. package/dist/lib/__tests__/date-functions.test.js +184 -0
  46. package/dist/lib/utils/groupeInstanceManager.d.ts +88 -0
  47. package/dist/lib/utils/groupeInstanceManager.d.ts.map +1 -0
  48. package/dist/lib/utils/groupeInstanceManager.js +606 -0
  49. package/dist/types/form-renderer.d.ts +115 -1
  50. package/dist/types/form-renderer.d.ts.map +1 -1
  51. package/package.json +5 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormRendererContext.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/FormRendererContext.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Contexte React pour le FormRenderer
3
+ * Partage l'état et les fonctions entre tous les sous-composants
4
+ * RSU v2 - Package Partagé
5
+ */
6
+ 'use client';
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ import { createContext, useContext, useMemo } from 'react';
9
+ import { useFormRenderer } from '../../hooks/useFormRenderer';
10
+ // Création du contexte avec valeur par défaut null
11
+ const FormRendererContext = createContext(null);
12
+ /**
13
+ * Provider pour le contexte FormRenderer
14
+ * Encapsule useFormRenderer et fournit l'état à tous les enfants
15
+ */
16
+ export const FormRendererProvider = ({ children, formulaire, enquete, initialResponses, config, callbacks, services, geographicComponents, disabled, isSubmitting: externalIsSubmitting, isVariableVisible, debug }) => {
17
+ // Utiliser le hook principal
18
+ const formRenderer = useFormRenderer(formulaire, enquete, {
19
+ config,
20
+ initialResponses: initialResponses || enquete?.reponses,
21
+ onResponsesChange: callbacks.onResponsesChange,
22
+ onGroupChange: callbacks.onGroupChange,
23
+ isVariableVisible,
24
+ debug
25
+ });
26
+ // Construire la valeur du contexte
27
+ const contextValue = useMemo(() => ({
28
+ ...formRenderer,
29
+ // Données initiales
30
+ formulaire,
31
+ enquete,
32
+ // Configuration
33
+ config,
34
+ // Callbacks
35
+ callbacks,
36
+ // Services
37
+ services,
38
+ geographicComponents,
39
+ // Surcharges externes
40
+ isSubmitting: externalIsSubmitting ?? formRenderer.isSubmitting,
41
+ effectiveDisabled: disabled ?? formRenderer.effectiveDisabled
42
+ }), [
43
+ formRenderer,
44
+ formulaire,
45
+ enquete,
46
+ config,
47
+ callbacks,
48
+ services,
49
+ geographicComponents,
50
+ externalIsSubmitting,
51
+ disabled
52
+ ]);
53
+ return (_jsx(FormRendererContext.Provider, { value: contextValue, children: children }));
54
+ };
55
+ /**
56
+ * Hook pour accéder au contexte FormRenderer
57
+ * Doit être utilisé à l'intérieur d'un FormRendererProvider
58
+ */
59
+ export function useFormRendererContext() {
60
+ const context = useContext(FormRendererContext);
61
+ if (!context) {
62
+ throw new Error('useFormRendererContext doit être utilisé à l\'intérieur d\'un FormRendererProvider');
63
+ }
64
+ return context;
65
+ }
66
+ /**
67
+ * Hook pour accéder uniquement à la navigation
68
+ */
69
+ export function useFormRendererNavigation() {
70
+ const { navigation } = useFormRendererContext();
71
+ return navigation;
72
+ }
73
+ /**
74
+ * Hook pour accéder uniquement à la validation
75
+ */
76
+ export function useFormRendererValidation() {
77
+ const { validation } = useFormRendererContext();
78
+ return validation;
79
+ }
80
+ /**
81
+ * Hook pour accéder uniquement aux instances
82
+ */
83
+ export function useFormRendererInstances() {
84
+ const { instances } = useFormRendererContext();
85
+ return instances;
86
+ }
87
+ /**
88
+ * Hook pour accéder à la configuration
89
+ */
90
+ export function useFormRendererConfig() {
91
+ const { mode, features, config } = useFormRendererContext();
92
+ return { mode, features, config };
93
+ }
94
+ /**
95
+ * Hook pour accéder aux réponses
96
+ */
97
+ export function useFormRendererResponses() {
98
+ const { responses, updateResponse, getResponseValue } = useFormRendererContext();
99
+ return { responses, updateResponse, getResponseValue };
100
+ }
101
+ /**
102
+ * Hook pour accéder à l'état global
103
+ */
104
+ export function useFormRendererState() {
105
+ const { hasUnsavedChanges, isSubmitting, effectiveDisabled, isReadOnly, isConsultationMode } = useFormRendererContext();
106
+ return {
107
+ hasUnsavedChanges,
108
+ isSubmitting,
109
+ effectiveDisabled,
110
+ isReadOnly,
111
+ isConsultationMode
112
+ };
113
+ }
114
+ export default FormRendererContext;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Composant d'interface à onglets pour les instances multiples de groupes
3
+ * RSU v2 - Moteur de Rendu des Formulaires d'Enquête
4
+ */
5
+ import React from 'react';
6
+ import { GroupeFormulaire, EnqueteReponse, GroupeInstance } from '../../types/enquete';
7
+ export interface GroupeInstanceTabsProps {
8
+ groupe: GroupeFormulaire;
9
+ currentInstanceIndex: number;
10
+ responses: Record<string, EnqueteReponse>;
11
+ onInstanceChange: (instanceIndex: number) => void;
12
+ onInstanceAdded: (instance: GroupeInstance) => void;
13
+ onInstanceRemoved: (instanceNumber: number) => void;
14
+ disabled?: boolean;
15
+ }
16
+ declare const GroupeInstanceTabs: React.FC<GroupeInstanceTabsProps>;
17
+ export default GroupeInstanceTabs;
18
+ //# sourceMappingURL=GroupeInstanceTabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupeInstanceTabs.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/GroupeInstanceTabs.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIvF,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,gBAAgB,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,gBAAgB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,iBAAiB,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA0RzD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Composant d'interface à onglets pour les instances multiples de groupes
3
+ * RSU v2 - Moteur de Rendu des Formulaires d'Enquête
4
+ */
5
+ 'use client';
6
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
+ import { useState, useEffect } from 'react';
8
+ import { Plus, Minus, AlertTriangle, Check, AlertCircle, AlertTriangle as ExclamationIcon } from 'lucide-react';
9
+ import { GroupeInstanceManager } from '../../lib/utils/groupeInstanceManager';
10
+ import ConfirmationModal from './ConfirmationModal';
11
+ const GroupeInstanceTabs = ({ groupe, currentInstanceIndex, responses, onInstanceChange, onInstanceAdded, onInstanceRemoved, disabled = false }) => {
12
+ const [isProcessing, setIsProcessing] = useState(false);
13
+ const [error, setError] = useState(null);
14
+ const [forceUpdate, setForceUpdate] = useState(0);
15
+ const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false);
16
+ // Ne pas afficher pour les groupes non multiples
17
+ if (!groupe.estMultiple || !groupe.instances) {
18
+ return null;
19
+ }
20
+ // Calculer les informations sur les instances
21
+ const currentCount = GroupeInstanceManager.getInstancesCount(groupe, responses);
22
+ const maxInstances = GroupeInstanceManager.getMaxInstances(groupe, responses);
23
+ const canAdd = GroupeInstanceManager.canAddInstance(groupe, responses);
24
+ const canRemove = GroupeInstanceManager.canRemoveInstance(groupe, responses);
25
+ // CORRECTION: Détecter les changements de maxInstances et forcer le re-rendu
26
+ useEffect(() => {
27
+ const newMaxInstances = GroupeInstanceManager.getMaxInstances(groupe, responses);
28
+ if (newMaxInstances !== maxInstances) {
29
+ console.log('GroupeInstanceTabs - Changement de maxInstances détecté:', {
30
+ groupeCode: groupe.code,
31
+ oldMaxInstances: maxInstances,
32
+ newMaxInstances,
33
+ codeVariable: groupe.codeVariable
34
+ });
35
+ setForceUpdate(prev => prev + 1);
36
+ }
37
+ }, [responses, groupe.codeVariable, groupe.maxInstances]);
38
+ // PROTECTION DES DONNÉES: Afficher toutes les instances existantes, même si la variable de contrôle est plus petite
39
+ // Le nombre d'onglets affichés = Math.max(maxInstances, instances existantes)
40
+ const minDisplayCount = Math.max(maxInstances, groupe.instances.length);
41
+ const displayedInstances = groupe.instances.slice(0, minDisplayCount);
42
+ console.log('GroupeInstanceTabs - Debug avec protection:', {
43
+ groupeCode: groupe.code,
44
+ codeVariable: groupe.codeVariable,
45
+ maxInstances,
46
+ totalInstances: groupe.instances.length,
47
+ minDisplayCount,
48
+ displayedInstances: displayedInstances.length,
49
+ canAdd: canAdd.canProceed,
50
+ canRemove: canRemove.canProceed,
51
+ canAddMessage: canAdd.constraints[0]?.message,
52
+ canRemoveMessage: canRemove.constraints[0]?.message
53
+ });
54
+ // Fonction pour déterminer l'état d'une instance
55
+ const getInstanceState = (instance) => {
56
+ const responseCount = Object.keys(instance.reponses).length;
57
+ if (responseCount === 0) {
58
+ return 'empty';
59
+ }
60
+ if (GroupeInstanceManager.isInstanceComplete(instance, groupe)) {
61
+ return 'complete';
62
+ }
63
+ return 'incomplete';
64
+ };
65
+ // Fonction pour obtenir l'icône et la couleur selon l'état
66
+ const getInstanceDisplay = (instance, isActive) => {
67
+ const state = getInstanceState(instance);
68
+ const baseClasses = `
69
+ flex items-center justify-center min-w-[3rem] h-10 px-3 rounded-lg font-medium text-sm
70
+ transition-all duration-200 cursor-pointer border-2
71
+ `;
72
+ let stateClasses = '';
73
+ let icon = null;
74
+ switch (state) {
75
+ case 'complete':
76
+ stateClasses = isActive
77
+ ? 'bg-blue-600 text-white border-blue-600 shadow-lg'
78
+ : 'bg-green-100 text-green-700 border-green-300 hover:bg-green-200';
79
+ icon = _jsx(Check, { className: "h-4 w-4 ml-1" });
80
+ break;
81
+ case 'incomplete':
82
+ stateClasses = isActive
83
+ ? 'bg-blue-600 text-white border-blue-600 shadow-lg'
84
+ : 'bg-green-100 text-orange-700 border-green-300 hover:bg-green-200';
85
+ icon = _jsx(AlertCircle, { className: "h-4 w-4 ml-1" });
86
+ break;
87
+ case 'empty':
88
+ stateClasses = isActive
89
+ ? 'bg-blue-600 text-white border-blue-600 shadow-lg'
90
+ : 'bg-gray-600 text-white border-gray-600 hover:bg-gray-700';
91
+ icon = _jsx(ExclamationIcon, { className: "h-4 w-4 ml-1" });
92
+ break;
93
+ }
94
+ return {
95
+ className: `${baseClasses} ${stateClasses}`,
96
+ icon
97
+ };
98
+ };
99
+ const handleInstanceClick = (instanceIndex) => {
100
+ // En mode consultation, permettre la navigation entre onglets mais pas les modifications
101
+ if (isProcessing)
102
+ return;
103
+ onInstanceChange(instanceIndex);
104
+ };
105
+ const handleAddInstance = async () => {
106
+ if (disabled || isProcessing)
107
+ return;
108
+ setIsProcessing(true);
109
+ setError(null);
110
+ try {
111
+ const result = GroupeInstanceManager.addInstance(groupe, responses);
112
+ if (result.success && result.instance) {
113
+ onInstanceAdded(result.instance);
114
+ }
115
+ else {
116
+ setError(result.error || 'Erreur lors de l\'ajout de l\'instance');
117
+ }
118
+ }
119
+ catch (err) {
120
+ setError('Erreur inattendue lors de l\'ajout de l\'instance');
121
+ console.error('Erreur ajout instance:', err);
122
+ }
123
+ finally {
124
+ setIsProcessing(false);
125
+ }
126
+ };
127
+ const handleRemoveInstanceClick = () => {
128
+ if (disabled || isProcessing || !groupe.instances)
129
+ return;
130
+ setShowDeleteConfirmation(true);
131
+ };
132
+ const handleConfirmRemoveInstance = async () => {
133
+ if (disabled || isProcessing || !groupe.instances)
134
+ return;
135
+ setShowDeleteConfirmation(false);
136
+ setIsProcessing(true);
137
+ setError(null);
138
+ try {
139
+ // Supprimer l'instance actuellement affichée (correction du bug)
140
+ const currentInstance = groupe.instances[currentInstanceIndex];
141
+ if (!currentInstance) {
142
+ setError('Aucune instance sélectionnée à supprimer');
143
+ return;
144
+ }
145
+ const result = GroupeInstanceManager.removeInstance(groupe, currentInstance.numeroInstance, responses);
146
+ if (result.success) {
147
+ onInstanceRemoved(currentInstance.numeroInstance);
148
+ }
149
+ else {
150
+ setError(result.error || 'Erreur lors de la suppression de l\'instance');
151
+ }
152
+ }
153
+ catch (err) {
154
+ setError('Erreur inattendue lors de la suppression de l\'instance');
155
+ console.error('Erreur suppression instance:', err);
156
+ }
157
+ finally {
158
+ setIsProcessing(false);
159
+ }
160
+ };
161
+ const handleCancelRemoveInstance = () => {
162
+ setShowDeleteConfirmation(false);
163
+ };
164
+ return (_jsxs("div", { className: "w-full", children: [_jsxs("div", { className: "flex items-center space-x-2 overflow-x-auto pb-2 relative", children: [_jsx("div", { className: "flex space-x-2 flex-shrink-0", children: displayedInstances.map((instance, index) => {
165
+ const isActive = index === currentInstanceIndex;
166
+ const display = getInstanceDisplay(instance, isActive);
167
+ return (_jsxs("button", { onClick: () => handleInstanceClick(index), disabled: isProcessing, className: display.className, title: `Instance ${instance.numeroInstance} - ${getInstanceState(instance) === 'complete' ? 'Complète' : getInstanceState(instance) === 'incomplete' ? 'Incomplète' : 'Vide'}`, children: [_jsx("span", { className: "font-semibold", children: instance.numeroInstance }), display.icon] }, instance.numeroInstance));
168
+ }) }), _jsx("div", { className: "h-6 w-px bg-gray-300 flex-shrink-0" }), _jsxs("div", { className: "flex items-center space-x-2 flex-shrink-0", children: [_jsx("button", { type: "button", onClick: handleAddInstance, disabled: disabled || isProcessing || !canAdd.canProceed, className: `p-2 rounded-lg transition-colors flex-shrink-0 ${disabled || isProcessing || !canAdd.canProceed
169
+ ? 'bg-gray-100 text-gray-400 cursor-not-allowed'
170
+ : 'bg-green-500 text-white hover:bg-green-600 focus:ring-2 focus:ring-green-500 focus:ring-offset-2'}`, title: canAdd.canProceed ? 'Ajouter une instance' : canAdd.constraints[0]?.message, children: _jsx(Plus, { className: "h-4 w-4" }) }), _jsx("button", { type: "button", onClick: handleRemoveInstanceClick, disabled: disabled || isProcessing || !canRemove.canProceed, className: `p-2 rounded-lg transition-colors flex-shrink-0 ${disabled || isProcessing || !canRemove.canProceed
171
+ ? 'bg-gray-100 text-gray-400 cursor-not-allowed'
172
+ : 'bg-red-500 text-white hover:bg-red-600 focus:ring-2 focus:ring-red-500 focus:ring-offset-2'}`, title: canRemove.canProceed ? 'Supprimer l\'instance courante' : canRemove.constraints[0]?.message, children: _jsx(Minus, { className: "h-4 w-4" }) }), isProcessing && (_jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600 flex-shrink-0" }))] })] }), error && (_jsxs("div", { className: "mt-2 p-2 bg-red-50 border border-red-200 rounded-lg shadow-sm", children: [_jsxs("div", { className: "flex items-start space-x-2", children: [_jsx(AlertTriangle, { className: "h-4 w-4 text-red-500 flex-shrink-0 mt-0.5" }), _jsx("div", { className: "text-sm text-red-700", children: error })] }), _jsx("button", { onClick: () => setError(null), className: "absolute top-1 right-1 text-red-400 hover:text-red-600", children: "\u00D7" })] })), showDeleteConfirmation && (_jsx(ConfirmationModal, { isOpen: showDeleteConfirmation, title: "Confirmer la suppression", message: `Êtes-vous sûr de vouloir supprimer l'instance ${groupe.instances?.[currentInstanceIndex]?.numeroInstance || currentInstanceIndex + 1} ? Cette action est irréversible.`, confirmText: "Supprimer", cancelText: "Annuler", onConfirm: handleConfirmRemoveInstance, onCancel: handleCancelRemoveInstance, type: "danger" }))] }));
173
+ };
174
+ export default GroupeInstanceTabs;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Modal de validation/rejet DR pour le FormRenderer
3
+ * RSU v2 - Package Partagé
4
+ */
5
+ import React from 'react';
6
+ export interface ValidationModalProps {
7
+ /** État d'ouverture de la modal */
8
+ isOpen: boolean;
9
+ /** Callback de fermeture */
10
+ onClose: () => void;
11
+ /** Callback de confirmation avec commentaire optionnel */
12
+ onConfirm: (commentaire?: string) => Promise<void>;
13
+ /** Action à effectuer: valider ou rejeter */
14
+ action: 'valider' | 'rejeter';
15
+ /** Nombre d'enquêtes concernées */
16
+ enquetesCount?: number;
17
+ /** État de chargement externe */
18
+ loading?: boolean;
19
+ }
20
+ /**
21
+ * Modal de validation/rejet d'enquête par le DR
22
+ */
23
+ export declare const ValidationModal: React.FC<ValidationModalProps>;
24
+ export default ValidationModal;
25
+ //# sourceMappingURL=ValidationModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationModal.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/ValidationModal.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,MAAM,WAAW,oBAAoB;IACnC,mCAAmC;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,4BAA4B;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,0DAA0D;IAC1D,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,6CAA6C;IAC7C,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAwI1D,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Modal de validation/rejet DR pour le FormRenderer
3
+ * RSU v2 - Package Partagé
4
+ */
5
+ 'use client';
6
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
+ import { useState } from 'react';
8
+ /**
9
+ * Modal de validation/rejet d'enquête par le DR
10
+ */
11
+ export const ValidationModal = ({ isOpen, onClose, onConfirm, action, enquetesCount = 1, loading = false }) => {
12
+ const [commentaire, setCommentaire] = useState('');
13
+ const [isSubmitting, setIsSubmitting] = useState(false);
14
+ if (!isOpen)
15
+ return null;
16
+ const handleConfirm = async () => {
17
+ setIsSubmitting(true);
18
+ try {
19
+ await onConfirm(commentaire || undefined);
20
+ setCommentaire('');
21
+ }
22
+ finally {
23
+ setIsSubmitting(false);
24
+ }
25
+ };
26
+ const handleClose = () => {
27
+ if (!isSubmitting) {
28
+ setCommentaire('');
29
+ onClose();
30
+ }
31
+ };
32
+ const isValider = action === 'valider';
33
+ const titre = isValider ? 'Valider l\'enquête' : 'Rejeter l\'enquête';
34
+ const couleurBouton = isValider ? 'bg-green-600 hover:bg-green-700' : 'bg-red-600 hover:bg-red-700';
35
+ return (_jsxs("div", { className: "fixed inset-0 z-50 overflow-y-auto", children: [_jsx("div", { className: "fixed inset-0 bg-black bg-opacity-50 transition-opacity", onClick: handleClose }), _jsx("div", { className: "flex min-h-full items-center justify-center p-4", children: _jsxs("div", { className: "relative bg-white rounded-lg shadow-xl max-w-md w-full p-6", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsxs("div", { className: "flex items-center space-x-3", children: [_jsx("div", { className: `${isValider ? 'text-green-600' : 'text-red-600'}`, children: isValider ? (_jsx("svg", { className: "w-6 h-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) })) : (_jsx("svg", { className: "w-6 h-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) })) }), _jsx("h3", { className: "text-lg font-semibold text-gray-900", children: titre })] }), _jsx("button", { onClick: handleClose, disabled: isSubmitting, className: "text-gray-400 hover:text-gray-600 transition-colors disabled:opacity-50", children: _jsx("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsxs("div", { className: "mb-6", children: [_jsxs("p", { className: "text-gray-700 mb-4", children: ["\u00CAtes-vous s\u00FBr de vouloir ", isValider ? 'valider' : 'rejeter', ' ', _jsxs("span", { className: "font-semibold", children: [enquetesCount, " enqu\u00EAte", enquetesCount > 1 ? 's' : ''] }), " ?"] }), !isValider && (_jsxs("div", { children: [_jsx("label", { htmlFor: "commentaire", className: "block text-sm font-medium text-gray-700 mb-2", children: "Commentaire (optionnel)" }), _jsx("textarea", { id: "commentaire", value: commentaire, onChange: (e) => setCommentaire(e.target.value), disabled: isSubmitting, rows: 4, className: "w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-red-500 disabled:bg-gray-100 disabled:cursor-not-allowed text-gray-900 placeholder:text-gray-400", placeholder: "Indiquez la raison du rejet (optionnel)..." }), _jsx("p", { className: "mt-1 text-xs text-gray-500", children: "Maximum 500 caract\u00E8res" })] }))] }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx("button", { onClick: handleClose, disabled: isSubmitting, className: "px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: "Annuler" }), _jsx("button", { onClick: handleConfirm, disabled: isSubmitting, className: `px-4 py-2 text-sm font-medium text-white rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${couleurBouton}`, children: isSubmitting ? (_jsxs("span", { className: "flex items-center", children: [_jsxs("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4 text-white", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), "Traitement..."] })) : ('Confirmer') })] })] }) })] }));
36
+ };
37
+ export default ValidationModal;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Exports du module form-renderer
3
+ * RSU v2 - Composants partagés de rendu de formulaires
4
+ */
5
+ export { default as ConfirmationModal } from './ConfirmationModal';
6
+ export type { ConfirmationModalProps, ConfirmationModalType } from './ConfirmationModal';
7
+ export { default as ValidationModal } from './ValidationModal';
8
+ export type { ValidationModalProps } from './ValidationModal';
9
+ export { default as GroupeInstanceTabs } from './GroupeInstanceTabs';
10
+ export type { GroupeInstanceTabsProps } from './GroupeInstanceTabs';
11
+ export { FormRendererProvider, useFormRendererContext, useFormRendererNavigation, useFormRendererValidation, useFormRendererInstances, useFormRendererConfig, useFormRendererResponses, useFormRendererState, type FormRendererContextValue, type FormRendererProviderProps } from './FormRendererContext';
12
+ export { default as FormProgress } from './FormProgress';
13
+ export type { FormProgressProps } from './FormProgress';
14
+ export { default as FormNavigationButtons } from './FormNavigationButtons';
15
+ export type { FormNavigationButtonsProps } from './FormNavigationButtons';
16
+ export { default as FormActions } from './FormActions';
17
+ export type { FormActionsProps } from './FormActions';
18
+ export { default as FormRenderer, type FormRendererProps } from './FormRenderer';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrE,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAMpE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC/B,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,YAAY,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAMtD,OAAO,EACL,OAAO,IAAI,YAAY,EACvB,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Exports du module form-renderer
3
+ * RSU v2 - Composants partagés de rendu de formulaires
4
+ */
5
+ // ========================================
6
+ // COMPOSANTS UI DE BASE
7
+ // ========================================
8
+ export { default as ConfirmationModal } from './ConfirmationModal';
9
+ export { default as ValidationModal } from './ValidationModal';
10
+ export { default as GroupeInstanceTabs } from './GroupeInstanceTabs';
11
+ // ========================================
12
+ // CONTEXTE ET PROVIDER
13
+ // ========================================
14
+ export { FormRendererProvider, useFormRendererContext, useFormRendererNavigation, useFormRendererValidation, useFormRendererInstances, useFormRendererConfig, useFormRendererResponses, useFormRendererState } from './FormRendererContext';
15
+ // ========================================
16
+ // SOUS-COMPOSANTS DU FORM RENDERER
17
+ // ========================================
18
+ export { default as FormProgress } from './FormProgress';
19
+ export { default as FormNavigationButtons } from './FormNavigationButtons';
20
+ export { default as FormActions } from './FormActions';
21
+ // ========================================
22
+ // COMPOSANT PRINCIPAL FORM RENDERER
23
+ // ========================================
24
+ export { default as FormRenderer } from './FormRenderer';
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Hook de gestion des instances multiples pour les formulaires d'enquête
3
+ * Gère l'ajout, la suppression et la synchronisation des instances de groupes
4
+ * RSU v2 - Package Partagé
5
+ */
6
+ import { GroupeFormulaire, GroupeInstance, EnqueteReponse } from '../types/enquete';
7
+ export interface UseFormInstancesOptions {
8
+ /** Callback appelé lors de l'ajout d'une instance */
9
+ onInstanceAdded?: (instance: GroupeInstance) => void;
10
+ /** Callback appelé lors de la suppression d'une instance */
11
+ onInstanceRemoved?: (instanceNumber: number) => void;
12
+ /** Callback appelé lors du changement d'instance active */
13
+ onInstanceChange?: (instanceIndex: number) => void;
14
+ /** Callback appelé lors de la mise à jour des groupes */
15
+ onGroupesUpdated?: (groupes: GroupeFormulaire[]) => void;
16
+ /** Mode debug */
17
+ debug?: boolean;
18
+ }
19
+ export interface UseFormInstancesResult {
20
+ /** Groupes avec leurs instances initialisées */
21
+ groupesWithInstances: GroupeFormulaire[];
22
+ /** Index de l'instance actuellement active */
23
+ currentInstanceIndex: number;
24
+ /** Instance actuellement active */
25
+ currentInstance: GroupeInstance | undefined;
26
+ /** Ajouter une instance au groupe actuel */
27
+ addInstance: (groupe: GroupeFormulaire, responses: Record<string, EnqueteReponse>) => {
28
+ success: boolean;
29
+ instance?: GroupeInstance;
30
+ error?: string;
31
+ };
32
+ /** Supprimer une instance du groupe actuel */
33
+ removeInstance: (groupe: GroupeFormulaire, instanceNumber: number, responses: Record<string, EnqueteReponse>) => {
34
+ success: boolean;
35
+ error?: string;
36
+ };
37
+ /** Changer d'instance active */
38
+ changeInstance: (instanceIndex: number) => void;
39
+ /** Synchroniser les réponses avec l'instance */
40
+ syncInstanceResponses: (instance: GroupeInstance, groupe: GroupeFormulaire, allResponses: Record<string, EnqueteReponse>) => void;
41
+ /** Mettre à jour les propriétés d'un groupe */
42
+ updateGroupeProperties: (groupe: GroupeFormulaire, responses: Record<string, EnqueteReponse>) => void;
43
+ /** Initialiser les groupes avec instances */
44
+ initializeGroupesWithInstances: (groupes: GroupeFormulaire[], responses: Record<string, EnqueteReponse>) => GroupeFormulaire[];
45
+ /** Vérifier si une instance est complète */
46
+ isInstanceComplete: (instance: GroupeInstance, groupe: GroupeFormulaire) => boolean;
47
+ /** Peut-on ajouter une instance ? */
48
+ canAddInstance: (groupe: GroupeFormulaire, responses: Record<string, EnqueteReponse>) => {
49
+ canProceed: boolean;
50
+ constraints: Array<{
51
+ message: string;
52
+ }>;
53
+ };
54
+ /** Peut-on supprimer une instance ? */
55
+ canRemoveInstance: (groupe: GroupeFormulaire, responses: Record<string, EnqueteReponse>) => {
56
+ canProceed: boolean;
57
+ constraints: Array<{
58
+ message: string;
59
+ }>;
60
+ };
61
+ /** Mettre à jour les groupes avec instances */
62
+ setGroupesWithInstances: React.Dispatch<React.SetStateAction<GroupeFormulaire[]>>;
63
+ }
64
+ /**
65
+ * Hook pour gérer les instances multiples dans un formulaire d'enquête
66
+ *
67
+ * @param initialGroupes - Liste initiale des groupes du formulaire
68
+ * @param initialResponses - Réponses initiales
69
+ * @param options - Options de configuration
70
+ * @returns Objet contenant l'état et les fonctions de gestion des instances
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * const {
75
+ * groupesWithInstances,
76
+ * addInstance,
77
+ * removeInstance,
78
+ * currentInstance
79
+ * } = useFormInstances(formulaire.groupes, enquete.reponses, {
80
+ * onInstanceAdded: (instance) => console.log('Added:', instance),
81
+ * onInstanceRemoved: (num) => console.log('Removed:', num)
82
+ * });
83
+ * ```
84
+ */
85
+ export declare function useFormInstances(initialGroupes: GroupeFormulaire[], initialResponses: Record<string, EnqueteReponse>, options?: UseFormInstancesOptions): UseFormInstancesResult;
86
+ export default useFormInstances;
87
+ //# sourceMappingURL=useFormInstances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFormInstances.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormInstances.ts"],"names":[],"mappings":"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"}