anteriority-ui 1.0.0

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 (199) hide show
  1. package/.github/workflows/ci.yml +31 -0
  2. package/.github/workflows/publish.yml +45 -0
  3. package/.npmrc.bak +1 -0
  4. package/.storybook/main.js +15 -0
  5. package/.storybook/preview.jsx +26 -0
  6. package/AnteriorityUI.md +2400 -0
  7. package/CLAUDE.md +91 -0
  8. package/README.md +182 -0
  9. package/assets/anteriorityUI/AnteriorityUI.logo.jpeg +0 -0
  10. package/assets/favicon/anteriorityUI.ico +0 -0
  11. package/common/api/client.js +43 -0
  12. package/common/storage/LocalStorage.js +13 -0
  13. package/common/styles/typography.css +5 -0
  14. package/common/styles/variables.css +192 -0
  15. package/common/theme/muiTheme.js +9 -0
  16. package/features/password-reset/api.js +39 -0
  17. package/features/user-profile/api.js +5 -0
  18. package/hooks/useAdminPasswordReset.js +133 -0
  19. package/index.js +57 -0
  20. package/package.json +57 -0
  21. package/pnpm-workspace.yaml +3 -0
  22. package/screens/components/AlertModal/AlertModal.jsx +259 -0
  23. package/screens/components/AlertModal/AlertModal.module.css +185 -0
  24. package/screens/components/AlertModal/AlertModal.stories.jsx +87 -0
  25. package/screens/components/Avatar/index.jsx +0 -0
  26. package/screens/components/Avatar/index.module.css +0 -0
  27. package/screens/components/Avatar/utils.js +0 -0
  28. package/screens/components/Badge/index.jsx +33 -0
  29. package/screens/components/Badge/index.module.css +18 -0
  30. package/screens/components/Badge/index.stories.jsx +40 -0
  31. package/screens/components/Barnner/index.jsx +21 -0
  32. package/screens/components/Barnner/index.module.css +33 -0
  33. package/screens/components/Barnner/index.stories.jsx +39 -0
  34. package/screens/components/Barnner/utils.js +0 -0
  35. package/screens/components/BlueLink/index.jsx +27 -0
  36. package/screens/components/BlueLink/index.module.css +11 -0
  37. package/screens/components/BlueLink/index.stories.jsx +29 -0
  38. package/screens/components/Breadcrumbs/index.jsx +62 -0
  39. package/screens/components/Breadcrumbs/index.module.css +158 -0
  40. package/screens/components/Breadcrumbs/index.stories.jsx +37 -0
  41. package/screens/components/Button/index.jsx +169 -0
  42. package/screens/components/Button/index.module.css +168 -0
  43. package/screens/components/Button/index.stories.jsx +71 -0
  44. package/screens/components/Button/utils.js +28 -0
  45. package/screens/components/CalendarComponent/CustomDatePicker.jsx +248 -0
  46. package/screens/components/CalendarComponent/CustomDatePicker.module.css +323 -0
  47. package/screens/components/CalendarComponent/CustomDatePicker.stories.jsx +45 -0
  48. package/screens/components/CalendarPicker/Constants.js +12 -0
  49. package/screens/components/CalendarPicker/index.jsx +263 -0
  50. package/screens/components/CalendarPicker/index.module.css +147 -0
  51. package/screens/components/CalendarPicker/index.stories.jsx +45 -0
  52. package/screens/components/CalendarPicker/utils.js +42 -0
  53. package/screens/components/CardV1/index.jsx +165 -0
  54. package/screens/components/CardV1/index.module.css +232 -0
  55. package/screens/components/CardV1/index.stories.jsx +62 -0
  56. package/screens/components/CardV1/utils.js +49 -0
  57. package/screens/components/ChatWindow/index.jsx +251 -0
  58. package/screens/components/ChatWindow/index.module.css +311 -0
  59. package/screens/components/ChatWindow/index.stories.jsx +62 -0
  60. package/screens/components/Checks/index.jsx +31 -0
  61. package/screens/components/Checks/index.module.css +32 -0
  62. package/screens/components/Checks/index.stories.jsx +32 -0
  63. package/screens/components/Container/index.jsx +36 -0
  64. package/screens/components/Container/index.module.css +24 -0
  65. package/screens/components/Container/index.stories.jsx +32 -0
  66. package/screens/components/CopyText/index.jsx +42 -0
  67. package/screens/components/CopyText/index.module.css +52 -0
  68. package/screens/components/CopyText/index.stories.jsx +24 -0
  69. package/screens/components/CountdownBar/constants.js +3 -0
  70. package/screens/components/CountdownBar/index.jsx +81 -0
  71. package/screens/components/CountdownBar/index.module.css +45 -0
  72. package/screens/components/CountdownBar/index.stories.jsx +43 -0
  73. package/screens/components/CountdownBar/utils.js +119 -0
  74. package/screens/components/DateTag/index.jsx +33 -0
  75. package/screens/components/DateTag/index.module.css +12 -0
  76. package/screens/components/DateTag/index.stories.jsx +29 -0
  77. package/screens/components/DesplegablePanel/constants.js +0 -0
  78. package/screens/components/DesplegablePanel/index.jsx +61 -0
  79. package/screens/components/DesplegablePanel/index.module.css +120 -0
  80. package/screens/components/DesplegablePanel/index.stories.jsx +44 -0
  81. package/screens/components/DesplegablePanel/utils.js +0 -0
  82. package/screens/components/DrawPanel/index.jsx +217 -0
  83. package/screens/components/DrawPanel/index.module.css +252 -0
  84. package/screens/components/DrawPanel/index.stories.jsx +66 -0
  85. package/screens/components/DrawPanel/utils.js +0 -0
  86. package/screens/components/Filter/index.jsx +105 -0
  87. package/screens/components/Filter/index.module.css +91 -0
  88. package/screens/components/Filter/index.stories.jsx +46 -0
  89. package/screens/components/Filter/utils.js +0 -0
  90. package/screens/components/FormControls/FormControls.module.css +86 -0
  91. package/screens/components/FormControls/index.jsx +51 -0
  92. package/screens/components/FormControls/index.stories.jsx +36 -0
  93. package/screens/components/Frame/index.jsx +54 -0
  94. package/screens/components/Frame/index.module.css +102 -0
  95. package/screens/components/Frame/index.stories.jsx +37 -0
  96. package/screens/components/Frame/utils.js +0 -0
  97. package/screens/components/GreenHighlight/index.jsx +11 -0
  98. package/screens/components/GreenHighlight/index.module.css +7 -0
  99. package/screens/components/GreenHighlight/index.stories.jsx +26 -0
  100. package/screens/components/GreenHighlight/utils.jsx +45 -0
  101. package/screens/components/HoursPicker/Constants.js +26 -0
  102. package/screens/components/HoursPicker/index.jsx +350 -0
  103. package/screens/components/HoursPicker/index.module.css +99 -0
  104. package/screens/components/HoursPicker/index.stories.jsx +44 -0
  105. package/screens/components/HoursPicker/utils.js +48 -0
  106. package/screens/components/InfoTooltip/index.jsx +59 -0
  107. package/screens/components/InfoTooltip/index.module.css +98 -0
  108. package/screens/components/InfoTooltip/index.stories.jsx +35 -0
  109. package/screens/components/Input/index.jsx +36 -0
  110. package/screens/components/Input/index.module.css +49 -0
  111. package/screens/components/Input/index.stories.jsx +37 -0
  112. package/screens/components/Input/utils.js +0 -0
  113. package/screens/components/Loading/index.jsx +76 -0
  114. package/screens/components/Loading/index.module.css +193 -0
  115. package/screens/components/Loading/index.stories.jsx +38 -0
  116. package/screens/components/Loading/utils.js +0 -0
  117. package/screens/components/MarkdownContent/index.jsx +16 -0
  118. package/screens/components/MarkdownContent/index.module.css +149 -0
  119. package/screens/components/MarkdownContent/index.stories.jsx +30 -0
  120. package/screens/components/MarkdownEditor/index.jsx +430 -0
  121. package/screens/components/MarkdownEditor/index.module.css +192 -0
  122. package/screens/components/MarkdownEditor/index.stories.jsx +50 -0
  123. package/screens/components/Material-UI/Components/InputWithIcon/index.jsx +87 -0
  124. package/screens/components/Material-UI/Components/InputWithIcon/index.stories.jsx +49 -0
  125. package/screens/components/Material-UI/Components/MenuPopover/index.jsx +117 -0
  126. package/screens/components/Material-UI/Components/MenuPopover/index.stories.jsx +36 -0
  127. package/screens/components/Material-UI/Components/MultilinePlaceholder/index.jsx +44 -0
  128. package/screens/components/Material-UI/Components/MultilinePlaceholder/index.stories.jsx +45 -0
  129. package/screens/components/Material-UI/Components/Paginador/index.jsx +79 -0
  130. package/screens/components/Material-UI/Components/Paginador/index.stories.jsx +49 -0
  131. package/screens/components/Material-UI/Components/Search/index.jsx +81 -0
  132. package/screens/components/Material-UI/Components/Search/index.stories.jsx +68 -0
  133. package/screens/components/Material-UI/Components/Selector/index.jsx +100 -0
  134. package/screens/components/Material-UI/Components/Selector/index.module.css +0 -0
  135. package/screens/components/Material-UI/Components/Selector/index.stories.jsx +52 -0
  136. package/screens/components/Material-UI/Components/Selector/utils.js +0 -0
  137. package/screens/components/Material-UI/Components/TextField/index.jsx +61 -0
  138. package/screens/components/Material-UI/Components/TextField/index.stories.jsx +53 -0
  139. package/screens/components/ModalTooltip/ModalTooltip.jsx +122 -0
  140. package/screens/components/ModalTooltip/ModalTooltip.module.css +65 -0
  141. package/screens/components/ModalTooltip/ModalTooltip.stories.jsx +39 -0
  142. package/screens/components/Notification/Error/ErrorMessage.jsx +30 -0
  143. package/screens/components/Notification/Error/ErrorMessage.module.css +57 -0
  144. package/screens/components/Notification/Error/ErrorMessage.stories.jsx +37 -0
  145. package/screens/components/PasswordResetPanel/index.jsx +325 -0
  146. package/screens/components/PasswordResetPanel/index.stories.jsx +26 -0
  147. package/screens/components/PlaceholderButton/index.jsx +169 -0
  148. package/screens/components/PlaceholderButton/index.module.css +162 -0
  149. package/screens/components/PlaceholderButton/index.stories.jsx +69 -0
  150. package/screens/components/PlaceholderButton/utils.js +42 -0
  151. package/screens/components/Profile/Avatar/index.jsx +125 -0
  152. package/screens/components/Profile/Avatar/index.module.css +86 -0
  153. package/screens/components/Profile/Avatar/index.stories.jsx +48 -0
  154. package/screens/components/Profile/Avatar/utils.js +18 -0
  155. package/screens/components/Profile/index.jsx +58 -0
  156. package/screens/components/Profile/index.module.css +0 -0
  157. package/screens/components/Profile/index.stories.jsx +38 -0
  158. package/screens/components/Profile/utils.js +0 -0
  159. package/screens/components/ScrollBar/index.jsx +62 -0
  160. package/screens/components/ScrollBar/index.module.css +78 -0
  161. package/screens/components/ScrollBar/index.stories.jsx +64 -0
  162. package/screens/components/ScrollBar/utils.js +127 -0
  163. package/screens/components/Sidebar/constants.js +16 -0
  164. package/screens/components/Sidebar/index.jsx +399 -0
  165. package/screens/components/Sidebar/index.module.css +405 -0
  166. package/screens/components/Sidebar/index.stories.jsx +86 -0
  167. package/screens/components/Sidebar/utils.js +75 -0
  168. package/screens/components/Skeleton/index.jsx +11 -0
  169. package/screens/components/Skeleton/index.module.css +26 -0
  170. package/screens/components/Skeleton/index.stories.jsx +42 -0
  171. package/screens/components/SubSidebarLayout/index.jsx +44 -0
  172. package/screens/components/SubSidebarLayout/index.module.css +80 -0
  173. package/screens/components/SubSidebarLayout/index.stories.jsx +51 -0
  174. package/screens/components/SummaryCard/index.jsx +50 -0
  175. package/screens/components/SummaryCard/index.module.css +30 -0
  176. package/screens/components/SummaryCard/index.stories.jsx +29 -0
  177. package/screens/components/Swich/constants.js +4 -0
  178. package/screens/components/Swich/index.jsx +85 -0
  179. package/screens/components/Swich/index.module.css +68 -0
  180. package/screens/components/Swich/index.stories.jsx +44 -0
  181. package/screens/components/Swich/utils.js +0 -0
  182. package/screens/components/TableA/index.jsx +156 -0
  183. package/screens/components/TableA/index.module.css +105 -0
  184. package/screens/components/TableA/index.stories.jsx +116 -0
  185. package/screens/components/TableA/utils.js +11 -0
  186. package/screens/components/TableB/index.jsx +222 -0
  187. package/screens/components/TableB/index.module.css +295 -0
  188. package/screens/components/TableB/index.stories.jsx +110 -0
  189. package/screens/components/TableB/utils.js +11 -0
  190. package/screens/components/ToggleCard/index.jsx +64 -0
  191. package/screens/components/ToggleCard/index.module.css +111 -0
  192. package/screens/components/ToggleCard/index.stories.jsx +49 -0
  193. package/screens/components/UserEditPopover/index.jsx +102 -0
  194. package/screens/components/UserEditPopover/index.module.css +97 -0
  195. package/screens/components/UserEditPopover/index.stories.jsx +49 -0
  196. package/scripts/build.mjs +129 -0
  197. package/scripts/check-case.mjs +127 -0
  198. package/scripts/verify-dist.mjs +45 -0
  199. package/vitest.config.js +36 -0
package/CLAUDE.md ADDED
@@ -0,0 +1,91 @@
1
+ # CLAUDE.md
2
+
3
+ Guía para trabajar en este repo. Para documentación orientada a consumidores de la librería, ver [README.md](README.md) (instalación, setup, estructura) y [AnteriorityUI.md](AnteriorityUI.md) (props y ejemplos de uso de cada uno de los 50 componentes, en un único documento).
4
+
5
+ ## Qué es este proyecto
6
+
7
+ `anteriority-ui` es una librería interna de componentes React, extraída originalmente del proyecto `vet-system-WEB` (en `C:\Users\Usuario\ProjectoUniversidad\vet-system-WEB`), con el objetivo de reutilizarla en otros proyectos. Los componentes viven en `screens/components/` y están construidos sobre MUI + CSS Modules + lucide-react.
8
+
9
+ ## Estructura
10
+
11
+ ```
12
+ index.js → barrel: re-exporta los ~50 componentes por nombre (import { Button } from 'anteriority-ui')
13
+ screens/components/ → ~50 componentes de UI, uno por carpeta (index.jsx + .module.css + .stories.jsx, siempre en minúscula)
14
+ common/
15
+ styles/ → variables.css (design tokens en :root) y typography.css (fuente global + import de Google Fonts)
16
+ theme/muiTheme.js → theme de MUI compartido (fontFamily: var(--font-sans))
17
+ api/client.js → cliente HTTP genérico (fetch wrapper), sin lógica de negocio ni endpoints hardcodeados
18
+ storage/LocalStorage.js → utilidades de sessionStorage/localStorage (getUserId/setUserId)
19
+ features/
20
+ password-reset/api.js → funciones de API específicas del flujo de reseteo de contraseña
21
+ user-profile/api.js → función de API para actualizar nombre de usuario
22
+ hooks/useAdminPasswordReset.js → hook que consume features/password-reset/api.js
23
+ .storybook/ → config de Storybook (main.js, preview.jsx)
24
+ ```
25
+
26
+ **Regla de separación:** `screens/components/*` es UI pura y reutilizable. `features/*` y `hooks/*` son lógica de negocio (llamadas a API con endpoints concretos) — solo dos componentes dependen de ellos (`PasswordResetPanel`, `UserEditPopover`), y ambos siguen funcionando/renderizando sin crashear aunque no haya backend real detrás (las llamadas fallan silenciosamente, atrapadas en try/catch).
27
+
28
+ ## Origen y por qué existen `common/api`, `features/`, `hooks/`
29
+
30
+ Al extraer componentes de `vet-system-WEB`, algunos (`Button`, `Sidebar`, `PasswordResetPanel`, `UserEditPopover`, etc.) importaban cosas fuera del árbol de componentes: `ModalTooltip`, `AlertModal`, `Notification/Error/ErrorMessage` (ya copiados dentro de `screens/components/`), y lógica real de negocio (`services/api`, `hooks/useAdminPasswordReset`, `context/LocalStorage`). Para esta última parte, en vez de copiar el cliente API completo de vet-system-WEB (771 líneas acopladas a axios/config/dummyDB/tokens de esa app específica), se reimplementó un cliente HTTP genérico (`common/api/client.js`) y solo las funciones puntuales que los dos componentes necesitan (`features/password-reset`, `features/user-profile`), para que la librería no dependa del backend de ningún proyecto en particular.
31
+
32
+ Un consumidor de la librería que quiera usar `PasswordResetPanel` o `UserEditPopover` con datos reales debe llamar `configureApiClient({ baseURL, getAuthToken })` (ver README.md) antes de que se disparen las llamadas.
33
+
34
+ ## Convención: props de color
35
+
36
+ La mayoría de los componentes con color propio (fondo, texto, ícono, borde) exponen props opcionales de color (`bgColor`, `textColor`, `iconColor`, `borderColor`, `accentColor`, o nombres específicos del rol cuando ninguno de esos encaja). Reglas al tocar o agregar componentes:
37
+
38
+ - **Todo prop de color es opcional y su default debe reproducir exactamente el color hardcodeado que existía antes** — es un cambio aditivo, nunca un rediseño.
39
+ - **Mecanismo:** si el color vive en el CSS module, se convierte a `var(--token-local, <valor-original>)` y el componente aplica `style={{ '--token-local': prop }}` solo cuando la prop viene definida (merge con cualquier `style` que el componente ya reciba). Esto funciona incluso para gradientes, `:hover` y contenido en portales (las CSS custom properties heredan).
40
+ - Si el color ya estaba inline en JSX (`style`, `sx`, `color=` de MUI), se reemplaza el literal por la prop con ese mismo valor como default de parámetro.
41
+ - **Los componentes con sistema `variant`/`type` (Barnner, DesplegablePanel, Notification/Error, TableB) mantienen su variant tal cual** — las props de color nuevas son un override opcional por encima de la paleta que resolvería el variant.
42
+ - Nombres reutilizados a propósito para consistencia entre componentes: `bgColor`, `textColor`, `iconColor`, `borderColor`, `accentColor`.
43
+
44
+ ## Tipografía y theme
45
+
46
+ La fuente global es **Plus Jakarta Sans** (Google Fonts), no Roboto (default de MUI) ni el serif por default del navegador. Esto requiere DOS piezas trabajando juntas:
47
+ - `common/styles/typography.css` → importa la fuente y define `body { font-family: var(--font-sans) }` (arregla elementos HTML planos, ej. un `<h3>` sin clase).
48
+ - `common/theme/muiTheme.js` → `ThemeProvider` de MUI con `typography.fontFamily: 'var(--font-sans)'` (arregla componentes MUI, que si no, ignoran el `body` y usan su propio theme default).
49
+
50
+ Si se agrega un componente nuevo con texto visible, verificar que se vea con la fuente correcta en Storybook (`.storybook/preview.jsx` ya envuelve todas las stories en ambos).
51
+
52
+ ## Comandos
53
+
54
+ ```bash
55
+ pnpm storybook # levanta Storybook en http://localhost:6006
56
+ pnpm build-storybook # build estático de Storybook
57
+ pnpm build # check-case + compila a dist/ + verify-dist — correr antes de confiar en un release
58
+ pnpm check-case # solo el audit de mayúsculas/minúsculas en imports (rápido, sin compilar)
59
+ ```
60
+
61
+ ## Barrel (`index.js`) — indexación de componentes
62
+
63
+ `index.js` en la raíz re-exporta cada componente por nombre (`export { default as Button } from './screens/components/Button/index.js'`, etc.) para que un consumidor pueda hacer `import { Button, Sidebar } from 'anteriority-ui'` sin conocer el subpath de cada uno. Es un archivo **mantenido a mano**, no generado — al agregar un componente nuevo en `screens/components/`, agregarlo también acá. Reglas:
64
+ - Alias siempre = nombre de la carpeta (no el nombre interno de la variable/función, que a veces difiere — ej. `Sidebar/index.jsx` exporta internamente `ProSidebar`, pero el barrel lo expone como `Sidebar`).
65
+ - Solo se re-exporta el `default` de cada componente, nunca `export *` — varios componentes tienen sus propios `VARIANTS`/`SIZES`/`COLORS` locales (ver [Convención: props de color](#convención-props-de-color) y el patrón `variant`/`type`) que colisionarían entre sí como named exports al tope del barrel. Quien necesite esos named exports sigue importando el subpath directo del componente.
66
+ - `screens/components/Avatar/` (el stub vacío) queda **fuera** del barrel a propósito — ver [Componentes sin implementar](#componentes-sin-implementar). El avatar real (`Profile/Avatar`) está en el barrel como `ProfileAvatar`.
67
+ - `FormControls` no tiene default export (exporta `FormCard`, `FormInput`, `FormTextArea` con nombre propio) — se re-exportan tal cual, sin alias de carpeta.
68
+
69
+ ## Build y publicación (versionado real, npm público)
70
+
71
+ El paquete se publica en el registro público de npm como `anteriority-ui`, no vía `git+https://...` apuntando a `main` (ese instalaba el HEAD del branch sin versión ni changelog — ver [.github/workflows/publish.yml](.github/workflows/publish.yml)). Se eligió npm público en vez de GitHub Packages a propósito: GitHub Packages exige autenticación hasta para instalar (incluso en repos públicos), y la prioridad acá era que instalar fuera tan simple como `pnpm add mui` — sin `.npmrc` ni token del lado del consumidor. El costo es que el código queda visible públicamente en npm (el repo de GitHub puede seguir siendo privado).
72
+
73
+ - `scripts/build.mjs` transpila JSX → JS con esbuild (`jsx: 'automatic'`) y copia CSS Modules/otros assets, preservando la misma estructura de carpetas que el código fuente para que los subpath imports documentados en README.md sigan resolviendo igual. También genera `dist/package.json` (subset de campos del `package.json` raíz — ver el script para la lista exacta) porque `publishConfig.directory: "dist"` en el `package.json` raíz le dice a `pnpm publish` que empaquete desde ahí, no desde la raíz del repo.
74
+ - **Todos los imports relativos internos deben ser sin extensión** (`from '../Loading/index'`, no `'../Loading/index.jsx'`). Un import con extensión `.jsx` explícita funciona en el código fuente (Vite/Storybook resuelve contra el archivo `.jsx` real), pero rompe en `dist/` una vez compilado, porque esbuild transpila `.jsx` → `.js` sin reescribir el string del import — queda apuntando a un archivo que ya no existe. `scripts/verify-dist.mjs` (bundlea `dist/index.js` completo con esbuild, con los peer deps como `external`) es lo único que detecta esto; `pnpm build-storybook` NO alcanza porque corre contra el código fuente, no contra el paquete compilado.
75
+ - `scripts/check-case.mjs` audita que cada import relativo matchee el nombre real en disco con mayúsculas/minúsculas exactas (había 22 componentes con entry file `Index.jsx` en vez de `index.jsx` — rompía deploys en Linux por ser case-sensitive, invisible en Windows/Mac). Corre como parte de `pnpm build` y en CI ([.github/workflows/ci.yml](.github/workflows/ci.yml)).
76
+ - **Gotcha real ya vivido:** un rename de archivo solo-de-casing (`Index.jsx` → `index.jsx`) en Windows puede quedar sin aplicar físicamente en disco después de un `git checkout`/merge, aunque el índice de git ya diga `index.jsx` — NTFS es case-insensitive y git a veces no reescribe el archivo físico si solo cambia el casing. Si `pnpm check-case` falla después de un pull que "debería" traer un fix de casing ya mergeado, sospechar de esto antes de asumir que el fix nunca se aplicó.
77
+ - El workflow de publish se dispara con push de un tag `vX.Y.Z` y valida que coincida con la versión de `package.json` antes de publicar — ver la sección "Versionado y releases" en README.md para el flujo (`pnpm version patch/minor/major` + `git push --tags`).
78
+ - Si se agrega un componente/carpeta nueva bajo `screens/`, `common/`, `features/` o `hooks/`, no hace falta tocar nada del build — `scripts/build.mjs` recorre esos cuatro directorios dinámicamente. Sí hay que agregarlo a mano al barrel `index.js` (ver arriba).
79
+ - `react`, `react-dom`, `@mui/material`, `@emotion/*` ya son `peerDependencies` (no van empaquetados) — eso ya estaba bien resuelto antes de este cambio; lo que faltaba era el build + versionado, no las peer deps.
80
+
81
+ ## ⚠️ Gotcha de pnpm workspace
82
+
83
+ `C:\Users\Usuario` (la carpeta home del usuario) es raíz de OTRO proyecto suyo no relacionado (`proyecto-hp-backend`, con su propio `package.json`/`pnpm-workspace.yaml`/`.git`). Como está dos niveles arriba de este repo, pnpm puede tratarlo como raíz del workspace y mezclar instalaciones ahí en vez de aislarlas acá. Por eso este repo tiene su propio `pnpm-workspace.yaml` (con `packages: []`) — **no lo borres** — sirve para que pnpm pare la búsqueda hacia arriba y trate `AnteriorityUI` como su propia raíz. Si algo similar vuelve a romperse (paquetes no encontrados en runtime pese a estar en `package.json`), sospechar primero de esto antes de reinstalar todo.
84
+
85
+ ## Storybook
86
+
87
+ Cada componente en `screens/components/` tiene un `.stories.jsx` (formato CSF3) al lado de su implementación. Al agregar un componente nuevo, agregarle también su story con variantes reales (no placeholders) — son la referencia que se usa para escribir/actualizar la sección correspondiente en AnteriorityUI.md.
88
+
89
+ ## Componentes sin implementar
90
+
91
+ `screens/components/Avatar/` (`index.jsx`, `utils.js`, `index.module.css`) son archivos vacíos (0 bytes) — un stub sin terminar, no lo usa nada del código. El avatar real y usado es `screens/components/Profile/Avatar/`. No confundir los dos ni documentar el stub hasta que tenga contenido real.
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ <p align="center">
2
+ <img src="assets/favicon/anteriorityUI.ico" alt="anteriority-ui" width="480" />
3
+ </p>
4
+
5
+ # anteriority-ui
6
+
7
+ Librería interna de componentes React (UI) para reutilizar entre proyectos. Construida sobre [MUI](https://mui.com/), [lucide-react](https://lucide.dev/) y CSS Modules, con [Storybook](https://storybook.js.org/) para navegar y probar cada componente de forma aislada.
8
+
9
+ ## Instalación
10
+
11
+ Publicada en el registro público de npm — se instala igual que cualquier otra dependencia, sin tokens ni configuración extra:
12
+
13
+ ```bash
14
+ pnpm add anteriority-ui
15
+ ```
16
+
17
+ Cada versión se genera a partir de un tag `vX.Y.Z` (semver real, no el HEAD de `main`) — ver [Versionado y releases](#versionado-y-releases).
18
+
19
+ ### Peer dependencies
20
+
21
+ Estas dependencias las provee el proyecto que consume la librería (no van empaquetadas, para evitar duplicar React/MUI):
22
+
23
+ ```bash
24
+ pnpm add react react-dom @mui/material @emotion/react @emotion/styled
25
+ ```
26
+
27
+ ## Setup en el proyecto consumidor
28
+
29
+ 1. Importar los estilos base (design tokens + tipografía) una sola vez, en el punto de entrada de la app:
30
+
31
+ ```js
32
+ import 'anteriority-ui/common/styles/variables.css';
33
+ import 'anteriority-ui/common/styles/typography.css';
34
+ ```
35
+
36
+ 2. Envolver la app en el `ThemeProvider` de MUI con el theme de la librería, para que los componentes basados en MUI (Button, TextField, Selector, etc.) usen la misma tipografía y no el Roboto por default de MUI:
37
+
38
+ ```jsx
39
+ import { ThemeProvider } from '@mui/material/styles';
40
+ import muiTheme from 'anteriority-ui/common/theme/muiTheme';
41
+
42
+ function App() {
43
+ return (
44
+ <ThemeProvider theme={muiTheme}>
45
+ {/* resto de la app */}
46
+ </ThemeProvider>
47
+ );
48
+ }
49
+ ```
50
+
51
+ 3. (Opcional) Si vas a usar `hooks/useAdminPasswordReset` o cualquier función de `features/*/api.js`, configurá el cliente HTTP genérico una vez al arrancar la app:
52
+
53
+ ```js
54
+ import { configureApiClient } from 'anteriority-ui/common/api/client';
55
+
56
+ configureApiClient({
57
+ baseURL: 'https://api.tu-proyecto.com',
58
+ getAuthToken: () => localStorage.getItem('token'),
59
+ });
60
+ ```
61
+
62
+ ## Importar componentes
63
+
64
+ Todos los componentes están indexados en el entry point principal — no hace falta conocer el subpath de cada uno:
65
+
66
+ ```jsx
67
+ import { Button, Sidebar, TableB } from 'anteriority-ui';
68
+ ```
69
+
70
+ Alternativa, importando el subpath directo de cada componente (útil para acceder a exports nombrados extra que no pasan por el barrel, ej. `Button.VARIANTS`):
71
+
72
+ ```jsx
73
+ import Button, { VARIANTS } from 'anteriority-ui/screens/components/Button';
74
+ ```
75
+
76
+ ## Estructura del proyecto
77
+
78
+ ```
79
+ screens/components/ → componentes de UI (uno por carpeta, ver docs abajo)
80
+ common/
81
+ styles/ → variables.css (design tokens) y typography.css (fuente global)
82
+ theme/ → muiTheme.js, el theme de MUI compartido
83
+ api/ → cliente HTTP genérico (client.js), sin lógica de negocio
84
+ storage/ → utilidades de localStorage/sessionStorage (LocalStorage.js)
85
+ features/
86
+ password-reset/ → lógica de API para el flujo de reseteo de contraseña
87
+ user-profile/ → lógica de API para edición de perfil de usuario
88
+ hooks/ → hooks reutilizables (useAdminPasswordReset)
89
+ .storybook/ → configuración de Storybook
90
+ ```
91
+
92
+ Cada componente en `screens/components/` es independiente entre sí salvo por composición explícita (por ejemplo, `Button` usa `ModalTooltip`, `TableB` usa `Barnner`). Ningún componente de UI importa nada de `features/` directamente salvo los que ya tienen lógica de negocio propia (`PasswordResetPanel`, `UserEditPopover`).
93
+
94
+ ## Versionado y releases
95
+
96
+ La librería se compila (JSX → JS, se preserva la estructura de carpetas) antes de publicarse — ver [scripts/build.mjs](scripts/build.mjs). El build corre solo en CI, no hace falta ejecutarlo a mano salvo para probarlo localmente con `pnpm run build`.
97
+
98
+ **Setup único, antes del primer release:** generar un [access token de npm](https://www.npmjs.com/) de tipo *Automation* (desde la cuenta/organización de npm que va a ser dueña del paquete) y cargarlo como secret `NPM_TOKEN` en Settings → Secrets and variables → Actions de este repo. Sin esto el workflow de publish falla.
99
+
100
+ Para publicar una nueva versión (ej. después de un fix en un componente):
101
+
102
+ ```bash
103
+ pnpm version patch # o minor / major — bumpea package.json, commitea y crea el tag vX.Y.Z
104
+ git push && git push --tags
105
+ ```
106
+
107
+ El push del tag dispara [.github/workflows/publish.yml](.github/workflows/publish.yml), que compila y publica a npm con el secret `NPM_TOKEN`. El workflow falla si el tag no coincide con la versión del `package.json`, como chequeo de seguridad.
108
+
109
+ Los proyectos consumidores controlan cuándo actualizar corriendo `pnpm update anteriority-ui` (respetando el rango semver que hayan fijado), en vez de recibir cambios de golpe con cada push a `main`.
110
+
111
+ ## Ver los componentes en Storybook
112
+
113
+ ```bash
114
+ pnpm storybook
115
+ ```
116
+
117
+ Abre `http://localhost:6006` con los ~50 componentes navegables, cada uno con varias variantes de ejemplo.
118
+
119
+ ## Convención de colores
120
+
121
+ La mayoría de los componentes con color propio (fondo, texto, ícono, borde) exponen props opcionales para sobreescribirlo — por ejemplo `bgColor`, `textColor`, `iconColor`, `borderColor`, `accentColor`. Si no se pasa la prop, el componente se ve exactamente igual que antes (el valor por default reproduce el color original). Ver [AnteriorityUI.md](AnteriorityUI.md) para la lista exacta de props de color que acepta cada componente.
122
+
123
+ Componentes que ya tenían un sistema de `variant`/`type` con paletas predefinidas (`Barnner`, `DesplegablePanel`, `Notification/Error`, `TableB`) lo conservan tal cual — las props de color nuevas son un override opcional por encima del `variant` elegido.
124
+
125
+ ## Componentes
126
+
127
+ Documentación completa de props y ejemplos de uso de los 50 componentes en **[AnteriorityUI.md](AnteriorityUI.md)**.
128
+
129
+ | Componente | Descripción |
130
+ |---|---|
131
+ | [AlertModal](AnteriorityUI.md#alertmodal) | Modal de confirmación/alerta, con soporte de input embebido |
132
+ | [Badge](AnteriorityUI.md#badge) | Etiqueta de estado con ícono, label y valor |
133
+ | [Barnner](AnteriorityUI.md#barnner) | Banner de aviso con variantes de color |
134
+ | [BlueLink](AnteriorityUI.md#bluelink) | Link de navegación con tooltip |
135
+ | [Breadcrumbs](AnteriorityUI.md#breadcrumbs) | Migas de pan de navegación |
136
+ | [Button](AnteriorityUI.md#button) | Botón (envoltorio de MUI Button) con variantes, loading, tooltip |
137
+ | [CalendarComponent](AnteriorityUI.md#calendarcomponent) | Selector de fecha standalone (date picker) |
138
+ | [CalendarPicker](AnteriorityUI.md#calendarpicker) | Selector de fecha integrado a un `TextField` |
139
+ | [CardV1](AnteriorityUI.md#cardv1) | Tarjeta con badges, acción e indicadores de estado |
140
+ | [ChatWindow](AnteriorityUI.md#chatwindow) | Ventana de chat completa (mensajes, input, avatar) |
141
+ | [Checks](AnteriorityUI.md#checks) | Checkbox de permisos/ítem seleccionable |
142
+ | [Container](AnteriorityUI.md#container) | Contenedor con paginación integrada |
143
+ | [CopyText](AnteriorityUI.md#copytext) | Texto con botón de copiar al portapapeles |
144
+ | [CountdownBar](AnteriorityUI.md#countdownbar) | Barra de progreso con cuenta regresiva |
145
+ | [DateTag](AnteriorityUI.md#datetag) | Etiqueta de fecha formateada |
146
+ | [DesplegablePanel](AnteriorityUI.md#desplegablepanel) | Panel colapsable con ícono temático |
147
+ | [DrawPanel](AnteriorityUI.md#drawpanel) | Panel lateral deslizable (drawer) |
148
+ | [Filter](AnteriorityUI.md#filter) | Panel de filtros con contador de activos |
149
+ | [FormControls](AnteriorityUI.md#formcontrols) | Controles de formulario (Card, Input, TextArea) |
150
+ | [Frame](AnteriorityUI.md#frame) | Marco/tarjeta base reutilizable, soporta modal |
151
+ | [GreenHighlight](AnteriorityUI.md#greenhighlight) | Resaltado de texto/valor destacado |
152
+ | [HoursPicker](AnteriorityUI.md#hourspicker) | Selector de horario |
153
+ | [InfoTooltip](AnteriorityUI.md#infotooltip) | Ícono de información con tooltip |
154
+ | [Input](AnteriorityUI.md#input) | Input de texto (envoltorio de MUI TextField) |
155
+ | [Loading](AnteriorityUI.md#loading) | Indicadores de carga (spinner, barras, rebote) |
156
+ | [MarkdownContent](AnteriorityUI.md#markdowncontent) | Render de contenido Markdown |
157
+ | [MarkdownEditor](AnteriorityUI.md#markdowneditor) | Editor de Markdown con vista previa |
158
+ | [Material-UI/Components/InputWithIcon](AnteriorityUI.md#inputwithicon) | Input con ícono embebido |
159
+ | [Material-UI/Components/MenuPopover](AnteriorityUI.md#menupopover) | Menú contextual (popover) |
160
+ | [Material-UI/Components/MultilinePlaceholder](AnteriorityUI.md#multilineplaceholder) | Textarea con placeholder multilinea |
161
+ | [Material-UI/Components/Paginador](AnteriorityUI.md#paginador) | Paginación (envoltorio de MUI Pagination) |
162
+ | [Material-UI/Components/Search](AnteriorityUI.md#search) | Buscador con autocompletado |
163
+ | [Material-UI/Components/Selector](AnteriorityUI.md#selector) | Select (envoltorio de MUI Select) |
164
+ | [Material-UI/Components/TextField](AnteriorityUI.md#textfield) | TextField base compartido por otros componentes |
165
+ | [ModalTooltip](AnteriorityUI.md#modaltooltip) | Tooltip flotante (portal) |
166
+ | [Notification/Error/ErrorMessage](AnteriorityUI.md#errormessage) | Mensaje de error/éxito inline |
167
+ | [PasswordResetPanel](AnteriorityUI.md#passwordresetpanel) | Panel de flujo de reseteo de contraseña (usa `features/password-reset`) |
168
+ | [PlaceholderButton](AnteriorityUI.md#placeholderbutton) | Botón que se convierte en input al hacer click |
169
+ | [Profile](AnteriorityUI.md#profile) | Header de perfil de usuario |
170
+ | [Profile/Avatar](AnteriorityUI.md#avatar-profileavatar) | Avatar con estado (online/offline) |
171
+ | [ScrollBar](AnteriorityUI.md#scrollbar) | Contenedor con scrollbar estilizada |
172
+ | [Sidebar](AnteriorityUI.md#sidebar) | Barra lateral de navegación completa |
173
+ | [Skeleton](AnteriorityUI.md#skeleton) | Placeholders de carga (shimmer) |
174
+ | [SubSidebarLayout](AnteriorityUI.md#subsidebarlayout) | Layout de sub-sidebar con menú |
175
+ | [SummaryCard](AnteriorityUI.md#summarycard) | Tarjeta de resumen con degradado |
176
+ | [Swich](AnteriorityUI.md#swich) | Interruptor (switch) on/off |
177
+ | [TableA](AnteriorityUI.md#tablea) | Tabla simple con columnas configurables |
178
+ | [TableB](AnteriorityUI.md#tableb) | Tabla con filas expandibles y badges |
179
+ | [ToggleCard](AnteriorityUI.md#togglecard) | Tarjeta colapsable con acción |
180
+ | [UserEditPopover](AnteriorityUI.md#usereditpopover) | Popover de edición de nombre de usuario (usa `features/user-profile`) |
181
+
182
+ > `screens/components/Avatar/` existe pero está sin implementar (archivos vacíos) — no se documenta hasta que tenga contenido.
Binary file
@@ -0,0 +1,43 @@
1
+ let baseURL = '';
2
+ let getAuthToken = () => null;
3
+
4
+ // Debe llamarse una vez al iniciar la app consumidora de la librería.
5
+ export function configureApiClient({ baseURL: base, getAuthToken: tokenGetter } = {}) {
6
+ if (base !== undefined) baseURL = base;
7
+ if (tokenGetter) getAuthToken = tokenGetter;
8
+ }
9
+
10
+ export async function request(path, { method = 'GET', body, headers = {}, auth = true } = {}) {
11
+ const cleanPath = path.startsWith('/') ? path : `/${path}`;
12
+ const url = `${baseURL}${cleanPath}`;
13
+
14
+ const opts = { method, headers: { ...headers } };
15
+
16
+ if (auth) {
17
+ const token = getAuthToken();
18
+ if (token) opts.headers['Authorization'] = `Bearer ${token}`;
19
+ }
20
+
21
+ if (body !== undefined && !['GET', 'HEAD'].includes(method.toUpperCase())) {
22
+ opts.headers['Content-Type'] = opts.headers['Content-Type'] || 'application/json';
23
+ opts.body = typeof body === 'string' ? body : JSON.stringify(body);
24
+ }
25
+
26
+ const res = await fetch(url, opts);
27
+
28
+ if (res.status === 204) return null;
29
+
30
+ const contentType = (res.headers.get('content-type') || '').toLowerCase();
31
+ const data = contentType.includes('application/json')
32
+ ? await res.json().catch(() => null)
33
+ : await res.text();
34
+
35
+ if (!res.ok) {
36
+ const err = new Error((data && (data.error || data.message)) || res.statusText || `Request failed (${res.status})`);
37
+ err.status = res.status;
38
+ err.body = data;
39
+ throw err;
40
+ }
41
+
42
+ return data;
43
+ }
@@ -0,0 +1,13 @@
1
+
2
+ // Guarda el id del usuario logueado
3
+ export function setUserId(id) {
4
+ if (!id) return;
5
+ localStorage.setItem('user_id', id);
6
+ sessionStorage.setItem('user_id', id);
7
+ }
8
+
9
+ // Obtiene el id del usuario logueado
10
+ export function getUserId() {
11
+ // Prioriza sessionStorage para evitar IDs viejos de otra sesión/pestaña.
12
+ return sessionStorage.getItem('user_id') || localStorage.getItem('user_id') || null;
13
+ }
@@ -0,0 +1,5 @@
1
+ @import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&display=swap');
2
+
3
+ body {
4
+ font-family: var(--font-sans);
5
+ }
@@ -0,0 +1,192 @@
1
+ :root {
2
+ /*fondo sistema*/
3
+ --bg-soft: rgba(216, 239, 220, 0);
4
+ --bg-modal-big: rgb(188, 219, 188);
5
+ --bg-marron-gueso: #E3DAC9;
6
+ /*colores de botones*/
7
+ --button-blue: linear-gradient(135deg, #0284c7, #0369a1);
8
+ --button-hover-blue: #0369a1;
9
+ --button-green: #0f766e;
10
+ --button-hover-green: rgb(0, 167, 39);
11
+ --cancel-button: red;
12
+ --button-hover-red: rgb(203, 3, 3);
13
+ /*letras*/
14
+ --letter: #103529;
15
+ --letter-white: #ffffff;
16
+ /*interfaz CitasDoctor*/
17
+ --ink: #0f172a;
18
+ --line: #008412;
19
+ --brand-dark: #115e59;
20
+ --danger-bg: #fdfdfd;
21
+ --danger-text: #991b1b;
22
+
23
+ /*diseño*/
24
+ --blur: blur(18px);
25
+ --shadow: 2px 1px 6px rgb(0, 0, 0);
26
+
27
+ --color-secondary: rgb(2, 169, 18);
28
+ --color-secondary-dark: #027800;
29
+ --color-primary: rgb(23, 23, 255);
30
+ --color-primary-dark: #032585;
31
+ --color-danger: #ea1f1f;
32
+ --color-danger-dark: #dc2626;
33
+ --color-danger-bg: #fee2e2;
34
+ --color-text: #1e293b;
35
+ --color-text-muted: #64748b;
36
+ --color-text-muted2: #b3b7bd;
37
+ --color-border: #e2e8f0;
38
+ --productCardConsulta: #088d4f;
39
+ --color-card-bg: #ffffff;
40
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
41
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
42
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
43
+ --radius-sm: 0.375rem;
44
+ --radius-md: 0.5rem;
45
+ --radius-lg: 0.75rem;
46
+ --font-sans: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
47
+ --transition: all 0.2s ease;
48
+
49
+
50
+ /* Glassmorphism Green-White Gradient */
51
+ --bg-glass-gradient-green: linear-gradient(135deg, rgb(101, 255, 49), rgba(85, 255, 0, 0.45));
52
+ --bg-glass-gradient-ross: linear-gradient(135deg, rgba(207, 173, 2, 0.25), rgba(255, 255, 255, 0.45));
53
+ --bg-glass-gradient-logo: linear-gradient(135deg, rgba(34, 197, 94, 0.15), rgba(255, 255, 255, 0.5), rgba(14, 165, 233, 0.15));
54
+
55
+ --logo-yellow-soft: #60aaff31;
56
+ --logo-yellow-border: rgba(254, 240, 138, 0.5);
57
+
58
+ --glass-blur-panel: blur(12px);
59
+ --glass-border: 1px solid rgba(255, 255, 255, 0.4);
60
+
61
+ /* Pink-Green Glassmorphism */
62
+ --gr-pink-green: linear-gradient(135deg, #f47fe9 0%, #017A51 100%);
63
+ --glass-blur-pink-green: blur(10px);
64
+
65
+ /* Sidebar Glassmorphism */
66
+ --sidebar-bg: linear-gradient(135deg, rgba(34, 197, 94, 0.5), rgba(255, 255, 255, 0.4), rgba(14, 165, 233, 0.5));
67
+ --sidebar-blur: blur(24px);
68
+ --sidebar-border-right: 1px solid rgba(14, 165, 233, 0.3);
69
+ --sidebar-text: #0f172a;
70
+ --sidebar-text-muted: #475569;
71
+ --sidebar-text-active: #0ea5e9;
72
+ --sidebar-hover-bg: rgba(14, 165, 233, 0.08);
73
+ --sidebar-border: rgba(14, 165, 233, 0.15);
74
+
75
+
76
+ /*AlertModal*/
77
+ --modal-overlay-bg: rgba(15, 23, 42, 0.65);
78
+ --modal-bg: #ffffff70;
79
+ --modal-border: 1px solid rgba(226, 232, 240, 0.8);
80
+ --modal-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.02);
81
+ --modal-title-color: #0f172a;
82
+ --modal-text-color: #faebeb;
83
+ --primary-color: #2563eb;
84
+ --primary-hover: #000000;
85
+ --secondary-color: #f1f5f9;
86
+ --secondary-hover: #e2e8f0;
87
+ --border-radius-md: 0.5rem;
88
+ --border-radius-lg: 0.75rem;
89
+ --transition: all 0.2s ease;
90
+
91
+
92
+ /*AgreeProduct*/
93
+ --input-border: #e2e8f0;
94
+ --input-focus: #2a4d97;
95
+ --bg-dropdown: #ffffff;
96
+ --text-muted: #64748b00;
97
+ --item-hover: #f8fafc;
98
+
99
+
100
+ /*CreatedCita*/
101
+ --bg-page: #f8fafc;
102
+ --bg-inputs: #ffffff;
103
+ --text-primary: #0f172a;
104
+ --text-secondary: #475569;
105
+ --text-muted: #64748b;
106
+ --border-light: #e2e8f0;
107
+ --border-focus: #0ea5e9;
108
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
109
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
110
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
111
+ --radius-sm: 0.375rem;
112
+ --radius-md: 0.5rem;
113
+ --radius-lg: 0.75rem;
114
+ --transition: all 0.2s ease;
115
+ --font-sans: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
116
+
117
+ /*Facturas*/
118
+ --bg-facturas: #1e293b;
119
+ --bg-main: #0f172a;
120
+ --bg-hover: rgb(0, 80, 47);
121
+ --text-main: #f1f5f9;
122
+ --text-muted: #ffffff;
123
+ --accent-green: #10b981;
124
+ --accent-blue: #0c3d9f;
125
+ --border-color: #ffffff;
126
+
127
+ /*colores*/
128
+ --color-black: #000000;
129
+ --color-white: #ffffff;
130
+
131
+ /*inputs*/
132
+ --inputs-bordes: #309ff9;
133
+ --inputs-px: 2px;
134
+
135
+ /*Buttons color */
136
+ --btn-login: #34cc06;
137
+ --btn-login-hover: #259e04;
138
+ --btn-blue: rgb(1, 1, 225);
139
+
140
+ /* Switch Colors */
141
+ --SW-green: rgb(0, 125, 0);
142
+ --SW-blue: rgb(1, 1, 225);
143
+ --SW-red: rgb(197, 0, 0);
144
+ --SW-white: white;
145
+ --SW-disable-default: rgb(100, 100, 100);
146
+ --SW-thumb-color: white;
147
+ --SW-thumb-color: black;
148
+
149
+
150
+ /*Bordes*/
151
+ --border-gray-low: #9b9b9b;
152
+ --border-gray-hight: #575757;
153
+ --border-white: #f3f4f6;
154
+ --border-black: #000000;
155
+
156
+ /* Gradients */
157
+ --gr-login: linear-gradient(135deg, #0041f2, #1341e0);
158
+ --gr-login-hover: linear-gradient(135deg, #0039d1, #1039c2);
159
+ --gr-create: linear-gradient(135deg, #0041f2, #0039d1);
160
+ --gr-create-hover: linear-gradient(135deg, #0039d1, #1039c2);
161
+ --gr-danger: linear-gradient(135deg, #d10000, #c20000);
162
+ --gr-danger-hover: linear-gradient(135deg, #c20000, #a30000);
163
+ --gr-cancel: linear-gradient(135deg, #d10000, #c20000);
164
+ --gr-cancel-hover: linear-gradient(135deg, #c20000, #a30000);
165
+ --gr-spinner-green-blue: linear-gradient(135deg, #027800, #0284c7);
166
+ --gr-spinner-green-blue-hover: linear-gradient(135deg, #0039d1, #1039c2);
167
+ }
168
+
169
+ .glass-panel-green {
170
+ background: var(--bg-glass-gradient-green) !important;
171
+ backdrop-filter: var(--glass-blur-panel) !important;
172
+ -webkit-backdrop-filter: var(--glass-blur-panel) !important;
173
+ border: var(--glass-border) !important;
174
+ }
175
+
176
+ .sidebar-glass {
177
+ background: var(--sidebar-bg) !important;
178
+ backdrop-filter: var(--sidebar-blur) !important;
179
+ -webkit-backdrop-filter: var(--sidebar-blur) !important;
180
+ border-right: var(--sidebar-border-right) !important;
181
+ }
182
+
183
+ .glass-pink-green {
184
+ background: var(--gr-pink-green) !important;
185
+ backdrop-filter: var(--glass-blur-pink-green) !important;
186
+ -webkit-backdrop-filter: var(--glass-blur-pink-green) !important;
187
+ border: 1px solid rgba(255, 255, 255, 0.2) !important;
188
+ }
189
+
190
+ .glass-pink-green * {
191
+ color: #ffffff !important;
192
+ }
@@ -0,0 +1,9 @@
1
+ import { createTheme } from '@mui/material/styles';
2
+
3
+ const muiTheme = createTheme({
4
+ typography: {
5
+ fontFamily: 'var(--font-sans)',
6
+ },
7
+ });
8
+
9
+ export default muiTheme;
@@ -0,0 +1,39 @@
1
+ import { request } from '../../common/api/client';
2
+
3
+ export async function requestPasswordReset(email) {
4
+ return request('/users/request-password-reset', {
5
+ method: 'POST',
6
+ body: { email: String(email).trim() },
7
+ });
8
+ }
9
+
10
+ export async function getResetStatus(email) {
11
+ return request(`/users/reset-status/${encodeURIComponent(email)}`, {
12
+ method: 'GET',
13
+ });
14
+ }
15
+
16
+ export async function getPendingResets() {
17
+ return request('/users/pending-resets', {
18
+ method: 'GET',
19
+ });
20
+ }
21
+
22
+ export async function assignNewPassword(email, new_password) {
23
+ return request('/users/assign-new-password', {
24
+ method: 'POST',
25
+ body: {
26
+ email: String(email).trim(),
27
+ new_password: String(new_password).trim(),
28
+ },
29
+ });
30
+ }
31
+
32
+ const api = {
33
+ requestPasswordReset,
34
+ getResetStatus,
35
+ getPendingResets,
36
+ assignNewPassword,
37
+ };
38
+
39
+ export default api;
@@ -0,0 +1,5 @@
1
+ import { request } from '../../common/api/client';
2
+
3
+ export async function updateUserName(payload) {
4
+ return request('/Users/update-user-name', { method: 'PATCH', body: payload });
5
+ }