max-remotes-helper 1.0.2 → 1.0.4

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.
@@ -15,6 +15,7 @@ interface DevButtonProps {
15
15
  size?: ButtonSize;
16
16
  className?: string;
17
17
  type?: "button" | "submit" | "reset";
18
+ style?: React.CSSProperties;
18
19
  }
19
20
  declare const DevButton: React.FC<DevButtonProps>;
20
21
  export default DevButton;
@@ -8,6 +8,7 @@ import React from "react";
8
8
  interface DevCardProps {
9
9
  children: React.ReactNode;
10
10
  className?: string;
11
+ style?: React.CSSProperties;
11
12
  }
12
13
  declare const DevCard: React.FC<DevCardProps>;
13
14
  export default DevCard;
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  interface DevWrapperProps {
3
3
  children: React.ReactNode;
4
+ defaultDevRoles?: string[];
4
5
  }
5
6
  declare const DevWrapper: React.FC<DevWrapperProps>;
6
7
  export default DevWrapper;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see index.js.LICENSE.txt */
2
- (()=>{var e={20:(e,t,r)=>{"use strict";var o=r(953),n=Symbol.for("react.element"),a=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,i=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var o,a={},c=null,d=null;for(o in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(d=t.ref),t)s.call(t,o)&&!l.hasOwnProperty(o)&&(a[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===a[o]&&(a[o]=t[o]);return{$$typeof:n,type:e,key:c,ref:d,props:a,_owner:i.current}}t.Fragment=a,t.jsx=c,t.jsxs=c},60:(e,t,r)=>{var o={"./moduleUtils":226,"./moduleUtils.ts":226,"./tokenUtils":433,"./tokenUtils.ts":433};function n(e){return Promise.resolve().then(()=>{if(!r.o(o,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r(o[e])})}n.keys=()=>Object.keys(o),n.id=60,e.exports=n},87:(e,t,r)=>{(()=>{var t={20:(e,t,r)=>{"use strict";var o=r(953),n=Symbol.for("react.element"),a=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,i=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.Fragment=a,t.jsx=function(e,t,r){var o,a={},c=null,d=null;for(o in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(d=t.ref),t)s.call(t,o)&&!l.hasOwnProperty(o)&&(a[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===a[o]&&(a[o]=t[o]);return{$$typeof:n,type:e,key:c,ref:d,props:a,_owner:i.current}}},60:(e,t,r)=>{var o={"./moduleUtils":226,"./moduleUtils.ts":226,"./tokenUtils":433,"./tokenUtils.ts":433};function n(e){return Promise.resolve().then(()=>{if(!r.o(o,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r(o[e])})}n.keys=()=>Object.keys(o),n.id=60,e.exports=n},226:(e,t,r)=>{"use strict";r.r(t),r.d(t,{createRemoteComponentLoader:()=>i,getRemoteEnvironment:()=>l,isRemoteAvailable:()=>s,loadRemoteModule:()=>a});var o=r(953),n=r.n(o);const a=async(e,t)=>{try{return await r(60)(`${e}/${t}`)}catch(r){throw console.error(`Failed to load remote module ${e}/${t}:`,r),r}},s=async e=>{try{const t=window[e];return"function"==typeof t?.get}catch(e){return!1}},i=(e,t,r)=>n().lazy(async()=>{try{return await a(e,t)}catch(o){return console.error(`Remote component loading failed: ${e}/${t}`,o),r?{default:r}:{default:()=>n().createElement("div",{style:{padding:"20px",color:"red"}},`Failed to load remote component: ${e}/${t}`)}}}),l=()=>({isDevelopment:!1,apiBaseUrl:process.env.REACT_APP_API_URL||"",frontUrl:process.env.REACT_APP_FRONT_URL||""})},433:(e,t,r)=>{"use strict";r.r(t),r.d(t,{decodeToken:()=>o,extractPermissions:()=>a,isTokenExpired:()=>n,tokenStorage:()=>s});const o=e=>{try{if(!e)return null;const t=e.split(".");if(3!==t.length)return null;const r=t[1],o=r+"=".repeat((4-r.length%4)%4),n=atob(o);return JSON.parse(n)}catch(e){return console.error("Error decoding token:",e),null}},n=e=>{const t=o(e);if(!t||!t.exp)return!0;const r=Math.floor(Date.now()/1e3);return t.exp<r},a=e=>{if(!e)return[];const t=["permissions","roles","authorities","scope"];for(const r of t){const t=e[r];if(Array.isArray(t))return t;if("string"==typeof t)return t.split(" ").filter(Boolean)}return[]},s={key:"bo-remote-token",save:e=>{try{sessionStorage.setItem(s.key,e)}catch(e){console.error("Error saving token:",e)}},get:()=>{try{return sessionStorage.getItem(s.key)}catch(e){return console.error("Error getting token:",e),null}},remove:()=>{try{sessionStorage.removeItem(s.key)}catch(e){console.error("Error removing token:",e)}},clear:()=>{try{sessionStorage.clear()}catch(e){console.error("Error clearing storage:",e)}}}},848:(e,t,r)=>{"use strict";e.exports=r(20)},953:e=>{"use strict";e.exports=r(953)}},o={};function n(e){var r=o[e];if(void 0!==r)return r.exports;var a=o[e]={exports:{}};return t[e](a,a.exports,n),a.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.e=()=>Promise.resolve(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var a={};(()=>{"use strict";n.r(a),n.d(a,{RemoteAuthProvider:()=>l,RemoteWrapper:()=>u,Secured:()=>d,createRemoteComponentLoader:()=>g.createRemoteComponentLoader,decodeToken:()=>r.decodeToken,extractPermissions:()=>r.extractPermissions,getRemoteEnvironment:()=>g.getRemoteEnvironment,isRemoteAvailable:()=>g.isRemoteAvailable,isTokenExpired:()=>r.isTokenExpired,loadRemoteModule:()=>g.loadRemoteModule,tokenStorage:()=>r.tokenStorage,useRemoteAuth:()=>c,useRemoteConfig:()=>m});var e=n(848),t=n(953),r=n(433);const o={token:null,isAuthenticated:!1,permissions:[],user:void 0},s=(e,t)=>{switch(t.type){case"SET_TOKEN":const n=(0,r.decodeToken)(t.payload),a=n?(0,r.extractPermissions)(n):[];return{...e,token:t.payload,isAuthenticated:!(0,r.isTokenExpired)(t.payload),permissions:a,user:n?{id:n.sub||"",email:n.email||"",name:n.name||n.email||""}:void 0};case"CLEAR_AUTH":return{...o};case"SET_USER_INFO":return{...e,user:{id:t.payload.sub||"",email:t.payload.email||"",name:t.payload.name||t.payload.email||""}};default:return e}},i=(0,t.createContext)(void 0),l=({children:n,initialToken:a})=>{const[l,c]=(0,t.useReducer)(s,o);(0,t.useEffect)(()=>{if(console.log("🔍 RemoteAuthContext: useEffect triggered",{initialToken:a?a.substring(0,30)+"...":"No initialToken"}),a)console.log("✅ RemoteAuthContext: Using initialToken from prop"),(0,r.isTokenExpired)(a)?(console.log("🔴 RemoteAuthContext: Provided token is expired, clearing auth"),r.tokenStorage.remove(),c({type:"CLEAR_AUTH"})):(console.log("🟢 RemoteAuthContext: Token is valid, dispatching SET_TOKEN"),c({type:"SET_TOKEN",payload:a}),r.tokenStorage.save(a));else{console.log("⚪ RemoteAuthContext: No initialToken, checking stored token");const e=r.tokenStorage.get();e&&!(0,r.isTokenExpired)(e)?(console.log("💾 RemoteAuthContext: Using stored token"),c({type:"SET_TOKEN",payload:e})):e&&(console.log("🗑️ RemoteAuthContext: Stored token expired, clearing"),r.tokenStorage.remove(),c({type:"CLEAR_AUTH"}))}},[a]);const d={state:l,setToken:e=>{e&&(r.tokenStorage.save(e),c({type:"SET_TOKEN",payload:e}))},clearAuth:()=>{r.tokenStorage.remove(),c({type:"CLEAR_AUTH"})},hasPermission:e=>!!l.isAuthenticated&&l.permissions.includes(e)};return(0,e.jsx)(i.Provider,{value:d,children:n})},c=()=>{const e=(0,t.useContext)(i);if(void 0===e)throw new Error("useRemoteAuth must be used within a RemoteAuthProvider");return e},d=({children:t,permission:r,fallback:o=null})=>{const{hasPermission:n,state:a}=c();return a.isAuthenticated&&n(r)?(0,e.jsx)(e.Fragment,{children:t}):(0,e.jsx)(e.Fragment,{children:o})},u=({children:t,token:r,apiBaseUrl:o,module:n})=>(0,e.jsx)(l,{initialToken:r,children:(0,e.jsx)("div",{"data-remote-module":n,"data-api-base":o,children:t})}),m=()=>{const e=(0,t.useMemo)(()=>({react:{singleton:!0,eager:!1},"react-dom":{singleton:!0,eager:!1},"aurora-web":{singleton:!0,eager:!1},"react-i18next":{singleton:!0,eager:!1},i18next:{singleton:!0,eager:!1}}),[]);return{sharedDependencies:e,getWebpackConfig:(t,r)=>({name:t,filename:"remoteEntry.js",exposes:r,shared:e})}};var g=n(226)})(),e.exports=a})()},226:(e,t,r)=>{"use strict";r.r(t),r.d(t,{createRemoteComponentLoader:()=>i,getRemoteEnvironment:()=>l,isRemoteAvailable:()=>s,loadRemoteModule:()=>a});var o=r(953),n=r.n(o);const a=async(e,t)=>{try{return await r(60)(`${e}/${t}`)}catch(r){throw console.error(`Failed to load remote module ${e}/${t}:`,r),r}},s=async e=>{try{const t=window[e];return"function"==typeof t?.get}catch(e){return!1}},i=(e,t,r)=>n().lazy(async()=>{try{return await a(e,t)}catch(o){return console.error(`Remote component loading failed: ${e}/${t}`,o),r?{default:r}:{default:()=>n().createElement("div",{style:{padding:"20px",color:"red"}},`Failed to load remote component: ${e}/${t}`)}}}),l=()=>({isDevelopment:!1,apiBaseUrl:process.env.REACT_APP_API_URL||"",frontUrl:process.env.REACT_APP_FRONT_URL||""})},433:(e,t,r)=>{"use strict";r.r(t),r.d(t,{decodeToken:()=>o,extractPermissions:()=>a,isTokenExpired:()=>n,tokenStorage:()=>s});const o=e=>{try{if(!e)return null;const t=e.split(".");if(3!==t.length)return null;const r=t[1],o=r+"=".repeat((4-r.length%4)%4),n=atob(o);return JSON.parse(n)}catch(e){return console.error("Error decoding token:",e),null}},n=e=>{const t=o(e);if(!t||!t.exp)return!0;const r=Math.floor(Date.now()/1e3);return t.exp<r},a=e=>{if(!e)return[];const t=["permissions","roles","authorities","scope"];for(const r of t){const t=e[r];if(Array.isArray(t))return t;if("string"==typeof t)return t.split(" ").filter(Boolean)}return[]},s={key:"bo-remote-token",save:e=>{try{sessionStorage.setItem(s.key,e)}catch(e){console.error("Error saving token:",e)}},get:()=>{try{return sessionStorage.getItem(s.key)}catch(e){return console.error("Error getting token:",e),null}},remove:()=>{try{sessionStorage.removeItem(s.key)}catch(e){console.error("Error removing token:",e)}},clear:()=>{try{sessionStorage.clear()}catch(e){console.error("Error clearing storage:",e)}}}},848:(e,t,r)=>{"use strict";e.exports=r(20)},953:e=>{"use strict";e.exports=require("react")}},t={};function r(o){var n=t[o];if(void 0!==n)return n.exports;var a=t[o]={exports:{}};return e[o](a,a.exports,r),a.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.e=()=>Promise.resolve(),r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var o={};(()=>{"use strict";r.r(o),r.d(o,{DevWrapper:()=>y,RemoteAuthProvider:()=>l,RemoteWrapper:()=>u,Secured:()=>d,createRemoteComponentLoader:()=>b.createRemoteComponentLoader,decodeToken:()=>n.decodeToken,extractPermissions:()=>n.extractPermissions,getRemoteEnvironment:()=>b.getRemoteEnvironment,isRemoteAvailable:()=>b.isRemoteAvailable,isTokenExpired:()=>n.isTokenExpired,loadRemoteModule:()=>b.loadRemoteModule,tokenStorage:()=>n.tokenStorage,useRemoteAuth:()=>c,useRemoteConfig:()=>v});var e=r(848),t=r(953),n=r(433);const a={token:null,isAuthenticated:!1,permissions:[],user:void 0},s=(e,t)=>{switch(t.type){case"SET_TOKEN":const r=(0,n.decodeToken)(t.payload),o=r?(0,n.extractPermissions)(r):[];return{...e,token:t.payload,isAuthenticated:!(0,n.isTokenExpired)(t.payload),permissions:o,user:r?{id:r.sub||"",email:r.email||"",name:r.name||r.email||""}:void 0};case"CLEAR_AUTH":return{...a};case"SET_USER_INFO":return{...e,user:{id:t.payload.sub||"",email:t.payload.email||"",name:t.payload.name||t.payload.email||""}};default:return e}},i=(0,t.createContext)(void 0),l=({children:r,initialToken:o})=>{const[l,c]=(0,t.useReducer)(s,a),d="dev"===process.env.REACT_APP_ENVIRONMENT?console.log:()=>{};(0,t.useEffect)(()=>{if(d("🔍 RemoteAuthContext: useEffect triggered",{initialToken:o?o.substring(0,30)+"...":"No initialToken"}),o)d("✅ RemoteAuthContext: Using initialToken from prop"),(0,n.isTokenExpired)(o)?(d("🔴 RemoteAuthContext: Provided token is expired, clearing auth"),n.tokenStorage.remove(),c({type:"CLEAR_AUTH"})):(d("🟢 RemoteAuthContext: Token is valid, dispatching SET_TOKEN"),c({type:"SET_TOKEN",payload:o}),n.tokenStorage.save(o));else{d("⚪ RemoteAuthContext: No initialToken, checking stored token");const e=n.tokenStorage.get();e&&!(0,n.isTokenExpired)(e)?(d("💾 RemoteAuthContext: Using stored token"),c({type:"SET_TOKEN",payload:e})):e&&(d("🗑️ RemoteAuthContext: Stored token expired, clearing"),n.tokenStorage.remove(),c({type:"CLEAR_AUTH"}))}},[o]);const u={state:l,setToken:e=>{e&&(n.tokenStorage.save(e),c({type:"SET_TOKEN",payload:e}))},clearAuth:()=>{n.tokenStorage.remove(),c({type:"CLEAR_AUTH"})},hasPermission:e=>!!l.isAuthenticated&&l.permissions.includes(e)};return(0,e.jsx)(i.Provider,{value:u,children:r})},c=()=>{const e=(0,t.useContext)(i);if(void 0===e)throw new Error("useRemoteAuth must be used within a RemoteAuthProvider");return e},d=({children:t,permission:r,fallback:o=null})=>{const{hasPermission:n,state:a}=c();return a.isAuthenticated&&n(r)?(0,e.jsx)(e.Fragment,{children:t}):(0,e.jsx)(e.Fragment,{children:o})},u=({children:t,token:r})=>(0,e.jsx)(l,{initialToken:r,children:(0,e.jsx)("div",{children:t})});var m=r(87);const g=({children:t,className:r=""})=>(0,e.jsx)("div",{className:`bg-white rounded-lg shadow-md border border-gray-20 ${r}`,children:t}),p=({label:t,onClick:r,disabled:o=!1,variant:n="primary",size:a="medium",className:s="",type:i="button"})=>(0,e.jsx)("button",{type:i,onClick:r,disabled:o,className:`rounded-lg font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed ${{primary:"bg-gradient-to-br from-blue-40 to-blue-70 hover:from-blue-50 hover:to-blue-90 text-white focus:ring-blue-50 shadow-sm hover:shadow-md",secondary:"bg-gray-20 hover:bg-gray-30 text-gray-80 focus:ring-gray-40 border border-gray-30",text:"bg-transparent hover:bg-gray-10 text-blue-60 hover:text-blue-80 focus:ring-blue-30"}[n]} ${{small:"px-4 py-2 text-sm",medium:"px-5 py-2.5 text-base",large:"px-6 py-3 text-lg"}[a]} ${s}`,children:t}),x=({onSubmit:r,onCancel:o,onClearStorage:n,defaultDevRoles:a=[],currentToken:s=""})=>{const[i,l]=(0,t.useState)(!1),[c,d]=(0,t.useState)(""),[u,m]=(0,t.useState)({user:"usuario@bdsol.com.ar",roles:a,channel:"mf-testing",sessionId:crypto.randomUUID()}),[x,h]=(0,t.useState)(a.join("\n")),f=(e,t)=>{m(r=>({...r,[e]:t}))};return(0,e.jsx)("div",{className:"p-6 w-full overflow-y-auto",children:(0,e.jsx)(g,{className:"p-6",children:(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)("h2",{className:"text-2xl font-bold text-gray-80 mb-4",children:"🔧 Generador de Tokens (Desarrollo)"}),(0,e.jsx)("p",{className:"text-gray-60 mb-6",children:"Genera un token JWT para desarrollo usando el BFF. Solo disponible cuando ENVIRONMENT=dev."}),c&&(0,e.jsx)("div",{className:"mb-4 p-3 bg-red-10 border border-red-40 text-red-70 rounded",children:c}),(0,e.jsxs)("div",{className:"space-y-4 mb-6",children:[(0,e.jsxs)("div",{children:[(0,e.jsx)("label",{className:"block text-sm font-medium text-gray-70 mb-1",children:"Email del usuario"}),(0,e.jsx)("input",{type:"email",value:u.user,onChange:e=>f("user",e.target.value),className:"w-full p-2 border border-gray-30 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-50",placeholder:"usuario@bdsol.com.ar"})]}),(0,e.jsxs)("div",{children:[(0,e.jsx)("label",{className:"block text-sm font-medium text-gray-70 mb-1",children:"Roles (uno por línea)"}),(0,e.jsx)("textarea",{value:x,onChange:e=>h(e.target.value),className:"w-full h-32 p-2 border border-gray-30 rounded-lg font-mono text-sm focus:outline-none focus:ring-2 focus:ring-blue-50",placeholder:a.join("&#10;")}),(0,e.jsx)("p",{className:"text-xs text-gray-50 mt-1",children:"Roles definidos en src/config/roles.ts"})]}),(0,e.jsxs)("div",{children:[(0,e.jsx)("label",{className:"block text-sm font-medium text-gray-70 mb-1",children:"Channel"}),(0,e.jsx)("input",{type:"text",value:u.channel,onChange:e=>f("channel",e.target.value),className:"w-full p-2 border border-gray-30 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-50",placeholder:"mf-testing"})]}),(0,e.jsxs)("div",{children:[(0,e.jsx)("label",{className:"block text-sm font-medium text-gray-70 mb-1",children:"Session ID"}),(0,e.jsxs)("div",{className:"flex gap-2",children:[(0,e.jsx)("input",{type:"text",value:u.sessionId,onChange:e=>f("sessionId",e.target.value),className:"flex-1 p-2 border border-gray-30 rounded-lg font-mono text-sm focus:outline-none focus:ring-2 focus:ring-blue-50",placeholder:"uuid-session-id"}),(0,e.jsx)(p,{label:"🎲",variant:"primary",size:"small",onClick:()=>{m(e=>({...e,sessionId:crypto.randomUUID()}))},className:"px-3"})]})]})]}),(0,e.jsxs)("div",{className:"flex gap-3 flex-wrap mb-4",children:[(0,e.jsx)(p,{label:i?"Generando...":"🚀 Generar Token",variant:"primary",size:"small",onClick:async()=>{l(!0),d(""),n();try{const e=x.split("\n").map(e=>e.trim()).filter(e=>e.length>0),t={...u,roles:e},o=process.env.REACT_APP_API_URL||"http://localhost:3020",n=await fetch(`${o}/template/api/dev/generate-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const e=await n.json();throw new Error(e.error||"Error al generar token")}const a=await n.json();r(a.token)}catch(e){d(e instanceof Error?e.message:"Error desconocido")}finally{l(!1)}},disabled:i||!u.user.trim()}),(0,e.jsx)(p,{label:"Limpiar almacenamiento",variant:"primary",size:"small",onClick:()=>{n(),alert("SessionStorage limpiado correctamente")}}),(0,e.jsx)(p,{label:"Cancelar",size:"small",variant:"secondary",onClick:o})]}),s&&(0,e.jsxs)("div",{className:"mt-4 p-4 bg-green-50 rounded-lg",children:[(0,e.jsx)("h3",{className:"font-semibold text-green-70 mb-2",children:"✅ Token cargado"}),(0,e.jsx)("p",{className:"text-sm text-green-60",children:"Tienes un token activo en el almacenamiento local."})]})," "]})})})},h=({onSubmit:r,onCancel:o,onClearStorage:n,currentToken:a=""})=>{const[s,i]=(0,t.useState)(a),[l,c]=(0,t.useState)(!0);return(0,e.jsxs)("div",{className:"bg-white rounded-lg shadow-lg p-6 w-full max-w-2xl",children:[(0,e.jsx)("h2",{className:"text-2xl font-bold text-gray-80 mb-4",children:"Modo Desarrollo - Cargar Token JWT"}),(0,e.jsx)("p",{className:"text-gray-60 mb-6",children:"Ingresa el token JWT decodificado (JSON) que normalmente recibiría desde el host:"}),(0,e.jsxs)("div",{className:"mb-4",children:[(0,e.jsx)("textarea",{value:s,onChange:e=>{const t=e.target.value;i(t),l||c(!0)},placeholder:"Pegue aquí el token JWT en formato JSON",className:`w-full h-40 p-3 border rounded-lg font-mono text-sm ${l?"border-gray-30":"border-red-50"} focus:outline-none focus:ring-2 focus:ring-blue-50`}),!l&&(0,e.jsx)("p",{className:"text-red-50 text-sm mt-2",children:"El JSON no es válido. Por favor verifica la sintaxis."})]}),(0,e.jsxs)("div",{className:"flex gap-3 flex-wrap",children:[(0,e.jsx)(p,{label:"Cargar Token",variant:"primary",size:"small",onClick:()=>{try{JSON.parse(s),c(!0),r(s)}catch(e){c(!1)}},disabled:!s.trim()}),(0,e.jsx)(p,{label:"Limpiar",size:"small",variant:"text",onClick:()=>i("")}),(0,e.jsx)(p,{label:"Limpiar Storage",variant:"primary",size:"small",onClick:()=>{n(),i(""),alert("SessionStorage limpiado correctamente")}}),(0,e.jsx)(p,{label:"Cancelar",variant:"secondary",size:"small",onClick:o})]})]})},f=({onClick:t})=>(0,e.jsxs)("button",{onClick:t,className:"fixed bottom-6 right-6 bg-gradient-to-br from-blue-40 to-blue-70 hover:from-blue-50 hover:to-blue-90 text-white p-4 rounded-full shadow-dropdown hover:shadow-2xl transition-all duration-300 z-50 group transform hover:scale-110",title:"Recargar Token",children:[(0,e.jsx)("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,e.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"})}),(0,e.jsx)("span",{className:"absolute bottom-full right-0 mb-3 px-3 py-1 text-xs text-white bg-gray-90/90 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap backdrop-blur-sm",children:"Recargar Token"})]}),y=({children:r})=>{const[o,n]=(0,t.useState)(""),[a,s]=(0,t.useState)(!1),[i,l]=(0,t.useState)(!1),[c,d]=(0,t.useState)(!0),u="dev"===process.env.REACT_APP_ENVIRONMENT&&!o;(0,t.useEffect)(()=>{const e=m.tokenStorage.get();e?(n(e),l(!1)):u&&l(!0)},[u]);const g=e=>{console.log("🔄 DevWrapper: Nuevo token generado",{token:e.substring(0,50)+"..."}),n(e),m.tokenStorage.save(e),console.log("💾 DevWrapper: Token guardado en storage"),s(!1),l(!1)},p=()=>{m.tokenStorage.clear(),n(""),l(u)};return i?(0,e.jsx)("div",{className:"min-h-screen bg-gray-50 flex items-center justify-center p-4",children:(0,e.jsx)(x,{onSubmit:g,onCancel:()=>l(!1),onClearStorage:p,currentToken:o})}):(0,e.jsxs)("div",{className:"min-h-screen bg-gray-50",children:[a&&(0,e.jsx)("div",{className:"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50",children:(0,e.jsxs)("div",{className:"bg-white rounded-lg shadow-lg max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto",children:[(0,e.jsxs)("div",{className:"flex border-b",children:[(0,e.jsx)("button",{onClick:()=>d(!0),className:"flex-1 py-3 px-4 text-sm font-medium "+(c?"bg-blue-50 ":"bg-gray-10 text-gray-70 hover:bg-gray-20"),children:"Generar Token"}),(0,e.jsx)("button",{onClick:()=>d(!1),className:"flex-1 py-3 px-4 text-sm font-medium "+(c?"bg-gray-10 text-gray-70 hover:bg-gray-20":"bg-blue-50 text-gray-50"),children:"Input Manual"})]}),(0,e.jsx)("div",{className:"p-0",children:c?(0,e.jsx)(x,{onSubmit:g,onCancel:()=>s(!1),onClearStorage:p,currentToken:o}):(0,e.jsx)("div",{className:"p-6",children:(0,e.jsx)(h,{onSubmit:g,onCancel:()=>s(!1),onClearStorage:p,currentToken:o})})})]})}),(0,e.jsx)(f,{onClick:()=>{s(!a)}}),(0,e.jsx)(m.RemoteWrapper,{token:o,children:r})]})},v=()=>{const e=(0,t.useMemo)(()=>({react:{singleton:!0,eager:!1},"react-dom":{singleton:!0,eager:!1},"aurora-web":{singleton:!0,eager:!1},"react-i18next":{singleton:!0,eager:!1},i18next:{singleton:!0,eager:!1}}),[]);return{sharedDependencies:e,getWebpackConfig:(t,r)=>({name:t,filename:"remoteEntry.js",exposes:r,shared:e})}};var b=r(226)})(),module.exports=o})();
2
+ (()=>{var e={20:(e,o,r)=>{"use strict";var t=r(953),n=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function d(e,o,r){var t,a={},d=null,c=null;for(t in void 0!==r&&(d=""+r),void 0!==o.key&&(d=""+o.key),void 0!==o.ref&&(c=o.ref),o)i.call(o,t)&&!l.hasOwnProperty(t)&&(a[t]=o[t]);if(e&&e.defaultProps)for(t in o=e.defaultProps)void 0===a[t]&&(a[t]=o[t]);return{$$typeof:n,type:e,key:d,ref:c,props:a,_owner:s.current}}o.Fragment=a,o.jsx=d,o.jsxs=d},60:(e,o,r)=>{var t={"./moduleUtils":226,"./moduleUtils.ts":226,"./tokenUtils":433,"./tokenUtils.ts":433};function n(e){return Promise.resolve().then(()=>{if(!r.o(t,e)){var o=new Error("Cannot find module '"+e+"'");throw o.code="MODULE_NOT_FOUND",o}return r(t[e])})}n.keys=()=>Object.keys(t),n.id=60,e.exports=n},87:(e,o,r)=>{(()=>{var o={20:(e,o,r)=>{"use strict";var t=r(953),n=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};o.Fragment=a,o.jsx=function(e,o,r){var t,a={},d=null,c=null;for(t in void 0!==r&&(d=""+r),void 0!==o.key&&(d=""+o.key),void 0!==o.ref&&(c=o.ref),o)i.call(o,t)&&!l.hasOwnProperty(t)&&(a[t]=o[t]);if(e&&e.defaultProps)for(t in o=e.defaultProps)void 0===a[t]&&(a[t]=o[t]);return{$$typeof:n,type:e,key:d,ref:c,props:a,_owner:s.current}}},60:(e,o,r)=>{var t={"./moduleUtils":226,"./moduleUtils.ts":226,"./tokenUtils":433,"./tokenUtils.ts":433};function n(e){return Promise.resolve().then(()=>{if(!r.o(t,e)){var o=new Error("Cannot find module '"+e+"'");throw o.code="MODULE_NOT_FOUND",o}return r(t[e])})}n.keys=()=>Object.keys(t),n.id=60,e.exports=n},226:(e,o,r)=>{"use strict";r.r(o),r.d(o,{createRemoteComponentLoader:()=>s,getRemoteEnvironment:()=>l,isRemoteAvailable:()=>i,loadRemoteModule:()=>a});var t=r(953),n=r.n(t);const a=async(e,o)=>{try{return await r(60)(`${e}/${o}`)}catch(r){throw console.error(`Failed to load remote module ${e}/${o}:`,r),r}},i=async e=>{try{const o=window[e];return"function"==typeof o?.get}catch(e){return!1}},s=(e,o,r)=>n().lazy(async()=>{try{return await a(e,o)}catch(t){return console.error(`Remote component loading failed: ${e}/${o}`,t),r?{default:r}:{default:()=>n().createElement("div",{style:{padding:"20px",color:"red"}},`Failed to load remote component: ${e}/${o}`)}}}),l=()=>({isDevelopment:!1,apiBaseUrl:process.env.REACT_APP_API_URL||"",frontUrl:process.env.REACT_APP_FRONT_URL||""})},433:(e,o,r)=>{"use strict";r.r(o),r.d(o,{decodeToken:()=>t,extractPermissions:()=>a,isTokenExpired:()=>n,tokenStorage:()=>i});const t=e=>{try{if(!e)return null;const o=e.split(".");if(3!==o.length)return null;const r=o[1],t=r+"=".repeat((4-r.length%4)%4),n=atob(t);return JSON.parse(n)}catch(e){return console.error("Error decoding token:",e),null}},n=e=>{const o=t(e);if(!o||!o.exp)return!0;const r=Math.floor(Date.now()/1e3);return o.exp<r},a=e=>{if(!e)return[];const o=["permissions","roles","authorities","scope"];for(const r of o){const o=e[r];if(Array.isArray(o))return o;if("string"==typeof o)return o.split(" ").filter(Boolean)}return[]},i={key:"bo-remote-token",save:e=>{try{sessionStorage.setItem(i.key,e)}catch(e){console.error("Error saving token:",e)}},get:()=>{try{return sessionStorage.getItem(i.key)}catch(e){return console.error("Error getting token:",e),null}},remove:()=>{try{sessionStorage.removeItem(i.key)}catch(e){console.error("Error removing token:",e)}},clear:()=>{try{sessionStorage.clear()}catch(e){console.error("Error clearing storage:",e)}}}},848:(e,o,r)=>{"use strict";e.exports=r(20)},953:e=>{"use strict";e.exports=r(953)}},t={};function n(e){var r=t[e];if(void 0!==r)return r.exports;var a=t[e]={exports:{}};return o[e](a,a.exports,n),a.exports}n.n=e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return n.d(o,{a:o}),o},n.d=(e,o)=>{for(var r in o)n.o(o,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:o[r]})},n.e=()=>Promise.resolve(),n.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var a={};(()=>{"use strict";n.r(a),n.d(a,{RemoteAuthProvider:()=>l,RemoteWrapper:()=>m,Secured:()=>c,createRemoteComponentLoader:()=>p.createRemoteComponentLoader,decodeToken:()=>r.decodeToken,extractPermissions:()=>r.extractPermissions,getRemoteEnvironment:()=>p.getRemoteEnvironment,isRemoteAvailable:()=>p.isRemoteAvailable,isTokenExpired:()=>r.isTokenExpired,loadRemoteModule:()=>p.loadRemoteModule,tokenStorage:()=>r.tokenStorage,useRemoteAuth:()=>d,useRemoteConfig:()=>u});var e=n(848),o=n(953),r=n(433);const t={token:null,isAuthenticated:!1,permissions:[],user:void 0},i=(e,o)=>{switch(o.type){case"SET_TOKEN":const n=(0,r.decodeToken)(o.payload),a=n?(0,r.extractPermissions)(n):[];return{...e,token:o.payload,isAuthenticated:!(0,r.isTokenExpired)(o.payload),permissions:a,user:n?{id:n.sub||"",email:n.email||"",name:n.name||n.email||""}:void 0};case"CLEAR_AUTH":return{...t};case"SET_USER_INFO":return{...e,user:{id:o.payload.sub||"",email:o.payload.email||"",name:o.payload.name||o.payload.email||""}};default:return e}},s=(0,o.createContext)(void 0),l=({children:n,initialToken:a})=>{const[l,d]=(0,o.useReducer)(i,t);(0,o.useEffect)(()=>{if(console.log("🔍 RemoteAuthContext: useEffect triggered",{initialToken:a?a.substring(0,30)+"...":"No initialToken"}),a)console.log("✅ RemoteAuthContext: Using initialToken from prop"),(0,r.isTokenExpired)(a)?(console.log("🔴 RemoteAuthContext: Provided token is expired, clearing auth"),r.tokenStorage.remove(),d({type:"CLEAR_AUTH"})):(console.log("🟢 RemoteAuthContext: Token is valid, dispatching SET_TOKEN"),d({type:"SET_TOKEN",payload:a}),r.tokenStorage.save(a));else{console.log("⚪ RemoteAuthContext: No initialToken, checking stored token");const e=r.tokenStorage.get();e&&!(0,r.isTokenExpired)(e)?(console.log("💾 RemoteAuthContext: Using stored token"),d({type:"SET_TOKEN",payload:e})):e&&(console.log("🗑️ RemoteAuthContext: Stored token expired, clearing"),r.tokenStorage.remove(),d({type:"CLEAR_AUTH"}))}},[a]);const c={state:l,setToken:e=>{e&&(r.tokenStorage.save(e),d({type:"SET_TOKEN",payload:e}))},clearAuth:()=>{r.tokenStorage.remove(),d({type:"CLEAR_AUTH"})},hasPermission:e=>!!l.isAuthenticated&&l.permissions.includes(e)};return(0,e.jsx)(s.Provider,{value:c,children:n})},d=()=>{const e=(0,o.useContext)(s);if(void 0===e)throw new Error("useRemoteAuth must be used within a RemoteAuthProvider");return e},c=({children:o,permission:r,fallback:t=null})=>{const{hasPermission:n,state:a}=d();return a.isAuthenticated&&n(r)?(0,e.jsx)(e.Fragment,{children:o}):(0,e.jsx)(e.Fragment,{children:t})},m=({children:o,token:r,apiBaseUrl:t,module:n})=>(0,e.jsx)(l,{initialToken:r,children:(0,e.jsx)("div",{"data-remote-module":n,"data-api-base":t,children:o})}),u=()=>{const e=(0,o.useMemo)(()=>({react:{singleton:!0,eager:!1},"react-dom":{singleton:!0,eager:!1},"aurora-web":{singleton:!0,eager:!1},"react-i18next":{singleton:!0,eager:!1},i18next:{singleton:!0,eager:!1}}),[]);return{sharedDependencies:e,getWebpackConfig:(o,r)=>({name:o,filename:"remoteEntry.js",exposes:r,shared:e})}};var p=n(226)})(),e.exports=a})()},226:(e,o,r)=>{"use strict";r.r(o),r.d(o,{createRemoteComponentLoader:()=>s,getRemoteEnvironment:()=>l,isRemoteAvailable:()=>i,loadRemoteModule:()=>a});var t=r(953),n=r.n(t);const a=async(e,o)=>{try{return await r(60)(`${e}/${o}`)}catch(r){throw console.error(`Failed to load remote module ${e}/${o}:`,r),r}},i=async e=>{try{const o=window[e];return"function"==typeof o?.get}catch(e){return!1}},s=(e,o,r)=>n().lazy(async()=>{try{return await a(e,o)}catch(t){return console.error(`Remote component loading failed: ${e}/${o}`,t),r?{default:r}:{default:()=>n().createElement("div",{style:{padding:"20px",color:"red"}},`Failed to load remote component: ${e}/${o}`)}}}),l=()=>({isDevelopment:!1,apiBaseUrl:process.env.REACT_APP_API_URL||"",frontUrl:process.env.REACT_APP_FRONT_URL||""})},433:(e,o,r)=>{"use strict";r.r(o),r.d(o,{decodeToken:()=>t,extractPermissions:()=>a,isTokenExpired:()=>n,tokenStorage:()=>i});const t=e=>{try{if(!e)return null;const o=e.split(".");if(3!==o.length)return null;const r=o[1],t=r+"=".repeat((4-r.length%4)%4),n=atob(t);return JSON.parse(n)}catch(e){return console.error("Error decoding token:",e),null}},n=e=>{const o=t(e);if(!o||!o.exp)return!0;const r=Math.floor(Date.now()/1e3);return o.exp<r},a=e=>{if(!e)return[];const o=["permissions","roles","authorities","scope"];for(const r of o){const o=e[r];if(Array.isArray(o))return o;if("string"==typeof o)return o.split(" ").filter(Boolean)}return[]},i={key:"bo-remote-token",save:e=>{try{sessionStorage.setItem(i.key,e)}catch(e){console.error("Error saving token:",e)}},get:()=>{try{return sessionStorage.getItem(i.key)}catch(e){return console.error("Error getting token:",e),null}},remove:()=>{try{sessionStorage.removeItem(i.key)}catch(e){console.error("Error removing token:",e)}},clear:()=>{try{sessionStorage.clear()}catch(e){console.error("Error clearing storage:",e)}}}},848:(e,o,r)=>{"use strict";e.exports=r(20)},953:e=>{"use strict";e.exports=require("react")}},o={};function r(t){var n=o[t];if(void 0!==n)return n.exports;var a=o[t]={exports:{}};return e[t](a,a.exports,r),a.exports}r.n=e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return r.d(o,{a:o}),o},r.d=(e,o)=>{for(var t in o)r.o(o,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},r.e=()=>Promise.resolve(),r.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var t={};(()=>{"use strict";r.r(t),r.d(t,{DevWrapper:()=>v,RemoteAuthProvider:()=>d,RemoteWrapper:()=>u,Secured:()=>m,createRemoteComponentLoader:()=>b.createRemoteComponentLoader,decodeToken:()=>a.decodeToken,extractPermissions:()=>a.extractPermissions,getRemoteEnvironment:()=>b.getRemoteEnvironment,isRemoteAvailable:()=>b.isRemoteAvailable,isTokenExpired:()=>a.isTokenExpired,loadRemoteModule:()=>b.loadRemoteModule,tokenStorage:()=>a.tokenStorage,useRemoteAuth:()=>c,useRemoteConfig:()=>k});var e=r(848),o=r(953),n=r.n(o),a=r(433);const i={token:null,isAuthenticated:!1,permissions:[],user:void 0},s=(e,o)=>{switch(o.type){case"SET_TOKEN":const r=(0,a.decodeToken)(o.payload),t=r?(0,a.extractPermissions)(r):[];return{...e,token:o.payload,isAuthenticated:!(0,a.isTokenExpired)(o.payload),permissions:t,user:r?{id:r.sub||"",email:r.email||"",name:r.name||r.email||""}:void 0};case"CLEAR_AUTH":return{...i};case"SET_USER_INFO":return{...e,user:{id:o.payload.sub||"",email:o.payload.email||"",name:o.payload.name||o.payload.email||""}};default:return e}},l=(0,o.createContext)(void 0),d=({children:r,initialToken:t})=>{const[n,d]=(0,o.useReducer)(s,i),c="dev"===process.env.REACT_APP_ENVIRONMENT?console.log:()=>{};(0,o.useEffect)(()=>{if(c("🔍 RemoteAuthContext: useEffect triggered",{initialToken:t?t.substring(0,30)+"...":"No initialToken"}),t)c("✅ RemoteAuthContext: Using initialToken from prop"),(0,a.isTokenExpired)(t)?(c("🔴 RemoteAuthContext: Provided token is expired, clearing auth"),a.tokenStorage.remove(),d({type:"CLEAR_AUTH"})):(c("🟢 RemoteAuthContext: Token is valid, dispatching SET_TOKEN"),d({type:"SET_TOKEN",payload:t}),a.tokenStorage.save(t));else{c("⚪ RemoteAuthContext: No initialToken, checking stored token");const e=a.tokenStorage.get();e&&!(0,a.isTokenExpired)(e)?(c("💾 RemoteAuthContext: Using stored token"),d({type:"SET_TOKEN",payload:e})):e&&(c("🗑️ RemoteAuthContext: Stored token expired, clearing"),a.tokenStorage.remove(),d({type:"CLEAR_AUTH"}))}},[t]);const m={state:n,setToken:e=>{e&&(a.tokenStorage.save(e),d({type:"SET_TOKEN",payload:e}))},clearAuth:()=>{a.tokenStorage.remove(),d({type:"CLEAR_AUTH"})},hasPermission:e=>!!n.isAuthenticated&&n.permissions.includes(e)};return(0,e.jsx)(l.Provider,{value:m,children:r})},c=()=>{const e=(0,o.useContext)(l);if(void 0===e)throw new Error("useRemoteAuth must be used within a RemoteAuthProvider");return e},m=({children:o,permission:r,fallback:t=null})=>{const{hasPermission:n,state:a}=c();return a.isAuthenticated&&n(r)?(0,e.jsx)(e.Fragment,{children:o}):(0,e.jsx)(e.Fragment,{children:t})},u=({children:o,token:r})=>(0,e.jsx)(d,{initialToken:r,children:(0,e.jsx)("div",{children:o})});var p=r(87);const g=({children:o,className:r="",style:t})=>{const n={backgroundColor:"white",borderRadius:"0.5rem",boxShadow:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",border:"1px solid #E5E7EB",...t};return(0,e.jsx)("div",{style:n,className:r,children:o})},h=({label:o,onClick:r,disabled:t=!1,variant:n="primary",size:a="medium",className:i="",type:s="button",style:l})=>{const d={borderRadius:"0.5rem",fontWeight:500,transition:"all 0.2s",outline:"none",cursor:t?"not-allowed":"pointer",opacity:t?.5:1,border:"none"};return(0,e.jsx)("button",{type:s,onClick:r,disabled:t,style:{...d,...{primary:{background:"linear-gradient(to bottom right, #3B82F6, #1E40AF)",color:"white",boxShadow:"0 1px 2px 0 rgb(0 0 0 / 0.05)"},secondary:{backgroundColor:"#F3F4F6",color:"#1F2937",border:"1px solid #D1D5DB"},text:{backgroundColor:"transparent",color:"#2563EB"}}[n],...{small:{padding:"0.5rem 1rem",fontSize:"0.875rem"},medium:{padding:"0.625rem 1.25rem",fontSize:"1rem"},large:{padding:"0.75rem 1.5rem",fontSize:"1.125rem"}}[a],...l},className:i,children:o})},x=({onSubmit:r,onCancel:t,onClearStorage:n,defaultDevRoles:a=[],currentToken:i=""})=>{const[s,l]=(0,o.useState)(!1),[d,c]=(0,o.useState)(""),[m,u]=(0,o.useState)({user:"usuario@bdsol.com.ar",roles:a,channel:"mf-testing",sessionId:crypto.randomUUID()}),[p,x]=(0,o.useState)(a.join("\n")),y=(e,o)=>{u(r=>({...r,[e]:o}))};return(0,e.jsx)("div",{style:{padding:"1.5rem",width:"100%",overflowY:"auto"},children:(0,e.jsx)(g,{style:{padding:"1.5rem"},children:(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)("h2",{style:{fontSize:"1.5rem",fontWeight:"bold",color:"#1F2937",marginBottom:"1rem"},children:"🔧 Generador de Tokens (Desarrollo)"}),(0,e.jsx)("p",{style:{color:"#6B7280",marginBottom:"1.5rem"},children:"Genera un token JWT para desarrollo usando el BFF. Solo disponible cuando ENVIRONMENT=dev."}),d&&(0,e.jsx)("div",{style:{marginBottom:"1rem",padding:"0.75rem",backgroundColor:"#FEE2E2",border:"1px solid #F87171",color:"#B91C1C",borderRadius:"0.25rem"},children:d}),(0,e.jsxs)("div",{style:{marginBottom:"1.5rem"},children:[(0,e.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,e.jsx)("label",{style:{display:"block",fontSize:"0.875rem",fontWeight:500,color:"#374151",marginBottom:"0.25rem"},children:"Email del usuario"}),(0,e.jsx)("input",{type:"email",value:m.user,onChange:e=>y("user",e.target.value),style:{width:"100%",padding:"0.5rem",border:"1px solid #D1D5DB",borderRadius:"0.5rem",outline:"none"},placeholder:"usuario@bdsol.com.ar"})]}),(0,e.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,e.jsx)("label",{style:{display:"block",fontSize:"0.875rem",fontWeight:500,color:"#374151",marginBottom:"0.25rem"},children:"Roles (uno por línea)"}),(0,e.jsx)("textarea",{value:p,onChange:e=>x(e.target.value),style:{width:"100%",height:"8rem",padding:"0.5rem",border:"1px solid #D1D5DB",borderRadius:"0.5rem",fontFamily:"monospace",fontSize:"0.875rem",outline:"none"},placeholder:a.join("&#10;")}),(0,e.jsx)("p",{style:{fontSize:"0.75rem",color:"#9CA3AF",marginTop:"0.25rem"},children:"Roles definidos en src/config/roles.ts"})]}),(0,e.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,e.jsx)("label",{style:{display:"block",fontSize:"0.875rem",fontWeight:500,color:"#374151",marginBottom:"0.25rem"},children:"Channel"}),(0,e.jsx)("input",{type:"text",value:m.channel,onChange:e=>y("channel",e.target.value),style:{width:"100%",padding:"0.5rem",border:"1px solid #D1D5DB",borderRadius:"0.5rem",outline:"none"},placeholder:"mf-testing"})]}),(0,e.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,e.jsx)("label",{style:{display:"block",fontSize:"0.875rem",fontWeight:500,color:"#374151",marginBottom:"0.25rem"},children:"Session ID"}),(0,e.jsxs)("div",{style:{display:"flex",gap:"0.5rem"},children:[(0,e.jsx)("input",{type:"text",value:m.sessionId,onChange:e=>y("sessionId",e.target.value),style:{flex:1,padding:"0.5rem",border:"1px solid #D1D5DB",borderRadius:"0.5rem",fontFamily:"monospace",fontSize:"0.875rem",outline:"none"},placeholder:"uuid-session-id"}),(0,e.jsx)(h,{label:"🎲",variant:"primary",size:"small",onClick:()=>{u(e=>({...e,sessionId:crypto.randomUUID()}))},style:{padding:"0.5rem 0.75rem"}})]})]})]}),(0,e.jsxs)("div",{style:{display:"flex",gap:"0.75rem",flexWrap:"wrap",marginBottom:"1rem"},children:[(0,e.jsx)(h,{label:s?"Generando...":"🚀 Generar Token",variant:"primary",size:"small",onClick:async()=>{l(!0),c(""),n();try{const e=p.split("\n").map(e=>e.trim()).filter(e=>e.length>0),o={...m,roles:e},t=process.env.REACT_APP_API_URL||"http://localhost:3020",n=await fetch(`${t}/template/api/dev/generate-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok){const e=await n.json();throw new Error(e.error||"Error al generar token")}const a=await n.json();r(a.token)}catch(e){c(e instanceof Error?e.message:"Error desconocido")}finally{l(!1)}},disabled:s||!m.user.trim()}),(0,e.jsx)(h,{label:"Limpiar almacenamiento",variant:"primary",size:"small",onClick:()=>{n(),alert("SessionStorage limpiado correctamente")}}),(0,e.jsx)(h,{label:"Cancelar",size:"small",variant:"secondary",onClick:t})]}),i&&(0,e.jsxs)("div",{style:{marginTop:"1rem",padding:"1rem",backgroundColor:"#D1FAE5",borderRadius:"0.5rem"},children:[(0,e.jsx)("h3",{style:{fontWeight:600,color:"#047857",marginBottom:"0.5rem"},children:"✅ Token cargado"}),(0,e.jsx)("p",{style:{fontSize:"0.875rem",color:"#059669"},children:"Tienes un token activo en el almacenamiento local."})]})," "]})})})},y=({onSubmit:r,onCancel:t,onClearStorage:n,currentToken:a=""})=>{const[i,s]=(0,o.useState)(a),[l,d]=(0,o.useState)(!0);return(0,e.jsxs)("div",{style:{backgroundColor:"white",borderRadius:"0.5rem",boxShadow:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",padding:"1.5rem",width:"100%",maxWidth:"42rem"},children:[(0,e.jsx)("h2",{style:{fontSize:"1.5rem",fontWeight:"bold",color:"#1F2937",marginBottom:"1rem"},children:"Modo Desarrollo - Cargar Token JWT"}),(0,e.jsx)("p",{style:{color:"#6B7280",marginBottom:"1.5rem"},children:"Ingresa el token JWT decodificado (JSON) que normalmente recibiría desde el host:"}),(0,e.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,e.jsx)("textarea",{value:i,onChange:e=>{const o=e.target.value;s(o),l||d(!0)},placeholder:"Pegue aquí el token JWT en formato JSON",style:{width:"100%",height:"10rem",padding:"0.75rem",border:"1px solid "+(l?"#D1D5DB":"#F87171"),borderRadius:"0.5rem",fontFamily:"monospace",fontSize:"0.875rem",outline:"none"}}),!l&&(0,e.jsx)("p",{style:{color:"#EF4444",fontSize:"0.875rem",marginTop:"0.5rem"},children:"El JSON no es válido. Por favor verifica la sintaxis."})]}),(0,e.jsxs)("div",{style:{display:"flex",gap:"0.75rem",flexWrap:"wrap"},children:[(0,e.jsx)(h,{label:"Cargar Token",variant:"primary",size:"small",onClick:()=>{try{JSON.parse(i),d(!0),r(i)}catch(e){d(!1)}},disabled:!i.trim()}),(0,e.jsx)(h,{label:"Limpiar",size:"small",variant:"text",onClick:()=>s("")}),(0,e.jsx)(h,{label:"Limpiar Storage",variant:"primary",size:"small",onClick:()=>{n(),s(""),alert("SessionStorage limpiado correctamente")}}),(0,e.jsx)(h,{label:"Cancelar",variant:"secondary",size:"small",onClick:t})]})]})},f=({onClick:o})=>{const[r,t]=n().useState(!1),a={position:"fixed",bottom:"1.5rem",right:"1.5rem",background:"linear-gradient(to bottom right, #3B82F6, #1E40AF)",color:"white",padding:"1rem",borderRadius:"9999px",boxShadow:r?"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)":"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",transition:"all 0.3s",zIndex:50,transform:r?"scale(1.1)":"scale(1)",border:"none",cursor:"pointer"},i={position:"absolute",bottom:"100%",right:0,marginBottom:"0.75rem",padding:"0.25rem 0.75rem",fontSize:"0.75rem",color:"white",backgroundColor:"rgba(17, 24, 39, 0.9)",borderRadius:"0.5rem",opacity:r?1:0,transition:"opacity 0.2s",whiteSpace:"nowrap",backdropFilter:"blur(4px)",pointerEvents:"none"};return(0,e.jsxs)("button",{onClick:o,style:a,title:"Recargar Token",onMouseEnter:()=>t(!0),onMouseLeave:()=>t(!1),children:[(0,e.jsx)("svg",{style:{width:"1.25rem",height:"1.25rem"},fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,e.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"})}),(0,e.jsx)("span",{style:i,children:"Recargar Token"})]})},v=({children:r,defaultDevRoles:t=[]})=>{const[n,a]=(0,o.useState)(""),[i,s]=(0,o.useState)(!1),[l,d]=(0,o.useState)(!1),[c,m]=(0,o.useState)(!0),u="dev"===process.env.REACT_APP_ENVIRONMENT&&!n;(0,o.useEffect)(()=>{const e=p.tokenStorage.get();e?(a(e),d(!1)):u&&d(!0)},[u]);const g=e=>{console.log("🔄 DevWrapper: Nuevo token generado",{token:e.substring(0,50)+"..."}),a(e),p.tokenStorage.save(e),console.log("💾 DevWrapper: Token guardado en storage"),s(!1),d(!1)},h=()=>{p.tokenStorage.clear(),a(""),d(u)};return l?(0,e.jsx)("div",{style:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",padding:"1rem"},children:(0,e.jsx)(x,{onSubmit:g,onCancel:()=>d(!1),onClearStorage:h,currentToken:n,defaultDevRoles:t})}):(0,e.jsxs)("div",{style:{minHeight:"100vh",backgroundColor:"#F9FAFB"},children:[i&&(0,e.jsx)("div",{style:{position:"fixed",inset:0,backgroundColor:"rgba(0, 0, 0, 0.5)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:50},children:(0,e.jsxs)("div",{style:{backgroundColor:"white",borderRadius:"0.5rem",boxShadow:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",maxWidth:"42rem",width:"100%",margin:"0 1rem",maxHeight:"90vh",overflowY:"auto"},children:[(0,e.jsxs)("div",{style:{display:"flex",borderBottom:"1px solid #E5E7EB"},children:[(0,e.jsx)("button",{onClick:()=>m(!0),style:{flex:1,padding:"0.75rem 1rem",fontSize:"0.875rem",fontWeight:500,backgroundColor:c?"#afd1f3":"#F3F4F6",color:c?"#1E3A8A":"#4B5563",border:"none",cursor:"pointer"},children:"Generar Token"}),(0,e.jsx)("button",{onClick:()=>m(!1),style:{flex:1,padding:"0.75rem 1rem",fontSize:"0.875rem",fontWeight:500,backgroundColor:c?"#F3F4F6":"#afd1f3",color:c?"#4B5563":"#1E3A8A",border:"none",cursor:"pointer"},children:"Input Manual"})]}),(0,e.jsx)("div",{style:{padding:0},children:c?(0,e.jsx)(x,{onSubmit:g,onCancel:()=>s(!1),onClearStorage:h,currentToken:n,defaultDevRoles:t}):(0,e.jsx)("div",{style:{padding:"1.5rem"},children:(0,e.jsx)(y,{onSubmit:g,onCancel:()=>s(!1),onClearStorage:h,currentToken:n})})})]})}),(0,e.jsx)(f,{onClick:()=>{s(!i)}}),(0,e.jsx)(p.RemoteWrapper,{token:n,children:r})]})},k=()=>{const e=(0,o.useMemo)(()=>({react:{singleton:!0,eager:!1},"react-dom":{singleton:!0,eager:!1},"aurora-web":{singleton:!0,eager:!1},"react-i18next":{singleton:!0,eager:!1},i18next:{singleton:!0,eager:!1}}),[]);return{sharedDependencies:e,getWebpackConfig:(o,r)=>({name:o,filename:"remoteEntry.js",exposes:r,shared:e})}};var b=r(226)})(),module.exports=t})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "max-remotes-helper",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Helper library for Module Federation remotes in BO ecosystem",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,6 +18,7 @@ interface DevButtonProps {
18
18
  size?: ButtonSize;
19
19
  className?: string;
20
20
  type?: "button" | "submit" | "reset";
21
+ style?: React.CSSProperties;
21
22
  }
22
23
 
23
24
  const DevButton: React.FC<DevButtonProps> = ({
@@ -28,22 +29,48 @@ const DevButton: React.FC<DevButtonProps> = ({
28
29
  size = "medium",
29
30
  className = "",
30
31
  type = "button",
32
+ style,
31
33
  }) => {
32
- const baseStyles =
33
- "rounded-lg font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed";
34
-
35
- const variantStyles = {
36
- primary:
37
- "bg-gradient-to-br from-blue-40 to-blue-70 hover:from-blue-50 hover:to-blue-90 text-white focus:ring-blue-50 shadow-sm hover:shadow-md",
38
- secondary:
39
- "bg-gray-20 hover:bg-gray-30 text-gray-80 focus:ring-gray-40 border border-gray-30",
40
- text: "bg-transparent hover:bg-gray-10 text-blue-60 hover:text-blue-80 focus:ring-blue-30",
34
+ const baseStyles: React.CSSProperties = {
35
+ borderRadius: "0.5rem",
36
+ fontWeight: 500,
37
+ transition: "all 0.2s",
38
+ outline: "none",
39
+ cursor: disabled ? "not-allowed" : "pointer",
40
+ opacity: disabled ? 0.5 : 1,
41
+ border: "none",
41
42
  };
42
43
 
43
- const sizeStyles = {
44
- small: "px-4 py-2 text-sm",
45
- medium: "px-5 py-2.5 text-base",
46
- large: "px-6 py-3 text-lg",
44
+ const variantStyles: Record<ButtonVariant, React.CSSProperties> = {
45
+ primary: {
46
+ background: "linear-gradient(to bottom right, #3B82F6, #1E40AF)",
47
+ color: "white",
48
+ boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
49
+ },
50
+ secondary: {
51
+ backgroundColor: "#F3F4F6",
52
+ color: "#1F2937",
53
+ border: "1px solid #D1D5DB",
54
+ },
55
+ text: {
56
+ backgroundColor: "transparent",
57
+ color: "#2563EB",
58
+ },
59
+ };
60
+
61
+ const sizeStyles: Record<ButtonSize, React.CSSProperties> = {
62
+ small: {
63
+ padding: "0.5rem 1rem",
64
+ fontSize: "0.875rem",
65
+ },
66
+ medium: {
67
+ padding: "0.625rem 1.25rem",
68
+ fontSize: "1rem",
69
+ },
70
+ large: {
71
+ padding: "0.75rem 1.5rem",
72
+ fontSize: "1.125rem",
73
+ },
47
74
  };
48
75
 
49
76
  return (
@@ -51,7 +78,13 @@ const DevButton: React.FC<DevButtonProps> = ({
51
78
  type={type}
52
79
  onClick={onClick}
53
80
  disabled={disabled}
54
- className={`${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]} ${className}`}
81
+ style={{
82
+ ...baseStyles,
83
+ ...variantStyles[variant],
84
+ ...sizeStyles[size],
85
+ ...style,
86
+ }}
87
+ className={className}
55
88
  >
56
89
  {label}
57
90
  </button>
@@ -10,13 +10,25 @@ import React from "react";
10
10
  interface DevCardProps {
11
11
  children: React.ReactNode;
12
12
  className?: string;
13
+ style?: React.CSSProperties;
13
14
  }
14
15
 
15
- const DevCard: React.FC<DevCardProps> = ({ children, className = "" }) => {
16
+ const DevCard: React.FC<DevCardProps> = ({
17
+ children,
18
+ className = "",
19
+ style,
20
+ }) => {
21
+ const cardStyles: React.CSSProperties = {
22
+ backgroundColor: "white",
23
+ borderRadius: "0.5rem",
24
+ boxShadow:
25
+ "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
26
+ border: "1px solid #E5E7EB",
27
+ ...style,
28
+ };
29
+
16
30
  return (
17
- <div
18
- className={`bg-white rounded-lg shadow-md border border-gray-20 ${className}`}
19
- >
31
+ <div style={cardStyles} className={className}>
20
32
  {children}
21
33
  </div>
22
34
  );
@@ -6,9 +6,13 @@ import FloatingTokenButton from "./FloatingTokenButton";
6
6
 
7
7
  interface DevWrapperProps {
8
8
  children: React.ReactNode;
9
+ defaultDevRoles?: string[];
9
10
  }
10
11
 
11
- const DevWrapper: React.FC<DevWrapperProps> = ({ children }) => {
12
+ const DevWrapper: React.FC<DevWrapperProps> = ({
13
+ children,
14
+ defaultDevRoles = [],
15
+ }) => {
12
16
  const [currentToken, setCurrentToken] = useState<string>("");
13
17
  const [showTokenInput, setShowTokenInput] = useState<boolean>(false);
14
18
  const [needsToken, setNeedsToken] = useState<boolean>(false);
@@ -52,57 +56,99 @@ const DevWrapper: React.FC<DevWrapperProps> = ({ children }) => {
52
56
  // Si estamos en desarrollo, sin host y sin token, mostrar pantalla de generación
53
57
  if (needsToken) {
54
58
  return (
55
- <div className="min-h-screen bg-gray-50 flex items-center justify-center p-4">
59
+ <div
60
+ style={{
61
+ minHeight: "100vh",
62
+ display: "flex",
63
+ alignItems: "center",
64
+ justifyContent: "center",
65
+ padding: "1rem",
66
+ }}
67
+ >
56
68
  <TokenGenerator
57
69
  onSubmit={handleTokenSubmit}
58
70
  onCancel={() => setNeedsToken(false)}
59
71
  onClearStorage={handleClearStorage}
60
72
  currentToken={currentToken}
73
+ defaultDevRoles={defaultDevRoles}
61
74
  />
62
75
  </div>
63
76
  );
64
77
  }
65
78
 
66
79
  return (
67
- <div className="min-h-screen bg-gray-50">
80
+ <div style={{ minHeight: "100vh", backgroundColor: "#F9FAFB" }}>
68
81
  {/* Token Input/Generator Modal */}
69
82
  {showTokenInput && (
70
- <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
71
- <div className="bg-white rounded-lg shadow-lg max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto">
83
+ <div
84
+ style={{
85
+ position: "fixed",
86
+ inset: 0,
87
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
88
+ display: "flex",
89
+ alignItems: "center",
90
+ justifyContent: "center",
91
+ zIndex: 50,
92
+ }}
93
+ >
94
+ <div
95
+ style={{
96
+ backgroundColor: "white",
97
+ borderRadius: "0.5rem",
98
+ boxShadow:
99
+ "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
100
+ maxWidth: "42rem",
101
+ width: "100%",
102
+ margin: "0 1rem",
103
+ maxHeight: "90vh",
104
+ overflowY: "auto",
105
+ }}
106
+ >
72
107
  {/* Tabs para cambiar entre generador y input manual */}
73
- <div className="flex border-b">
108
+ <div style={{ display: "flex", borderBottom: "1px solid #E5E7EB" }}>
74
109
  <button
75
110
  onClick={() => setShowGenerator(true)}
76
- className={`flex-1 py-3 px-4 text-sm font-medium ${
77
- showGenerator
78
- ? "bg-blue-50 "
79
- : "bg-gray-10 text-gray-70 hover:bg-gray-20"
80
- }`}
111
+ style={{
112
+ flex: 1,
113
+ padding: "0.75rem 1rem",
114
+ fontSize: "0.875rem",
115
+ fontWeight: 500,
116
+ backgroundColor: showGenerator ? "#afd1f3" : "#F3F4F6",
117
+ color: showGenerator ? "#1E3A8A" : "#4B5563",
118
+ border: "none",
119
+ cursor: "pointer",
120
+ }}
81
121
  >
82
122
  Generar Token
83
123
  </button>
84
124
  <button
85
125
  onClick={() => setShowGenerator(false)}
86
- className={`flex-1 py-3 px-4 text-sm font-medium ${
87
- !showGenerator
88
- ? "bg-blue-50 text-gray-50"
89
- : "bg-gray-10 text-gray-70 hover:bg-gray-20"
90
- }`}
126
+ style={{
127
+ flex: 1,
128
+ padding: "0.75rem 1rem",
129
+ fontSize: "0.875rem",
130
+ fontWeight: 500,
131
+ backgroundColor: !showGenerator ? "#afd1f3" : "#F3F4F6",
132
+ color: !showGenerator ? "#1E3A8A" : "#4B5563",
133
+ border: "none",
134
+ cursor: "pointer",
135
+ }}
91
136
  >
92
137
  Input Manual
93
138
  </button>
94
139
  </div>
95
140
 
96
- <div className="p-0">
141
+ <div style={{ padding: 0 }}>
97
142
  {showGenerator ? (
98
143
  <TokenGenerator
99
144
  onSubmit={handleTokenSubmit}
100
145
  onCancel={() => setShowTokenInput(false)}
101
146
  onClearStorage={handleClearStorage}
102
147
  currentToken={currentToken}
148
+ defaultDevRoles={defaultDevRoles}
103
149
  />
104
150
  ) : (
105
- <div className="p-6">
151
+ <div style={{ padding: "1.5rem" }}>
106
152
  <TokenInput
107
153
  onSubmit={handleTokenSubmit}
108
154
  onCancel={() => setShowTokenInput(false)}
@@ -7,14 +7,53 @@ interface FloatingTokenButtonProps {
7
7
  const FloatingTokenButton: React.FC<FloatingTokenButtonProps> = ({
8
8
  onClick,
9
9
  }) => {
10
+ const [isHovered, setIsHovered] = React.useState(false);
11
+
12
+ const buttonStyles: React.CSSProperties = {
13
+ position: "fixed",
14
+ bottom: "1.5rem",
15
+ right: "1.5rem",
16
+ background: "linear-gradient(to bottom right, #3B82F6, #1E40AF)",
17
+ color: "white",
18
+ padding: "1rem",
19
+ borderRadius: "9999px",
20
+ boxShadow: isHovered
21
+ ? "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"
22
+ : "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
23
+ transition: "all 0.3s",
24
+ zIndex: 50,
25
+ transform: isHovered ? "scale(1.1)" : "scale(1)",
26
+ border: "none",
27
+ cursor: "pointer",
28
+ };
29
+
30
+ const tooltipStyles: React.CSSProperties = {
31
+ position: "absolute",
32
+ bottom: "100%",
33
+ right: 0,
34
+ marginBottom: "0.75rem",
35
+ padding: "0.25rem 0.75rem",
36
+ fontSize: "0.75rem",
37
+ color: "white",
38
+ backgroundColor: "rgba(17, 24, 39, 0.9)",
39
+ borderRadius: "0.5rem",
40
+ opacity: isHovered ? 1 : 0,
41
+ transition: "opacity 0.2s",
42
+ whiteSpace: "nowrap",
43
+ backdropFilter: "blur(4px)",
44
+ pointerEvents: "none",
45
+ };
46
+
10
47
  return (
11
48
  <button
12
49
  onClick={onClick}
13
- className="fixed bottom-6 right-6 bg-gradient-to-br from-blue-40 to-blue-70 hover:from-blue-50 hover:to-blue-90 text-white p-4 rounded-full shadow-dropdown hover:shadow-2xl transition-all duration-300 z-50 group transform hover:scale-110"
50
+ style={buttonStyles}
14
51
  title="Recargar Token"
52
+ onMouseEnter={() => setIsHovered(true)}
53
+ onMouseLeave={() => setIsHovered(false)}
15
54
  >
16
55
  <svg
17
- className="w-5 h-5"
56
+ style={{ width: "1.25rem", height: "1.25rem" }}
18
57
  fill="none"
19
58
  stroke="currentColor"
20
59
  viewBox="0 0 24 24"
@@ -26,9 +65,7 @@ const FloatingTokenButton: React.FC<FloatingTokenButtonProps> = ({
26
65
  d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"
27
66
  />
28
67
  </svg>
29
- <span className="absolute bottom-full right-0 mb-3 px-3 py-1 text-xs text-white bg-gray-90/90 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap backdrop-blur-sm">
30
- {"Recargar Token"}
31
- </span>
68
+ <span style={tooltipStyles}>{"Recargar Token"}</span>
32
69
  </button>
33
70
  );
34
71
  };
@@ -101,79 +101,162 @@ const TokenGenerator: React.FC<TokenGeneratorProps> = ({
101
101
  };
102
102
 
103
103
  return (
104
- <div className="p-6 w-full overflow-y-auto">
105
- <DevCard className="p-6">
104
+ <div style={{ padding: "1.5rem", width: "100%", overflowY: "auto" }}>
105
+ <DevCard style={{ padding: "1.5rem" }}>
106
106
  <>
107
- <h2 className="text-2xl font-bold text-gray-80 mb-4">
107
+ <h2
108
+ style={{
109
+ fontSize: "1.5rem",
110
+ fontWeight: "bold",
111
+ color: "#1F2937",
112
+ marginBottom: "1rem",
113
+ }}
114
+ >
108
115
  🔧 Generador de Tokens (Desarrollo)
109
116
  </h2>
110
- <p className="text-gray-60 mb-6">
117
+ <p style={{ color: "#6B7280", marginBottom: "1.5rem" }}>
111
118
  Genera un token JWT para desarrollo usando el BFF. Solo disponible
112
119
  cuando ENVIRONMENT=dev.
113
120
  </p>
114
121
  {error && (
115
- <div className="mb-4 p-3 bg-red-10 border border-red-40 text-red-70 rounded">
122
+ <div
123
+ style={{
124
+ marginBottom: "1rem",
125
+ padding: "0.75rem",
126
+ backgroundColor: "#FEE2E2",
127
+ border: "1px solid #F87171",
128
+ color: "#B91C1C",
129
+ borderRadius: "0.25rem",
130
+ }}
131
+ >
116
132
  {error}
117
133
  </div>
118
134
  )}
119
- <div className="space-y-4 mb-6">
135
+ <div style={{ marginBottom: "1.5rem" }}>
120
136
  {/* Email */}
121
- <div>
122
- <label className="block text-sm font-medium text-gray-70 mb-1">
137
+ <div style={{ marginBottom: "1rem" }}>
138
+ <label
139
+ style={{
140
+ display: "block",
141
+ fontSize: "0.875rem",
142
+ fontWeight: 500,
143
+ color: "#374151",
144
+ marginBottom: "0.25rem",
145
+ }}
146
+ >
123
147
  Email del usuario
124
148
  </label>
125
149
  <input
126
150
  type="email"
127
151
  value={formData.user}
128
152
  onChange={(e) => handleInputChange("user", e.target.value)}
129
- className="w-full p-2 border border-gray-30 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-50"
153
+ style={{
154
+ width: "100%",
155
+ padding: "0.5rem",
156
+ border: "1px solid #D1D5DB",
157
+ borderRadius: "0.5rem",
158
+ outline: "none",
159
+ }}
130
160
  placeholder="usuario@bdsol.com.ar"
131
161
  />
132
162
  </div>
133
163
 
134
164
  {/* Roles */}
135
- <div>
136
- <label className="block text-sm font-medium text-gray-70 mb-1">
165
+ <div style={{ marginBottom: "1rem" }}>
166
+ <label
167
+ style={{
168
+ display: "block",
169
+ fontSize: "0.875rem",
170
+ fontWeight: 500,
171
+ color: "#374151",
172
+ marginBottom: "0.25rem",
173
+ }}
174
+ >
137
175
  Roles (uno por línea)
138
176
  </label>
139
177
  <textarea
140
178
  value={rolesText}
141
179
  onChange={(e) => setRolesText(e.target.value)}
142
- className="w-full h-32 p-2 border border-gray-30 rounded-lg font-mono text-sm focus:outline-none focus:ring-2 focus:ring-blue-50"
180
+ style={{
181
+ width: "100%",
182
+ height: "8rem",
183
+ padding: "0.5rem",
184
+ border: "1px solid #D1D5DB",
185
+ borderRadius: "0.5rem",
186
+ fontFamily: "monospace",
187
+ fontSize: "0.875rem",
188
+ outline: "none",
189
+ }}
143
190
  placeholder={defaultDevRoles.join("&#10;")}
144
191
  />
145
- <p className="text-xs text-gray-50 mt-1">
192
+ <p
193
+ style={{
194
+ fontSize: "0.75rem",
195
+ color: "#9CA3AF",
196
+ marginTop: "0.25rem",
197
+ }}
198
+ >
146
199
  Roles definidos en src/config/roles.ts
147
200
  </p>
148
201
  </div>
149
202
 
150
203
  {/* Channel */}
151
- <div>
152
- <label className="block text-sm font-medium text-gray-70 mb-1">
204
+ <div style={{ marginBottom: "1rem" }}>
205
+ <label
206
+ style={{
207
+ display: "block",
208
+ fontSize: "0.875rem",
209
+ fontWeight: 500,
210
+ color: "#374151",
211
+ marginBottom: "0.25rem",
212
+ }}
213
+ >
153
214
  Channel
154
215
  </label>
155
216
  <input
156
217
  type="text"
157
218
  value={formData.channel}
158
219
  onChange={(e) => handleInputChange("channel", e.target.value)}
159
- className="w-full p-2 border border-gray-30 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-50"
220
+ style={{
221
+ width: "100%",
222
+ padding: "0.5rem",
223
+ border: "1px solid #D1D5DB",
224
+ borderRadius: "0.5rem",
225
+ outline: "none",
226
+ }}
160
227
  placeholder="mf-testing"
161
228
  />
162
229
  </div>
163
230
 
164
231
  {/* Session ID */}
165
- <div>
166
- <label className="block text-sm font-medium text-gray-70 mb-1">
232
+ <div style={{ marginBottom: "1rem" }}>
233
+ <label
234
+ style={{
235
+ display: "block",
236
+ fontSize: "0.875rem",
237
+ fontWeight: 500,
238
+ color: "#374151",
239
+ marginBottom: "0.25rem",
240
+ }}
241
+ >
167
242
  Session ID
168
243
  </label>
169
- <div className="flex gap-2">
244
+ <div style={{ display: "flex", gap: "0.5rem" }}>
170
245
  <input
171
246
  type="text"
172
247
  value={formData.sessionId}
173
248
  onChange={(e) =>
174
249
  handleInputChange("sessionId", e.target.value)
175
250
  }
176
- className="flex-1 p-2 border border-gray-30 rounded-lg font-mono text-sm focus:outline-none focus:ring-2 focus:ring-blue-50"
251
+ style={{
252
+ flex: 1,
253
+ padding: "0.5rem",
254
+ border: "1px solid #D1D5DB",
255
+ borderRadius: "0.5rem",
256
+ fontFamily: "monospace",
257
+ fontSize: "0.875rem",
258
+ outline: "none",
259
+ }}
177
260
  placeholder="uuid-session-id"
178
261
  />
179
262
  <DevButton
@@ -181,12 +264,19 @@ const TokenGenerator: React.FC<TokenGeneratorProps> = ({
181
264
  variant="primary"
182
265
  size="small"
183
266
  onClick={generateNewSessionId}
184
- className="px-3"
267
+ style={{ padding: "0.5rem 0.75rem" }}
185
268
  />
186
269
  </div>
187
270
  </div>
188
271
  </div>
189
- <div className="flex gap-3 flex-wrap mb-4">
272
+ <div
273
+ style={{
274
+ display: "flex",
275
+ gap: "0.75rem",
276
+ flexWrap: "wrap",
277
+ marginBottom: "1rem",
278
+ }}
279
+ >
190
280
  <DevButton
191
281
  label={loading ? "Generando..." : "🚀 Generar Token"}
192
282
  variant="primary"
@@ -209,11 +299,24 @@ const TokenGenerator: React.FC<TokenGeneratorProps> = ({
209
299
  </div>
210
300
  {/* Información del token actual */}
211
301
  {currentToken && (
212
- <div className="mt-4 p-4 bg-green-50 rounded-lg">
213
- <h3 className="font-semibold text-green-70 mb-2">
302
+ <div
303
+ style={{
304
+ marginTop: "1rem",
305
+ padding: "1rem",
306
+ backgroundColor: "#D1FAE5",
307
+ borderRadius: "0.5rem",
308
+ }}
309
+ >
310
+ <h3
311
+ style={{
312
+ fontWeight: 600,
313
+ color: "#047857",
314
+ marginBottom: "0.5rem",
315
+ }}
316
+ >
214
317
  ✅ Token cargado
215
318
  </h3>
216
- <p className="text-sm text-green-60">
319
+ <p style={{ fontSize: "0.875rem", color: "#059669" }}>
217
320
  Tienes un token activo en el almacenamiento local.
218
321
  </p>
219
322
  </div>
@@ -44,32 +44,62 @@ const TokenInput: React.FC<TokenInputProps> = ({
44
44
  };
45
45
 
46
46
  return (
47
- <div className="bg-white rounded-lg shadow-lg p-6 w-full max-w-2xl">
48
- <h2 className="text-2xl font-bold text-gray-80 mb-4">
47
+ <div
48
+ style={{
49
+ backgroundColor: "white",
50
+ borderRadius: "0.5rem",
51
+ boxShadow:
52
+ "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
53
+ padding: "1.5rem",
54
+ width: "100%",
55
+ maxWidth: "42rem",
56
+ }}
57
+ >
58
+ <h2
59
+ style={{
60
+ fontSize: "1.5rem",
61
+ fontWeight: "bold",
62
+ color: "#1F2937",
63
+ marginBottom: "1rem",
64
+ }}
65
+ >
49
66
  Modo Desarrollo - Cargar Token JWT
50
67
  </h2>
51
- <p className="text-gray-60 mb-6">
68
+ <p style={{ color: "#6B7280", marginBottom: "1.5rem" }}>
52
69
  Ingresa el token JWT decodificado (JSON) que normalmente recibiría desde
53
70
  el host:
54
71
  </p>
55
72
 
56
- <div className="mb-4">
73
+ <div style={{ marginBottom: "1rem" }}>
57
74
  <textarea
58
75
  value={token}
59
76
  onChange={handleTextareaChange}
60
77
  placeholder="Pegue aquí el token JWT en formato JSON"
61
- className={`w-full h-40 p-3 border rounded-lg font-mono text-sm ${
62
- !isValidJson ? "border-red-50" : "border-gray-30"
63
- } focus:outline-none focus:ring-2 focus:ring-blue-50`}
78
+ style={{
79
+ width: "100%",
80
+ height: "10rem",
81
+ padding: "0.75rem",
82
+ border: `1px solid ${!isValidJson ? "#F87171" : "#D1D5DB"}`,
83
+ borderRadius: "0.5rem",
84
+ fontFamily: "monospace",
85
+ fontSize: "0.875rem",
86
+ outline: "none",
87
+ }}
64
88
  />
65
89
  {!isValidJson && (
66
- <p className="text-red-50 text-sm mt-2">
90
+ <p
91
+ style={{
92
+ color: "#EF4444",
93
+ fontSize: "0.875rem",
94
+ marginTop: "0.5rem",
95
+ }}
96
+ >
67
97
  El JSON no es válido. Por favor verifica la sintaxis.
68
98
  </p>
69
99
  )}
70
100
  </div>
71
101
 
72
- <div className="flex gap-3 flex-wrap">
102
+ <div style={{ display: "flex", gap: "0.75rem", flexWrap: "wrap" }}>
73
103
  <DevButton
74
104
  label="Cargar Token"
75
105
  variant="primary"
@@ -1 +0,0 @@
1
- /c/ReposIntive/bdsol/bo/bo-remotes-helper