forlogic-core 2.0.3 → 2.0.5

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 (207) hide show
  1. package/.note/memory/features/crud-defaults-batteries-included.md +1 -1
  2. package/README.md +187 -917
  3. package/dist/components/ui/dialog-wizard.d.ts +82 -0
  4. package/dist/components/ui/input-group.d.ts +1 -1
  5. package/dist/components/ui/input.d.ts +5 -23
  6. package/dist/components/ui/resizable.d.ts +1 -1
  7. package/dist/components/ui/sidebar.d.ts +1 -1
  8. package/dist/components/ui/step-selector.d.ts +11 -9
  9. package/dist/components/ui/textarea.d.ts +1 -0
  10. package/dist/crud/components/CrudTable.d.ts +3 -1
  11. package/dist/crud/createCrudPage.d.ts +2 -0
  12. package/dist/crud/hooks/useColumnManager.d.ts +3 -1
  13. package/dist/exports/ui.d.ts +1 -0
  14. package/dist/index.css +1 -1
  15. package/dist/index.css.map +1 -1
  16. package/dist/index.esm.js +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/types/sidebar.d.ts +2 -1
  19. package/dist/types.d.ts +3 -0
  20. package/docs/AUDIT_PROMPT.md +74 -0
  21. package/docs/PROJECT_KNOWLEDGE_TEMPLATE.md +117 -0
  22. package/docs/PROMPT_TEMPLATE.md +77 -0
  23. package/docs/STARTER_TEMPLATE.md +114 -0
  24. package/docs/design-system/README.md +45 -0
  25. package/docs/design-system/buttons-actions.md +433 -0
  26. package/docs/design-system/charts-dashboards.md +547 -0
  27. package/docs/design-system/crud.md +243 -0
  28. package/docs/design-system/data-display.md +360 -0
  29. package/docs/design-system/dialogs.md +588 -0
  30. package/docs/design-system/domain.md +661 -0
  31. package/docs/design-system/examples.md +275 -0
  32. package/docs/design-system/foundation.md +82 -0
  33. package/docs/design-system/infra-utils.md +36 -0
  34. package/docs/design-system/inputs.md +556 -0
  35. package/docs/design-system/layout.md +351 -0
  36. package/docs/design-system/navigation.md +604 -0
  37. package/docs/design-system/notifications-feedback.md +139 -0
  38. package/docs/design-system/platform.md +95 -0
  39. package/docs/design-system/selectors.md +424 -0
  40. package/docs/design-system/tables-grids.md +114 -0
  41. package/package.json +2 -2
  42. package/dist/assets/AccordionDoc-CGNlubG3.js +0 -31
  43. package/dist/assets/ActionButtonDoc-CYtkXR0k.js +0 -47
  44. package/dist/assets/ActionPlanDoc-BSuPRftQ.js +0 -65
  45. package/dist/assets/AlertDoc-Cpvxneqg.js +0 -37
  46. package/dist/assets/AliasUrlDoc-DIpUWf4Y.js +0 -189
  47. package/dist/assets/AppHeaderDoc-DNQErj_t.js +0 -74
  48. package/dist/assets/AppSidebarDoc-DkeQarDu.js +0 -221
  49. package/dist/assets/ApprovalFlowDoc-8YgXbhKJ.js +0 -31
  50. package/dist/assets/AuditLogDoc-BBvNcHIo.js +0 -67
  51. package/dist/assets/AuditTrailDoc-DgFHO-uo.js +0 -17
  52. package/dist/assets/AuthDoc-WIA_Aetl.js +0 -200
  53. package/dist/assets/AvatarDoc-B6go1C1T.js +0 -11
  54. package/dist/assets/BadgeDoc-BONhfqB_.js +0 -36
  55. package/dist/assets/BaseFormDoc-CuyUArcj.js +0 -169
  56. package/dist/assets/BodyContentDoc-CterHC1E.js +0 -83
  57. package/dist/assets/BreadcrumbDoc-Dwn9nLeO.js +0 -75
  58. package/dist/assets/ButtonDoc-BOjRseZT.js +0 -41
  59. package/dist/assets/ButtonGroupDoc-8IS6PPh4.js +0 -7
  60. package/dist/assets/CalendarDoc-CMwIEqgT.js +0 -81
  61. package/dist/assets/CardDoc-BZz1CVg2.js +0 -49
  62. package/dist/assets/ChartDoc-B5vZVtqD.js +0 -76
  63. package/dist/assets/CheckboxDoc-lAbYO9I5.js +0 -55
  64. package/dist/assets/ColorPickerDoc-Dpsprp4N.js +0 -10
  65. package/dist/assets/ColorsFoundationDoc-CCHeSL3p.js +0 -13
  66. package/dist/assets/ComboTreeDoc-D4dTkIt-.js +0 -46
  67. package/dist/assets/ComboboxDoc-CqqZPvZq.js +0 -134
  68. package/dist/assets/ComponentDocTemplate-CQbBhfvZ.js +0 -1
  69. package/dist/assets/ContextMenuDoc-D3jC-MVA.js +0 -182
  70. package/dist/assets/ContextsDoc-XFH0-JdS.js +0 -211
  71. package/dist/assets/CreateCrudPageDoc-CpuiWI-g.js +0 -106
  72. package/dist/assets/CrudActionBarDoc-wuBGXD9Y.js +0 -112
  73. package/dist/assets/CrudGridDoc-BYWqSXBH.js +0 -85
  74. package/dist/assets/CrudOverviewDoc-B_bk2a2t.js +0 -14
  75. package/dist/assets/CrudPrimitivesDoc-CxaTB94A.js +0 -164
  76. package/dist/assets/CrudTableDoc-Dga1VgCu.js +0 -113
  77. package/dist/assets/CustomFormFieldsDoc-C1hwwSl3.js +0 -33
  78. package/dist/assets/DashboardFormDoc-BUDCmrMl.js +0 -49
  79. package/dist/assets/DashboardGeneralViewDoc-Cyg1SIiG.js +0 -71
  80. package/dist/assets/DashboardGridDoc-BavePiRF.js +0 -49
  81. package/dist/assets/DashboardListDoc-CLyMA6UK.js +0 -37
  82. package/dist/assets/DashboardOverviewDoc-DRVvNIF1.js +0 -35
  83. package/dist/assets/DashboardPanelRendererDoc--mfwb8Nc.js +0 -60
  84. package/dist/assets/DashboardPanelsBasicDoc-BQ2V_52D.js +0 -62
  85. package/dist/assets/DashboardPanelsCartesianDoc-sy-hcVQY.js +0 -75
  86. package/dist/assets/DashboardPanelsSpecialDoc-DsIUCRRP.js +0 -83
  87. package/dist/assets/DashboardViewDoc-CtlCNlEF.js +0 -45
  88. package/dist/assets/DataListDoc-DUy88lCQ.js +0 -13
  89. package/dist/assets/DesignSystemHome-DHl9YtbH.js +0 -1
  90. package/dist/assets/DialogDoc-CMQqnTV-.js +0 -981
  91. package/dist/assets/DropdownMenuDoc-S7X9csGt.js +0 -175
  92. package/dist/assets/ElectronicSignatureDialogDoc-BfithaL_.js +0 -57
  93. package/dist/assets/EmptyStateDoc-CHGCiGIk.js +0 -35
  94. package/dist/assets/EnvironmentsDoc-DZHJZ2nm.js +0 -96
  95. package/dist/assets/ErrorBoundaryDoc-DoaAg68p.js +0 -111
  96. package/dist/assets/ExampleActionPlanPage-C0fIMZCD.js +0 -1
  97. package/dist/assets/ExampleAppDoc-DzIU81Fn.js +0 -1
  98. package/dist/assets/ExampleCard-DuLrb3t-.js +0 -1
  99. package/dist/assets/ExampleCrudReportsPage-M0pz6tdM.js +0 -1
  100. package/dist/assets/ExampleDashboardPage-CRG5r3Vw.js +0 -1
  101. package/dist/assets/ExampleIdeasPage-I84ZMLY4.js +0 -1
  102. package/dist/assets/ExampleImportWizardPage-h4YqrrSe.js +0 -1
  103. package/dist/assets/ExampleSettingsPage-CwdWqoaP.js +0 -1
  104. package/dist/assets/FileUploadDoc-9-UujFNX.js +0 -34
  105. package/dist/assets/FilterBar-DDTqqUfZ.js +0 -1
  106. package/dist/assets/FormDoc-CVES6n3d.js +0 -81
  107. package/dist/assets/FoundationOverview-DT0u11Gz.js +0 -1
  108. package/dist/assets/GridDoc-CbHFSILF.js +0 -28
  109. package/dist/assets/HooksDoc-Ctxdk6Wq.js +0 -665
  110. package/dist/assets/HoverCardDoc-8Wkaafdj.js +0 -31
  111. package/dist/assets/I18nDoc-D3Q2m7ik.js +0 -167
  112. package/dist/assets/IconPickerDoc-DZ26Gdpg.js +0 -10
  113. package/dist/assets/IconsFoundationDoc-xOxtC7CW.js +0 -33
  114. package/dist/assets/InputDoc-BhztAiuJ.js +0 -211
  115. package/dist/assets/LabelDoc-A4hmTRRV.js +0 -42
  116. package/dist/assets/LeadershipDoc-CqOSfWsP.js +0 -452
  117. package/dist/assets/MediaDoc-C78gvC8p.js +0 -459
  118. package/dist/assets/MenubarDoc-DCnmd2tO.js +0 -165
  119. package/dist/assets/ModuleAccessDoc-CmD5nHDp.js +0 -153
  120. package/dist/assets/ModulesDialogDoc-DVit1CA-.js +0 -46
  121. package/dist/assets/MultiselectPermissionsDoc-tlJMs04L.js +0 -34
  122. package/dist/assets/NavigationMenuDoc-q1fbc89j.js +0 -116
  123. package/dist/assets/OnboardingDialogDoc-3A3eBYrq.js +0 -55
  124. package/dist/assets/PaginationDoc-B8-bMz5J.js +0 -27
  125. package/dist/assets/PaginationDoc-BkGdxHL3.js +0 -98
  126. package/dist/assets/PlacesDoc-CKPO6ATs.js +0 -226
  127. package/dist/assets/PopoverDoc-CJPU4Ags.js +0 -64
  128. package/dist/assets/ProgressDoc-CpjbTL4o.js +0 -29
  129. package/dist/assets/QualiexUserFieldDoc-DDwumlRw.js +0 -149
  130. package/dist/assets/RadioGroupDoc-D6tSZz8G.js +0 -57
  131. package/dist/assets/RadiusDoc-B4xSnajw.js +0 -7
  132. package/dist/assets/ReportRequestListDoc-C0LIaU8P.js +0 -15
  133. package/dist/assets/RequiredFieldsCounterDoc-COesoSdx.js +0 -58
  134. package/dist/assets/ResizableDoc-CW0-XQuB.js +0 -104
  135. package/dist/assets/RichTextEditorDoc-C8c_XA9P.js +0 -24
  136. package/dist/assets/ScrollAreaDoc-BxtoAPaZ.js +0 -28
  137. package/dist/assets/SecurityDoc-wOVqpg2F.js +0 -204
  138. package/dist/assets/SelectDoc-C75gtY9D.js +0 -80
  139. package/dist/assets/SeparatorDoc-BjQBPB1P.js +0 -4
  140. package/dist/assets/ServicesDoc-CXTctwBl.js +0 -308
  141. package/dist/assets/ShadowsDoc-C6Lw8_x2.js +0 -9
  142. package/dist/assets/SignDoc-Bh5ZUg5x.js +0 -66
  143. package/dist/assets/SkeletonDoc-rTLGK5VE.js +0 -54
  144. package/dist/assets/SliderDoc-JMAMDub7.js +0 -41
  145. package/dist/assets/SpacingDoc-RljOrpwA.js +0 -12
  146. package/dist/assets/SplitButtonDoc-CvShUW3w.js +0 -53
  147. package/dist/assets/StepSelectorDoc-C-nAap9H.js +0 -41
  148. package/dist/assets/SwitchDoc-DLnqmkPr.js +0 -56
  149. package/dist/assets/TableDoc-B8EpWLVg.js +0 -128
  150. package/dist/assets/TabsDoc-DIBtl_uC.js +0 -42
  151. package/dist/assets/TeamSelectorDoc-B7OnCbL7.js +0 -10
  152. package/dist/assets/TermsOfUseDoc-Bb-pw08s.js +0 -16
  153. package/dist/assets/TextareaDoc-DGnqMqEC.js +0 -46
  154. package/dist/assets/ToastDoc-DjYyc7ae.js +0 -157
  155. package/dist/assets/ToggleDoc-C9ZOVjkY.js +0 -51
  156. package/dist/assets/TooltipDoc-BEx4l9-i.js +0 -58
  157. package/dist/assets/TruncatedCellDoc-BbV1bRSY.js +0 -12
  158. package/dist/assets/TypographyFoundationDoc-CUDYjRo9.js +0 -7
  159. package/dist/assets/UpdatesNotificationDoc-7nyjzLMJ.js +0 -29
  160. package/dist/assets/UsersGroupsSelectorDoc-C0KlTAL5.js +0 -18
  161. package/dist/assets/UtilitiesDoc-DGxaHVV1.js +0 -145
  162. package/dist/assets/ViewerDialogsDoc-CnTPTEz0.js +0 -1
  163. package/dist/assets/blocks-B6LrJeAM.js +0 -1
  164. package/dist/assets/building-DeVappnD.js +0 -1
  165. package/dist/assets/calendar-days-BQ0na5kM.js +0 -1
  166. package/dist/assets/check-check-C_-PJCJa.js +0 -1
  167. package/dist/assets/circle-plus-CpIcep-O.js +0 -1
  168. package/dist/assets/circle-x-jPpBPew0.js +0 -1
  169. package/dist/assets/clipboard-list-CXNPdciZ.js +0 -1
  170. package/dist/assets/cloud-upload-BEjzumjl.js +0 -1
  171. package/dist/assets/crown-CqNsQIsm.js +0 -1
  172. package/dist/assets/date-picker-BW3eGOe_.js +0 -1
  173. package/dist/assets/disabled-menu-item-C2YaMvSt.js +0 -1
  174. package/dist/assets/drawer-D5rflIcD.js +0 -3
  175. package/dist/assets/file-braces-DFb5X9so.js +0 -1
  176. package/dist/assets/file-pen-line-CyUGKkEN.js +0 -1
  177. package/dist/assets/git-branch-BcXv9mpp.js +0 -1
  178. package/dist/assets/globe-CpMIWAcv.js +0 -1
  179. package/dist/assets/hash-cQWdKjya.js +0 -1
  180. package/dist/assets/hourglass-BahQ3eDv.js +0 -1
  181. package/dist/assets/hover-card-R66N85sZ.js +0 -1
  182. package/dist/assets/iframe-dialog-V0mW5aBb.js +0 -1
  183. package/dist/assets/index-DkiftrvI.js +0 -352
  184. package/dist/assets/index-nmBjO9Th.css +0 -1
  185. package/dist/assets/life-buoy-ByXiPddz.js +0 -1
  186. package/dist/assets/loading-state-Cb5_t5uE.js +0 -1
  187. package/dist/assets/lucide-react-Cp3Yw3Zm.js +0 -1
  188. package/dist/assets/package-B3-pVvPM.js +0 -1
  189. package/dist/assets/pen-Bi_lmmKT.js +0 -1
  190. package/dist/assets/pin-DVsSl8QA.js +0 -1
  191. package/dist/assets/printer-BnJ8B6m-.js +0 -1
  192. package/dist/assets/radio-group-BHAaNGsm.js +0 -1
  193. package/dist/assets/server-CtzFTfKR.js +0 -1
  194. package/dist/assets/share-2-Dv8Do445.js +0 -1
  195. package/dist/assets/shield-check-CFXjOV_w.js +0 -1
  196. package/dist/assets/shield-x-DJTRfVux.js +0 -1
  197. package/dist/assets/slider-v9tXBSnB.js +0 -1
  198. package/dist/assets/smartphone-BSNR60L7.js +0 -1
  199. package/dist/assets/step-selector-ATTh_9Wa.js +0 -1
  200. package/dist/assets/text-align-start-qE-MbYYw.js +0 -1
  201. package/dist/assets/thumbs-up-D_XIW_uX.js +0 -1
  202. package/dist/assets/trash-DTWQwpwA.js +0 -1
  203. package/dist/assets/trending-up-jip5-leJ.js +0 -1
  204. package/dist/assets/useMockCrud-CN4vjyOZ.js +0 -1
  205. package/dist/assets/user-check-BlH3EDWK.js +0 -1
  206. package/dist/assets/user-plus-BqwXwD-c.js +0 -1
  207. package/dist/index.html +0 -33
@@ -1,665 +0,0 @@
1
- import{r as t,j as e,em as W,x as N,B as C,dw as R,a as F,d as E,E as J,G as Z,H as X,I as Y,X as _,ew as T,S as B,ak as ee,al as ae,bk as se,an as te,ao as re,bs as I,o as L,ac as ie,J as S,W as U,K as A}from"./index-DkiftrvI.js";import{C as oe}from"./ComponentDocTemplate-CQbBhfvZ.js";import{R as ne,a as le}from"./radio-group-BHAaNGsm.js";import"./ExampleCard-DuLrb3t-.js";function de(p){const{steps:c,initialStep:g=0,initialData:b={},onComplete:v,onCancel:z}=p,[o,u]=t.useState(g),[h,a]=t.useState(b),[d,j]=t.useState(!1),[f,w]=t.useState(!1),l=c.length,y=o===0,s=o===l-1,r=c[o],x=l>1?(o+1)/l*100:100,m=t.useCallback(()=>r?.canProceed?r.canProceed():!0,[r]),M=t.useMemo(()=>m(),[m,h]),D=t.useMemo(()=>!(y||r?.disableBack),[y,r]),Q=t.useCallback(i=>{a(k=>({...k,...i}))},[]),q=t.useCallback((i,k)=>{a($=>({...$,[i]:k}))},[]),H=t.useCallback(()=>{u(g),a(b),j(!1),w(!1),z?.()},[g,b,z]),P=t.useCallback(async()=>{if(!(!m()||f)){w(!0);try{await v?.(h)}finally{w(!1)}}},[m,f,h,v]),G=t.useCallback(async()=>{!m()||d||(s?await P():u(i=>Math.min(i+1,l-1)))},[m,d,s,l,P]),V=t.useCallback(()=>{!D||d||u(i=>Math.max(i-1,0))},[D,d]),O=t.useCallback(i=>{i<0||i>=l||d||(i<=o||i===o+1)&&u(i)},[o,l,d]),K=t.useCallback(i=>{j(i)},[]);return{currentStep:o,currentStepConfig:r,data:h,isFirstStep:y,isLastStep:s,isLoading:d,isCompleting:f,next:G,back:V,goTo:O,canProceed:M,canGoBack:D,setData:Q,updateField:q,reset:H,complete:P,setLoading:K,progress:x,stepIndex:o,totalSteps:l}}const ce=`import {
2
- useDebounce,
3
- useActiveModules,
4
- usePermissionQuery,
5
- useI18nFormatters,
6
- usePageTitle,
7
- useColumnResize,
8
- useRowResize,
9
- useSidebarResize,
10
- useQualiexUsers,
11
- useWizard
12
- } from 'forlogic-core/modular';`;function ue(){const[p,c]=t.useState(!1),[g,b]=t.useState(!1),[v,z]=t.useState(null),o={name:"",email:"",plan:"basic",notifications:!0,newsletter:!1},u=t.useRef(o),h=t.useMemo(()=>[{id:"personal",label:"Dados Pessoais",canProceed:()=>{const s=u.current;return s.name.length>=2&&s.email.includes("@")}},{id:"plan",label:"Escolha do Plano",canProceed:()=>!!u.current.plan},{id:"preferences",label:"Preferências"},{id:"review",label:"Confirmação"}],[]),a=de({steps:h,initialData:o,onComplete:async s=>{await new Promise(r=>setTimeout(r,1e3)),z(s),b(!0),c(!1)},onCancel:()=>{c(!1)}});u.current=a.data;const d=()=>{a.reset(),b(!1),z(null),c(!0)},j=h.map(s=>s.label),f={basic:{name:"Básico",price:"Grátis",features:["5 projetos","Suporte por email"]},pro:{name:"Pro",price:"R$ 49/mês",features:["Projetos ilimitados","Suporte prioritário","API access"]},enterprise:{name:"Enterprise",price:"Personalizado",features:["Tudo do Pro","SLA dedicado","Consultoria"]}},w=[e.jsx(T,{className:"h-5 w-5"}),e.jsx(W,{className:"h-5 w-5"}),e.jsx(B,{className:"h-5 w-5"}),e.jsx(R,{className:"h-5 w-5"})],l=()=>{switch(a.currentStep){case 0:return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("div",{className:"p-3 rounded-full bg-primary/10 text-primary",children:e.jsx(T,{className:"h-6 w-6"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold",children:"Seus dados"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Preencha suas informações básicas"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(S,{htmlFor:"name",children:"Nome *"}),e.jsx(A,{id:"name",value:a.data.name,onChange:s=>a.updateField("name",s.target.value),placeholder:"Seu nome completo"}),a.data.name.length>0&&a.data.name.length<2&&e.jsx("p",{className:"text-xs text-destructive",children:"Nome deve ter pelo menos 2 caracteres"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(S,{htmlFor:"email",children:"Email *"}),e.jsx(A,{id:"email",type:"email",value:a.data.email,onChange:s=>a.updateField("email",s.target.value),placeholder:"seu@email.com"}),a.data.email.length>0&&!a.data.email.includes("@")&&e.jsx("p",{className:"text-xs text-destructive",children:"Email inválido"})]})]});case 1:return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("div",{className:"p-3 rounded-full bg-primary/10 text-primary",children:e.jsx(W,{className:"h-6 w-6"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold",children:"Escolha seu plano"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Selecione o plano que melhor atende suas necessidades"})]})]}),e.jsx(ne,{value:a.data.plan,onValueChange:s=>a.updateField("plan",s),className:"space-y-3",children:Object.entries(f).map(([s,r])=>e.jsxs("label",{className:L("flex items-start gap-4 p-4 rounded-lg border-2 cursor-pointer transition-all",a.data.plan===s?"border-primary bg-primary/5":"border-border hover:border-muted-foreground/50"),children:[e.jsx(le,{value:s,className:"mt-1"}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"font-medium",children:r.name}),e.jsx(C,{variant:s==="pro"?"default":"outline",children:r.price})]}),e.jsx("ul",{className:"mt-2 space-y-1",children:r.features.map((x,m)=>e.jsxs("li",{className:"text-sm text-muted-foreground flex items-center gap-2",children:[e.jsx(I,{className:"h-3 w-3 text-green-500"})," ",x]},m))})]})]},s))})]});case 2:return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("div",{className:"p-3 rounded-full bg-primary/10 text-primary",children:e.jsx(B,{className:"h-6 w-6"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold",children:"Preferências"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Configure suas preferências de comunicação"})]})]}),e.jsx(F,{children:e.jsxs(E,{className:"p-4 space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(S,{htmlFor:"notifications",className:"font-medium",children:"Notificações"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Receber notificações sobre atualizações"})]}),e.jsx(U,{id:"notifications",checked:a.data.notifications,onCheckedChange:s=>a.updateField("notifications",s)})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(S,{htmlFor:"newsletter",className:"font-medium",children:"Newsletter"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Receber dicas e novidades por email"})]}),e.jsx(U,{id:"newsletter",checked:a.data.newsletter,onCheckedChange:s=>a.updateField("newsletter",s)})]})]})})]});case 3:return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("div",{className:"p-3 rounded-full bg-green-100 text-green-600",children:e.jsx(R,{className:"h-6 w-6"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold",children:"Confirme seus dados"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Revise as informações antes de finalizar"})]})]}),e.jsx(F,{children:e.jsxs(E,{className:"p-4 space-y-3",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nome"}),e.jsx("p",{className:"font-medium",children:a.data.name})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Email"}),e.jsx("p",{className:"font-medium",children:a.data.email})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Plano"}),e.jsx(C,{children:f[a.data.plan].name})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Preço"}),e.jsx("p",{className:"font-medium",children:f[a.data.plan].price})]})]}),e.jsxs("div",{className:"pt-3 border-t",children:[e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"Preferências"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(C,{variant:a.data.notifications?"default":"outline",children:["Notificações: ",a.data.notifications?"Sim":"Não"]}),e.jsxs(C,{variant:a.data.newsletter?"default":"outline",children:["Newsletter: ",a.data.newsletter?"Sim":"Não"]})]})]})]})})]});default:return null}},y=()=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs(ee,{children:[e.jsx(ae,{asChild:!0,children:e.jsxs(N,{variant:"ghost",size:"sm",className:"h-auto py-1 px-2 text-sm text-muted-foreground hover:text-foreground",children:["Etapa ",a.currentStep+1,"/",a.totalSteps,e.jsx(se,{className:"h-3 w-3 ml-1"})]})}),e.jsx(te,{align:"start",children:j.map((s,r)=>{const x=r>a.currentStep;return e.jsxs(re,{onClick:()=>!x&&a.goTo(r),disabled:x,className:L("cursor-pointer",r===a.currentStep&&"bg-muted font-medium",x&&"opacity-50 cursor-not-allowed"),children:[e.jsxs("span",{className:"mr-2 text-muted-foreground",children:[r+1,"."]}),s,r===a.currentStep&&e.jsx(I,{className:"h-4 w-4 ml-auto"})]},r)})})]}),e.jsx(ie,{value:a.progress,className:"w-32 h-2"})]});return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx(N,{onClick:d,children:"Abrir Wizard de Cadastro"}),g&&v&&e.jsxs(C,{variant:"outline",className:"text-green-600 border-green-600",children:[e.jsx(R,{className:"h-3 w-3 mr-1"}),"Cadastro concluído!"]})]}),v&&e.jsx(F,{className:"bg-muted/50",children:e.jsxs(E,{className:"p-4",children:[e.jsx("p",{className:"text-sm font-medium mb-2",children:"Dados enviados:"}),e.jsx("pre",{className:"text-xs bg-background p-2 rounded overflow-x-auto",children:JSON.stringify(v,null,2)})]})}),e.jsx(J,{open:p,onOpenChange:s=>!s&&a.reset(),children:e.jsxs(Z,{size:"md",children:[e.jsxs(X,{showSeparator:!0,children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsxs(Y,{className:"flex items-center gap-2",children:[w[a.currentStep],a.currentStepConfig.label]})}),e.jsx(y,{})]}),e.jsx("div",{className:"flex-1 min-h-0 overflow-auto py-4 px-1 -mx-1",children:l()}),e.jsxs(_,{children:[a.canGoBack&&e.jsx(N,{variant:"outline",onClick:a.back,disabled:a.isCompleting,children:"Voltar"}),e.jsx(N,{onClick:a.next,disabled:!a.canProceed||a.isCompleting,children:a.isCompleting?"Finalizando...":a.isLastStep?"Finalizar Cadastro":"Próximo"})]})]})})]})}const me=`import { useDebounce } from 'forlogic-core/modular';
13
-
14
- function SearchInput() {
15
- const [searchTerm, setSearchTerm] = useState('');
16
- const [debouncedSearch, cancelDebounce] = useDebounce(searchTerm, 500);
17
-
18
- // API é chamada apenas quando usuário para de digitar por 500ms
19
- const { data } = useQuery({
20
- queryKey: ['search', debouncedSearch],
21
- queryFn: () => api.search(debouncedSearch),
22
- enabled: debouncedSearch.length > 0
23
- });
24
-
25
- return (
26
- <Input
27
- value={searchTerm}
28
- onChange={(e) => setSearchTerm(e.target.value)}
29
- placeholder="Buscar..."
30
- />
31
- );
32
- }`,pe=`import { useActiveModules } from 'forlogic-core/modular';
33
-
34
- function App() {
35
- const { data: modules, isLoading } = useActiveModules();
36
-
37
- const hasTrainingModule = modules?.some(m => m.name === 'training');
38
-
39
- if (isLoading) return <Spinner />;
40
-
41
- return (
42
- <nav>
43
- {hasTrainingModule && <Link to="/training">Treinamentos</Link>}
44
- </nav>
45
- );
46
- }`,ge=`import { usePermissionQuery } from 'forlogic-core/modular';
47
- import { useAuth } from 'forlogic-core';
48
-
49
- function ProtectedPage() {
50
- const { isAuthenticated } = useAuth();
51
-
52
- const { data: hasAccess, isLoading } = usePermissionQuery({
53
- key: 'can-manage-users',
54
- enabled: isAuthenticated,
55
- checkFn: async () => {
56
- const response = await fetch('/api/permissions/manage-users');
57
- return response.ok;
58
- },
59
- staleTime: 5 * 60 * 1000 // Cache por 5 minutos
60
- });
61
-
62
- if (isLoading) return <div>Verificando permissões...</div>;
63
- if (!hasAccess) return <div>Acesso negado</div>;
64
-
65
- return <div>Conteúdo protegido</div>;
66
- }`,he=`import { useI18nFormatters } from 'forlogic-core/modular';
67
-
68
- function DateDisplay({ date }: { date: string }) {
69
- const { formatDatetime, formatDate, locale, timezone } = useI18nFormatters();
70
-
71
- return (
72
- <div>
73
- <p>Data: {formatDate(date)}</p>
74
- <p>Data e hora: {formatDatetime(date)}</p>
75
- <p>Locale: {locale}, Timezone: {timezone}</p>
76
- </div>
77
- );
78
- }`,fe=`import { usePageTitle } from 'forlogic-core/modular';
79
-
80
- function PageHeader() {
81
- const title = usePageTitle();
82
-
83
- return <h1>{title}</h1>;
84
- // Se pathname for '/employees', retorna 'Funcionários'
85
- // Se pathname for '/m', retorna 'Gestão'
86
- // Se não encontrar, retorna 'Página'
87
- }`,xe=`import { useColumnResize } from 'forlogic-core/modular';
88
-
89
- function ResizableTable() {
90
- const columns = [
91
- { key: 'name', minWidth: 100, maxWidth: 300, defaultWidth: 150 },
92
- { key: 'email', minWidth: 150, maxWidth: 400, defaultWidth: 200 },
93
- { key: 'status', minWidth: 80, maxWidth: 150, defaultWidth: 100 },
94
- ];
95
-
96
- const {
97
- columnWidths,
98
- isDragging,
99
- handleMouseDown,
100
- resetWidths
101
- } = useColumnResize({
102
- columns,
103
- storageKey: 'my-table-columns',
104
- enabled: true
105
- });
106
-
107
- return (
108
- <table>
109
- <thead>
110
- <tr>
111
- {columns.map((col) => (
112
- <th
113
- key={col.key}
114
- style={{ width: columnWidths[col.key] }}
115
- >
116
- {col.key}
117
- <div
118
- onMouseDown={() => handleMouseDown(col.key)}
119
- className="resize-handle"
120
- />
121
- </th>
122
- ))}
123
- </tr>
124
- </thead>
125
- </table>
126
- );
127
- }`,be=`import { useRowResize } from 'forlogic-core/modular';
128
-
129
- function ResizableRows() {
130
- const rowIds = ['row-1', 'row-2', 'row-3'];
131
-
132
- const {
133
- getRowHeight,
134
- isDragging,
135
- handleMouseDown
136
- } = useRowResize({
137
- rowIds,
138
- minHeight: 40,
139
- maxHeight: 200,
140
- defaultHeight: 60,
141
- storageKey: 'my-rows-height'
142
- });
143
-
144
- return (
145
- <div>
146
- {rowIds.map((id) => (
147
- <div
148
- key={id}
149
- style={{ height: getRowHeight(id) }}
150
- className="border-b"
151
- >
152
- Conteúdo da linha
153
- <div onMouseDown={() => handleMouseDown(id)} className="resize-handle" />
154
- </div>
155
- ))}
156
- </div>
157
- );
158
- }`,ve=`import { useSidebarResize } from 'forlogic-core/modular';
159
-
160
- function ResizableSidebar() {
161
- const {
162
- width,
163
- isDragging,
164
- handleMouseDown
165
- } = useSidebarResize({
166
- direction: 'right',
167
- minWidth: 224,
168
- maxWidth: 384,
169
- defaultWidth: 240,
170
- storageKey: 'sidebar-width',
171
- isOpen: true
172
- });
173
-
174
- return (
175
- <aside style={{ width }} className="sidebar-container">
176
- <nav>...</nav>
177
- <div
178
- onMouseDown={handleMouseDown}
179
- className="resize-handle absolute right-0 top-0 h-full w-1 cursor-ew-resize"
180
- />
181
- </aside>
182
- );
183
- }`,ze=`import { useQualiexUsers } from 'forlogic-core/modular';
184
-
185
- // ✅ Uso padrão - Busca automática ao montar
186
- function UserList() {
187
- const { data: users, isLoading, error } = useQualiexUsers();
188
-
189
- if (isLoading) return <Spinner />;
190
- if (error) return <div>Erro ao carregar usuários</div>;
191
-
192
- return (
193
- <ul>
194
- {users?.map(user => (
195
- <li key={user.id || user.userId}>
196
- {user.displayName || user.userName} - {user.userEmail}
197
- </li>
198
- ))}
199
- </ul>
200
- );
201
- }
202
-
203
- // ✅ Busca condicional - Apenas quando modal está aberto
204
- function UserSelectModal({ isOpen }: { isOpen: boolean }) {
205
- const { data: users, isLoading } = useQualiexUsers({
206
- enabled: isOpen // Só busca quando modal abre
207
- });
208
-
209
- return (
210
- <Modal open={isOpen}>
211
- {isLoading ? <Spinner /> : (
212
- <select>
213
- {users?.map(user => (
214
- <option key={user.id} value={user.id}>
215
- {user.displayName}
216
- </option>
217
- ))}
218
- </select>
219
- )}
220
- </Modal>
221
- );
222
- }
223
-
224
- // ✅ Lazy loading com refetch manual
225
- function LazyUserLoader() {
226
- const { data: users, refetch, isFetching } = useQualiexUsers({
227
- enabled: false // Não busca automaticamente
228
- });
229
-
230
- const handleLoadUsers = async () => {
231
- await refetch(); // Busca quando usuário clica
232
- };
233
-
234
- return (
235
- <div>
236
- <Button onClick={handleLoadUsers} disabled={isFetching}>
237
- {isFetching ? 'Carregando...' : 'Carregar Usuários'}
238
- </Button>
239
- {users && <UserList users={users} />}
240
- </div>
241
- );
242
- }
243
-
244
- // Retorno do hook (UseQueryResult<QualiexUser[]>):
245
- // - data: QualiexUser[] | undefined
246
- // - isLoading: boolean (carregando pela primeira vez)
247
- // - isFetching: boolean (qualquer requisição em andamento)
248
- // - error: Error | null
249
- // - refetch: () => Promise<...> (reexecutar query)
250
- // - isSuccess: boolean
251
- // - isError: boolean`,we=`import { useWizard, WizardStep } from 'forlogic-core';
252
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, Button, Input, Progress } from 'forlogic-core';
253
-
254
- interface PlanData {
255
- name: string;
256
- type: 'basic' | 'premium';
257
- features: string[];
258
- }
259
-
260
- function CreatePlanWizard({ open, onClose }: { open: boolean; onClose: () => void }) {
261
- const steps: WizardStep[] = [
262
- {
263
- id: 'info',
264
- label: 'Informações',
265
- canProceed: () => wizard.data.name?.length > 0
266
- },
267
- {
268
- id: 'type',
269
- label: 'Tipo do Plano',
270
- canProceed: () => !!wizard.data.type
271
- },
272
- {
273
- id: 'features',
274
- label: 'Funcionalidades',
275
- canProceed: () => wizard.data.features?.length > 0
276
- },
277
- { id: 'review', label: 'Revisão' },
278
- ];
279
-
280
- const wizard = useWizard<PlanData>({
281
- steps,
282
- initialData: { name: '', type: 'basic', features: [] },
283
- onComplete: async (data) => {
284
- await api.createPlan(data);
285
- onClose();
286
- },
287
- onCancel: onClose,
288
- });
289
-
290
- const renderStep = () => {
291
- switch (wizard.currentStep) {
292
- case 0:
293
- return (
294
- <Input
295
- value={wizard.data.name}
296
- onChange={(e) => wizard.updateField('name', e.target.value)}
297
- placeholder="Nome do plano"
298
- />
299
- );
300
- case 1:
301
- return (
302
- <RadioGroup
303
- value={wizard.data.type}
304
- onValueChange={(v) => wizard.updateField('type', v as 'basic' | 'premium')}
305
- >
306
- <RadioGroupItem value="basic" label="Básico" />
307
- <RadioGroupItem value="premium" label="Premium" />
308
- </RadioGroup>
309
- );
310
- case 2:
311
- return <FeatureSelector data={wizard.data} setData={wizard.setData} />;
312
- case 3:
313
- return <ReviewStep data={wizard.data} />;
314
- default:
315
- return null;
316
- }
317
- };
318
-
319
- return (
320
- <Dialog open={open} onOpenChange={() => wizard.reset()}>
321
- <DialogContent size="md">
322
- <DialogHeader>
323
- <DialogTitle>{wizard.currentStepConfig.label}</DialogTitle>
324
- <Progress value={wizard.progress} className="h-1" />
325
- </DialogHeader>
326
-
327
- <div className="py-4">{renderStep()}</div>
328
-
329
- <DialogFooter>
330
- {wizard.canGoBack && (
331
- <Button variant="outline" onClick={wizard.back}>
332
- Voltar
333
- </Button>
334
- )}
335
- <Button
336
- onClick={wizard.next}
337
- disabled={!wizard.canProceed || wizard.isCompleting}
338
- >
339
- {wizard.isLastStep ? 'Concluir' : 'Próximo'}
340
- </Button>
341
- </DialogFooter>
342
- </DialogContent>
343
- </Dialog>
344
- );
345
- }`,ye=`import { useWizard, WizardStep } from 'forlogic-core';
346
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, Button, Input, Alert } from 'forlogic-core';
347
- import { useState } from 'react';
348
-
349
- interface UserData {
350
- email: string;
351
- username: string;
352
- password: string;
353
- }
354
-
355
- function RegisterWizard({ open, onClose }: { open: boolean; onClose: () => void }) {
356
- const [emailError, setEmailError] = useState<string | null>(null);
357
- const [usernameError, setUsernameError] = useState<string | null>(null);
358
-
359
- // Validação assíncrona de email
360
- const validateEmail = async (email: string): Promise<boolean> => {
361
- wizard.setLoading(true);
362
- setEmailError(null);
363
-
364
- try {
365
- const response = await fetch(\`/api/check-email?email=\${encodeURIComponent(email)}\`);
366
- const { available } = await response.json();
367
-
368
- if (!available) {
369
- setEmailError('Este email já está em uso');
370
- return false;
371
- }
372
- return true;
373
- } catch (error) {
374
- setEmailError('Erro ao verificar email');
375
- return false;
376
- } finally {
377
- wizard.setLoading(false);
378
- }
379
- };
380
-
381
- // Validação assíncrona de username
382
- const validateUsername = async (username: string): Promise<boolean> => {
383
- wizard.setLoading(true);
384
- setUsernameError(null);
385
-
386
- try {
387
- const response = await fetch(\`/api/check-username?username=\${encodeURIComponent(username)}\`);
388
- const { available } = await response.json();
389
-
390
- if (!available) {
391
- setUsernameError('Este nome de usuário já está em uso');
392
- return false;
393
- }
394
- return true;
395
- } catch (error) {
396
- setUsernameError('Erro ao verificar nome de usuário');
397
- return false;
398
- } finally {
399
- wizard.setLoading(false);
400
- }
401
- };
402
-
403
- const steps: WizardStep[] = [
404
- {
405
- id: 'email',
406
- label: 'Email',
407
- canProceed: () => wizard.data.email?.includes('@') && !emailError
408
- },
409
- {
410
- id: 'username',
411
- label: 'Usuário',
412
- canProceed: () => wizard.data.username?.length >= 3 && !usernameError
413
- },
414
- {
415
- id: 'password',
416
- label: 'Senha',
417
- canProceed: () => wizard.data.password?.length >= 8
418
- },
419
- ];
420
-
421
- const wizard = useWizard<UserData>({
422
- steps,
423
- initialData: { email: '', username: '', password: '' },
424
- onComplete: async (data) => {
425
- await api.register(data);
426
- onClose();
427
- },
428
- });
429
-
430
- // Handler customizado para próximo com validação assíncrona
431
- const handleNext = async () => {
432
- if (wizard.currentStep === 0) {
433
- const isValid = await validateEmail(wizard.data.email);
434
- if (!isValid) return;
435
- }
436
-
437
- if (wizard.currentStep === 1) {
438
- const isValid = await validateUsername(wizard.data.username);
439
- if (!isValid) return;
440
- }
441
-
442
- wizard.next();
443
- };
444
-
445
- return (
446
- <Dialog open={open} onOpenChange={() => wizard.reset()}>
447
- <DialogContent size="sm">
448
- <DialogHeader showSeparator>
449
- <DialogTitle>Criar conta - {wizard.currentStepConfig.label}</DialogTitle>
450
- </DialogHeader>
451
-
452
- <div className="py-4 space-y-4">
453
- {wizard.currentStep === 0 && (
454
- <>
455
- <Input
456
- value={wizard.data.email}
457
- onChange={(e) => {
458
- wizard.updateField('email', e.target.value);
459
- setEmailError(null);
460
- }}
461
- placeholder="seu@email.com"
462
- type="email"
463
- />
464
- {emailError && <Alert variant="destructive">{emailError}</Alert>}
465
- </>
466
- )}
467
-
468
- {wizard.currentStep === 1 && (
469
- <>
470
- <Input
471
- value={wizard.data.username}
472
- onChange={(e) => {
473
- wizard.updateField('username', e.target.value);
474
- setUsernameError(null);
475
- }}
476
- placeholder="Nome de usuário"
477
- />
478
- {usernameError && <Alert variant="destructive">{usernameError}</Alert>}
479
- </>
480
- )}
481
-
482
- {wizard.currentStep === 2 && (
483
- <Input
484
- value={wizard.data.password}
485
- onChange={(e) => wizard.updateField('password', e.target.value)}
486
- placeholder="Senha (mínimo 8 caracteres)"
487
- type="password"
488
- />
489
- )}
490
- </div>
491
-
492
- <DialogFooter>
493
- {wizard.canGoBack && (
494
- <Button variant="outline" onClick={wizard.back} disabled={wizard.isLoading}>
495
- Voltar
496
- </Button>
497
- )}
498
- <Button
499
- onClick={handleNext}
500
- disabled={!wizard.canProceed || wizard.isLoading || wizard.isCompleting}
501
- >
502
- {wizard.isLoading ? 'Validando...' : wizard.isLastStep ? 'Criar conta' : 'Próximo'}
503
- </Button>
504
- </DialogFooter>
505
- </DialogContent>
506
- </Dialog>
507
- );
508
- }`,Ce=`import { useWizard, WizardStep } from 'forlogic-core';
509
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, Button, BaseForm, StepSelector } from 'forlogic-core';
510
- import { z } from 'zod';
511
-
512
- // Schemas Zod para cada etapa
513
- const personalInfoSchema = z.object({
514
- firstName: z.string().min(2, 'Nome deve ter pelo menos 2 caracteres'),
515
- lastName: z.string().min(2, 'Sobrenome deve ter pelo menos 2 caracteres'),
516
- email: z.string().email('Email inválido'),
517
- });
518
-
519
- const addressSchema = z.object({
520
- street: z.string().min(5, 'Endereço deve ter pelo menos 5 caracteres'),
521
- city: z.string().min(2, 'Cidade é obrigatória'),
522
- zipCode: z.string().regex(/^\\d{5}-?\\d{3}$/, 'CEP inválido'),
523
- });
524
-
525
- const preferencesSchema = z.object({
526
- newsletter: z.boolean(),
527
- notifications: z.boolean(),
528
- });
529
-
530
- interface FormData {
531
- firstName: string;
532
- lastName: string;
533
- email: string;
534
- street: string;
535
- city: string;
536
- zipCode: string;
537
- newsletter: boolean;
538
- notifications: boolean;
539
- }
540
-
541
- function OnboardingWizard({ open, onClose }: { open: boolean; onClose: () => void }) {
542
- const steps: WizardStep[] = [
543
- {
544
- id: 'personal',
545
- label: 'Dados Pessoais',
546
- canProceed: () => {
547
- try {
548
- personalInfoSchema.parse({
549
- firstName: wizard.data.firstName,
550
- lastName: wizard.data.lastName,
551
- email: wizard.data.email,
552
- });
553
- return true;
554
- } catch { return false; }
555
- }
556
- },
557
- {
558
- id: 'address',
559
- label: 'Endereço',
560
- canProceed: () => {
561
- try {
562
- addressSchema.parse({
563
- street: wizard.data.street,
564
- city: wizard.data.city,
565
- zipCode: wizard.data.zipCode,
566
- });
567
- return true;
568
- } catch { return false; }
569
- }
570
- },
571
- {
572
- id: 'preferences',
573
- label: 'Preferências'
574
- },
575
- ];
576
-
577
- const wizard = useWizard<FormData>({
578
- steps,
579
- initialData: {
580
- firstName: '',
581
- lastName: '',
582
- email: '',
583
- street: '',
584
- city: '',
585
- zipCode: '',
586
- newsletter: true,
587
- notifications: true,
588
- },
589
- onComplete: async (data) => {
590
- await api.completeOnboarding(data);
591
- onClose();
592
- },
593
- });
594
-
595
- const stepLabels = steps.map(s => s.label);
596
-
597
- // Campos BaseForm para cada etapa
598
- const personalFields = [
599
- { name: 'firstName', label: 'Nome', type: 'text' as const, required: true },
600
- { name: 'lastName', label: 'Sobrenome', type: 'text' as const, required: true },
601
- { name: 'email', label: 'Email', type: 'text' as const, required: true },
602
- ];
603
-
604
- const addressFields = [
605
- { name: 'street', label: 'Endereço', type: 'text' as const, required: true },
606
- { name: 'city', label: 'Cidade', type: 'text' as const, required: true },
607
- { name: 'zipCode', label: 'CEP', type: 'text' as const, required: true, placeholder: '00000-000' },
608
- ];
609
-
610
- const preferencesFields = [
611
- { name: 'newsletter', label: 'Receber newsletter', type: 'switch' as const },
612
- { name: 'notifications', label: 'Notificações por email', type: 'switch' as const },
613
- ];
614
-
615
- const getCurrentFields = () => {
616
- switch (wizard.currentStep) {
617
- case 0: return personalFields;
618
- case 1: return addressFields;
619
- case 2: return preferencesFields;
620
- default: return [];
621
- }
622
- };
623
-
624
- return (
625
- <Dialog open={open} onOpenChange={() => wizard.reset()}>
626
- <DialogContent size="lg">
627
- <DialogHeader showSeparator>
628
- <DialogTitle>Configuração Inicial</DialogTitle>
629
- <StepSelector
630
- currentStep={wizard.currentStep}
631
- totalSteps={wizard.totalSteps}
632
- labels={stepLabels}
633
- onStepClick={(step) => {
634
- // Só permite voltar, não avançar clicando
635
- if (step < wizard.currentStep) wizard.goTo(step);
636
- }}
637
- />
638
- </DialogHeader>
639
-
640
- <div className="flex-1 min-h-0 overflow-auto py-4 px-1 -mx-1">
641
- <BaseForm
642
- fields={getCurrentFields()}
643
- values={wizard.data}
644
- onChange={(field, value) => wizard.updateField(field as keyof FormData, value)}
645
- columns={2}
646
- />
647
- </div>
648
-
649
- <DialogFooter>
650
- {wizard.canGoBack && (
651
- <Button variant="outline" onClick={wizard.back}>
652
- Voltar
653
- </Button>
654
- )}
655
- <Button
656
- onClick={wizard.next}
657
- disabled={!wizard.canProceed || wizard.isCompleting}
658
- >
659
- {wizard.isCompleting ? 'Salvando...' : wizard.isLastStep ? 'Concluir' : 'Próximo'}
660
- </Button>
661
- </DialogFooter>
662
- </DialogContent>
663
- </Dialog>
664
- );
665
- }`,je=[{name:"useDebounce<T>(value, delay)",type:"[T, () => void]",default:"-",description:"Retorna [valor com debounce, função para cancelar]. Útil para otimizar chamadas de API em campos de busca."},{name:"useActiveModules(options?)",type:"UseQueryResult<Module[]>",default:"{ enabled: true }",description:"Busca módulos ativos da empresa/unidade. Usa cache do React Query."},{name:"usePermissionQuery(options)",type:"UseQueryResult<boolean>",default:"staleTime: 5min",description:"Verifica permissões com cache otimizado. Evita chamadas repetidas ao servidor."},{name:"useI18nFormatters()",type:"{ formatDatetime, formatDate, locale, timezone, datetimeFormat }",default:"-",description:"Formatação de datas com locale e timezone do usuário."},{name:"usePageTitle()",type:"string",default:"'Página'",description:"Retorna título da página atual baseado na rota do NavigationContext."},{name:"useColumnResize(options)",type:"{ columnWidths, isDragging, handleMouseDown, resetWidths }",default:"-",description:"Gerencia redimensionamento de colunas com persistência em localStorage."},{name:"useRowResize(options)",type:"{ getRowHeight, isDragging, handleMouseDown, resetHeights }",default:"-",description:"Gerencia redimensionamento de linhas com persistência em localStorage."},{name:"useSidebarResize(options)",type:"{ width, isDragging, handleMouseDown }",default:"minWidth: 224, maxWidth: 384",description:"Gerencia redimensionamento da sidebar com persistência e CSS variable."},{name:"useQualiexUsers(options?)",type:"UseQueryResult<QualiexUser[]>",default:"{ enabled: true }",description:"Busca usuários ativos da API Qualiex. Retorna apenas usuários com status ativo."},{name:"options.enabled",type:"boolean",default:"true",description:"Controla se a query executa. Use false para lazy loading com refetch() manual."},{name:"useWizard<TData>(options)",type:"UseWizardReturn<TData>",default:"-",description:"Gerencia estado completo de wizard: steps, navegação, validação e dados."},{name:"options.steps",type:"WizardStep[]",default:"-",description:"Array de steps com id, label e opcionalmente canProceed() e disableBack."},{name:"options.initialData",type:"TData",default:"{}",description:"Dados iniciais do wizard."},{name:"options.initialStep",type:"number",default:"0",description:"Índice do step inicial."},{name:"options.onComplete",type:"(data: TData) => void | Promise<void>",default:"-",description:"Callback executado ao concluir o wizard."},{name:"options.onCancel",type:"() => void",default:"-",description:"Callback executado ao cancelar/resetar o wizard."},{name:"return.currentStep",type:"number",default:"-",description:"Índice do step atual (0-indexed)."},{name:"return.currentStepConfig",type:"WizardStep",default:"-",description:"Configuração do step atual (id, label, canProceed, disableBack)."},{name:"return.data",type:"TData",default:"-",description:"Dados acumulados do wizard."},{name:"return.canProceed",type:"boolean",default:"-",description:"Se pode avançar (baseado em canProceed do step)."},{name:"return.canGoBack",type:"boolean",default:"-",description:"Se pode voltar (false se primeiro step ou disableBack)."},{name:"return.isLoading",type:"boolean",default:"-",description:"Estado de loading controlável via setLoading()."},{name:"return.isCompleting",type:"boolean",default:"-",description:"True durante execução do onComplete."},{name:"return.next()",type:"() => Promise<void>",default:"-",description:"Avança para próximo step ou executa onComplete no último."},{name:"return.back()",type:"() => void",default:"-",description:"Volta para step anterior."},{name:"return.goTo(step)",type:"(step: number) => void",default:"-",description:"Navega para step específico (apenas anteriores ou próximo)."},{name:"return.setData(data)",type:"(data: Partial<TData>) => void",default:"-",description:"Atualiza múltiplos campos de uma vez."},{name:"return.updateField(field, value)",type:"<K>(field: K, value: TData[K]) => void",default:"-",description:"Atualiza um campo específico."},{name:"return.reset()",type:"() => void",default:"-",description:"Reseta wizard para estado inicial e executa onCancel."},{name:"return.setLoading(loading)",type:"(loading: boolean) => void",default:"-",description:"Controla estado de loading (útil para validação assíncrona)."},{name:"return.progress",type:"number",default:"-",description:"Progresso em porcentagem (0-100)."},{name:"return.totalSteps",type:"number",default:"-",description:"Número total de steps."}];function n({title:p,description:c,code:g}){return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:p}),e.jsx("p",{className:"text-sm text-muted-foreground",children:c})]}),e.jsx("pre",{className:"rounded-lg border bg-muted/50 p-4 overflow-x-auto",children:e.jsx("code",{className:"text-sm font-mono",children:g})})]})}function ke(){const p=[{id:"exemplos",label:"Exemplos"},{id:"usedebounce",label:"useDebounce"},{id:"useactivemodules",label:"useActiveModules"},{id:"usepermissionquery",label:"usePermissionQuery"},{id:"usei18nformatters",label:"useI18nFormatters"},{id:"usepagetitle",label:"usePageTitle"},{id:"usecolumnresize",label:"useColumnResize"},{id:"userowresize",label:"useRowResize"},{id:"usesidebarresize",label:"useSidebarResize"},{id:"usequaliexusers",label:"useQualiexUsers"},{id:"usewizard-preview",label:"useWizard - Preview"},{id:"usewizard-basico",label:"useWizard - Básico"},{id:"usewizard-async",label:"useWizard - Validação Assíncrona"},{id:"usewizard-baseform",label:"useWizard - BaseForm"}];return e.jsx(oe,{title:"Hooks",description:"Hooks utilitários da biblioteca forlogic-core para otimização, dados, formatação e UI. Todos os hooks seguem padrões React e são compatíveis com React Query quando aplicável.",usage:ce,props:je,tocItems:p,notes:["Todos os hooks de resize persistem automaticamente no localStorage usando a storageKey fornecida.","useDebounce retorna uma tupla com o valor debounced e uma função para cancelar o debounce pendente.","useActiveModules e usePermissionQuery utilizam React Query internamente para gerenciamento de cache.","useI18nFormatters depende do LocaleContext configurado via CoreProviders.","usePageTitle depende do NavigationContext com array de rotas configurado.","useQualiexUsers retorna apenas usuários ativos (filterStatus=active) e requer autenticação.",'useQualiexUsers usa queryKey ["qualiex-users", alias] para cache automático por unidade.',"useWizard gerencia estado completo de wizard e é ideal para uso com Dialog para criar formulários multi-etapas."],children:e.jsxs("div",{id:"exemplos",className:"space-y-8 scroll-mt-4",children:[e.jsx("h2",{className:"text-2xl font-semibold tracking-tight border-b pb-2",children:"Exemplos"}),e.jsx("div",{id:"usedebounce",className:"scroll-mt-4",children:e.jsx(n,{title:"useDebounce",description:"Aplica debounce em um valor com capacidade de cancelamento. Útil para otimizar chamadas de API em campos de busca.",code:me})}),e.jsx("div",{id:"useactivemodules",className:"scroll-mt-4",children:e.jsx(n,{title:"useActiveModules",description:"Busca módulos ativos da empresa/unidade atual. Usa cache do React Query para evitar chamadas repetidas.",code:pe})}),e.jsx("div",{id:"usepermissionquery",className:"scroll-mt-4",children:e.jsx(n,{title:"usePermissionQuery",description:"Verifica permissões com cache otimizado. Ideal para controle de acesso em páginas protegidas.",code:ge})}),e.jsx("div",{id:"usei18nformatters",className:"scroll-mt-4",children:e.jsx(n,{title:"useI18nFormatters",description:"Formatação de datas respeitando locale e timezone do usuário configurado no LocaleContext.",code:he})}),e.jsx("div",{id:"usepagetitle",className:"scroll-mt-4",children:e.jsx(n,{title:"usePageTitle",description:"Obtém título da página atual baseado na configuração do NavigationContext.",code:fe})}),e.jsx("div",{id:"usecolumnresize",className:"scroll-mt-4",children:e.jsx(n,{title:"useColumnResize",description:"Gerencia redimensionamento de colunas de tabela com persistência em localStorage.",code:xe})}),e.jsx("div",{id:"userowresize",className:"scroll-mt-4",children:e.jsx(n,{title:"useRowResize",description:"Gerencia redimensionamento de linhas com persistência em localStorage.",code:be})}),e.jsx("div",{id:"usesidebarresize",className:"scroll-mt-4",children:e.jsx(n,{title:"useSidebarResize",description:"Gerencia redimensionamento da sidebar com persistência e atualização de CSS variable.",code:ve})}),e.jsx("div",{id:"usequaliexusers",className:"scroll-mt-4",children:e.jsx(n,{title:"useQualiexUsers",description:"Busca usuários ativos da API Qualiex. Suporta busca automática, condicional ou lazy loading com refetch manual.",code:ze})}),e.jsxs("div",{id:"usewizard-preview",className:"space-y-4 p-6 border rounded-lg bg-card scroll-mt-4",children:[e.jsxs("div",{children:[e.jsxs("h3",{className:"text-lg font-semibold flex items-center gap-2",children:[e.jsx(W,{className:"h-5 w-5 text-primary"}),"useWizard - Preview Interativo"]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Experimente o wizard em funcionamento. Navegue pelas etapas, preencha os campos e veja a validação em tempo real."})]}),e.jsx(ue,{})]}),e.jsx("div",{id:"usewizard-basico",className:"scroll-mt-4",children:e.jsx(n,{title:"useWizard - Básico",description:"Gerencia estado completo de wizard: steps, navegação, validação, dados e callbacks. Ideal para formulários multi-etapas.",code:we})}),e.jsx("div",{id:"usewizard-async",className:"scroll-mt-4",children:e.jsx(n,{title:"useWizard - Validação Assíncrona",description:"Exemplo de wizard com validação assíncrona de campos (verificação de email/username disponível) usando setLoading() para controlar estados de carregamento.",code:ye})}),e.jsx("div",{id:"usewizard-baseform",className:"scroll-mt-4",children:e.jsx(n,{title:"useWizard - Integração com BaseForm",description:"Exemplo completo de wizard usando BaseForm para renderização de campos, StepSelector para navegação visual e validação Zod por etapa.",code:Ce})})]})})}export{ke as HooksDoc};