diff --git a/package-lock.json b/package-lock.json
index b9f9b87d..44324acb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2630,9 +2630,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-alignment/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -3143,9 +3143,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-autosave/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -4125,9 +4125,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-bookmark/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -7240,9 +7240,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-clipboard/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -7757,9 +7757,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-code-block/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -8283,9 +8283,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-editor-balloon/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -8799,9 +8799,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-editor-decoupled/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -8902,9 +8902,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-editor-inline/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -9005,9 +9005,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-editor-multi-root/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -9124,9 +9124,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-emoji/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -9234,9 +9234,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-enter/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -9749,9 +9749,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-find-and-replace/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -9852,9 +9852,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-font/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -9971,9 +9971,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-fullscreen/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -10485,9 +10485,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-highlight/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -10588,9 +10588,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-horizontal-line/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -10691,9 +10691,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-html-embed/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -10901,9 +10901,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-html-support/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -11847,9 +11847,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-language/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -12789,9 +12789,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-markdown-gfm/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -13318,9 +13318,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-mention/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -13420,9 +13420,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-minimap/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -13523,9 +13523,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-page-break/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -14061,9 +14061,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-remove-format/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -14164,9 +14164,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-restricted-editing/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -14266,9 +14266,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-select-all/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -14368,9 +14368,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-show-blocks/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -14471,9 +14471,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-source-editing/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -14587,9 +14587,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-special-characters/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -14743,9 +14743,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-style/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -15255,9 +15255,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-theme-lark/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -15383,9 +15383,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-undo/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -15482,9 +15482,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-upload/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -15593,9 +15593,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-watchdog/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -15711,9 +15711,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-widget/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -15813,9 +15813,9 @@
}
},
"node_modules/@ckeditor/ckeditor5-word-count/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -19567,9 +19567,9 @@
}
},
"node_modules/@types/react-dom": {
- "version": "19.2.2",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz",
- "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==",
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"license": "MIT",
"peer": true,
"peerDependencies": {
@@ -22017,9 +22017,9 @@
}
},
"node_modules/ckeditor5/node_modules/color-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
- "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"license": "MIT",
"peer": true,
"engines": {
@@ -28911,9 +28911,9 @@
}
},
"node_modules/mdast-util-to-hast": {
- "version": "13.2.0",
- "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz",
- "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
+ "version": "13.2.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz",
+ "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==",
"license": "MIT",
"peer": true,
"dependencies": {
@@ -31881,6 +31881,23 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/prettier": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+ "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
"node_modules/pretty-bytes": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
diff --git a/src/PagesAdm/gestao.css b/src/PagesAdm/gestao.css
index 5991041d..9951eae1 100644
--- a/src/PagesAdm/gestao.css
+++ b/src/PagesAdm/gestao.css
@@ -1,4 +1,3 @@
-
.dashboard-container {
padding: 2rem;
font-family: 'Arial', sans-serif;
@@ -6,7 +5,6 @@
min-height: 100vh;
}
-
.dashboard-header {
display: flex;
justify-content: space-between;
@@ -34,143 +32,133 @@
border: none;
border-radius: 8px;
font-size: 1rem;
+ font-weight: 600;
cursor: pointer;
- transition: background-color 0.3s, transform 0.25s ease, box-shadow 0.25s ease;
+ transition: all 0.3s ease;
+ box-shadow: 0 2px 8px rgba(30, 58, 138, 0.3);
}
.new-user-btn:hover {
background-color: #162d6b;
transform: translateY(-2px);
- box-shadow: 0px 4px 12px rgba(30, 58, 138, 0.3);
+ box-shadow: 0 4px 12px rgba(30, 58, 138, 0.4);
}
-
.filters-container {
background: #fff;
border-radius: 12px;
- padding: 1.5rem;
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+ padding: 1.2rem;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
margin-bottom: 2rem;
- transition: transform 0.2s ease, box-shadow 0.2s ease;
-}
-
-.filters-container:hover {
- transform: translateY(-3px);
- box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
}
.filters-title {
- font-size: 18px;
+ font-size: 16px;
font-weight: bold;
margin-bottom: 0.3rem;
color: #333;
}
.filters-subtitle {
- font-size: 0.9rem;
+ font-size: 0.85rem;
color: #666;
margin-bottom: 1rem;
}
.filters-content {
display: flex;
- gap: 1rem;
+ gap: 0.8rem;
align-items: center;
}
.filters-input {
flex: 1;
- padding: 0.6rem 1rem;
+ padding: 0.5rem 0.8rem;
border: 1px solid #d1d5db;
- border-radius: 8px;
- font-size: 0.95rem;
+ border-radius: 6px;
+ font-size: 0.9rem;
color: #333;
- transition: border-color 0.2s, box-shadow 0.2s;
+ min-width: 200px;
+ transition: all 0.2s ease;
}
.filters-input:focus {
border-color: #1e3a8a;
- box-shadow: 0px 0px 0px 3px rgba(30, 58, 138, 0.2);
+ box-shadow: 0 0 0 2px rgba(30, 58, 138, 0.1);
outline: none;
}
.filters-select {
- padding: 0.6rem 1rem;
+ padding: 0.5rem 0.8rem;
border: 1px solid #d1d5db;
- border-radius: 8px;
- font-size: 0.95rem;
+ border-radius: 6px;
+ font-size: 0.9rem;
background: #fff;
color: #333;
cursor: pointer;
- transition: border-color 0.2s, box-shadow 0.2s;
+ min-width: 140px;
+ transition: all 0.2s ease;
}
.filters-select:focus {
border-color: #1e3a8a;
- box-shadow: 0px 0px 0px 3px rgba(30, 58, 138, 0.2);
+ box-shadow: 0 0 0 2px rgba(30, 58, 138, 0.1);
outline: none;
}
-
.cards-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
- gap: 1.5rem;
+ gap: 1.2rem;
margin-bottom: 2rem;
}
.card {
background-color: white;
- padding: 1.5rem;
- border-radius: 12px;
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+ padding: 1.2rem;
+ border-radius: 10px;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
border: 1px solid transparent;
- transition: transform 0.25s ease, box-shadow 0.25s ease, border 0.25s ease, background 0.25s ease;
+ transition: all 0.25s ease;
cursor: pointer;
}
.highlight:hover {
- transform: translateY(-6px);
- box-shadow: 0 8px 20px rgba(30, 58, 138, 0.2);
+ transform: translateY(-4px);
+ box-shadow: 0 6px 16px rgba(30, 58, 138, 0.2);
background: #f8faff;
border: 1px solid #1e3a8a33;
}
.card-label {
- font-size: 0.9rem;
+ font-size: 0.85rem;
color: #999;
margin-bottom: 0.5rem;
}
.card-value {
- font-size: 1.8rem;
+ font-size: 1.6rem;
font-weight: bold;
margin: 0;
color: #333;
}
.card-extra {
- font-size: 0.85rem;
+ font-size: 0.8rem;
color: #666;
}
.card-extra.positive {
color: #1e3a8a;
+ font-weight: 600;
}
-
.user-table-container {
background: #fff;
border-radius: 12px;
- padding: 1.5rem;
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
+ padding: 1.2rem;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
margin-top: 2rem;
- transition: transform 0.25s ease, box-shadow 0.25s ease;
-}
-
-.user-table-container:hover {
- transform: translateY(-4px);
- box-shadow: 0 6px 14px rgba(0,0,0,0.15);
}
.user-table-container h2 {
@@ -193,7 +181,7 @@
.user-table th,
.user-table td {
- padding: 12px 15px;
+ padding: 10px 12px;
text-align: left;
border-bottom: 1px solid #e0e0e0;
}
@@ -202,10 +190,11 @@
background-color: #f3f4f6;
color: #333;
font-weight: 600;
+ font-size: 0.9rem;
}
.user-table tr {
- transition: background-color 0.25s ease;
+ transition: background-color 0.2s ease;
}
.user-table tr:hover {
@@ -214,44 +203,115 @@
.profile-badge {
background-color: #1e3a8a;
- color: #f7f7f7;
- padding: 3px 8px;
- border-radius: 8px;
- font-size: 0.85rem;
+ color: white;
+ padding: 4px 10px;
+ border-radius: 6px;
+ font-size: 0.8rem;
+ font-weight: 500;
display: inline-block;
}
.status-badge {
- padding: 3px 8px;
- border-radius: 8px;
- font-size: 0.85rem;
+ padding: 4px 10px;
+ border-radius: 6px;
+ font-size: 0.8rem;
color: #fff;
+ font-weight: 500;
display: inline-block;
text-transform: capitalize;
}
.status-badge.ativo {
- background-color: #28a745;
+ background-color: #1e3a8a;
}
.status-badge.inativo {
- background-color: #dc3545;
+ background-color: #6c757d;
}
.actions {
display: flex;
- gap: 10px;
+ gap: 8px;
+ flex-wrap: wrap;
}
-.action-icon {
+.action-btn {
+ border: none;
+ padding: 6px 12px;
+ font-size: 0.8rem;
+ font-weight: 500;
cursor: pointer;
- color: #555;
- transition: color 0.2s, transform 0.2s;
+ transition: all 0.2s ease;
+ border-radius: 4px;
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
}
-.action-icon:hover {
- color: #1e3a8a;
- transform: scale(1.2);
+.action-btn.detalhes {
+ background-color: #e6f2ff;
+ color: #004085;
+ border: 1px solid #b8d4ff;
+}
+
+.action-btn.detalhes:hover {
+ background-color: #cce4ff;
+ transform: translateY(-1px);
+}
+
+.action-btn.editar {
+ background-color: #fff3cd;
+ color: #856405;
+ border: 1px solid #ffeaa7;
+}
+
+.action-btn.editar:hover {
+ background-color: #ffeaa7;
+ transform: translateY(-1px);
+}
+
+.action-btn.excluir {
+ background-color: #f8d7da;
+ color: #721c24;
+ border: 1px solid #f1b0b7;
+}
+
+.action-btn.excluir:hover {
+ background-color: #f1b0b7;
+ transform: translateY(-1px);
+}
+
+.save-btn {
+ background-color: #1e3a8a;
+ color: white;
+ border: none;
+ padding: 8px 16px;
+ border-radius: 6px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.3s ease;
+}
+
+.save-btn:hover {
+ background-color: #162d6b;
+ transform: translateY(-1px);
+ box-shadow: 0 4px 8px rgba(30, 58, 138, 0.3);
+}
+
+.edit-btn {
+ background-color: #fff3cd;
+ color: #856405;
+ border: 1px solid #ffeaa7;
+ padding: 8px 16px;
+ border-radius: 6px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.3s ease;
+}
+
+.edit-btn:hover {
+ background-color: #ffeaa7;
+ transform: translateY(-1px);
}
html[data-bs-theme="dark"] .dashboard-container {
@@ -266,18 +326,17 @@ html[data-bs-theme="dark"] .dashboard-subtitle {
}
html[data-bs-theme="dark"] .new-user-btn {
- background-color: #2563eb;
- color: #fff;
+ background-color: #1e3a8a;
}
html[data-bs-theme="dark"] .new-user-btn:hover {
- background-color: #1e40af;
+ background-color: #162d6b;
}
html[data-bs-theme="dark"] .filters-container,
html[data-bs-theme="dark"] .user-table-container {
background: #1a1a1a;
- box-shadow: 0 4px 6px rgba(0,0,0,0.4);
+ box-shadow: 0 2px 8px rgba(0,0,0,0.4);
}
html[data-bs-theme="dark"] .filters-title,
@@ -299,19 +358,19 @@ html[data-bs-theme="dark"] .filters-select {
html[data-bs-theme="dark"] .filters-input:focus,
html[data-bs-theme="dark"] .filters-select:focus {
- border-color: #2563eb;
- box-shadow: 0px 0px 0px 3px rgba(37, 99, 235, 0.2);
+ border-color: #1e3a8a;
+ box-shadow: 0 0 0 2px rgba(30, 58, 138, 0.2);
}
html[data-bs-theme="dark"] .cards-container .card {
background-color: #181818;
color: #e0e0e0;
- box-shadow: 0 4px 6px rgba(0,0,0,0.4);
+ box-shadow: 0 2px 6px rgba(0,0,0,0.4);
}
html[data-bs-theme="dark"] .highlight:hover {
- background: #232a3a;
- border: 1px solid #2563eb33;
+ background: #1a1f2e;
+ border: 1px solid #1e3a8a33;
}
html[data-bs-theme="dark"] .card-label {
@@ -327,7 +386,7 @@ html[data-bs-theme="dark"] .card-extra {
}
html[data-bs-theme="dark"] .card-extra.positive {
- color: #2563eb;
+ color: #1e3a8a;
}
html[data-bs-theme="dark"] .user-table th {
@@ -341,26 +400,39 @@ html[data-bs-theme="dark"] .user-table td {
}
html[data-bs-theme="dark"] .user-table tr:hover {
- background-color: #232a3a;
+ background-color: #1a1f2e;
}
html[data-bs-theme="dark"] .profile-badge {
- background-color: #2563eb;
- color: #fff;
+ background-color: #1e3a8a;
}
-html[data-bs-theme="dark"] .status-badge.ativo {
- background-color: #28a745;
+html[data-bs-theme="dark"] .action-btn.detalhes {
+ background-color: #e6f2ff;
+ color: #004085;
+ border: 1px solid #b8d4ff;
}
-html[data-bs-theme="dark"] .status-badge.inativo {
- background-color: #dc3545;
+html[data-bs-theme="dark"] .action-btn.detalhes:hover {
+ background-color: #cce4ff;
}
-html[data-bs-theme="dark"] .action-icon {
- color: #bdbdbd;
+html[data-bs-theme="dark"] .action-btn.editar {
+ background-color: #fff3cd;
+ color: #856405;
+ border: 1px solid #ffeaa7;
}
-html[data-bs-theme="dark"] .action-icon:hover {
- color: #2563eb;
+html[data-bs-theme="dark"] .action-btn.editar:hover {
+ background-color: #ffeaa7;
+}
+
+html[data-bs-theme="dark"] .action-btn.excluir {
+ background-color: #f8d7da;
+ color: #721c24;
+ border: 1px solid #f1b0b7;
+}
+
+html[data-bs-theme="dark"] .action-btn.excluir:hover {
+ background-color: #f1b0b7;
}
\ No newline at end of file
diff --git a/src/PagesAdm/gestao.jsx b/src/PagesAdm/gestao.jsx
index 7d982b9c..a5ecd889 100644
--- a/src/PagesAdm/gestao.jsx
+++ b/src/PagesAdm/gestao.jsx
@@ -1,14 +1,9 @@
-
import React from "react";
import "./gestao.css";
-import { FaEdit, FaTrash } from "react-icons/fa";
-
function UserDashboard() {
return (
-
-
-
+
Gestão de Usuários
@@ -91,8 +86,9 @@ function UserDashboard() {
Ativo |
20/12/2024, 08:30 |
-
-
+
+
+
|
@@ -103,8 +99,9 @@ function UserDashboard() {
| Ativo |
19/12/2024, 14:20 |
-
-
+
+
+
|
@@ -115,8 +112,9 @@ function UserDashboard() {
| Ativo |
20/12/2024, 07:45 |
-
-
+
+
+
|
@@ -127,8 +125,9 @@ function UserDashboard() {
| Inativo |
15/12/2024, 16:30 |
-
-
+
+
+
|
@@ -138,5 +137,4 @@ function UserDashboard() {
);
}
-
export default UserDashboard;
\ No newline at end of file
diff --git a/src/PagesMedico/DoctorAgendamentoManager.jsx b/src/PagesMedico/DoctorAgendamentoManager.jsx
index 34eb2946..d89a68fb 100644
--- a/src/PagesMedico/DoctorAgendamentoManager.jsx
+++ b/src/PagesMedico/DoctorAgendamentoManager.jsx
@@ -1,22 +1,14 @@
-import React, { useState, useMemo, useEffect, useCallback } from "react";
-import { useNavigate } from "react-router-dom";
-import API_KEY from "../components/utils/apiKeys.js";
-import AgendamentoCadastroManager from "../pages/AgendamentoCadastroManager.jsx";
-// Removidos imports não utilizados no novo fluxo
-import { GetAllDoctors } from "../components/utils/Functions-Endpoints/Doctor.js";
-import { useAuth } from "../components/utils/AuthProvider.js";
-import dayjs from "dayjs";
-import "dayjs/locale/pt-br";
-import isBetween from "dayjs/plugin/isBetween";
-import localeData from "dayjs/plugin/localeData";
-import {
- Search,
- ChevronLeft,
- ChevronRight,
- Edit,
- Trash2,
- CheckCircle,
-} from "lucide-react";
+import React, { useState, useMemo, useEffect, useCallback } from 'react';
+import { useNavigate } from 'react-router-dom';
+import API_KEY from '../components/utils/apiKeys.js';
+import AgendamentoCadastroManager from '../pages/AgendamentoCadastroManager.jsx';
+import { GetAllDoctors } from '../components/utils/Functions-Endpoints/Doctor.js';
+import { useAuth } from '../components/utils/AuthProvider.js';
+import dayjs from 'dayjs';
+import 'dayjs/locale/pt-br';
+import isBetween from 'dayjs/plugin/isBetween';
+import localeData from 'dayjs/plugin/localeData';
+import { Search, ChevronLeft, ChevronRight, Edit, Trash2, CheckCircle } from 'lucide-react';
import "../pages/style/Agendamento.css";
import "../pages/style/FilaEspera.css";
import Spinner from "../components/Spinner.jsx";
@@ -30,8 +22,8 @@ const Agendamento = () => {
const { getAuthorizationHeader, user } = useAuth();
const authHeader = getAuthorizationHeader();
- // ID do médico que você quer visualizar
- const ID_MEDICO_ESPECIFICO = "078d2a67-b4c1-43c8-ae32-c1e75bb5b3df";
+
+ const ID_MEDICO_ESPECIFICO = "078d2a67-b4c1-43c8-ae32-c1e75bb5b3df";
const [listaTodosAgendamentos, setListaTodosAgendamentos] = useState([]);
const [selectedID, setSelectedId] = useState("0");
@@ -63,21 +55,17 @@ const Agendamento = () => {
year: currentDate.year(),
});
- // ✨ ALTERAÇÃO PRINCIPAL: A busca agora filtra pelo ID do médico direto na API
- const fetchAppointments = useCallback(async () => {
- if (!authHeader) return;
- setShowSpinner(true);
- const myHeaders = new Headers();
- myHeaders.append("Authorization", authHeader);
- myHeaders.append("apikey", API_KEY);
- const requestOptions = {
- method: "GET",
- headers: myHeaders,
- redirect: "follow",
- };
- // A URL agora contém o filtro para o ID do médico específico
- const apiUrl = `https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?doctor_id=eq.${ID_MEDICO_ESPECIFICO}&select=*`;
+ const fetchAppointments = useCallback(async () => {
+ if (!authHeader) return;
+ setShowSpinner(true);
+ const myHeaders = new Headers();
+ myHeaders.append("Authorization", authHeader);
+ myHeaders.append("apikey", API_KEY);
+ const requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' };
+
+
+ const apiUrl = `https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?doctor_id=eq.${ID_MEDICO_ESPECIFICO}&select=*`;
try {
const res = await fetch(apiUrl, requestOptions);
@@ -163,36 +151,33 @@ const Agendamento = () => {
[updateAppointmentStatus]
);
- useEffect(() => {
- if (authHeader) {
- fetchAppointments();
- // A busca de todos os médicos pode continuar caso a secretária precise ver a lista
- if (user?.role !== "doctor") {
- GetAllDoctors(authHeader).then((docs) => {
- if (docs) {
- setListaDeMedicos(
- docs.map((d) => ({ nomeMedico: d.full_name, idMedico: d.id }))
- );
- }
- });
- }
- }
- }, [authHeader, fetchAppointments, user?.role]);
+ useEffect(() => {
+ if(authHeader) {
+ fetchAppointments();
+
+ if (user?.role !== 'doctor') {
+ GetAllDoctors(authHeader).then(docs => {
+ if (docs) {
+ setListaDeMedicos(docs.map(d => ({ nomeMedico: d.full_name, idMedico: d.id })));
+ }
+ });
+ }
+ }
+ }, [authHeader, fetchAppointments, user?.role]);
- useEffect(() => {
- const processData = async () => {
- // Como os dados já vêm filtrados da API, não precisamos mais da verificação de 'user' aqui
- if (!listaTodosAgendamentos.length) {
- setAgendamentosOrganizados({});
- setFilaEsperaData([]);
- return;
- }
+ useEffect(() => {
+ const processData = async () => {
+
+ if (!listaTodosAgendamentos.length) {
+ setAgendamentosOrganizados({});
+ setFilaEsperaData([]);
+ return;
+ }
setShowSpinner(true);
- // ✨ SIMPLIFICAÇÃO: Não é mais necessário filtrar por `user.role`,
- // pois a API já retornou apenas os agendamentos do médico desejado.
- const appointmentsToShow = listaTodosAgendamentos;
+
+ const appointmentsToShow = listaTodosAgendamentos;
const patientIdsToFetch = new Set();
const doctorIdsToFetch = new Set();
@@ -208,19 +193,16 @@ const Agendamento = () => {
const fetchPromises = [];
- if (patientIdsToFetch.size > 0) {
- const query = `id=in.(${Array.from(patientIdsToFetch).join(",")})`;
- fetchPromises.push(
- fetch(
- `https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients?${query}&select=*`,
- {
- headers: { apikey: API_KEY, Authorization: authHeader },
+ if (patientIdsToFetch.size > 0) {
+ const query = `id=in.(${Array.from(patientIdsToFetch).join(',')})`;
+ fetchPromises.push(
+ fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients?${query}&select=*`, {
+ headers: { apikey: API_KEY, Authorization: authHeader }
+ }).then(res => res.json())
+ );
+ } else {
+ fetchPromises.push(Promise.resolve(null));
}
- ).then((res) => res.json())
- );
- } else {
- fetchPromises.push(Promise.resolve(null)); // Mantém a ordem do Promise.all
- }
if (doctorIdsToFetch.size > 0) {
const query = `id=in.(${Array.from(doctorIdsToFetch).join(",")})`;
@@ -289,10 +271,10 @@ const Agendamento = () => {
setShowSpinner(false);
};
- processData();
- }, [listaTodosAgendamentos, authHeader]); // Removido 'user' das dependências pois não é mais usado aqui
+ processData();
+ }, [listaTodosAgendamentos, authHeader]);
+
- // O restante do código permanece o mesmo...
const handleEditConsulta = (agendamento) => {
setAgendamentoParaEdicao(agendamento);
@@ -323,59 +305,28 @@ const Agendamento = () => {
return grid;
};
- const dateGrid = useMemo(() => generateDateGrid(), [currentDate]);
- const weekDays = ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"];
- const handleDateClick = (day) => setSelectedDay(day);
- const DeleteModal = () => (
-
-
-
-
-
Confirmação de Cancelamento
-
-
-
-
Qual o motivo do cancelamento? (Opcional)
-
-
-
-
- {/* ✨ Botão sempre ativo ✨ */}
-
-
+ const dateGrid = useMemo(() => generateDateGrid(), [currentDate]);
+ const weekDays = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'];
+ const handleDateClick = (day) => setSelectedDay(day);
+const DeleteModal = () => (
+
+
+
+
+
Confirmação de Cancelamento
+
+
+
Qual o motivo do cancelamento?
+
+
+
+
+
+
+
-
);
@@ -458,561 +409,320 @@ const Agendamento = () => {
setSelectedDay(newDate);
};
- return (
-
-
Agendar nova consulta
- {!PageNovaConsulta ? (
-
- {user?.role !== "doctor" && (
-
-
-
-
-
- handleSearchMedicos(e.target.value)}
- />
-
-
- {searchTermDoctor && FiltredTodosMedicos.length > 0 && (
-
- {FiltredTodosMedicos.map((medico) => (
-
{
- setSearchTermDoctor(medico.nomeMedico);
- setFiltredTodosMedicos([]);
- setMedicoFiltrado({ id: medico.idMedico });
- }}
- >
-
{medico.nomeMedico}
-
- ))}
-
- )}
-
-
+ return (
+
+
Agendar nova consulta
+
+
+
+
- )}
-
-
-
-
-
-
-
-
-
-
-
-
- {!FiladeEspera ? (
-
-
-
- {selectedDay.format("MMM")}
- {selectedDay.format("DD")}
-
-
-
{selectedDay.format("dddd")}
-
{selectedDay.format("D [de] MMMM [de] YYYY")}
-
-
-
Consultas para {selectedDay.format("DD/MM")}
- {showSpinner ? (
-
- ) : DictAgendamentosOrganizados[
- selectedDay.format("YYYY-MM-DD")
- ]?.filter(
- (app) =>
- MedicoFiltrado.id === "vazio" ||
- app.doctor_id === MedicoFiltrado.id
- ).length > 0 ? (
- DictAgendamentosOrganizados[
- selectedDay.format("YYYY-MM-DD")
- ]
- .filter(
- (app) =>
- MedicoFiltrado.id === "vazio" ||
- app.doctor_id === MedicoFiltrado.id
- )
- .map((app) => (
-
-
- {dayjs(app.scheduled_at).format("HH:mm")}
-
-
- {app.paciente_nome}
- Dr(a). {app.medico_nome}
-
-
- {app.status === "cancelled" ? (
-
- ) : (
-
- )}
- {app.status !== "cancelled" && (
-
- )}
-
-
- ))
- ) : (
-
-
Nenhuma consulta agendada.
-
- )}
-
-
-
-
-
- Realizado
-
-
- Confirmado
-
-
- Agendado
-
-
- Cancelado
-
-
-
-
-
{currentDate.format("MMMM [de] YYYY")}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {weekDays.map((day) => (
-
- {day}
-
- ))}
- {dateGrid.map((day, index) => {
- const dayString = day.format("YYYY-MM-DD");
- const appointmentsOnDay =
- DictAgendamentosOrganizados[dayString] || [];
- const filteredAppointments = appointmentsOnDay.filter(
- (app) =>
- MedicoFiltrado.id === "vazio" ||
- app.doctor_id === MedicoFiltrado.id
- );
- const cellClasses = `day-cell ${
- day.isSame(currentDate, "month")
- ? "current-month"
- : "other-month"
- } ${day.isSame(dayjs(), "day") ? "today" : ""} ${
- day.isSame(selectedDay, "day") ? "selected" : ""
- }`;
- return (
-
handleDateClick(day)}
- >
-
{day.format("D")}
- {filteredAppointments.length > 0 && (
-
- {filteredAppointments.length}
-
- )}
-
- );
- })}
-
-
-
- ) : (
-
-
-
-
-
-
Fila de Espera
-
-
+ {!PageNovaConsulta ? (
+
+ {user?.role !== 'doctor' && (
-
- {" "}
- Filtros
-
-
-
- setWaitlistSearch(e.target.value)
- }
- />
-
- Digite o nome do paciente, CPF ou nome do médico
-
-
-
-
-
- Ordenar por:
-
-
-
-
-
-
- {filaEsperaFiltrada.length} DE{" "}
- {filaEsperaData.length} SOLICITAÇÕES ENCONTRADAS
-
-
-
-
-
-
-
- | Nome do Paciente |
- CPF |
- Médico Solicitado |
- Data da Solicitação |
- Ações |
-
-
-
- {filaEsperaPaginada.length > 0 ? (
- filaEsperaPaginada.map((item, index) => (
-
- | {item?.Infos?.paciente_nome} |
- {item?.Infos?.paciente_cpf} |
- {item?.Infos?.medico_nome} |
-
- {dayjs(
- item.agendamento.scheduled_at
- ).format("DD/MM/YYYY")}
- |
-
-
- |
-
- ))
- ) : (
-
-
-
- {showSpinner ? (
-
- ) : (
- <>
-
-
- Nenhuma solicitação encontrada.
-
- >
- )}
+
+
+ Filtrar por Médico
+
+
+ handleSearchMedicos(e.target.value)}
+ />
+ Buscar médico para filtrar consultas
+
+ {searchTermDoctor && FiltredTodosMedicos.length > 0 && (
+
+ {FiltredTodosMedicos.map((medico) => (
+
+ ))}
- |
-
- )}
-
-
- {filaEsperaFiltrada.length > 0 && (
-
-
-
- Itens por página:
-
-
-
-
-
- Página {waitPage} de {waitTotalPages} •
- Mostrando {waitIndiceInicial + 1}-
- {Math.min(
- waitIndiceFinal,
- filaEsperaFiltrada.length
- )}{" "}
- de {filaEsperaFiltrada.length}
-
-
-
+ )}
- )}
+
+ {MedicoFiltrado.id !== "vazio" && (
+
+
+
+ {searchTermDoctor}
+
+
+
+ )}
-
+ )}
+
+
+
-
-
-
+
+ {!FiladeEspera ? (
+
+
+
{selectedDay.format('MMM')}{selectedDay.format('DD')}
+
{selectedDay.format('dddd')}
{selectedDay.format('D [de] MMMM [de] YYYY')}
+
+
Consultas para {selectedDay.format('DD/MM')}
+ {showSpinner ?
: (DictAgendamentosOrganizados[selectedDay.format('YYYY-MM-DD')]?.filter(app => MedicoFiltrado.id === "vazio" || app.doctor_id === MedicoFiltrado.id).length > 0) ? (
+ DictAgendamentosOrganizados[selectedDay.format('YYYY-MM-DD')]
+ .filter(app => MedicoFiltrado.id === "vazio" || app.doctor_id === MedicoFiltrado.id)
+ .map(app => (
+
+
{dayjs(app.scheduled_at).format('HH:mm')}
+
{app.paciente_nome}Dr(a). {app.medico_nome}
+
+ {app.status === 'cancelled' ? (
+
+ ) : (
+
+ )}
+ {app.status !== 'cancelled' && (
+
+ )}
+
+
+ ))
+ ) : (
Nenhuma consulta agendada.
)}
+
+
+
+
+
Realizado
+
Confirmado
+
Agendado
+
Cancelado
+
+
+
+
{currentDate.format('MMMM [de] YYYY')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {weekDays.map(day =>
{day}
)}
+ {dateGrid.map((day, index) => {
+ const dayString = day.format('YYYY-MM-DD');
+ const appointmentsOnDay = DictAgendamentosOrganizados[dayString] || [];
+ const filteredAppointments = appointmentsOnDay.filter(app => MedicoFiltrado.id === "vazio" || app.doctor_id === MedicoFiltrado.id);
+ const cellClasses = `day-cell ${day.isSame(currentDate, 'month') ? 'current-month' : 'other-month'} ${day.isSame(dayjs(), 'day') ? 'today' : ''} ${day.isSame(selectedDay, 'day') ? 'selected' : ''}`;
+ return (
+
handleDateClick(day)}>
+
{day.format('D')}
+ {filteredAppointments.length > 0 &&
{filteredAppointments.length}
}
+
+ );
+ })}
+
+
+
+ ) : (
+
+
+
+
+
Fila de Espera
+
+
+
Filtros
+
setWaitlistSearch(e.target.value)} />Digite o nome do paciente, CPF ou nome do médico
+
+
+ Ordenar por:
+
+
+
+
+
{filaEsperaFiltrada.length} DE {filaEsperaData.length} SOLICITAÇÕES ENCONTRADAS
+
+
+
+
+
+
+ | Nome do Paciente |
+ CPF |
+ Médico Solicitado |
+ Data da Solicitação |
+ Ações |
+
+
+
+ {filaEsperaPaginada.length > 0 ? (
+ filaEsperaPaginada.map((item, index) => (
+
+ | {item?.Infos?.paciente_nome} |
+ {item?.Infos?.paciente_cpf} |
+ {item?.Infos?.medico_nome} |
+ {dayjs(item.agendamento.scheduled_at).format('DD/MM/YYYY')} |
+
+
+ |
+
+ ))
+ ) : (
+
+
+
+ {showSpinner ? : (<> Nenhuma solicitação encontrada. >)}
+
+ |
+
+ )}
+
+
+ {filaEsperaFiltrada.length > 0 && (
+
+
+ Itens por página:
+
+
+
+
Página {waitPage} de {waitTotalPages} • Mostrando {waitIndiceInicial + 1}-{Math.min(waitIndiceFinal, filaEsperaFiltrada.length)} de {filaEsperaFiltrada.length}
+
+
+
+ )}
+
+
+
+
+
+
+ )}
+
+
+ ) : (
+ {
+ setPageConsulta(false);
+ fetchAppointments();
+ }}
+ />
)}
-
+ {showDeleteModal &&
}
- ) : (
- {
- setPageConsulta(false);
- fetchAppointments();
- }}
- />
- )}
- {showDeleteModal && }
-
- );
-};
+ );
+}
export default Agendamento;
diff --git a/src/PagesMedico/DoctorRelatorioManager.jsx b/src/PagesMedico/DoctorRelatorioManager.jsx
index 13add577..6f86f001 100644
--- a/src/PagesMedico/DoctorRelatorioManager.jsx
+++ b/src/PagesMedico/DoctorRelatorioManager.jsx
@@ -46,7 +46,7 @@ const DoctorRelatorioManager = () => {
if (authHeader) myHeaders.append('Authorization', authHeader);
const requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' };
- // Tenta descobrir o ID do usuário logado para aplicar filtro por médico
+
let userId = null;
let userFullName = null;
try {
@@ -60,12 +60,12 @@ const DoctorRelatorioManager = () => {
console.warn('Não foi possível obter UserInfos (pode não estar logado):', err);
}
- // Monta a URL com possíveis filtros preferenciais
+
const baseUrl = "https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?select=*";
let data = [];
if (userId) {
- // 1) tenta por doctor_id
+
try {
const res = await fetch(`${baseUrl}&doctor_id=eq.${userId}`, requestOptions);
data = await res.json();
@@ -74,7 +74,7 @@ const DoctorRelatorioManager = () => {
data = [];
}
- // 2) fallback para created_by (se vazio)
+
if ((!Array.isArray(data) || data.length === 0) && userId) {
try {
const res2 = await fetch(`${baseUrl}&created_by=eq.${userId}`, requestOptions);
@@ -85,10 +85,9 @@ const DoctorRelatorioManager = () => {
}
}
- // 3) fallback para requested_by com nome completo (se ainda vazio)
if ((!Array.isArray(data) || data.length === 0) && userFullName) {
try {
- // encode para evitar problemas com espaços/caracteres especiais
+
const encodedName = encodeURIComponent(userFullName);
const res3 = await fetch(`${baseUrl}&requested_by=eq.${encodedName}`, requestOptions);
data = await res3.json();
@@ -99,7 +98,6 @@ const DoctorRelatorioManager = () => {
}
}
- // Se não obteve userId ou nenhuma das tentativas acima retornou algo, busca tudo (comportamento anterior)
if (!userId || (!Array.isArray(data) || data.length === 0)) {
try {
const resAll = await fetch(baseUrl, requestOptions);
@@ -110,7 +108,7 @@ const DoctorRelatorioManager = () => {
}
}
- // garante unicidade e ordenação por criação
+
const uniqueMap = new Map();
(Array.isArray(data) ? data : []).forEach(r => {
if (r && r.id) uniqueMap.set(r.id, r);
@@ -144,14 +142,14 @@ const DoctorRelatorioManager = () => {
};
}, [authHeader]);
- // Busca dados de pacientes e médicos baseados na lista final que aparece na tela
+
useEffect(() => {
const fetchRelData = async () => {
const pacientes = [];
const medicos = [];
for (let i = 0; i < relatoriosFinais.length; i++) {
const rel = relatoriosFinais[i];
- // paciente
+
try {
const pacienteRes = await GetPatientByID(rel.patient_id, authHeader);
pacientes.push(Array.isArray(pacienteRes) ? pacienteRes[0] : pacienteRes);
@@ -159,13 +157,12 @@ const DoctorRelatorioManager = () => {
pacientes.push(null);
}
- // médico: prioriza campos com id (doctor_id ou created_by). Se tiver somente requested_by (nome), usa nome.
try {
if (rel.doctor_id) {
const docRes = await GetDoctorByID(rel.doctor_id, authHeader);
medicos.push(Array.isArray(docRes) ? docRes[0] : docRes);
} else if (rel.created_by) {
- // created_by costuma ser id
+
const docRes = await GetDoctorByID(rel.created_by, authHeader);
medicos.push(Array.isArray(docRes) ? docRes[0] : docRes);
} else if (rel.requested_by) {
@@ -174,7 +171,6 @@ const DoctorRelatorioManager = () => {
medicos.push({ full_name: '' });
}
} catch (err) {
- // fallback para requested_by se houver
medicos.push({ full_name: rel.requested_by || '' });
}
}
@@ -190,7 +186,6 @@ const DoctorRelatorioManager = () => {
}, [relatoriosFinais, authHeader]);
const abrirModal = (relatorio, pageIndex) => {
- // encontra índice global do relatório no array relatoriosFinais (para alinhar com pacientes/medicos)
const globalIndex = relatoriosFinais.findIndex(r => r.id === relatorio.id);
const indexToUse = globalIndex >= 0 ? globalIndex : (indiceInicial + pageIndex);
setRelatorioModal(relatorio);
@@ -198,7 +193,7 @@ const DoctorRelatorioManager = () => {
setShowModal(true);
};
- // Função para limpar filtros
+
const limparFiltros = () => {
setTermoPesquisa('');
setFiltroExame('');
@@ -256,12 +251,11 @@ const DoctorRelatorioManager = () => {
return (
{showModal && (
-
setShowModal(false)}>
-
e.stopPropagation()}>
+
+
-
+
Relatório de {pacientesComRelatorios[modalIndex]?.full_name}
-
@@ -290,11 +284,11 @@ const DoctorRelatorioManager = () => {
-
+
-
diff --git a/src/components/Header/Header.css b/src/components/Header/Header.css
index 0a4737d3..b07ccaef 100644
--- a/src/components/Header/Header.css
+++ b/src/components/Header/Header.css
@@ -489,28 +489,27 @@
}
}
-/* permite que cliques "passem" através do header (exceto para os elementos interativos) */
.header-container {
- pointer-events: none; /* header não captura cliques */
+ pointer-events: none;
}
-/* mas permite que os controles no canto (telefone e profile) continuem clicáveis */
+
.phone-icon-container,
.profile-section {
pointer-events: auto;
}
-/* Garantir pointer-events nos elementos do header e overlays criados por portal */
+
.header-container { pointer-events: auto; }
.phone-icon-container, .profile-section { pointer-events: auto; }
-/* Força que os overlays criados por portal fiquem por cima */
+
.logout-modal-overlay, .suporte-card-overlay, .chat-overlay {
z-index: 110000 !important;
pointer-events: auto !important;
}
-/* Pequeno ajuste visual dos botões do modal (pode se misturar com seu CSS atual) */
+
.logout-cancel-button {
padding: 10px 18px;
border-radius: 8px;
diff --git a/src/data/sidebar-items-adm.json b/src/data/sidebar-items-adm.json
index 5b4c5542..1eb3da2c 100644
--- a/src/data/sidebar-items-adm.json
+++ b/src/data/sidebar-items-adm.json
@@ -25,5 +25,10 @@
"name": "Painel Administrativo",
"icon": "file-bar-graph-fill",
"url": "/admin/painel"
+ },
+ {
+ "name": "Gestão de Usuários",
+ "icon": "people-fill",
+ "url": "/admin/gestao"
}
]
diff --git a/src/pages/DisponibilidadesDoctorPage.jsx b/src/pages/DisponibilidadesDoctorPage.jsx
index ef488d82..5f79a675 100644
--- a/src/pages/DisponibilidadesDoctorPage.jsx
+++ b/src/pages/DisponibilidadesDoctorPage.jsx
@@ -38,6 +38,9 @@ const DisponibilidadesDoctorPage = () => {
const [expandedDoctors, setExpandedDoctors] = useState({});
const [showSuggestions, setShowSuggestions] = useState(false);
const [availabilityEdit, setAvailabilityEdit] = useState([]);
+ // Add the missing state variables
+ const [showDeleteModal, setShowDeleteModal] = useState(false);
+ const [selectedDisponibilidadeId, setSelectedDisponibilidadeId] = useState(null);
const getHeaders = () => {
const myHeaders = new Headers();
@@ -170,8 +173,24 @@ const DisponibilidadesDoctorPage = () => {
if (!window.confirm("Deseja realmente excluir esta disponibilidade?")) return;
try {
const res = await fetch(`${ENDPOINT}?id=eq.${id}`, { method: "DELETE", headers: getHeaders() });
- if (res.ok) setDisponibilidades((prev) => prev.filter((d) => d.id !== id));
- } catch (error) {}
+ if (res.ok) {
+ setDisponibilidades((prev) => prev.filter((d) => d.id !== id));
+ setShowDeleteModal(false);
+ setSelectedDisponibilidadeId(null);
+ }
+ } catch (error) {
+ console.error("Erro ao excluir disponibilidade:", error);
+ }
+ };
+
+ const handleOpenDeleteModal = (id) => {
+ setSelectedDisponibilidadeId(id);
+ setShowDeleteModal(true);
+ };
+
+ const handleCloseDeleteModal = () => {
+ setShowDeleteModal(false);
+ setSelectedDisponibilidadeId(null);
};
const disponibilidadesAgrupadas = useMemo(() => {
@@ -420,7 +439,16 @@ const DisponibilidadesDoctorPage = () => {
{getStatusText(disp)}
|
-
{!disp.is_empty && deletarDisponibilidade(disp.id)} className="disp-btn-delete">Excluir} |
+
+ {!disp.is_empty && (
+ handleOpenDeleteModal(disp.id)}
+ className="disp-btn-delete"
+ >
+ Excluir
+
+ )}
+ |
))}
@@ -435,6 +463,51 @@ const DisponibilidadesDoctorPage = () => {
)}
+
+ {showDeleteModal && (
+
+
+
+
+
+ Confirmação de Exclusão
+
+
+
+
+
+ Tem certeza que deseja excluir esta disponibilidade?
+
+
+
+
+
+ Cancelar
+
+
+ deletarDisponibilidade(selectedDisponibilidadeId)}
+ >
+ Excluir
+
+
+
+
+
+ )}
);
};
diff --git a/src/pages/DoctorTable.jsx b/src/pages/DoctorTable.jsx
index a0f36504..e5becd73 100644
--- a/src/pages/DoctorTable.jsx
+++ b/src/pages/DoctorTable.jsx
@@ -27,9 +27,8 @@ function TableDoctor({setDictInfo}) {
const [showDeleteModal, setShowDeleteModal] = useState(false);
const [selectedDoctorId, setSelectedDoctorId] = useState(null);
- // Ordenação rápida
- const [sortKey, setSortKey] = useState(null); // 'nome' | 'idade' | null
- const [sortDir, setSortDir] = useState('asc'); // 'asc' | 'desc'
+ const [sortKey, setSortKey] = useState(null);
+ const [sortDir, setSortDir] = useState('asc');
const limparFiltros = () => {
setSearch("");
@@ -147,7 +146,6 @@ function TableDoctor({setDictInfo}) {
return resultado;
}) : [];
-
const applySorting = (arr) => {
if (!Array.isArray(arr) || !sortKey) return arr;
const copy = [...arr];
@@ -277,7 +275,7 @@ function TableDoctor({setDictInfo}) {
- {/* Ordenação rápida */}
+
Ordenar por:
@@ -481,7 +479,6 @@ function TableDoctor({setDictInfo}) {
- {/* Paginação */}
{medicosFiltrados.length > 0 && (
@@ -554,15 +551,10 @@ function TableDoctor({setDictInfo}) {
>
-
+
Confirmação de Exclusão
- setShowDeleteModal(false)}
- >
diff --git a/src/pages/EditPage.jsx b/src/pages/EditPage.jsx
index 0f9bb18c..dac83d8d 100644
--- a/src/pages/EditPage.jsx
+++ b/src/pages/EditPage.jsx
@@ -9,6 +9,7 @@ import { useAuth } from '../components/utils/AuthProvider'
const EditPage = ({DictInfo}) => {
const navigate = useNavigate()
const [PatientToPUT, setPatientPUT] = useState({})
+ const [showSuccessModal, setShowSuccessModal] = useState(false)
const { getAuthorizationHeader, isAuthenticated } = useAuth();
@@ -37,9 +38,15 @@ const HandlePutPatient = async () => {
};
fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients?id=eq.${PatientToPUT.id}`,requestOptions)
- .then(response => console.log(response))
+ .then(response => {
+ console.log(response)
+ if (response.ok) {
+ setShowSuccessModal(true)
+ }
+ return response
+ })
.then(result => console.log(result))
- .catch(console.log("erro"))
+ .catch(error => console.log("erro", error))
};
@@ -52,6 +59,46 @@ const HandlePutPatient = async () => {
formData={PatientToPUT}
setFormData={setPatientPUT}
/>
+
+ {showSuccessModal && (
+
+
+
+
+
+ Paciente Editado
+
+
+
+
+
+ Paciente editado com sucesso!
+
+
+
+
+ {
+ setShowSuccessModal(false)
+ navigate(-1)
+ }}
+ >
+ OK
+
+
+
+
+
+ )}
)
diff --git a/src/pages/ExcecoesDisponibilidade.jsx b/src/pages/ExcecoesDisponibilidade.jsx
index db2e034c..e4f834bf 100644
--- a/src/pages/ExcecoesDisponibilidade.jsx
+++ b/src/pages/ExcecoesDisponibilidade.jsx
@@ -1,4 +1,5 @@
import React, { useState, useEffect, useCallback, useMemo } from 'react';
+import { useNavigate } from 'react-router-dom';
import dayjs from 'dayjs';
import 'dayjs/locale/pt-br';
import weekday from 'dayjs/plugin/weekday';
@@ -23,12 +24,10 @@ const getDateRange = (date, view) => {
toDate = startDayjs.format('YYYY-MM-DD');
titleRange = startDayjs.format('DD/MM/YYYY');
} else if (view === 'semanal') {
- // Padrão Dayjs: Sunday=0, Monday=1.
- // startOf('week') pode ser Domingo ou Segunda, dependendo do locale.
- // Se precisar forçar a Segunda-feira:
+
let weekStart = startDayjs.startOf('week');
- if (weekStart.day() !== 1) { // Se não for segunda-feira (1), ajusta
- weekStart = startDayjs.weekday(1); // Vai para a segunda-feira desta semana
+ if (weekStart.day() !== 1) {
+ weekStart = startDayjs.weekday(1);
}
const weekEnd = weekStart.add(6, 'day');
@@ -52,12 +51,21 @@ const getDateRange = (date, view) => {
const ExcecoesDisponibilidade = () => {
const { getAuthorizationHeader } = useAuth();
+ const navigate = useNavigate();
const [pageNovaExcecao, setPageNovaExcecao] = useState(false);
const [excecoes, setExcecoes] = useState([]);
const [loading, setLoading] = useState(false);
+ const [showDeleteModal, setShowDeleteModal] = useState(false);
+ const [selectedExceptionId, setSelectedExceptionId] = useState(null);
+ const [showSuccessModal, setShowSuccessModal] = useState(false);
+ const [successMessage, setSuccessMessage] = useState('');
const [filtroMedicoId, setFiltroMedicoId] = useState('');
const [filtroData, setFiltroData] = useState(dayjs().format('YYYY-MM-DD'));
+ const [listaDeMedicos, setListaDeMedicos] = useState([]);
+ const [searchTermDoctor, setSearchTermDoctor] = useState('');
+ const [filteredDoctors, setFilteredDoctors] = useState([]);
+ const [selectedDoctor, setSelectedDoctor] = useState(null);
const [visualizacao, setVisualizacao] = useState('diario');
@@ -123,8 +131,51 @@ const ExcecoesDisponibilidade = () => {
fetchExcecoes(fromDate, toDate, filtroMedicoId);
}, [fetchExcecoes, filtroMedicoId, fromDate, toDate]);
+ useEffect(() => {
+ const fetchDoctors = async () => {
+ const myHeaders = new Headers();
+ const authHeader = resolveAuthHeader();
+ if (authHeader) myHeaders.append("Authorization", authHeader);
+ if (API_KEY) myHeaders.append("apikey", API_KEY);
+
+ try {
+ const response = await fetch('https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors?select=id,full_name', {
+ method: 'GET',
+ headers: myHeaders
+ });
+ if (response.ok) {
+ const doctors = await response.json();
+ setListaDeMedicos(doctors);
+ }
+ } catch (error) {
+ console.error('Erro ao buscar médicos:', error);
+ }
+ };
+ fetchDoctors();
+ }, []);
+
+ const handleSearchDoctors = (term) => {
+ setSearchTermDoctor(term);
+ if (term.trim() === '') {
+ setFilteredDoctors([]);
+ return;
+ }
+ const filtered = listaDeMedicos.filter(doc =>
+ doc.full_name.toLowerCase().includes(term.toLowerCase())
+ );
+ setFilteredDoctors(filtered);
+ };
+
+ const limparFiltros = () => {
+ setSearchTermDoctor('');
+ setFilteredDoctors([]);
+ setSelectedDoctor(null);
+ setFiltroMedicoId('');
+ setFiltroData(dayjs().format('YYYY-MM-DD'));
+ setVisualizacao('diario');
+ };
+
const deleteExcecao = async (id) => {
- if (!window.confirm("Confirma exclusão desta exceção?")) return;
const myHeaders = new Headers();
const authHeader = resolveAuthHeader();
if (authHeader) myHeaders.append("Authorization", authHeader);
@@ -139,6 +190,9 @@ const ExcecoesDisponibilidade = () => {
});
if (res.ok) {
setExcecoes(prev => prev.filter(x => x.id !== id));
+ setShowDeleteModal(false);
+ setSuccessMessage('Exceção excluída com sucesso!');
+ setShowSuccessModal(true);
} else {
const text = await res.text();
console.error('Erro ao deletar exceção', res.status, text);
@@ -163,7 +217,7 @@ const ExcecoesDisponibilidade = () => {
return (
- {/* Título e Botão de Criação */}
+
Gerenciar Exceções de Disponibilidade
{
-
+
+
+
+ Filtros
+
- {/* Filtros de Médico e Data */}
-
-
-
+
- {/* Botões de Visualização (Dia/Semana/Mês) */}
+
+
+ {selectedDoctor && (
+
+
+ {selectedDoctor.full_name}
+
+ )}
+
+ {excecoes.length} DE {excecoes.length} EXCEÇÕES ENCONTRADAS
+
+
+
+
+ Limpar Filtros
+
+
+
+
+
+
+
{
- {/* Tabela de Exceções (Título usa o titleRange calculado) */}
+
Exceções em {titleRange} ({excecoes.length})
@@ -264,7 +368,10 @@ const ExcecoesDisponibilidade = () => {
deleteExcecao(exc.id)}
+ onClick={() => {
+ setSelectedExceptionId(exc.id);
+ setShowDeleteModal(true);
+ }}
>
Excluir
@@ -278,6 +385,89 @@ const ExcecoesDisponibilidade = () => {
+
+ {showDeleteModal && (
+
+
+
+
+
+ Confirmação de Exclusão
+
+
+
+
+
+ Tem certeza que deseja excluir esta exceção?
+
+
+
+
+ setShowDeleteModal(false)}
+ >
+ Cancelar
+
+
+ deleteExcecao(selectedExceptionId)}
+ >
+ Excluir
+
+
+
+
+
+ )}
+
+
+ {showSuccessModal && (
+
+
+
+
+
+ Sucesso
+
+
+
+
+
+
+ setShowSuccessModal(false)}
+ >
+ OK
+
+
+
+
+
+ )}
);
}
diff --git a/src/pages/LaudoManager.jsx b/src/pages/LaudoManager.jsx
index e603dfaa..e881d77d 100644
--- a/src/pages/LaudoManager.jsx
+++ b/src/pages/LaudoManager.jsx
@@ -32,7 +32,6 @@ const LaudoManager = () => {
const [paginaAtual, setPaginaAtual] = useState(1);
const [itensPorPagina, setItensPorPagina] = useState(10);
- // agora guardamos a mensagem (null = sem aviso)
const [noPermissionText, setNoPermissionText] = useState(null);
const isSecretary = true;
@@ -162,11 +161,11 @@ const LaudoManager = () => {
const handleLiberarLaudo = async (relatorio) => {
if (isSecretary) {
- // MUDANÇA: mostrar "Ainda não implementado"
+
setNoPermissionText('Ainda não implementado');
return;
}
- // para médicos: implementação real já estava antes (mantive o bloco, caso queira)
+
try {
const myHeaders = new Headers();
myHeaders.append('apikey', API_KEY);
@@ -187,7 +186,6 @@ const LaudoManager = () => {
throw new Error('Erro ao liberar laudo: ' + res.status + ' ' + txt);
}
- // refetch simples
const refreshed = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?select=*", {
method: 'GET',
headers: (() => { const h=new Headers(); h.append('apikey', API_KEY); if(authHeader) h.append('Authorization', authHeader); return h; })(),
@@ -327,7 +325,7 @@ const LaudoManager = () => {
Editar
- {/* Removido o botão "Imprimir" daqui (agora no Ver Detalhes) */}
+
handleOpenProtocol(relatorio, index)}>
Protocolo
@@ -405,14 +403,13 @@ const LaudoManager = () => {
- {/* Modal principal (detalhes) */}
+
{showModal && relatorioModal && (
-
setShowModal(false)}>
-
e.stopPropagation()}>
+
+
-
+
Relatório de {pacientesComRelatorios[modalIndex]?.full_name || relatorioModal.patient_name || 'Paciente'}
- setShowModal(false)}>
@@ -441,11 +438,11 @@ const LaudoManager = () => {
-
+
BaixarPDFdoRelatorio(pacientesComRelatorios[modalIndex]?.full_name || 'paciente', modalIndex)}>
- baixar em pdf
+ Baixar em PDF
- { setShowModal(false) }}>
+ { setShowModal(false) }}>
Fechar
@@ -454,14 +451,13 @@ const LaudoManager = () => {
)}
- {/* Modal Protocolo */}
+
{showProtocolModal && protocolForIndex && (
-
setShowProtocolModal(false)}>
-
e.stopPropagation()}>
+
+
-
+
Protocolo de Entrega - {protocolForIndex.relatorio?.patient_name || 'Paciente'}
- setShowProtocolModal(false)}>
@@ -474,14 +470,14 @@ const LaudoManager = () => {
-
+
{
const idx = protocolForIndex.index ?? 0;
BaixarPDFdoRelatorio(protocolForIndex.relatorio?.patient_name || 'paciente', idx);
}}>
- baixar protocolo (PDF)
+ Baixar Protocolo (PDF)
- setShowProtocolModal(false)}>
+ setShowProtocolModal(false)}>
Fechar
@@ -490,17 +486,18 @@ const LaudoManager = () => {
)}
- {/* Variável de aviso: mostra texto personalizado */}
{noPermissionText && (
-
setNoPermissionText(null)}>
-
e.stopPropagation()}>
+
+
-
-
{noPermissionText}
-
{/* opcional descrição aqui */}
-
- setNoPermissionText(null)}>Fechar
-
+
+
Aviso
+
+
+
+ setNoPermissionText(null)}>Fechar
diff --git a/src/pages/ProfilePage.jsx b/src/pages/ProfilePage.jsx
index ab47356d..a41bfe8a 100644
--- a/src/pages/ProfilePage.jsx
+++ b/src/pages/ProfilePage.jsx
@@ -2,14 +2,6 @@ import React, { useState, useEffect, useCallback } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import "./style/ProfilePage.css";
-
-const MOCK_API_BASE_URL = "https://mock.apidog.com/m1/1053378-0-default";
-
-
-const getLocalAvatar = () => localStorage.getItem('user_avatar');
-const setLocalAvatar = (avatarData) => localStorage.setItem('user_avatar', avatarData);
-const clearLocalAvatar = () => localStorage.removeItem('user_avatar');
-
const ROLES = {
ADMIN: "Administrador",
SECRETARY: "Secretária",
@@ -36,7 +28,6 @@ const ProfilePage = () => {
const [userEmail, setUserEmail] = useState("admin@squad23.com");
const [avatarUrl, setAvatarUrl] = useState(null);
const [isEditingName, setIsEditingName] = useState(false);
- const [isUploading, setIsUploading] = useState(false);
const [error, setError] = useState(null);
@@ -52,14 +43,21 @@ const ProfilePage = () => {
useEffect(() => {
const loadProfileData = () => {
-
- const localAvatar = getLocalAvatar();
+ const localAvatar = localStorage.getItem('user_avatar');
if (localAvatar) {
setAvatarUrl(localAvatar);
}
};
loadProfileData();
+
+
+ const handleStorageChange = () => {
+ loadProfileData();
+ };
+
+ window.addEventListener('storage', handleStorageChange);
+ return () => window.removeEventListener('storage', handleStorageChange);
}, []);
const handleNameSave = () => {
@@ -83,104 +81,6 @@ const ProfilePage = () => {
const handleClose = () => navigate(-1);
-
- const handleAvatarUpload = async (event) => {
- const file = event.target.files[0];
- if (!file) return;
-
- setError(null);
-
-
- const MAX_FILE_SIZE = 5 * 1024 * 1024;
- const ACCEPTED_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
-
- if (file.size > MAX_FILE_SIZE) {
- setError("Arquivo muito grande. Máximo 5MB.");
- return;
- }
-
- if (!ACCEPTED_TYPES.includes(file.type)) {
- setError("Tipo de arquivo não suportado. Use JPEG, PNG, GIF ou WebP.");
- return;
- }
-
- setIsUploading(true);
-
- try {
-
- try {
- const result = await uploadAvatarToMockAPI(file);
-
- const newAvatarUrl = result.url || result.avatarUrl;
- if (newAvatarUrl) {
- setAvatarUrl(newAvatarUrl);
- setLocalAvatar(newAvatarUrl);
- console.log('Avatar enviado para API com sucesso');
- return;
- }
- } catch (apiError) {
-
- console.log('API não disponível, salvando localmente...');
- }
-
-
- const reader = new FileReader();
- reader.onload = (e) => {
- const imageDataUrl = e.target.result;
- setLocalAvatar(imageDataUrl);
- setAvatarUrl(imageDataUrl);
- console.log('Avatar salvo localmente');
- };
- reader.readAsDataURL(file);
-
- } catch (error) {
-
- console.error('Erro no processamento:', error);
- const reader = new FileReader();
- reader.onload = (e) => {
- const imageDataUrl = e.target.result;
- setLocalAvatar(imageDataUrl);
- setAvatarUrl(imageDataUrl);
- };
- reader.readAsDataURL(file);
- } finally {
- setIsUploading(false);
- event.target.value = '';
- }
- };
-
-
- const uploadAvatarToMockAPI = async (file) => {
- const formData = new FormData();
- formData.append("avatar", file);
-
- const response = await fetch(`${MOCK_API_BASE_URL}/storage/v1/object/avatars/[path]`, {
- method: "POST",
- body: formData
- });
-
- if (!response.ok) {
-
- return null;
- }
-
- return await response.json();
- };
-
-
- const clearAvatar = () => {
-
- fetch(`${MOCK_API_BASE_URL}/storage/v1/object/avatars/[path]`, {
- method: "DELETE"
- }).catch(() => {
-
- });
-
-
- clearLocalAvatar();
- setAvatarUrl(null);
- };
-
return (
@@ -203,7 +103,7 @@ const ProfilePage = () => {
className="avatar-img"
onError={() => {
setAvatarUrl(null);
- clearLocalAvatar();
+ localStorage.removeItem('user_avatar');
}}
/>
) : (
@@ -212,26 +112,15 @@ const ProfilePage = () => {
)}
-
-
-
- {isUploading && (
-
- Processando imagem...
-
- )}
+
+
+ Gerencie seu avatar no menu do perfil acima
+
@@ -287,11 +176,6 @@ const ProfilePage = () => {
- {avatarUrl && (
-
- Remover Avatar
-
- )}
{
if (!Array.isArray(arr) || !sortKey) return arr;
const copy = [...arr];
@@ -377,7 +378,6 @@ function TablePaciente({ setCurrentPage, setPatientID,setDictInfo }) {
Aniversariantes
- {/* Ordenação rápida (estilo compacto por select) */}
Ordenar por:
@@ -550,11 +550,15 @@ function TablePaciente({ setCurrentPage, setPatientID,setDictInfo }) {
-
-
setDictInfo(paciente)}>
- Editar
-
-
+
{
+ setDictInfo(paciente);
+ navigate('edit');
+ }}
+ >
+ Editar
+
- {/* Paginação */}
+
{pacientesFiltrados.length > 0 && (
@@ -661,15 +665,10 @@ function TablePaciente({ setCurrentPage, setPatientID,setDictInfo }) {
>
-
+
Confirmação de Exclusão
- setShowDeleteModal(false)}
- >