@africanies/angular-web-sdk 0.1.0 → 0.1.2

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 (71) hide show
  1. package/.angular/cache/22.0.9/playground/.tsbuildinfo +1 -1
  2. package/.angular/cache/22.0.9/playground/angular-compiler.db +0 -0
  3. package/.angular/cache/22.0.9/playground/angular-compiler.db-lock +0 -0
  4. package/.github/workflows/deploy-demo.yml +63 -0
  5. package/.nx/cache/run.json +14 -14
  6. package/.nx/cache/terminalOutputs/13524438527920092277 +196 -21
  7. package/.nx/cache/terminalOutputs/14153928176747262656 +45 -21
  8. package/.nx/cache/terminalOutputs/14416694322692463866 +108 -21
  9. package/.nx/cache/terminalOutputs/15255861479705594703 +51 -21
  10. package/.nx/cache/terminalOutputs/18132311043100376919 +315 -21
  11. package/.nx/cache/terminalOutputs/2436781291243085315 +8 -0
  12. package/.nx/cache/terminalOutputs/6664915487114632770 +44 -21
  13. package/.nx/cache/terminalOutputs/8767335728598176888 +37 -0
  14. package/.nx/cache/terminalOutputs/9739655320223921719 +47 -0
  15. package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db +0 -0
  16. package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db-shm +0 -0
  17. package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db-wal +0 -0
  18. package/.nx/workspace-data/d/daemon.log +1683 -0
  19. package/.nx/workspace-data/d/server-process.json +2 -2
  20. package/.nx/workspace-data/file-map.json +475 -518
  21. package/.nx/workspace-data/nx_files.nxt +0 -0
  22. package/.nx/workspace-data/project-graph.json +6 -6
  23. package/.nx/workspace-data/project-graph.lock +0 -0
  24. package/.nx/workspace-data/source-maps.json +80 -0
  25. package/.pnpm-store/v11/index.db +0 -0
  26. package/README.md +14 -2
  27. package/apps/playground/src/app/app.config.ts +28 -3
  28. package/dist/apps/playground/3rdpartylicenses.txt +415 -0
  29. package/dist/apps/playground/browser/assets/africanies-icons/icons.sprite.svg +1844 -0
  30. package/dist/apps/playground/browser/assets/africanies-ui/brand/africanies-logo-mini.png +0 -0
  31. package/dist/apps/playground/browser/assets/africanies-ui/brand/africanies-logo.png +0 -0
  32. package/dist/apps/playground/browser/assets/africanies-ui/brand/africanies-logo.svg +5 -0
  33. package/dist/apps/playground/browser/assets/africanies-ui/carriers/dhl.svg +7 -0
  34. package/dist/apps/playground/browser/chunk--VJ6U9Ev.js +2 -0
  35. package/dist/apps/playground/browser/chunk-B1QVY0hA.js +1 -0
  36. package/dist/apps/playground/browser/chunk-BHI7MG2Y.js +1 -0
  37. package/dist/apps/playground/browser/chunk-BJ5IK8Re.js +1 -0
  38. package/dist/apps/playground/browser/chunk-BOSfyWK2.js +1 -0
  39. package/dist/apps/playground/browser/chunk-BYPboEAg.js +1 -0
  40. package/dist/apps/playground/browser/chunk-BZBRtbFJ.js +1 -0
  41. package/dist/apps/playground/browser/chunk-BdrGkq40.js +1 -0
  42. package/dist/apps/playground/browser/chunk-Bej5a2xR.js +1 -0
  43. package/dist/apps/playground/browser/chunk-Bg3QC1eL.js +1 -0
  44. package/dist/apps/playground/browser/chunk-BsnTz1m5.js +1 -0
  45. package/dist/apps/playground/browser/chunk-C5kLunTi.js +1 -0
  46. package/dist/apps/playground/browser/chunk-C6tu3y81.js +1 -0
  47. package/dist/apps/playground/browser/chunk-C96WSpFp.js +1 -0
  48. package/dist/apps/playground/browser/chunk-CCnOVzbz.js +2 -0
  49. package/dist/apps/playground/browser/chunk-CERmZ9We.js +1 -0
  50. package/dist/apps/playground/browser/chunk-CZBTrY_H.js +68 -0
  51. package/dist/apps/playground/browser/chunk-Cg7brw6x.js +4070 -0
  52. package/dist/apps/playground/browser/chunk-CjTyStrr.js +1 -0
  53. package/dist/apps/playground/browser/chunk-CjYlnYC7.js +1 -0
  54. package/dist/apps/playground/browser/chunk-ClSUoZp8.js +292 -0
  55. package/dist/apps/playground/browser/chunk-CsrxfMap.js +1 -0
  56. package/dist/apps/playground/browser/chunk-CtndMAe2.js +1 -0
  57. package/dist/apps/playground/browser/chunk-Cy-ZOZI8.js +1 -0
  58. package/dist/apps/playground/browser/chunk-D3-jrtyv.js +1 -0
  59. package/dist/apps/playground/browser/chunk-D3vgrlDF.js +1 -0
  60. package/dist/apps/playground/browser/chunk-D48aVVTv.js +1 -0
  61. package/dist/apps/playground/browser/chunk-D4V3eSCv.js +1 -0
  62. package/dist/apps/playground/browser/chunk-DK715t6D.js +1 -0
  63. package/dist/apps/playground/browser/chunk-DUkct7WP.js +1 -0
  64. package/dist/apps/playground/browser/chunk-Y9ccR-I6.js +1 -0
  65. package/dist/apps/playground/browser/chunk-lfUHaltX.js +1 -0
  66. package/dist/apps/playground/browser/favicon.ico +0 -0
  67. package/dist/apps/playground/browser/index.html +14 -0
  68. package/dist/apps/playground/browser/main-WEJC3BLT.js +148 -0
  69. package/dist/apps/playground/browser/styles-4FSELHYD.css +1 -0
  70. package/dist/apps/playground/prerendered-routes.json +3 -0
  71. package/package.json +31 -8
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 88 24" role="img" aria-label="AIES">
2
+ <rect x="0" y="2" width="20" height="20" rx="5" fill="#2563eb"/>
3
+ <path d="M6.2 16.5 10 7.5h1.6l3.8 9h-1.9l-.8-2H8.9l-.8 2H6.2Zm2.5-3.6h2.6l-1.3-3.4-1.3 3.4Z" fill="#ffffff"/>
4
+ <text x="26" y="17" font-family="system-ui, -apple-system, sans-serif" font-size="15" font-weight="700" fill="#111827">AIES</text>
5
+ </svg>
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" overflow="visible" version="1.0" viewBox="-26.3622 -9.6965 228.4724 58.179">
2
+ <path fill="#FECC00" d="M0 38.786V0h175.748v38.786z" />
3
+ <path
4
+ fill="#D50029"
5
+ d="M56.665 16.206c-.768 1.04-2.053 2.848-2.835 3.904-.397.537-1.114 1.512 1.263 1.512h12.515s2.017-2.744 3.708-5.039c2.3-3.122.199-9.618-8.024-9.618H30.908l-5.615 7.629h30.603c1.545 0 1.524.588.769 1.612zm-9.194 7.298c-2.377 0-1.66-.977-1.263-1.514.782-1.056 2.088-2.845 2.856-3.885.756-1.024.776-1.612-.771-1.612H34.297L23.02 31.819h27.501c9.083 0 14.14-6.178 15.699-8.314 0-.001-16.235-.001-18.749-.001zm17.89 8.315h16.133l6.116-8.316-16.131.002c-.005-.001-6.118 8.314-6.118 8.314zm41.625-24.854l-6.188 8.405h-7.2l6.185-8.405H83.655l-10.79 14.657h39.46l10.787-14.657zM88.694 31.819h16.127l6.119-8.314H94.813c-.006-.001-6.119 8.314-6.119 8.314zM0 26.784v1.766h22.468l1.298-1.766zm26.181-3.28H0v1.764h24.88zM0 31.819h20.061l1.292-1.756H0zm152.072-3.27h23.676v-1.766h-22.376zm-2.405 3.27h26.081v-1.756h-24.79zm6.116-8.315l-1.297 1.766h21.262v-1.766zm-21.124-1.882l10.789-14.657h-17.081c-.006 0-10.797 14.657-10.797 14.657zm-18.472 1.882s-1.179 1.611-1.752 2.387c-2.025 2.736-.234 5.928 6.376 5.928h25.901l6.119-8.314h-36.644z"
6
+ />
7
+ </svg>
@@ -0,0 +1,2 @@
1
+ import {r}from'./chunk-CjYlnYC7.js';import {M as Mr,I as Ir,N as Nr,R as Rr,O as Or,D as Dr,P as Pr,L as Lr,F as Fr,s as Br,H as Ht}from'./chunk-Cg7brw6x.js';import'./chunk-CZBTrY_H.js';import {b}from'./chunk-Cy-ZOZI8.js';import {T,af as vn,ag as dt,ah as Ee,ai as Ke,C as Co,aj as Zr,ak as Jr,al as eo,am as In,an as dn,ao as Q,ap as Aa,aq as ln,ar as ah,as as vh,at as Xc,au as ch,av as to,aw as el,ax as Di,I as IE,Z,a7 as Ea,e as ei,c as Zf,V as VE,a as gc,t as tp,M as MI,aa as HI,Q as Qy,d as Qf,b as HE,f as gp,ac as $I,G as GE,X as XE,i as Ic,m as mI,ay as cp,p as Gl,z as zl}from'./main-WEJC3BLT.js';var de=(d,t)=>t.id,pe=(d,t)=>t.value;function ce(d,t){if(d&1){let i=GE();ei(0,"button",30),tp("click",function(){let l=Gl(i).$implicit,_=XE();return zl(_.selectModule(l))}),MI(1),gc();}if(d&2){let i=t.$implicit,e=XE();Qf("variant",e.activeId()===i.id?"primary":"secondary"),Qy(),Ic(" ",i.label," ");}}function me(d,t){if(d&1){let i=GE();ei(0,"button",31),tp("click",function(){let l=Gl(i).$implicit,_=XE();return zl(_.demoEnum.set(l.value))}),MI(1),gc();}if(d&2){let i=t.$implicit,e=XE();mI(e.demoEnum()===i.value?"font-medium":"border-neutral-300 text-neutral-600 dark:border-white/15 dark:text-neutral-300"),cp("color",e.demoEnum()===i.value?i.color:null)("border-color",e.demoEnum()===i.value?i.color:null)("background-color",e.demoEnum()===i.value?i.color+"1A":null),Qy(),Ic(" ",i.label," ");}}var le=class d{filterDrawer=T(vn);filterQuery=T(dt);route=T(Ee);toast=T(Ke);openApplyCode=Mr;customConfigCode=Ir;authorConfigCode=Nr;enumColorsCode=Rr;filterByCode=Or;dateRangeCode=Dr;legacyCode=Pr;namedCode=Lr;asyncOptionsCode=Fr;hydrateCode=Br;shipmentStatusOptions=[{value:"pending",label:"Pending",color:"#DBB316"},{value:"in-process",label:"In Process",color:"#3B82F6"},{value:"completed",label:"Completed",color:"#25945c"}];demoEnum=Co("pending");legacyDemoJson=Co("// Click the button to run");hydrateDemoJson=Co("// Click the button to run");modules=[{id:"track-shipments",label:"Track shipments",config:Zr},{id:"update-shipments",label:"Update shipments",config:Jr,optionListOverrides:{shipment_manifest_id:[{value:"100",label:"Manifest A (playground mock)"},{value:"101",label:"Manifest B (playground mock)"}]}},{id:"users",label:"Users",config:eo}];activeId=Co(this.modules[0]?.id??"track-shipments");state=Co(In());lastParams=Co(dn(In(),Zr));constructor(){this.hydrateFromUrl(this.activeConfig()),this.route.queryParamMap.pipe(Q()).subscribe(()=>{this.hydrateFromUrl(this.activeConfig());});}activeConfig(){return this.modules.find(t=>t.id===this.activeId())?.config??Aa["track-shipments"]}transportLabel(){return ln(this.activeConfig())}selectModule(t){this.activeId.set(t.id),this.state.set(In()),this.lastParams.set(dn(this.state(),t.config));}openFilters(){this.openWithApply(t=>ah(t).pipe(vh(500)));}openFiltersFail(){this.openWithApply(()=>ah(null).pipe(vh(400),Xc(()=>ch(()=>new Error("List request failed (playground demo)")))));}openNamed(){this.filterDrawer.open({config:to,state:In(),title:"Tracking items",onApply:({params:t})=>ah(t).pipe(vh(500),el(()=>this.toast.success("Named-transport filters applied.","Applied")))}).afterClosed().subscribe({next:t=>{t?.applied&&(this.activeId.set(to.id),this.state.set(t.state),this.lastParams.set(t.params));},error:t=>{this.toast.error(r(t),"Filters failed");}});}runLegacyDemo(){let i=dn({search:"SFN-1042",date:"created_at",from:"2026-01-01",to:"2026-01-31",order:"desc",page:1,size:15,values:{payment_status:"paid",shipment_status:"pending",tracking_number:"TN-9"}},Zr),e=Di(i,Zr);this.legacyDemoJson.set(JSON.stringify({params:i,restored:e},null,2));}runHydrateDemo(){let i=Di({search:"SFN",filterColumn:"payment_status,shipment_status",filterValue:"unpaid,completed",from:"2026-02-01",to:"2026-02-28",date:"created_at"},Zr);this.state.set(i),this.lastParams.set(dn(i,Zr)),this.hydrateDemoJson.set(JSON.stringify(i,null,2));}reset(){let t=In();this.state.set(t),this.lastParams.set(dn(t,this.activeConfig())),this.filterQuery.write(t,this.activeConfig());}hydrateFromUrl(t){if(!this.filterQuery.hasParams(t))return;let i=this.filterQuery.read(t);this.state.set(i),this.lastParams.set(dn(i,t));}openWithApply(t){let i=this.modules.find(e=>e.id===this.activeId())??this.modules[0];i&&this.filterDrawer.open({config:i.config,state:this.state(),optionLists:i.optionListOverrides,title:i.label,onApply:e=>t(e).pipe(el({next:()=>this.toast.success(`${i.label} filters applied.`,"Applied"),error:l=>this.toast.error(r(l),"Apply failed")}))}).afterClosed().subscribe(e=>{e?.applied&&(this.state.set(e.state),this.lastParams.set(e.params));});}static \u0275fac=function(i){return new(i||d)};static \u0275cmp=IE({type:d,selectors:[["app-filters-page"]],decls:73,vars:17,consts:[[1,"pg-page-enter","flex","flex-col","gap-10"],["eyebrow","Components","title","Filters","description","Schema-driven filter drawer for list pages. Author one ModuleFilterConfigModel per module; keep FilterStateModel as a values map in the UI. The drawer hydrates from the browser URL when filter queries are present, and Apply writes that bag back to the URL."],["title","Open drawer + onApply","hint","End-to-end flow: pick a module config, open the shared drawer, Apply runs your async work, then the drawer closes.","subtext","Wire onApply to your list fetch. If the call fails, the drawer stays open with an error. Skip onApply for local-only demos.",3,"code"],[1,"flex","flex-col","gap-4"],[1,"flex","flex-wrap","gap-2"],["africanies-button","","type","button","size","sm",3,"variant"],[1,"flex","flex-wrap","items-center","gap-3"],["africanies-button","","type","button","variant","primary",3,"click"],["africanies-button","","type","button","variant","secondary","size","sm",3,"click"],["africanies-button","","type","button","variant","ghost","size","sm",3,"click"],[1,"m-0","text-body-sm","text-neutral-600","dark:text-neutral-400"],[1,"font-medium","text-ink","dark:text-white"],[1,"font-mono","text-caption"],[1,"overflow-hidden","rounded-xl","border","border-border","bg-[#1e1e1e]","text-white","dark:border-white/10"],[1,"border-b","border-white/10","px-4","py-2","text-caption","font-medium","uppercase","tracking-wide","text-white/50"],[1,"m-0","max-h-64","overflow-auto","p-4","font-mono","text-caption","leading-relaxed","text-white/90"],["title","Custom ModuleFilterConfigModel","hint","Define your own schema per list screen \u2014 field keys must match API column / query names. Omit transport for legacy Laravel CSV; use FilterTransport.Named for direct params.","subtext","Full seed configs (track-shipments, update-shipments, \u2026) live in FILTER_CONFIGS. Expand \u201CFull seed example\u201D below for every field type.",3,"code"],["title","Full seed example (update-shipments)","hint","Reference config bundled with the SDK \u2014 search, date range, sort, enums, selects, booleans.","subtext","Field type chooses the control; transport chooses the query shape.",3,"code"],["title","Enum chips + colors","hint","Status-style options as chips. Optional color highlights only the selected chip \u2014 never the wire payload.","subtext","color stays in the UI \u2014 it never goes out in toFilterParams.",3,"code"],["type","button",1,"rounded-md","border","px-2.5","py-1.5","text-body-sm","transition-colors",3,"color","border-color","background-color","class"],["title","Filter by (multi-select)","hint","Let users choose which fields appear in the drawer. Add a chip to show a control; remove it to hide that section.","subtext","Keep field.key stable \u2014 it becomes the API column (legacy) or query key (named).",3,"code"],["title","Date range","hint","Filter by a date column with From / To. Clear resets only this block; the range fields constrain each other.","subtext","Goes out as from, to, and date \u2014 not as filterColumn pairs.",3,"code"],[1,"pg-code"],["title","legacy-parallel transport","hint","Older APIs that expect filterColumn / filterValue CSV pairs aligned by index. Use this when the backend still speaks that format.","subtext","Empty values are skipped. Keep a values map inside the app; flatten when you hit the API.",3,"code"],[1,"flex","flex-col","gap-3"],[1,"m-0","max-h-48","overflow-auto","rounded-lg","border","border-border","bg-background-welcome","p-3","font-mono","text-caption","dark:border-white/10","dark:bg-ink-950"],["title","named transport","hint","Newer APIs where each field key is its own query param (e.g. status=pending). Same drawer UI \u2014 only the wire format changes.","subtext","Same drawer and state \u2014 only transport flips the wire format.",3,"code"],["title","Async option lists","hint","Select fields with optionsSource load lazily when added via Filter by. SDK catalogs toast on HTTP failure; the select shows a field error.","subtext","Host optionLists cover sources without a built-in service (e.g. manifests).",3,"code"],["title","Cold load from URL","hint","Restore filters from the query string on first paint so shared list links reopen with the same criteria.","subtext","FilterQueryService.read() uses fromFilterParams. Apply / pagination keep the URL in sync \u2014 try Open filters then check the address bar.",3,"code"],[1,"mt-3","m-0","max-h-48","overflow-auto","rounded-lg","border","border-border","bg-background-welcome","p-3","font-mono","text-caption","dark:border-white/10","dark:bg-ink-950"],["africanies-button","","type","button","size","sm",3,"click","variant"],["type","button",1,"rounded-md","border","px-2.5","py-1.5","text-body-sm","transition-colors",3,"click"]],template:function(i,e){i&1&&(ei(0,"div",0),Zf(1,"app-page-header",1),ei(2,"app-demo-section",2)(3,"div",3)(4,"div",4),VE(5,ce,2,2,"button",5,de),gc(),ei(7,"div",6)(8,"button",7),tp("click",function(){return e.openFilters()}),MI(9," Open filters "),gc(),ei(10,"button",8),tp("click",function(){return e.openFiltersFail()}),MI(11," Open (demo Apply error) "),gc(),ei(12,"button",9),tp("click",function(){return e.reset()}),MI(13," Reset state "),gc(),ei(14,"p",10),MI(15," Active: "),ei(16,"span",11),MI(17),gc(),MI(18," \xB7 transport "),ei(19,"span",12),MI(20),gc()()(),ei(21,"div",13)(22,"div",14),MI(23," Live host state \u2192 toFilterParams(state, config) "),gc(),ei(24,"pre",15),MI(25),HI(26,"json"),gc()()()(),ei(27,"app-demo-section",16)(28,"p",10),MI(29," Open "),ei(30,"span",11),MI(31,"Update shipments"),gc(),MI(32," above to exercise every field type in the live drawer. "),gc()(),Zf(33,"app-demo-section",17),ei(34,"app-demo-section",18)(35,"div",4),VE(36,me,2,9,"button",19,pe),gc()(),ei(38,"app-demo-section",20)(39,"p",10),MI(40," Try it in the live drawer: open "),ei(41,"span",11),MI(42,"Update shipments"),gc(),MI(43,", add several Filter by rows, Apply, and inspect the params bag above. "),gc()(),ei(44,"app-demo-section",21)(45,"p",10),MI(46," Open any module that declares "),ei(47,"span",22),MI(48,"config.date"),gc(),MI(49," and use Clear after picking a range. "),gc()(),ei(50,"app-demo-section",23)(51,"div",24)(52,"button",8),tp("click",function(){return e.runLegacyDemo()}),MI(53," Run serialize \u2192 hydrate round-trip "),gc(),ei(54,"pre",25),MI(55),gc()()(),ei(56,"app-demo-section",26)(57,"button",7),tp("click",function(){return e.openNamed()}),MI(58," Open tracking-item filters "),gc()(),ei(59,"app-demo-section",27)(60,"p",10),MI(61," Open "),ei(62,"span",11),MI(63,"Update shipments"),gc(),MI(64," \u2014 add Warehouse or Carrier under Filter by; catalogs load then (paste a token via "),ei(65,"span",11),MI(66,"API token"),gc(),MI(67," in the header). Manifests use playground mocks. "),gc()(),ei(68,"app-demo-section",28)(69,"button",8),tp("click",function(){return e.runHydrateDemo()}),MI(70," Hydrate from sample query bag "),gc(),ei(71,"pre",29),MI(72),gc()()()),i&2&&(Qy(2),Qf("code",e.openApplyCode),Qy(3),HE(e.modules),Qy(12),gp(e.activeId()),Qy(3),gp(e.transportLabel()),Qy(5),gp($I(26,15,e.lastParams())),Qy(2),Qf("code",e.customConfigCode),Qy(6),Qf("code",e.authorConfigCode),Qy(),Qf("code",e.enumColorsCode),Qy(2),HE(e.shipmentStatusOptions),Qy(2),Qf("code",e.filterByCode),Qy(6),Qf("code",e.dateRangeCode),Qy(6),Qf("code",e.legacyCode),Qy(5),gp(e.legacyDemoJson()),Qy(),Qf("code",e.namedCode),Qy(3),Qf("code",e.asyncOptionsCode),Qy(9),Qf("code",e.hydrateCode),Qy(4),gp(e.hydrateDemoJson()));},dependencies:[Z,b,Ht,Ea],encapsulation:2})};
2
+ export{le as FiltersPage};
@@ -0,0 +1 @@
1
+ import {I as IE,c as Zf,k as TP,n as mc,M as MI,y as yc,Q as Qy,i as Ic}from'./main-WEJC3BLT.js';var s=class t{title=TP.required();body=TP.required();static \u0275fac=function(e){return new(e||t)};static \u0275cmp=IE({type:t,selectors:[["app-nav-route-panel"]],inputs:{title:[1,"title"],body:[1,"body"]},decls:7,vars:2,consts:[[1,"rounded-lg","border","border-border","bg-background-welcome","px-4","py-3","dark:border-white/10","dark:bg-ink-950"],[1,"m-0","text-body","font-medium","text-ink","dark:text-white"],[1,"mt-1","m-0","text-body-sm","text-neutral-600","dark:text-neutral-400"],[1,"mt-2","m-0","text-caption","text-neutral-500"]],template:function(e,a){e&1&&(mc(0,"div",0)(1,"p",1),MI(2),yc(),mc(3,"p",2),MI(4),yc(),mc(5,"p",3),MI(6," Loaded from the URL \u2014 refresh or paste this path to land on this tab. "),yc()()),e&2&&(Qy(2),Ic(" ",a.title()," "),Qy(2),Ic(" ",a.body()," "));},encapsulation:2})},u=class t{static \u0275fac=function(e){return new(e||t)};static \u0275cmp=IE({type:t,selectors:[["app-nav-overview-panel"]],decls:1,vars:0,consts:[["title","Overview","body","Route-driven overview panel for the active shipment."]],template:function(e,a){e&1&&Zf(0,"app-nav-route-panel",0);},dependencies:[s],encapsulation:2})},v=class t{static \u0275fac=function(e){return new(e||t)};static \u0275cmp=IE({type:t,selectors:[["app-nav-documents-panel"]],decls:1,vars:0,consts:[["title","Documents","body","Airway bills, invoices, and packing lists for this shipment."]],template:function(e,a){e&1&&Zf(0,"app-nav-route-panel",0);},dependencies:[s],encapsulation:2})},f=class t{static \u0275fac=function(e){return new(e||t)};static \u0275cmp=IE({type:t,selectors:[["app-nav-events-panel"]],decls:1,vars:0,consts:[["title","Events","body","Scan history and exception notes for this shipment."]],template:function(e,a){e&1&&Zf(0,"app-nav-route-panel",0);},dependencies:[s],encapsulation:2})};export{v as NavDocumentsPanel,f as NavEventsPanel,u as NavOverviewPanel,s as NavRoutePanelComponent};
@@ -0,0 +1 @@
1
+ import {I as IE,aZ as pi,c as Zf}from'./main-WEJC3BLT.js';var p=class t{static \u0275fac=function(e){return new(e||t)};static \u0275cmp=IE({type:t,selectors:[["app-shipment-usecase-page"]],decls:1,vars:0,template:function(e,i){e&1&&Zf(0,"router-outlet");},dependencies:[pi],encapsulation:2})};export{p as ShipmentUsecasePage};
@@ -0,0 +1 @@
1
+ import {a4 as Co$1,a5 as xo,H as Ht}from'./chunk-Cg7brw6x.js';import'./chunk-CZBTrY_H.js';import {b}from'./chunk-Cy-ZOZI8.js';import {C as Co,u as QI,I as IE,aL as Lr,aM as Zt,Z,U as Gt,e as ei,c as Zf,t as tp,a as gc,M as MI,aJ as Uf,Q as Qy,d as Qf,aN as mp,G as GE,a8 as Ep,X as XE,ab as vp,f as gp,p as Gl,a9 as AI,z as zl}from'./main-WEJC3BLT.js';function R(a,d){if(a&1){let i=GE();ei(0,"div",18)(1,"p",19),MI(2," Origin and destination for this shipment. "),gc(),ei(3,"div",20)(4,"africanies-text-input",21),Ep("valueChange",function(r){Gl(i);let o=XE();return AI(o.origin,r)||(o.origin=r),zl(r)}),gc(),ei(5,"africanies-text-input",22),Ep("valueChange",function(r){Gl(i);let o=XE();return AI(o.destination,r)||(o.destination=r),zl(r)}),gc()()();}if(a&2){let i=XE();Qy(4),vp("value",i.origin),Qy(),vp("value",i.destination);}}function B(a,d){if(a&1){let i=GE();ei(0,"div",18)(1,"p",19),MI(2,"Describe what you are shipping."),gc(),ei(3,"africanies-text-input",23),Ep("valueChange",function(r){Gl(i);let o=XE();return AI(o.commodity,r)||(o.commodity=r),zl(r)}),gc()();}if(a&2){let i=XE();Qy(3),vp("value",i.commodity);}}function L(a,d){if(a&1&&(ei(0,"div",24)(1,"p",25),MI(2,"Review"),gc(),ei(3,"ul",26)(4,"li"),MI(5),gc(),ei(6,"li"),MI(7),gc()()()),a&2){let i=XE();Qy(5),mp("",i.origin()||"\u2014"," \u2192 ",i.destination()||"\u2014"),Qy(2),gp(i.commodity()||"No commodity set");}}function A(a,d){a&1&&(ei(0,"p",27),MI(1,"Account details step body."),gc());}function z(a,d){a&1&&(ei(0,"p",27),MI(1,"Billing step body."),gc());}function F(a,d){a&1&&(ei(0,"p",27),MI(1,"Confirmation step body."),gc());}var W=class a{linearIndex=Co(0);freeIndex=Co(0);routeValid=Co(false);origin=Co("Lagos");destination=Co("");commodity=Co("");linearSteps=QI(()=>[{key:"route",label:"Route",isValid:this.routeValid()},{key:"cargo",label:"Cargo",isValid:true},{key:"review",label:"Review"}]);freeSteps=[{key:"account",label:"Account"},{key:"billing",label:"Billing"},{key:"confirm",label:"Confirm"}];linearCode=Co$1;freeCode=xo;canGoNext(){return this.linearSteps()[this.linearIndex()]?.isValid!==false}static \u0275fac=function(i){return new(i||a)};static \u0275cmp=IE({type:a,selectors:[["app-stepper-page"]],decls:23,vars:13,consts:[[1,"pg-page-enter","flex","flex-col","gap-10"],["eyebrow","Components","title","Stepper","description","Step-by-step wizard for multi-page forms (create shipment, onboarding). Not a shipment status timeline \u2014 use chips or a custom track for that."],["title","Linear wizard","hint","Users move forward in order. Next stays disabled while the active step reports isValid false.","badge","linear",3,"code"],[1,"mb-5","flex","flex-wrap","items-center","gap-4"],[1,"inline-flex","items-center","gap-2","text-body-sm","text-ink","dark:text-white"],["type","checkbox",1,"accent-export",3,"change","checked"],[1,"text-caption","text-neutral-600"],[3,"activeIndexChange","steps","activeIndex","linear"],["africaniesStepDef","route"],["africaniesStepDef","cargo"],["africaniesStepDef","review"],[1,"mt-5","flex","gap-2"],["africanies-button","","type","button","variant","ghost",3,"click","disabled"],["africanies-button","","type","button",3,"click","disabled"],["title","Non-linear","hint","Allow jumping to any step via the header \u2014 useful when reviewing or editing an already-filled flow.","badge","free nav",3,"code"],["africaniesStepDef","account"],["africaniesStepDef","billing"],["africaniesStepDef","confirm"],[1,"flex","flex-col","gap-4"],[1,"m-0","text-body-sm","text-neutral-600"],[1,"grid","gap-4","md:grid-cols-2"],["label","Origin city",3,"valueChange","value"],["label","Destination city",3,"valueChange","value"],["label","Commodity",3,"valueChange","value"],[1,"rounded-lg","border","border-border","bg-background-welcome","p-4","text-body-sm","dark:border-white/10","dark:bg-ink-950"],[1,"m-0","font-medium","text-ink","dark:text-white"],[1,"mt-2","mb-0","list-disc","pl-5","text-neutral-600"],[1,"m-0","text-body","text-ink","dark:text-white"]],template:function(i,e){i&1&&(ei(0,"div",0),Zf(1,"app-page-header",1),ei(2,"app-demo-section",2)(3,"div",3)(4,"label",4)(5,"input",5),tp("change",function(o){return e.routeValid.set(o.target.checked)}),gc(),MI(6," Mark Route as valid "),gc(),ei(7,"span",6),MI(8),gc()(),ei(9,"africanies-stepper",7),tp("activeIndexChange",function(o){return e.linearIndex.set(o)}),Uf(10,R,6,2,"ng-template",8)(11,B,4,1,"ng-template",9)(12,L,8,3,"ng-template",10),gc(),ei(13,"div",11)(14,"button",12),tp("click",function(){return e.linearIndex.set(e.linearIndex()-1)}),MI(15," Back "),gc(),ei(16,"button",13),tp("click",function(){return e.linearIndex.set(e.linearIndex()+1)}),MI(17," Next "),gc()()(),ei(18,"app-demo-section",14)(19,"africanies-stepper",7),tp("activeIndexChange",function(o){return e.freeIndex.set(o)}),Uf(20,A,2,0,"ng-template",15)(21,z,2,0,"ng-template",16)(22,F,2,0,"ng-template",17),gc()()()),i&2&&(Qy(2),Qf("code",e.linearCode),Qy(3),Qf("checked",e.routeValid()),Qy(3),mp(" Step ",e.linearIndex()+1," of ",e.linearSteps().length," "),Qy(),Qf("steps",e.linearSteps())("activeIndex",e.linearIndex())("linear",true),Qy(5),Qf("disabled",e.linearIndex()===0),Qy(2),Qf("disabled",e.linearIndex()>=e.linearSteps().length-1||!e.canGoNext()),Qy(2),Qf("code",e.freeCode),Qy(),Qf("steps",e.freeSteps)("activeIndex",e.freeIndex())("linear",false));},dependencies:[Lr,Zt,Z,Gt,b,Ht],encapsulation:2})};export{W as StepperPage};
@@ -0,0 +1 @@
1
+ import {T,r as re,I as IE,H as Hs,Z,g,e as ei,M as MI,a as gc,V as VE,Q as Qy,b as HE,c as Zf,X as XE,d as Qf,m as mI,f as gp}from'./main-WEJC3BLT.js';var y=(r,a)=>a.path;function S(r,a){if(r&1&&(ei(0,"a",17)(1,"div",18)(2,"span",19),Zf(3,"africanies-icon",20),gc(),ei(4,"span",21),MI(5),gc()(),ei(6,"div",13)(7,"span",22),MI(8),gc(),ei(9,"span",23),MI(10),gc()()()),r&2){let o=a.$implicit,s=XE();Qf("routerLink",o.path),Qy(2),mI(s.modeColor.classes().bgSubtle),Qy(),Qf("name",o.icon)("size",20),Qy(2),gp(o.group),Qy(3),gp(o.title),Qy(2),gp(o.blurb);}}var k=class r{modeColor=T(re);cards=[{path:"/components/button",title:"Button",blurb:"Primary, secondary, ghost, and danger actions \u2014 mode-colored primary.",icon:"adjust",group:"Components"},{path:"/components/alert",title:"Alert",blurb:"Inline page notices the user can dismiss \u2014 not fetch errors.",icon:"info-circle",group:"Components"},{path:"/components/chip",title:"Chip",blurb:"Status and category labels for tables, filters, and tags.",icon:"tags",group:"Components"},{path:"/components/action-menu",title:"Action menu",blurb:"Overflow (\u2026) menu for row and toolbar actions.",icon:"ellipsis-v",group:"Components"},{path:"/components/feedback",title:"Feedback states",blurb:"Loading, error, empty, and AsyncState for query-driven regions.",icon:"warning",group:"Components"},{path:"/components/overlays",title:"Overlays",blurb:"Modal, drawer, and confirm via service APIs.",icon:"modal",group:"Components"},{path:"/components/forms",title:"Form controls",blurb:"Shared inputs with label, hint, error, and form binding.",icon:"accordion-menu",group:"Components"},{path:"/components/filters",title:"Filters",blurb:"Schema-driven list filter drawer and URL/HTTP serialize.",icon:"filter",group:"Components"},{path:"/components/tooltip",title:"Tooltip",blurb:"Short help beside dense labels and controls.",icon:"info-circle",group:"Components"},{path:"/components/toast",title:"Toast",blurb:"Corner messages after actions \u2014 timed, sticky errors, HTTP tags.",icon:"warning",group:"Components"},{path:"/components/navigation/overview",title:"Navigation",blurb:"App shell, side nav, breadcrumbs, tabs, and segments.",icon:"panel",group:"Components"},{path:"/components/table",title:"Table & pagination",blurb:"Presentational grid with template cells and server paging.",icon:"align-justify",group:"Components"},{path:"/components/stepper",title:"Stepper",blurb:"Multi-step wizards \u2014 linear or free navigation.",icon:"warehouse",group:"Components"},{path:"/usecases/shipment",title:"Back button and Breadcrumbs",blurb:"App-shell Back and breadcrumbs, plus a list that restores filters and page from the URL.",icon:"truck",group:"Use cases"},{path:"/usecases/onboarding/login",title:"Forgot password",blurb:"Email-only reset link from login. First-login default password is a separate screen.",icon:"key",group:"Use cases"},{path:"/icons",title:"Icon gallery",blurb:"Browse and copy every IconName from the sprite.",icon:"abacus",group:"Foundation"},{path:"/tokens",title:"Design tokens",blurb:"Colors, type, and Import/Export accents from the theme.",icon:"palette",group:"Foundation"},{path:"/models",title:"Shared models",blurb:"Field shapes from @africanies/africanies-models \u2014 types only.",icon:"code",group:"Foundation"},{path:"/api",title:"SDK API",blurb:"How to call services \u2014 ResourceId, paths, and usage snippets.",icon:"globe",group:"Foundation"},{path:"/lecture",title:"Lecture",blurb:"Angular & RxJS concepts linked from Show code panels.",icon:"book",group:"Learn"}];static \u0275fac=function(o){return new(o||r)};static \u0275cmp=IE({type:r,selectors:[["app-home-page"]],decls:40,vars:0,consts:[[1,"pg-page-enter","flex","flex-col","gap-12"],[1,"relative","overflow-hidden","rounded-2xl","bg-ink-brand","text-white"],[1,"relative","grid","gap-8","px-6","py-10","sm:px-10","sm:py-14","lg:grid-cols-[1.4fr_1fr]","lg:items-end"],[1,"flex","flex-col","gap-5"],[1,"m-0","text-caption","font-medium","uppercase","tracking-[0.16em]","text-white/70"],[1,"m-0","max-w-xl","text-heading-1","text-white"],[1,"m-0","max-w-lg","text-body-lg","text-white/75"],[1,"flex","flex-wrap","gap-3"],["africanies-button","","routerLink","/components/button",1,"!no-underline"],["africanies-button","","variant","secondary","routerLink","/tokens",1,"!border-white/30","!bg-transparent","!text-white","!no-underline","hover:!bg-white/10"],[1,"grid","grid-cols-3","gap-4","rounded-xl","border","border-white/15","bg-black/20","p-5","backdrop-blur-sm"],[1,"text-caption","text-white/60"],[1,"m-0","mt-1","text-heading-3","text-white"],[1,"flex","flex-col","gap-1"],[1,"pg-kicker","m-0"],[1,"m-0","text-heading-3","text-ink","dark:text-white"],[1,"grid","gap-4","sm:grid-cols-2","xl:grid-cols-3"],[1,"flex","flex-col","gap-4","rounded-xl","border","border-border","bg-white","p-5","no-underline","transition-colors","hover:border-neutral-400","dark:border-white/10","dark:bg-ink","dark:hover:border-white/25",3,"routerLink"],[1,"flex","items-center","justify-between"],[1,"inline-flex","h-10","w-10","items-center","justify-center","rounded-lg","bg-background-welcome","text-ink","dark:bg-ink-950","dark:text-white"],[3,"name","size"],[1,"text-caption","text-neutral-600"],[1,"text-body","font-medium","text-ink","dark:text-white"],[1,"text-body-sm","text-neutral-600","dark:text-neutral-400"]],template:function(o,s){o&1&&(ei(0,"div",0)(1,"section",1)(2,"div",2)(3,"div",3)(4,"p",4),MI(5," African Import Export Solutions "),gc(),ei(6,"h1",5),MI(7," The shared UI toolkit for Import & Export apps. "),gc(),ei(8,"p",6),MI(9," Owned by AFRICANIES for every product surface we ship. One Angular SDK \u2014 components, icons, tokens, and API wiring \u2014 with Import (STN) and Export (SFN) modes built in so accents and behavior match production. "),gc(),ei(10,"div",7)(11,"a",8),MI(12," Explore components "),gc(),ei(13,"a",9),MI(14," View tokens "),gc()()(),ei(15,"dl",10)(16,"div")(17,"dt",11),MI(18,"Packages"),gc(),ei(19,"dd",12),MI(20,"6"),gc()(),ei(21,"div")(22,"dt",11),MI(23,"Icons"),gc(),ei(24,"dd",12),MI(25,"638"),gc()(),ei(26,"div")(27,"dt",11),MI(28,"API services"),gc(),ei(29,"dd",12),MI(30,"6"),gc()()()()(),ei(31,"section",3)(32,"div",13)(33,"p",14),MI(34,"Catalog"),gc(),ei(35,"h2",15),MI(36,"Jump into a surface"),gc()(),ei(37,"div",16),VE(38,S,11,8,"a",17,y),gc()()()),o&2&&(Qy(38),HE(s.cards));},dependencies:[Hs,Z,g],encapsulation:2})};export{k as HomePage};
@@ -0,0 +1 @@
1
+ import {r}from'./chunk-CjYlnYC7.js';import {ad as Uo,H as Ht}from'./chunk-Cg7brw6x.js';import'./chunk-CZBTrY_H.js';import {b}from'./chunk-Cy-ZOZI8.js';import {T,a$ as Ui,C as Co,u as QI,b0 as za,b1 as lh,I as IE,H as Hs,x as xr,Z,U as Gt,e as ei,c as Zf,L as LE,a as gc,Q as Qy,d as Qf,P as PE,M as MI,G as GE,t as tp,a8 as Ep,X as XE,ab as vp,p as Gl,z as zl,a9 as AI}from'./main-WEJC3BLT.js';function B(t,e){t&1&&(ei(0,"div",3),Zf(1,"africanies-alert",4),ei(2,"a",5),MI(3," Reset completed? Login here "),gc()()),t&2&&(Qy(),Qf("message",e)("dismissible",false));}function R(t,e){t&1&&Zf(0,"africanies-alert",7),t&2&&Qf("message",e)("dismissible",false);}function I(t,e){if(t&1){let i=GE();ei(0,"form",6),tp("submit",function(a){Gl(i);let m=XE();return a.preventDefault(),zl(m.forgot())}),LE(1,R,1,2,"africanies-alert",7),ei(2,"africanies-text-input",8),Ep("valueChange",function(a){Gl(i);let m=XE();return AI(m.email,a)||(m.email=a),zl(a)}),gc(),ei(3,"button",9),MI(4," Send reset link "),gc(),ei(5,"a",10),MI(6," Back to login "),gc()();}if(t&2){let i,n=XE();Qy(),PE((i=n.errorMessage())?1:-1,i),Qy(),vp("value",n.email),Qy(),Qf("loading",n.sending())("disabled",!n.canSubmit());}}var W=class t{authApi=T(Ui);email=Co("");sending=Co(false);successMessage=Co(null);errorMessage=Co(null);routeCode=Uo;canSubmit=QI(()=>za(this.email())&&!this.sending());async forgot(){if(this.canSubmit()){this.sending.set(true),this.errorMessage.set(null);try{let e=await lh(this.authApi.forgot(this.email()));if(e.success){this.successMessage.set(e.message?.trim()||"We have emailed your reset password.");return}this.errorMessage.set(e.message?.trim()||"Could not send a reset email.");}catch(e){this.errorMessage.set(r(e));}finally{this.sending.set(false);}}}static \u0275fac=function(i){return new(i||t)};static \u0275cmp=IE({type:t,selectors:[["app-onboarding-forgot-password-page"]],decls:5,vars:2,consts:[[1,"pg-page-enter","mx-auto","flex","w-full","max-w-lg","flex-col","gap-8"],["eyebrow","Use cases","title","Forgot password","description","Product path /onboarding/forgot-password. Submit calls AuthService.forgot() \u2014 POST { email } to /auth/forgot/password. This app never shows a new-password form for the emailed link."],["title","Email only","hint","Submit is enabled only when the address looks valid. Admins can call the same forgot(email) from user/partner screens.",3,"code"],[1,"flex","flex-col","gap-4"],["variant","success",3,"message","dismissible"],["routerLink","/usecases/onboarding/login",1,"cursor-pointer","text-body-sm","font-medium","text-ink","underline-offset-2","hover:underline","dark:text-white"],[1,"flex","flex-col","gap-4",3,"submit"],["variant","danger",3,"message","dismissible"],["type","email","label","Email","hint","We will send you a password reset link.","autocomplete","email",3,"valueChange","value"],["africanies-button","","type","submit","variant","primary",3,"loading","disabled"],["routerLink","/usecases/onboarding/login",1,"cursor-pointer","text-center","text-body-sm","font-medium","text-ink","underline-offset-2","hover:underline","dark:text-white"]],template:function(i,n){if(i&1&&(ei(0,"div",0),Zf(1,"app-page-header",1),ei(2,"app-demo-section",2),LE(3,B,4,2,"div",3)(4,I,7,4,"form",3),gc()()),i&2){let a;Qy(2),Qf("code",n.routeCode),Qy(),PE((a=n.successMessage())?3:4,a);}},dependencies:[Hs,xr,Z,Gt,b,Ht],encapsulation:2})};export{W as OnboardingForgotPasswordPage};
@@ -0,0 +1 @@
1
+ import {w as wr,E as Er,k as kr,A as Ar,_ as _r,H as Ht}from'./chunk-Cg7brw6x.js';import'./chunk-CZBTrY_H.js';import {b as b$1}from'./chunk-Cy-ZOZI8.js';import {C as Co,u as QI,I as IE,A as At,v as Tt,D as Dt,B as Mt,E as Cr,g,e as ei,c as Zf,M as MI,a as gc,t as tp,V as VE,j as jE,L as LE,Q as Qy,d as Qf,b as HE,i as Ic,F as FI,P as PE,G as GE,X as XE,m as mI,J as zf,p as Gl,z as zl}from'./main-WEJC3BLT.js';var Q=()=>[],U=(d,a)=>a.id;function V(d,a){if(d&1){let i=GE();ei(0,"button",43),tp("click",function(){let c=Gl(i).$implicit,$=XE();return zl($.setDemo(c))}),MI(1),gc();}if(d&2){let i=a.$implicit,e=XE();mI(e.demo()===i?"bg-white text-ink shadow-sm dark:bg-ink dark:text-white":"text-neutral-600 hover:text-ink dark:text-neutral-400 dark:hover:text-white"),zf("aria-selected",e.demo()===i),Qy(),Ic(" ",e.kindLabels[i]," ");}}function W(d,a){if(d&1&&(ei(0,"li",41)(1,"div",44)(2,"p",45),MI(3),gc(),ei(4,"p",46),MI(5),gc()(),ei(6,"span",47),MI(7),gc(),ei(8,"span",48),MI(9),gc()()),d&2){let i=a.$implicit,e=XE();Qy(3),Ic(" ",i.id," "),Qy(2),Ic(" ",i.route," "),Qy(2),Ic(" ETA ",i.eta," "),Qy(),mI(e.statusClass(i.status)),Qy(),Ic(" ",i.status," ");}}function Y(d,a){if(d&1&&(ei(0,"p",42),Zf(1,"africanies-icon",49),MI(2),gc()),d&2){let i=XE();Qy(),Qf("size",12),Qy(),Ic(" Last retry: ",i.lastRetry()," ");}}var b=[{id:"SFN-1001",route:"Lagos \u2192 London",status:"In transit",eta:"Aug 14"},{id:"SFN-1002",route:"Accra \u2192 Dubai",status:"Pending",eta:"Aug 16"},{id:"SFN-1003",route:"Nairobi \u2192 Amsterdam",status:"Delivered",eta:"Aug 09"}],j=class d{demo=Co("content");lastRetry=Co(null);reconnecting=Co(false);refreshingStale=Co(false);asyncState=Co(this.buildState("content"));rowCount=QI(()=>this.asyncState().data?.length??0);demoKinds=["loading","error","empty","content","fetching","stale"];kindLabels={loading:"First load",error:"Blocking error",empty:"Empty",content:"Success",fetching:"Background refresh",stale:"Stale error"};loadingCode=wr;errorCode=Er;errorIndicatorCode=kr;emptyCode=Ar;asyncCode=_r;simulateReconnect(){this.reconnecting.set(true),this.onRetry("error-indicator-reconnect"),globalThis.setTimeout(()=>this.reconnecting.set(false),1800);}simulateStaleRefresh(){this.refreshingStale.set(true),this.onRetry("error-indicator-stale"),globalThis.setTimeout(()=>this.refreshingStale.set(false),1800);}setDemo(a){this.demo.set(a),this.asyncState.set(this.buildState(a));}onRetry(a){this.lastRetry.set(a);}statusClass(a){switch(a){case "Delivered":return "bg-export/10 text-export dark:bg-export/15 dark:text-export-light";case "Pending":return "bg-warning-subtle text-warning-dark dark:bg-warning/15 dark:text-warning";default:return "bg-import/10 text-import dark:bg-import/15 dark:text-import-light"}}buildState(a){switch(a){case "loading":return {data:void 0,isLoading:true,isFetching:true,isError:false,error:null};case "error":return {data:void 0,isLoading:false,isFetching:false,isError:true,error:"Network request failed."};case "empty":return {data:[],isLoading:false,isFetching:false,isError:false,error:null};case "fetching":return {data:b,isLoading:false,isFetching:true,isError:false,error:null};case "stale":return {data:b.slice(0,2),isLoading:false,isFetching:false,isError:true,error:"Refresh failed."};default:return {data:b,isLoading:false,isFetching:false,isError:false,error:null}}}static \u0275fac=function(i){return new(i||d)};static \u0275cmp=IE({type:d,selectors:[["app-feedback-page"]],decls:63,vars:14,consts:[[1,"pg-page-enter","flex","flex-col","gap-10"],["eyebrow","Components","title","Feedback states","description","What to show while a page or section is loading, failed, or empty. Use these for data fetches \u2014 not for field validation errors on form controls. Prefer AsyncState when one query owns the whole region."],["title","LoadingState","hint","Spinner while data is in flight. Use block to fill a whole region; use inline next to a toolbar label or refresh control.",3,"code"],[1,"grid","gap-6","md:grid-cols-2"],[1,"flex","flex-col","gap-2"],[1,"m-0","text-caption","font-medium","text-neutral-600","dark:text-neutral-400"],[1,"flex","min-h-[10rem]","items-center","justify-center","rounded-lg","border","border-dashed","border-border","bg-background-welcome","dark:border-white/10","dark:bg-ink-950"],["message","Loading shipments\u2026"],[1,"flex","min-h-[10rem]","items-center","rounded-lg","border","border-dashed","border-border","bg-background-welcome","px-5","dark:border-white/10","dark:bg-ink-950"],["mode","inline","message","Refreshing rates\u2026"],["title","ErrorState","hint","Replace the content when the request failed and there is nothing useful to show. Retry is always present \u2014 wire (retry) to refetch.",3,"code"],[1,"grid","gap-4","md:grid-cols-2"],[1,"rounded-lg","border","border-border","bg-background-welcome","dark:border-white/10","dark:bg-ink-950"],["message","Failed to load shipments.",3,"retry"],["message","The rate service timed out after 30s. Check your network and try again.",3,"retry"],["title","ErrorIndicator","hint","Keep showing the last good data and put a small retry pill above the content when a background refresh fails.",3,"code"],[1,"flex","flex-col","gap-6"],[1,"flex","min-h-[8rem]","flex-col","gap-3","rounded-xl","border","border-border","bg-white","p-4","dark:border-white/10","dark:bg-ink-950"],[1,"flex","justify-end"],["error","Connection lost \u2014 showing cached data","retryText","Reconnect","refreshingText","Connecting...",1,"max-w-[min(100%,20rem)]",3,"retry","refreshing","disabled"],[1,"m-0","text-body-sm","text-neutral-600","dark:text-neutral-400"],["error","Error fetching currencies",1,"max-w-[min(100%,20rem)]",3,"retry"],["error","Failed to fetch the most recent data.","retryText","Refresh","refreshingText","Refreshing...",1,"max-w-[min(100%,20rem)]",3,"retry","refreshing"],["title","EmptyState","hint","The request succeeded, but there is nothing to show (no rows, no drafts). Wire Retry to clear filters or start a create flow.",3,"code"],["message","No shipments match your filters.",3,"retry"],["message","You have not created any drafts yet.",3,"retry"],["title","AsyncState playground","hint","One wrapper around a query result: first load and hard errors block the content; empty shows EmptyState; success renders your template; a background refetch keeps the list visible (use your own control, e.g. table Refresh). Switch scenarios to see each mapping.","badge","6 scenarios",3,"code"],["role","tablist","aria-label","Async scenario",1,"mb-5","inline-flex","max-w-full","flex-wrap","gap-1","rounded-lg","bg-background-welcome","p-1","dark:bg-ink-950"],["type","button","role","tab",1,"rounded-md","px-3","py-1.5","text-body-sm","transition-colors","duration-150",3,"class"],[1,"relative","min-h-[16rem]","overflow-hidden","rounded-xl","border","border-border","dark:border-white/10"],[3,"retry","state"],[1,"bg-white","dark:bg-ink-950"],[1,"flex","items-center","justify-between","gap-3","border-b","border-border","px-5","py-3.5","dark:border-white/10"],[1,"flex","items-center","gap-2.5","min-w-0"],[1,"inline-flex","size-8","shrink-0","items-center","justify-center","rounded-md","bg-export/10","text-export","dark:bg-export/15","dark:text-export-light"],["name","airplane",3,"size"],[1,"min-w-0"],[1,"m-0","text-body","font-medium","text-ink","dark:text-white"],[1,"m-0","text-caption","text-neutral-600","dark:text-neutral-400"],[1,"shrink-0","rounded-md","bg-background-welcome","px-2","py-0.5","text-caption","tabular-nums","text-neutral-600","dark:bg-white/10","dark:text-neutral-400"],[1,"m-0","list-none","divide-y","divide-border","p-0","dark:divide-white/10"],[1,"flex","items-center","gap-4","px-5","py-3.5","transition-colors","hover:bg-background-welcome/80","dark:hover:bg-white/[0.03]"],["role","status",1,"mt-3","m-0","inline-flex","items-center","gap-1.5","text-caption","text-neutral-600","dark:text-neutral-400"],["type","button","role","tab",1,"rounded-md","px-3","py-1.5","text-body-sm","transition-colors","duration-150",3,"click"],[1,"min-w-0","flex-1"],[1,"m-0","font-mono","text-body-sm","font-medium","tracking-tight","text-ink","dark:text-white"],[1,"m-0","mt-0.5","text-caption","text-neutral-600","dark:text-neutral-400"],[1,"hidden","text-caption","text-neutral-500","sm:inline","dark:text-neutral-500"],[1,"inline-flex","shrink-0","rounded-md","px-2","py-0.5","text-caption","font-medium"],["name","refresh",3,"size"]],template:function(i,e){i&1&&(ei(0,"div",0),Zf(1,"app-page-header",1),ei(2,"app-demo-section",2)(3,"div",3)(4,"div",4)(5,"p",5),MI(6," Block "),gc(),ei(7,"div",6),Zf(8,"africanies-loading-state",7),gc()(),ei(9,"div",4)(10,"p",5),MI(11," Inline "),gc(),ei(12,"div",8),Zf(13,"africanies-loading-state",9),gc()()()(),ei(14,"app-demo-section",10)(15,"div",11)(16,"div",12)(17,"africanies-error-state",13),tp("retry",function(){return e.onRetry("error-default")}),gc()(),ei(18,"div",12)(19,"africanies-error-state",14),tp("retry",function(){return e.onRetry("error-long")}),gc()()()(),ei(20,"app-demo-section",15)(21,"div",16)(22,"div",17)(23,"div",18)(24,"africanies-error-indicator",19),tp("retry",function(){return e.simulateReconnect()}),gc()(),ei(25,"p",20),MI(26," Socket feed panel \u2014 list remains interactive while the indicator prompts reconnect. "),gc()(),ei(27,"div",17)(28,"div",18)(29,"africanies-error-indicator",21),tp("retry",function(){return e.onRetry("error-indicator-currencies")}),gc()(),ei(30,"p",20),MI(31," Toolbar rates \u2014 default Retry label, no background refresh. "),gc()(),ei(32,"div",17)(33,"div",18)(34,"africanies-error-indicator",22),tp("retry",function(){return e.simulateStaleRefresh()}),gc()(),ei(35,"p",20),MI(36," Same pattern AsyncState uses for stale errors. "),gc()()()(),ei(37,"app-demo-section",23)(38,"div",11)(39,"africanies-empty-state",24),tp("retry",function(){return e.onRetry("empty")}),gc(),ei(40,"africanies-empty-state",25),tp("retry",function(){return e.onRetry("empty-drafts")}),gc()()(),ei(41,"app-demo-section",26)(42,"div",27),VE(43,V,2,4,"button",28,jE),gc(),ei(45,"div",29)(46,"africanies-async-state",30),tp("retry",function(){return e.setDemo("content")}),ei(47,"div",31)(48,"div",32)(49,"div",33)(50,"span",34),Zf(51,"africanies-icon",35),gc(),ei(52,"div",36)(53,"p",37),MI(54," Shipment list "),gc(),ei(55,"p",38),MI(56),gc()()(),ei(57,"span",39),MI(58),gc()(),ei(59,"ul",40),VE(60,W,10,6,"li",41,U),gc()()()(),LE(62,Y,3,2,"p",42),gc()()),i&2&&(Qy(2),Qf("code",e.loadingCode),Qy(12),Qf("code",e.errorCode),Qy(6),Qf("code",e.errorIndicatorCode),Qy(4),Qf("refreshing",e.reconnecting())("disabled",e.reconnecting()),Qy(10),Qf("refreshing",e.refreshingStale()),Qy(3),Qf("code",e.emptyCode),Qy(4),Qf("code",e.asyncCode),Qy(2),HE(e.demoKinds),Qy(3),Qf("state",e.asyncState()),Qy(5),Qf("size",16),Qy(5),Ic(" ",e.rowCount()," active consignments "),Qy(2),Ic(" ",e.rowCount()," "),Qy(2),HE(e.asyncState().data??FI(13,Q)),Qy(2),PE(e.lastRetry()?62:-1));},dependencies:[At,Tt,Dt,Mt,Cr,g,b$1,Ht],encapsulation:2})};export{j as FeedbackPage};
@@ -0,0 +1 @@
1
+ import {t as Oo,x as Do,J as Po,Q as Lo,H as Ht}from'./chunk-Cg7brw6x.js';import'./chunk-CZBTrY_H.js';import {b}from'./chunk-Cy-ZOZI8.js';import {C as Co,I as IE,Z,U as Gt,az as kr,aA as jt,H as Hs,e as ei,M as MI,a as gc,c as Zf,t as tp,Q as Qy,d as Qf}from'./main-WEJC3BLT.js';var k=class p{defaultCode=Oo;customTriggerCode=Do;placementCode=Po;formLabelCode=Lo;tracking=Co("");static \u0275fac=function(l){return new(l||p)};static \u0275cmp=IE({type:p,selectors:[["app-tooltip-page"]],decls:32,vars:5,consts:[[1,"pg-page-enter","flex","flex-col","gap-10"],["eyebrow","Components","title","Tooltip"],["description","",1,"m-0","text-body","text-neutral-600","dark:text-neutral-400"],["routerLink","/lecture","fragment","CDK",1,"pg-glossary-link"],["title","Default icon","hint","Drop the default info icon beside a field or label when a one-line explanation is enough.","subtext","Opens on hover, focus, or tap. Escape or an outside click closes a sticky tip.",3,"code"],[1,"flex","flex-wrap","items-center","gap-6"],[1,"inline-flex","items-center","gap-1.5","text-body","text-ink","dark:text-white"],["text","Coverage against loss or damage while the shipment is in transit."],["text","Created through the public shipping API rather than the portal UI.","icon","question-circle","ariaLabel","About API request"],["title","Custom trigger","hint","When you need a text link or button instead of the info icon, put africaniesTooltipTrigger on that control.","subtext","Use a focusable trigger (button or link) so keyboard users can open it.",3,"code"],["text","Required when the declared value exceeds $2,000."],["type","button","africanies-button","","africaniesTooltipTrigger","","variant","ghost","size","sm"],["title","Placement","hint","Prefer a side that fits the layout; the tip flips automatically if there is no room.","subtext","top (default), bottom, left, or right.",3,"code"],[1,"flex","flex-wrap","items-center","gap-8","py-6"],["text","Opens above when possible.","placement","top"],["text","Opens below when possible.","placement","bottom"],["text","Opens to the left.","placement","left"],["text","Opens to the right.","placement","right"],["title","Next to a form label","hint","Common pattern: label + tip on one row, input underneath \u2014 keeps long help out of the hint line.","subtext","Add ariaLabel on the icon when the visible label is not enough for screen readers.",3,"code"],[1,"flex","max-w-sm","flex-col","gap-1.5"],[1,"flex","items-center","gap-1.5"],[1,"text-body-sm","font-medium","text-ink","dark:text-white"],["text","Carrier AWB or internal shipment reference used on the warehouse floor.","icon","question-circle","ariaLabel","About tracking number"],["label","","placeholder","SFN-\u2026",3,"valueChange","value"]],template:function(l,i){l&1&&(ei(0,"div",0)(1,"app-page-header",1)(2,"p",2),MI(3," Short help next to a label or control when the UI is dense. Uses a "),ei(4,"a",3),MI(5,"CDK"),gc(),MI(6," connected overlay (same pattern as select / action menu). Default info icon, or mark your own element with africaniesTooltipTrigger. Opens on hover, focus, and click/tap. "),gc()(),ei(7,"app-demo-section",4)(8,"div",5)(9,"div",6),MI(10," Insured "),Zf(11,"africanies-tooltip",7),gc(),ei(12,"div",6),MI(13," API request "),Zf(14,"africanies-tooltip",8),gc()()(),ei(15,"app-demo-section",9)(16,"africanies-tooltip",10)(17,"button",11),MI(18," Why is this required? "),gc()()(),ei(19,"app-demo-section",12)(20,"div",13),Zf(21,"africanies-tooltip",14)(22,"africanies-tooltip",15)(23,"africanies-tooltip",16)(24,"africanies-tooltip",17),gc()(),ei(25,"app-demo-section",18)(26,"div",19)(27,"div",20)(28,"span",21),MI(29," Tracking number "),gc(),Zf(30,"africanies-tooltip",22),gc(),ei(31,"africanies-text-input",23),tp("valueChange",function(O){return i.tracking.set(O)}),gc()()()()),l&2&&(Qy(7),Qf("code",i.defaultCode),Qy(8),Qf("code",i.customTriggerCode),Qy(4),Qf("code",i.placementCode),Qy(6),Qf("code",i.formLabelCode),Qy(6),Qf("value",i.tracking()));},dependencies:[Z,Gt,kr,jt,b,Ht,Hs],encapsulation:2})};export{k as TooltipPage};
@@ -0,0 +1 @@
1
+ import {a,i,l,n,d,u}from'./chunk-CZBTrY_H.js';import {b}from'./chunk-Cy-ZOZI8.js';import {T,ah as Ee,aO as pt,b4 as qn,b5 as xe,C as Co,b6 as Cy,b7 as xi,b8 as Eh,ao as Q$1,I as IE,H as Hs,g,e as ei,c as Zf,M as MI,a as gc,V as VE,j as jE,t as tp,Q as Qy,b as HE,i as Ic,b9 as lp,d as Qf,J as zf,X as XE,F as FI,f as gp,L as LE,P as PE,aK as Hd}from'./main-WEJC3BLT.js';var k=()=>["/lecture"],z=(t,r)=>r.id,V=(t,r)=>r.href;function q(t,r){if(t&1&&(ei(0,"a",12)(1,"dt",13),MI(2),gc(),ei(3,"dd",14),MI(4),gc()()),t&2){let e=r.$implicit,i=XE();lp("pg-lecture-category-link--active",i.activeId()===i.categoryFragmentId(e)),Qf("routerLink",FI(6,k))("fragment",i.categoryFragmentId(e)),Qy(2),Ic(" ",i.categoryHeading(e)," "),Qy(2),Ic(" ",i.categoryMeta(e).description," ");}}function J(t,r){if(t&1&&(ei(0,"a",8),MI(1),gc()),t&2){let e=r.$implicit;Qf("routerLink",FI(3,k))("fragment",e.id),Qy(),Ic(" ",e.title," ");}}function K(t,r){if(t&1&&(ei(0,"p",26),MI(1),gc()),t&2){let e=r.$implicit;Qy(),Ic(" ",e," ");}}function W(t,r){if(t&1&&(ei(0,"pre",27)(1,"code"),MI(2),gc()()),t&2){let e=XE().$implicit;Qy(2),gp(e.example);}}function Q(t,r){if(t&1&&(ei(0,"a",31),MI(1),gc()),t&2){let e=r.$implicit;Qf("href",e.href,Hd),Qy(),Ic(" ",e.label," ");}}function X(t,r){if(t&1&&(ei(0,"div",28)(1,"span",30),MI(2," Docs "),gc(),VE(3,Q,2,2,"a",31,V),gc()),t&2){let e=XE().$implicit;Qy(3),HE(e.links);}}function Z(t,r){if(t&1&&(ei(0,"a",8),MI(1),gc()),t&2){let e=r.$implicit,i=XE(4);Qf("routerLink",FI(3,k))("fragment",e),Qy(),Ic(" ",i.titleFor(e)," ");}}function ee(t,r){if(t&1&&(ei(0,"div",29)(1,"span",30),MI(2," See also "),gc(),VE(3,Z,2,4,"a",8,jE),gc()),t&2){let e=XE().$implicit;Qy(3),HE(e.seeAlso);}}function te(t,r){if(t&1&&(ei(0,"article",20)(1,"header",21)(2,"div",22)(3,"h3",23),MI(4),gc(),ei(5,"p",24),MI(6),gc()(),ei(7,"span",25),MI(8),gc()(),VE(9,K,2,1,"p",26,jE),LE(11,W,3,1,"pre",27),LE(12,X,5,0,"div",28),LE(13,ee,5,0,"div",29),gc()),t&2){let e=r.$implicit,i=XE(2);lp("ring-2",i.activeId()===e.id)("ring-export",i.activeId()===e.id),Qf("id",e.id),Qy(4),Ic(" ",e.title," "),Qy(2),Ic(" ",e.summary," "),Qy(),Qf("title",i.categoryHeading(e.category)),Qy(),Ic(" ",e.category," "),Qy(),HE(i.paragraphs(e.detail)),Qy(2),PE(e.example?11:-1),Qy(),PE(e.links?.length?12:-1),Qy(),PE(e.seeAlso?.length?13:-1);}}function re(t,r){if(t&1&&(ei(0,"section",9)(1,"div",15)(2,"p",16),MI(3),gc(),ei(4,"h2",3),MI(5),gc(),ei(6,"p",17),MI(7),gc()(),ei(8,"div",18),VE(9,te,14,12,"article",19,z),gc()()),t&2){let e=r.$implicit,i=XE();Qf("id",i.categoryFragmentId(e)),Qy(3),gp(e),Qy(2),Ic(" ",i.categoryHeading(e)," "),Qy(2),Ic(" ",i.categoryMeta(e).description," "),Qy(2),HE(i.entriesFor(e));}}var j=class t{GLOSSARY_ENTRIES=a;GLOSSARY_CATEGORIES=i;categoryHeading=l;categoryMeta=n;categoryFragmentId=d;route=T(Ee);router=T(pt);document=T(qn);destroyRef=T(xe);activeId=Co(null);showScrollTop=Co(false);constructor(){Cy(()=>{let r=this.document.defaultView;if(!r)return;let e=()=>{this.showScrollTop.set(r.scrollY>320);};e(),xi(r,"scroll",{passive:true}).pipe(Eh(100),Q$1(this.destroyRef)).subscribe(()=>e()),this.route.fragment.subscribe(i=>{this.activeId.set(i),i&&queueMicrotask(()=>{this.document.getElementById(i)?.scrollIntoView({behavior:"smooth",block:"start"});});});});}scrollToTop(){this.document.defaultView?.scrollTo({top:0,behavior:"smooth"}),this.activeId.set(null),this.router.navigate([],{relativeTo:this.route,fragment:void 0,replaceUrl:true});}entriesFor(r){return u(r)}paragraphs(r){return r.split(/\n\n+/).filter(Boolean)}titleFor(r){return a.find(e=>e.id===r)?.title??r}static \u0275fac=function(e){return new(e||t)};static \u0275cmp=IE({type:t,selectors:[["app-lecture-page"]],decls:22,vars:6,consts:[[1,"pg-page-enter","relative","flex","flex-col","gap-10"],["eyebrow","Learn","title","Lecture","description","Plain-language notes on Angular and RxJS patterns used in the SDK. When a Show code panel highlights a term, it links here so you can look up what it means without leaving the playground."],[1,"rounded-xl","border","border-border","bg-white","p-5","dark:border-white/10","dark:bg-ink","sm:p-6"],[1,"m-0","text-heading-3","text-ink","dark:text-white"],[1,"mt-2","mb-4","text-body-sm","text-neutral-600","dark:text-neutral-400"],[1,"m-0","grid","gap-3","sm:grid-cols-2"],[1,"pg-lecture-category-link",3,"routerLink","fragment","pg-lecture-category-link--active"],[1,"flex","flex-wrap","gap-2"],[1,"pg-lecture-chip",3,"routerLink","fragment"],[1,"scroll-mt-24","flex","flex-col","gap-4",3,"id"],["type","button","aria-label","Scroll to top",1,"pg-lecture-scroll-top",3,"click","tabindex"],["name","chevron-up",3,"size"],[1,"pg-lecture-category-link",3,"routerLink","fragment"],[1,"m-0","font-medium","text-ink","dark:text-white"],[1,"m-0","mt-1","text-body-sm","text-neutral-600","dark:text-neutral-400"],[1,"flex","flex-col","gap-1"],[1,"pg-kicker","m-0"],[1,"m-0","text-body-sm","text-neutral-600","dark:text-neutral-400"],[1,"flex","flex-col","gap-4"],[1,"scroll-mt-24","rounded-xl","border","border-border","bg-white","p-5","dark:border-white/10","dark:bg-ink","sm:p-6",3,"id","ring-2","ring-export"],[1,"scroll-mt-24","rounded-xl","border","border-border","bg-white","p-5","dark:border-white/10","dark:bg-ink","sm:p-6",3,"id"],[1,"flex","flex-wrap","items-start","justify-between","gap-3"],[1,"flex","min-w-0","flex-col","gap-1"],[1,"m-0","font-mono","text-heading-3","text-ink","dark:text-white"],[1,"m-0","text-body-sm","font-medium","text-export","dark:text-export-light"],[1,"shrink-0","rounded-md","bg-background-welcome","px-2","py-0.5","text-caption","text-neutral-600","dark:bg-white/10","dark:text-neutral-400",3,"title"],[1,"mb-0","mt-3","text-body-sm","text-neutral-700","dark:text-neutral-300"],[1,"pg-lecture-example","mt-4","overflow-x-auto","rounded-lg","bg-[#1e1e1e]","p-4","font-mono","text-caption","leading-relaxed","text-[#d4d4d4]"],[1,"mt-4","flex","flex-wrap","items-baseline","gap-x-3","gap-y-1"],[1,"mt-4","flex","flex-wrap","items-center","gap-2"],[1,"text-caption","font-medium","uppercase","tracking-wide","text-neutral-500"],["target","_blank","rel","noopener noreferrer",1,"pg-glossary-link","text-body-sm","text-neutral-700","dark:text-neutral-300",3,"href"]],template:function(e,i){e&1&&(ei(0,"div",0),Zf(1,"app-page-header",1),ei(2,"section",2)(3,"h2",3),MI(4," Category abbreviations "),gc(),ei(5,"p",4),MI(6," Section labels use short names where docs usually do. Expanded forms are shown in parentheses. "),gc(),ei(7,"dl",5),VE(8,q,5,7,"a",6,jE),gc()(),ei(10,"section",2)(11,"h2",3),MI(12,"On this page"),gc(),ei(13,"p",4),MI(14),gc(),ei(15,"div",7),VE(16,J,2,4,"a",8,z),gc()(),VE(18,re,11,4,"section",9,jE),gc(),ei(20,"button",10),tp("click",function(){return i.scrollToTop()}),Zf(21,"africanies-icon",11),gc()),e&2&&(Qy(8),HE(i.GLOSSARY_CATEGORIES),Qy(6),Ic(" ",i.GLOSSARY_ENTRIES.length," entries \xB7 click a term in any implementation snippet to jump to its definition. "),Qy(2),HE(i.GLOSSARY_ENTRIES),Qy(2),HE(i.GLOSSARY_CATEGORIES),Qy(2),lp("pg-lecture-scroll-top--visible",i.showScrollTop()),Qf("tabindex",i.showScrollTop()?0:-1),zf("aria-hidden",i.showScrollTop()?null:true),Qy(),Qf("size",20));},dependencies:[Hs,b,g],encapsulation:2})};export{j as LecturePage};
@@ -0,0 +1 @@
1
+ import {b}from'./chunk-Cy-ZOZI8.js';import {C as Co,I as IE,H as Hs,Z,U as Gt,e as ei,c as Zf,t as tp,a8 as Ep,a as gc,M as MI,Q as Qy,ab as vp,a9 as AI}from'./main-WEJC3BLT.js';var h=class m{email=Co("");password=Co("");static \u0275fac=function(o){return new(o||m)};static \u0275cmp=IE({type:m,selectors:[["app-onboarding-login-page"]],decls:18,vars:2,consts:[[1,"pg-page-enter","mx-auto","flex","w-full","max-w-lg","flex-col","gap-8"],["eyebrow","Use cases","title","Login","description","Product path /onboarding/login. Forgot Password? is email-only \u2014 it never opens a new-password form for the emailed link."],[1,"flex","flex-col","gap-4","rounded-xl","border","border-border","bg-white","p-6","dark:border-white/10","dark:bg-ink",3,"submit"],["type","email","label","Email","autocomplete","email",3,"valueChange","value"],["type","password","label","Password","autocomplete","current-password",3,"valueChange","value"],[1,"flex","justify-end"],["routerLink","/usecases/onboarding/forgot-password",1,"cursor-pointer","text-body-sm","font-medium","text-ink","underline-offset-2","hover:underline","dark:text-white"],["africanies-button","","type","submit","variant","primary"],[1,"m-0","text-caption","text-neutral-600","dark:text-neutral-400"],[1,"font-mono"],["routerLink","/usecases/onboarding/reset-password",1,"cursor-pointer","font-medium","text-ink","underline-offset-2","hover:underline","dark:text-white"]],template:function(o,i){o&1&&(ei(0,"div",0),Zf(1,"app-page-header",1),ei(2,"form",2),tp("submit",function(t){return t.preventDefault()}),ei(3,"africanies-text-input",3),Ep("valueChange",function(t){return AI(i.email,t)||(i.email=t),t}),gc(),ei(4,"africanies-text-input",4),Ep("valueChange",function(t){return AI(i.password,t)||(i.password=t),t}),gc(),ei(5,"div",5)(6,"a",6),MI(7," Forgot Password? "),gc()(),ei(8,"button",7),MI(9,"Sign in"),gc(),ei(10,"p",8),MI(11," After a real login, if "),ei(12,"code",9),MI(13,"user.default_password"),gc(),MI(14," is set, send the user to "),ei(15,"a",10),MI(16,"/onboarding/reset-password"),gc(),MI(17," to change current \u2192 new password. That is not this forgot-password flow. "),gc()()()),o&2&&(Qy(3),vp("value",i.email),Qy(),vp("value",i.password));},dependencies:[Hs,Z,Gt,b],encapsulation:2})};export{h as OnboardingLoginPage};
@@ -0,0 +1 @@
1
+ import {r}from'./chunk-CjYlnYC7.js';import {ao as qi,ap as $i,aq as Ki,ar as Yi,as as Zi,at as Qi,au as Xi,av as er,aw as tr,ax as nr,ay as ar,az as ir,aA as rr,aB as or,aC as Ji,aD as sr,H as Ht}from'./chunk-Cg7brw6x.js';import'./chunk-CZBTrY_H.js';import {b as b$1}from'./chunk-Cy-ZOZI8.js';import {bc as Ua,bd as Ga,be as $a,bf as Wa,bg as qa,bh as Ya,bi as Ka,bj as Qa,bk as Xa,bl as Za,bm as $i$1,bn as qi$1,bo as es,bp as rs,bq as zi,br as Ki$1,bs as Qi$1,bt as Xi$1,bu as Un,bv as er$1,bw as lo,bx as ja,I as IE,H as Hs,e as ei,c as Zf,M as MI,a as gc,V as VE,Q as Qy,d as Qf,b as HE,T,a$ as Ui,C as Co,u as QI,b0 as za,b1 as lh,x as xr,Z,U as Gt,t as tp,L as LE,P as PE,f as gp,i as Ic,J as zf,G as GE,a8 as Ep,X as XE,ab as vp,p as Gl,a9 as AI,z as zl}from'./main-WEJC3BLT.js';function we(a,o){a&1&&(Zf(0,"africanies-alert",3),ei(1,"a",4),MI(2," Reset completed? Login here "),gc()),a&2&&Qf("message",o)("dismissible",false);}function Re(a,o){a&1&&Zf(0,"africanies-alert",5),a&2&&Qf("message",o)("dismissible",false);}function ke(a,o){if(a&1){let n=GE();LE(0,Re,1,2,"africanies-alert",5),ei(1,"div",6)(2,"africanies-text-input",7),Ep("valueChange",function(c){Gl(n);let y=XE();return AI(y.email,c)||(y.email=c),zl(c)}),gc(),ei(3,"button",8),MI(4," Send reset link "),gc()();}if(a&2){let n,d=XE();PE((n=d.errorMessage())?0:-1,n),Qy(2),vp("value",d.email),Qy(),Qf("loading",d.sending())("disabled",!d.canSubmit());}}var b=class a{authApi=T(Ui);email=Co("");sending=Co(false);successMessage=Co(null);errorMessage=Co(null);canSubmit=QI(()=>za(this.email())&&!this.sending());async forgot(){if(this.canSubmit()){this.sending.set(true),this.errorMessage.set(null);try{let o=await lh(this.authApi.forgot(this.email()));if(o.success){this.successMessage.set(o.message?.trim()||"We have emailed your reset password.");return}this.errorMessage.set(o.message?.trim()||"Could not send a reset email.");}catch(o){this.errorMessage.set(r(o));}finally{this.sending.set(false);}}}static \u0275fac=function(n){return new(n||a)};static \u0275cmp=IE({type:a,selectors:[["app-playground-forgot-password"]],decls:7,vars:1,consts:[[1,"mt-5","flex","flex-col","gap-3","rounded-xl","border","border-border","bg-background-welcome","p-4","dark:border-white/10","dark:bg-white/[0.03]",3,"submit"],[1,"m-0","text-body-sm","font-medium","text-ink","dark:text-white"],[1,"m-0","text-caption","text-neutral-600","dark:text-neutral-400"],["variant","success",3,"message","dismissible"],["routerLink","/usecases/onboarding/login",1,"cursor-pointer","text-body-sm","font-medium","text-ink","underline-offset-2","hover:underline","dark:text-white"],["variant","danger",3,"message","dismissible"],[1,"flex","flex-col","gap-3","sm:flex-row","sm:items-end"],["type","email","label","Email","autocomplete","email","placeholder","you@example.com",1,"min-w-0","flex-1",3,"valueChange","value"],["africanies-button","","type","submit","variant","primary","size","sm",1,"shrink-0",3,"loading","disabled"]],template:function(n,d){if(n&1&&(ei(0,"form",0),tp("submit",function(y){return y.preventDefault(),d.forgot()}),ei(1,"p",1),MI(2," Try it "),gc(),ei(3,"p",2),MI(4," We will send you a password reset link. "),gc(),LE(5,we,3,2)(6,ke,5,4),gc()),n&2){let c;Qy(5),PE((c=d.successMessage())?5:6,c);}},dependencies:[xr,Z,Gt,Hs],encapsulation:2})};var S=(a,o)=>o.id;function De(a,o){if(a&1&&(ei(0,"tr",11)(1,"td",16)(2,"code",17),MI(3),gc()(),ei(4,"td",18),MI(5),gc(),ei(6,"td",16)(7,"code",19),MI(8),gc()(),ei(9,"td",16)(10,"code",19),MI(11),gc()(),ei(12,"td",20)(13,"code",19),MI(14),gc()()()),a&2){let n=o.$implicit;Qy(3),gp(n.id),Qy(2),Ic(" ",n.meaning," "),Qy(3),gp(n.path),Qy(3),gp(n.serviceCall),Qy(3),gp(n.customCall);}}function Ne(a,o){if(a&1&&(ei(0,"dt",25),MI(1," Calls "),gc(),ei(2,"dd",29)(3,"span"),MI(4),gc(),ei(5,"span"),MI(6),gc(),ei(7,"span"),MI(8),gc()()),a&2){let n=o;Qy(4),gp(n.page),Qy(2),gp(n.all),Qy(2),gp(n.byId);}}function Fe(a,o){if(a&1&&(ei(0,"dt",25),MI(1," Returns "),gc(),ei(2,"dd",26),MI(3),gc()),a&2){let n=XE().$implicit;Qy(3),Ic(" ",n.returns," ");}}function Oe(a,o){a&1&&Zf(0,"app-playground-forgot-password");}function He(a,o){if(a&1&&(ei(0,"app-demo-section",23)(1,"dl",24)(2,"dt",25),MI(3," Path "),gc(),ei(4,"dd",26),MI(5),gc(),LE(6,Ne,9,3),LE(7,Fe,4,1),ei(8,"dt",25),MI(9," Model "),gc(),ei(10,"dd",27)(11,"a",28),MI(12),gc()()(),LE(13,Oe,1,0,"app-playground-forgot-password"),gc()),a&2){let n,d=o.$implicit;Qf("anchorId",d.id)("title",d.title)("hint",d.hint)("code",d.code),Qy(5),Ic(" ",d.path," "),Qy(),PE((n=d.resourceCalls)?6:-1,n),Qy(),PE(d.returns?7:-1),Qy(4),Qf("fragment",d.modelAnchor),Qy(),gp(d.modelLabel),Qy(),PE(d.id==="auth"?13:-1);}}function Le(a,o){if(a&1&&(ei(0,"section",15)(1,"div",21)(2,"h2",22),MI(3),gc(),ei(4,"p",3),MI(5),gc()(),VE(6,He,14,10,"app-demo-section",23,S),gc()),a&2){let n=o.$implicit;zf("id",n.id),Qy(3),Ic(" ",n.title," "),Qy(2),Ic(" ",n.hint," "),Qy(),HE(n.services);}}var Me=class a{overviewCode=qi;resourceIdRows=[{id:"null",meaning:"Paginated page",path:"{base}",serviceCall:"read() / readPage({ page })",customCall:"getResourcePage(base, query)"},{id:"'all'",meaning:"Full list, not paginated",path:"{base}/all",serviceCall:"read('all') / readAll()",customCall:"getResourceAll(base)"},{id:"number",meaning:"Single matching record",path:"{base}/{id}",serviceCall:"read(42) / readById(42)",customCall:"getResourceById(base, 42)"}];serviceGroups=[{id:"reference-data",title:"Reference data",hint:"Catalog GETs that follow ResourceId \u2014 page, all, or by id.",services:[{id:"country",title:"CountryService",hint:"Public countries for destination pickers and address forms.",path:`GET ${Ua}/{id?}`,modelAnchor:"country",modelLabel:"CountryModel",resourceCalls:{page:"readPage({ page }) \u2192 CountryModel[]",all:"readAll() \u2192 CountryModel[]",byId:"readById(n) \u2192 CountryModel"},code:$i},{id:"service",title:"ServiceService",hint:"Public App Settings subscription/add-on services. No auth required \u2014 same catalog the admin boards use for Services, Plans, and Plan Packages.",path:`GET ${Ga}/{id?}`,modelAnchor:"service",modelLabel:"ServiceModel",resourceCalls:{page:"readPage({ page, order, search, from, to }) \u2192 ServiceModel[]",all:"readAll() \u2192 ServiceModel[]",byId:"readById(n) \u2192 ServiceModel"},code:Ki},{id:"document",title:"DocumentService",hint:"Document catalog by numeric id \u2014 preview via readById \u2192 data.file_ref.base_64. For raw file_ref strings on records, use FileService.",path:`GET ${$a}/{id?}`,modelAnchor:"document",modelLabel:"DocumentModel",resourceCalls:{page:"readPage({ page, order, search, from, to }) \u2192 DocumentModel[]",all:"readAll() \u2192 DocumentModel[]",byId:"readById(n) \u2192 DocumentModel (file_ref preview)"},code:Yi},{id:"plan",title:"PlanService",hint:"Public subscription plans with nested packages. Authenticated create/update/delete use api/plan/*.",path:`GET ${Wa}/{id?}`,modelAnchor:"plan",modelLabel:"PlanModel",resourceCalls:{page:"readPage({ page, order, search, from, to }) \u2192 PlanModel[]",all:"readAll() \u2192 PlanModel[]",byId:"readById(n) \u2192 PlanModel"},code:Zi},{id:"currency",title:"CurrencyService",hint:"App Settings currencies. PaymentMethodService.readPage() fills create/update checkboxes. Create name/code come from the host list, not GET. After each write, show res.message and readPage again.",path:`GET ${qa}/{id?} \xB7 POST ${Ya} \xB7 PUT ${Ka} \xB7 DELETE ${Qa}`,modelAnchor:"currency",modelLabel:"CurrencyModel",resourceCalls:{page:"readPage({ page, order, search, from, to }) \u2192 CurrencyModel[]",all:"readAll() \u2192 CurrencyModel[]",byId:"readById(n) \u2192 CurrencyModel"},returns:"create(body) \xB7 update(body) \xB7 remove({ id }) \u2192 ApiResponseModel",code:Qi},{id:"payment-method",title:"PaymentMethodService",hint:"App Settings payment methods. Read + active toggle only (no create/delete). After update, show res.message and patch that row\u2019s updated_at \u2014 do not reload the list. Processors are linked from Currencies via payment_method_ids.",path:`GET ${Xa}/{id?} \xB7 PUT ${Za}`,modelAnchor:"payment-method",modelLabel:"PaymentMethodModel",resourceCalls:{page:"readPage({ page, order, search, from, to }) \u2192 PaymentMethodModel[]",all:"readAll() \u2192 PaymentMethodModel[]",byId:"readById(n) \u2192 PaymentMethodModel"},returns:"update({ id, name, model, active }) \u2192 ApiResponseModel",code:Xi},{id:"shipment-method",title:"ShipmentMethodService",hint:"Carriers with delivery windows and zone values.",path:`GET ${$i$1}/{id?}`,modelAnchor:"shipment-method",modelLabel:"ShipmentMethodModel",resourceCalls:{page:"readPage({ page }) \u2192 ShipmentMethodModel[]",all:"readAll() \u2192 ShipmentMethodModel[]",byId:"readById(n) \u2192 ShipmentMethodModel"},code:er},{id:"warehouse",title:"WarehouseService",hint:"Warehouse locations with address, charges, and nested country.",path:`GET ${qi$1}/{id?}`,modelAnchor:"warehouse",modelLabel:"WarehouseModel",resourceCalls:{page:"readPage({ page }) \u2192 WarehouseModel[]",all:"readAll() \u2192 WarehouseModel[]",byId:"readById(n) \u2192 WarehouseModel"},code:tr},{id:"zone",title:"ZoneService",hint:"Shipping zones for routing and pricing rules.",path:`GET ${es}/{id?}`,modelAnchor:"zone",modelLabel:"ZoneModel",resourceCalls:{page:"readPage({ page }) \u2192 ZoneModel[]",all:"readAll() \u2192 ZoneModel[]",byId:"readById(n) \u2192 ZoneModel"},code:nr},{id:"product",title:"ProductService",hint:"Catalog products with HS codes and document / ETW labels.",path:`GET ${rs}/{id?}`,modelAnchor:"product",modelLabel:"ProductModel",resourceCalls:{page:"readPage({ page }) \u2192 ProductModel[]",all:"readAll() \u2192 ProductModel[]",byId:"readById(n) \u2192 ProductModel"},code:ar}]},{id:"session-config",title:"Session & config",hint:"Auth email flows, current user, and STN/SFN region units \u2014 not ResourceId list reads.",services:[{id:"auth",title:"AuthService",hint:"Email-only. POST { email } \u2014 backend emails a reset link. This UI never collects a new password for that link. Admins reuse forgot(email).",path:`POST ${zi}`,modelAnchor:"auth",modelLabel:"ForgotPasswordRequestModel",returns:"forgot(email) \u2192 ApiResponseModel<unknown[]>",code:ir},{id:"user",title:"UserService",hint:"Current user. Call AuthTokenService.set(access_token) after login. If user.default_password, send them to /onboarding/reset-password (not the email-link flow). Logout: POST while the token is set, then AuthTokenService.clear().",path:`GET ${Ki$1} \xB7 POST ${Qi$1} \xB7 POST ${Xi$1}`,modelAnchor:"user",modelLabel:"UserModel",returns:"me() \u2192 UserModel \xB7 changePassword(body) \u2192 ApiResponseModel \xB7 logoutFromAllSessions() \u2192 ApiResponseModel",code:rr},{id:"notification",title:"NotificationService",hint:"Authenticated inbox for the header bell \u2014 readPage for badge + drawer infinite scroll.",path:`GET ${Un}/{id?} \xB7 PUT ${er$1}`,modelAnchor:"notification",modelLabel:"NotificationModel",resourceCalls:{page:"readPage({ page }) \u2192 NotificationModel[]",all:"readAll() \u2192 NotificationModel[]",byId:"readOne(uuid) \u2192 NotificationModel"},returns:"markRead(id?) \u2192 ApiResponseModel ({} marks all read)",code:or},{id:"mode-config",title:"ModeConfigService",hint:"Region currency and units for STN/SFN \u2014 usually loaded at startup.",path:`GET ${lo}`,modelAnchor:"mode-config",modelLabel:"ModeConfigDataModel",returns:"loadConfig() \u2192 ModeConfigDataModel",code:Ji}]},{id:"files",title:"Files",hint:"Single-object file resolve \u2014 not a list, not paginated.",services:[{id:"file",title:"FileService",hint:"Primary preview when a record stores file_ref \u2014 POST { ref }. Waybills: readMultiple(ref) \u2192 POST ?multiple=yes.",path:`POST ${ja} \xB7 POST ${ja}?multiple=yes`,modelAnchor:"file",modelLabel:"FileReadModel",returns:"read(ref) \u2192 FileReadModel \xB7 readMultiple(ref) \u2192 FileReadModel[]",code:sr}]}];static \u0275fac=function(n){return new(n||a)};static \u0275cmp=IE({type:a,selectors:[["app-api-page"]],decls:61,vars:1,consts:[[1,"pg-page-enter","flex","flex-col","gap-10"],["eyebrow","Foundation","title","SDK API","description","How to call built-in services and custom list GETs. Bootstrap once, learn ResourceId, then pick a service. Field shapes live under Foundation \u2192 Models."],["title","Bootstrap","hint","Wire the SDK once: provideAfricaniesSdk (base URL) and provideAfricaniesHttpClient (interceptors). Relative paths resolve against baseUrl.",3,"code"],[1,"m-0","text-body-sm","text-neutral-600","dark:text-neutral-400"],["anchorId","resource-id","title","ResourceId","hint","Every list-style GET uses the same id segment. Built-in reference services and custom ApiClient calls share this rule."],[1,"flex","flex-col","gap-5"],[1,"overflow-x-auto"],[1,"w-full","min-w-[36rem]","border-collapse","text-left","text-body-sm"],[1,"border-b","border-border","text-caption","uppercase","tracking-wide","text-neutral-500","dark:border-white/10"],[1,"py-2","pr-4","font-medium"],[1,"py-2","font-medium"],[1,"border-b","border-border/70","last:border-0","dark:border-white/10"],[1,"m-0","text-caption","text-neutral-500","dark:text-neutral-400"],[1,"font-mono"],["routerLink","/models","fragment","pagination",1,"font-medium","text-ink","underline-offset-2","hover:underline","dark:text-white"],[1,"flex","flex-col","gap-6"],[1,"py-3","pr-4","align-top"],[1,"font-mono","text-ink","dark:text-white"],[1,"py-3","pr-4","align-top","text-neutral-600","dark:text-neutral-400"],[1,"font-mono","text-caption","text-ink","dark:text-white"],[1,"py-3","align-top"],[1,"flex","flex-col","gap-1","border-b","border-border","pb-3","dark:border-white/10"],[1,"m-0","text-heading-3","text-ink","dark:text-white"],[3,"anchorId","title","hint","code"],[1,"m-0","grid","gap-3","text-body-sm","sm:grid-cols-[7rem_1fr]","sm:gap-x-4","sm:gap-y-3"],[1,"m-0","text-caption","font-medium","uppercase","tracking-wide","text-neutral-500"],[1,"m-0","font-mono","text-ink","dark:text-white"],[1,"m-0"],["routerLink","/models",1,"font-mono","text-ink","underline-offset-2","hover:underline","dark:text-white",3,"fragment"],[1,"m-0","flex","flex-col","gap-1.5","font-mono","text-caption","text-ink","dark:text-white"]],template:function(n,d){n&1&&(ei(0,"div",0),Zf(1,"app-page-header",1),ei(2,"app-demo-section",2)(3,"p",3),MI(4," After setup, inject a domain service below \u2014 or use ApiClient helpers for custom routes. "),gc()(),ei(5,"app-demo-section",4)(6,"div",5)(7,"div",6)(8,"table",7)(9,"thead")(10,"tr",8)(11,"th",9),MI(12,"id"),gc(),ei(13,"th",9),MI(14,"Meaning"),gc(),ei(15,"th",9),MI(16,"Path"),gc(),ei(17,"th",9),MI(18,"Service"),gc(),ei(19,"th",10),MI(20,"Custom"),gc()()(),ei(21,"tbody"),VE(22,De,15,5,"tr",11,S),gc()()(),ei(24,"p",12),MI(25," Paginated calls may send "),ei(26,"code",13),MI(27,"page"),gc(),MI(28," / "),ei(29,"code",13),MI(30,"size"),gc(),MI(31," / "),ei(32,"code",13),MI(33,"order"),gc(),MI(34,". Page size defaults to "),ei(35,"code",13),MI(36,"15"),gc(),MI(37," when omitted (UI sizes: "),ei(38,"code",13),MI(39,"5"),gc(),MI(40," / "),ei(41,"code",13),MI(42,"15"),gc(),MI(43," / "),ei(44,"code",13),MI(45,"30"),gc(),MI(46,"). Notifications default to "),ei(47,"code",13),MI(48,"30"),gc(),MI(49,". Bind "),ei(50,"code",13),MI(51,"res.pagination"),gc(),MI(52," to "),ei(53,"code",13),MI(54,"africanies-pagination"),gc(),MI(55,". Shapes: "),ei(56,"a",14),MI(57,"Pagination & ResourceId"),gc(),MI(58,". "),gc()()(),VE(59,Le,8,3,"section",15,S),gc()),n&2&&(Qy(2),Qf("code",d.overviewCode),Qy(20),HE(d.resourceIdRows),Qy(37),HE(d.serviceGroups));},dependencies:[b$1,Ht,Hs,b],encapsulation:2})};export{Me as ApiPage};
@@ -0,0 +1 @@
1
+ import {S}from'./chunk-CtndMAe2.js';import {T,ah as Ee,aP as Y,aS as ve,u as QI,I as IE,w as wr,e as ei,L as LE,a as gc,Q as Qy,P as PE,M as MI,X as XE,i as Ic,d as Qf}from'./main-WEJC3BLT.js';function E(p,r){if(p&1&&(ei(0,"div",2)(1,"div")(2,"p",3),MI(3," Shipment "),gc(),ei(4,"p",4),MI(5),gc(),ei(6,"p",5),MI(7),gc()(),ei(8,"africanies-chip",6),MI(9),gc()(),ei(10,"dl",7)(11,"div")(12,"dt",8),MI(13,"Origin"),gc(),ei(14,"dd",9),MI(15),gc()(),ei(16,"div")(17,"dt",8),MI(18,"Destination"),gc(),ei(19,"dd",9),MI(20),gc()(),ei(21,"div")(22,"dt",8),MI(23,"Updated"),gc(),ei(24,"dd",9),MI(25),gc()()(),ei(26,"p",5),MI(27," The chevron and breadcrumbs above are provided by the SDK \u2014 this page does not add them. List filters and page stay on the query string; Back returns to "),ei(28,"code",10),MI(29," /usecases/shipment "),gc(),MI(30," with those queries intact. Paste "),ei(31,"code",10),MI(32),gc(),MI(33," in a new tab and Back still appears. "),gc()),p&2){let n=r,o=XE();Qy(5),Ic(" ",n.reference," "),Qy(2),Ic(" ",n.route," "),Qy(),Qf("variant",o.statusVariant(n.status)),Qy(),Ic(" ",n.status," "),Qy(6),Ic(" ",n.origin," "),Qy(5),Ic(" ",n.destination," "),Qy(5),Ic(" ",n.updated," "),Qy(7),Ic(" /usecases/shipment/",n.reference," ");}}function w(p,r){p&1&&(ei(0,"p",1),MI(1," Unknown shipment. "),gc());}var k=class p{route=T(Ee);reference=Y(this.route.paramMap.pipe(ve(r=>r.get("id")??"")),{initialValue:this.route.snapshot.paramMap.get("id")??""});shipment=QI(()=>S(this.reference()));statusVariant(r){switch(r){case "Delivered":return "success";case "Exception":return "danger";case "Pending":return "warning";default:return "neutral"}}static \u0275fac=function(n){return new(n||p)};static \u0275cmp=IE({type:p,selectors:[["app-shipment-detail-page"]],decls:3,vars:1,consts:[[1,"pg-page-enter","flex","flex-col","gap-6"],[1,"m-0","text-body","text-neutral-600","dark:text-neutral-400"],[1,"flex","flex-wrap","items-start","justify-between","gap-3"],[1,"m-0","text-caption","uppercase","tracking-wide","text-neutral-500"],[1,"m-0","text-heading-3","text-ink","dark:text-white"],[1,"m-0","text-body-sm","text-neutral-600","dark:text-neutral-400"],[3,"variant"],[1,"grid","gap-4","rounded-xl","border","border-border","bg-white","px-5","py-4","sm:grid-cols-3","dark:border-white/10","dark:bg-ink"],[1,"text-caption","text-neutral-500"],[1,"m-0","mt-0.5","text-body-sm","font-medium","text-ink","dark:text-white"],[1,"rounded","bg-background-welcome","px-1","py-0.5","dark:bg-ink-950"]],template:function(n,o){if(n&1&&(ei(0,"div",0),LE(1,E,34,8)(2,w,2,0,"p",1),gc()),n&2){let m;Qy(),PE((m=o.shipment())?1:2,m);}},dependencies:[wr],encapsulation:2})};export{k as ShipmentDetailPage};
@@ -0,0 +1 @@
1
+ import {I as IE,aZ as pi,c as Zf}from'./main-WEJC3BLT.js';var o=class a{static \u0275fac=function(e){return new(e||a)};static \u0275cmp=IE({type:a,selectors:[["app-onboarding-usecase-page"]],decls:1,vars:0,template:function(e,i){e&1&&Zf(0,"router-outlet");},dependencies:[pi],encapsulation:2})};export{o as OnboardingUsecasePage};
@@ -0,0 +1 @@
1
+ import {af as Qr,ag as io,ah as ro,ai as no,aj as to,ak as eo,al as Jr,am as Xr,H as Ht}from'./chunk-Cg7brw6x.js';import'./chunk-CZBTrY_H.js';import {b}from'./chunk-Cy-ZOZI8.js';import {I as IE,e as ei,c as Zf,M as MI,a as gc,V as VE,j as jE,Q as Qy,d as Qf,b as HE,X as XE,m as mI,i as Ic}from'./main-WEJC3BLT.js';var I=(i,a)=>a.name;function v(i,a){if(i&1&&(ei(0,"div",26),Zf(1,"div",27),ei(2,"div",28)(3,"p",29),MI(4),gc(),ei(5,"p",30),MI(6),gc()()()),i&2){let r=a.$implicit;Qy(),mI(r.bgClass),Qy(3),Ic(" ",r.name," "),Qy(2),Ic(" ",r.hex," ");}}function _(i,a){if(i&1&&(ei(0,"app-demo-section",5)(1,"div",25),VE(2,v,7,4,"div",26,I),gc()()),i&2){let r=a.$implicit,s=XE();Qf("title",r)("badge",s.countIn(r)+" tokens")("code",s.codeForGroup(r)),Qy(2),HE(s.colorsIn(r));}}var F=class i{groups=["Core","Neutral","Export (SFN)","Import (STN)","Feedback"];setupCode=Qr;typeCode=io;modeAccentsCode=ro;groupCode={Core:Xr,Neutral:Jr,"Export (SFN)":eo,"Import (STN)":to,Feedback:no};codeForGroup(a){return this.groupCode[a]??this.setupCode}colors=[{name:"black",bgClass:"bg-black",hex:"#000000",group:"Core"},{name:"white",bgClass:"bg-white",hex:"#ffffff",group:"Core"},{name:"ink",bgClass:"bg-ink",hex:"#212529",group:"Core"},{name:"ink-blue",bgClass:"bg-ink-blue",hex:"#192a3e",group:"Core"},{name:"ink-brand",bgClass:"bg-ink-brand",hex:"#1c2b3f",group:"Core"},{name:"ink-950",bgClass:"bg-ink-950",hex:"#272729",group:"Core"},{name:"neutral-300",bgClass:"bg-neutral-300",hex:"#c9d5e1",group:"Neutral"},{name:"neutral-400",bgClass:"bg-neutral-400",hex:"#a9b5cb",group:"Neutral"},{name:"neutral-600",bgClass:"bg-neutral-600",hex:"#667185",group:"Neutral"},{name:"border",bgClass:"bg-border",hex:"#c9d5e1",group:"Neutral"},{name:"background-welcome",bgClass:"bg-background-welcome",hex:"#f9fafb",group:"Neutral"},{name:"export",bgClass:"bg-export",hex:"#1cbd5d",group:"Export (SFN)"},{name:"export-light",bgClass:"bg-export-light",hex:"#24dc6d",group:"Export (SFN)"},{name:"export-subtle",bgClass:"bg-export-subtle",hex:"#e4fff3",group:"Export (SFN)"},{name:"export-tint",bgClass:"bg-export-tint",hex:"#f2fff8",group:"Export (SFN)"},{name:"import",bgClass:"bg-import",hex:"#f08829",group:"Import (STN)"},{name:"import-light",bgClass:"bg-import-light",hex:"#ffa95b",group:"Import (STN)"},{name:"import-subtle",bgClass:"bg-import-subtle",hex:"#fffcef",group:"Import (STN)"},{name:"danger",bgClass:"bg-danger",hex:"#ff001c",group:"Feedback"},{name:"danger-dark",bgClass:"bg-danger-dark",hex:"#b41433",group:"Feedback"},{name:"danger-strong",bgClass:"bg-danger-strong",hex:"#C00B19",group:"Feedback"},{name:"danger-subtle",bgClass:"bg-danger-subtle",hex:"#FFF2F2",group:"Feedback"},{name:"warning",bgClass:"bg-warning",hex:"#DBB316",group:"Feedback"},{name:"warning-dark",bgClass:"bg-warning-dark",hex:"#EF8833",group:"Feedback"},{name:"warning-subtle",bgClass:"bg-warning-subtle",hex:"#FFF6E6",group:"Feedback"}];colorsIn(a){return this.colors.filter(r=>r.group===a)}countIn(a){return this.colorsIn(a).length}static \u0275fac=function(r){return new(r||i)};static \u0275cmp=IE({type:i,selectors:[["app-tokens-page"]],decls:71,vars:3,consts:[[1,"pg-page-enter","flex","flex-col","gap-10"],["eyebrow","Foundation","title","Design tokens","description","Color and type from the Tailwind preset (@africanies/africanies-theme). Use these classes so product UIs match. Flip STN/SFN in the sidebar to see Import/Export accents. Open Show code for setup notes."],["title","Tailwind setup","hint","One-time consumer setup: extend the AFRICANIES preset and scan @africanies/africanies-ui so JIT does not purge library classes.",3,"code"],[1,"m-0","text-body-sm","text-neutral-600","dark:text-neutral-400"],[1,"pg-code"],[3,"title","badge","code"],["title","Typography scale","hint","Shared type sizes for headings, body, and captions across product UIs. Scale is provisional pending design sign-off.",3,"code"],[1,"m-0","flex","list-none","flex-col","gap-5","p-0"],[1,"pg-kicker","m-0","mb-1"],[1,"m-0","text-heading-1","text-ink","dark:text-white"],[1,"m-0","text-heading-2","text-ink","dark:text-white"],[1,"m-0","text-heading-3","text-ink","dark:text-white"],[1,"m-0","text-body-lg","text-ink","dark:text-white"],[1,"m-0","text-body","text-ink","dark:text-white"],[1,"m-0","text-body-sm","text-neutral-600"],[1,"m-0","text-caption","text-neutral-600"],["title","Mode accents in context","hint","How Export (SFN green) and Import (STN orange) show up on real surfaces. Flip mode in the sidebar and compare with primary buttons.","muted","",3,"code"],[1,"m-0","mb-4","text-body-sm","text-neutral-600","dark:text-neutral-400"],[1,"grid","gap-4","sm:grid-cols-2"],[1,"rounded-xl","bg-export-subtle","p-5"],[1,"m-0","text-caption","font-medium","uppercase","tracking-wide","text-export"],[1,"mt-2","m-0","text-heading-3","text-ink","dark:text-ink"],[1,"mt-1","m-0","text-body-sm","text-neutral-600"],[1,"rounded-xl","bg-import-subtle","p-5"],[1,"m-0","text-caption","font-medium","uppercase","tracking-wide","text-import"],[1,"grid","gap-3",2,"grid-template-columns","repeat(auto-fill, minmax(9.5rem, 1fr))"],[1,"overflow-hidden","rounded-xl","border","border-border","dark:border-white/10"],[1,"h-20","border-b","border-border","dark:border-white/10"],[1,"bg-white","px-3","py-2.5","dark:bg-ink"],[1,"m-0","text-body-sm","font-medium","text-ink","dark:text-white"],[1,"m-0","mt-0.5","font-mono","text-caption","text-neutral-600"]],template:function(r,s){r&1&&(ei(0,"div",0),Zf(1,"app-page-header",1),ei(2,"app-demo-section",2)(3,"p",3),MI(4," Extend the AFRICANIES theme preset and scan both your app sources and the published "),ei(5,"span",4),MI(6,"@africanies/africanies-ui"),gc(),MI(7," bundle so JIT keeps classes used inside the library. "),gc()(),VE(8,_,4,3,"app-demo-section",5,jE),ei(10,"app-demo-section",6)(11,"ul",7)(12,"li")(13,"p",8),MI(14,"heading-1 \xB7 2.5rem / 700"),gc(),ei(15,"p",9),MI(16,"Ship across continents"),gc()(),ei(17,"li")(18,"p",8),MI(19,"heading-2 \xB7 2rem / 700"),gc(),ei(20,"p",10),MI(21,"Shipment details"),gc()(),ei(22,"li")(23,"p",8),MI(24,"heading-3 \xB7 1.5rem / 600"),gc(),ei(25,"p",11),MI(26,"Cargo summary"),gc()(),ei(27,"li")(28,"p",8),MI(29,"body-lg"),gc(),ei(30,"p",12),MI(31," Supporting sentence for denser marketing or empty states. "),gc()(),ei(32,"li")(33,"p",8),MI(34,"body"),gc(),ei(35,"p",13),MI(36," Default reading size for forms, tables, and dialogs. "),gc()(),ei(37,"li")(38,"p",8),MI(39,"body-sm"),gc(),ei(40,"p",14),MI(41,"Secondary copy and dense metadata."),gc()(),ei(42,"li")(43,"p",8),MI(44,"caption"),gc(),ei(45,"p",15),MI(46,"Hints, timestamps, and chip labels."),gc()()()(),ei(47,"app-demo-section",16)(48,"p",17),MI(49," The color grids above show raw tokens. These cards show the same "),ei(50,"span",4),MI(51,"export"),gc(),MI(52," (SFN green) and "),ei(53,"span",4),MI(54,"import"),gc(),MI(55," (STN orange) families applied to panels \u2014 the way mode accents appear in product UI. Switch shipping mode in the sidebar header and compare with primary buttons elsewhere. "),gc(),ei(56,"div",18)(57,"div",19)(58,"p",20),MI(59,"SFN / export"),gc(),ei(60,"p",21),MI(61,"Lagos outbound"),gc(),ei(62,"p",22),MI(63,"Uses export green tokens."),gc()(),ei(64,"div",23)(65,"p",24),MI(66,"STN / import"),gc(),ei(67,"p",21),MI(68,"US inbound"),gc(),ei(69,"p",22),MI(70,"Uses import orange tokens."),gc()()()()()),r&2&&(Qy(2),Qf("code",s.setupCode),Qy(6),HE(s.groups),Qy(2),Qf("code",s.typeCode),Qy(37),Qf("code",s.modeAccentsCode));},dependencies:[b,Ht],encapsulation:2})};export{F as TokensPage};
@@ -0,0 +1,2 @@
1
+ import {a0 as _o,a1 as Eo,a2 as Ao,a3 as ko,H as Ht}from'./chunk-Cg7brw6x.js';import'./chunk-CZBTrY_H.js';import {b}from'./chunk-Cy-ZOZI8.js';import {T,af as vn,ag as dt,ah as Ee$1,aB as He,C as Co,aC as pt,am as In,u as QI,an as dn,aj as Zr,ao as Q,aD as mu,aE as ZI,I as IE,aF as Vr,aG as Qt,aH as Xt,q as yn,w as wr,aI as Sr,h as br,Z,e as ei,c as Zf,V as VE,j as jE,a as gc,t as tp,aJ as Uf,L as LE,Q as Qy,d as Qf,b as HE,F as FI,P as PE,G as GE,M as MI,X as XE,i as Ic,f as gp,p as Gl,z as zl,aK as Hd}from'./main-WEJC3BLT.js';var fe=()=>[];function ye(a,e){if(a&1){let t=GE();ei(0,"button",30),tp("click",function(){let d=Gl(t).$implicit,p=XE();return zl(p.setListDemo(d))}),MI(1),gc();}if(a&2){let t=e.$implicit,n=XE();Qf("variant",n.listDemo()===t?"primary":"secondary"),Qy(),Ic(" ",t," ");}}function he(a,e){if(a&1&&(ei(0,"div",31)(1,"span",32),MI(2),gc(),Zf(3,"africanies-copy",33),gc()),a&2){let t=e.$implicit;Qy(2),gp(t.reference),Qy(),Qf("value",t.reference)("ariaLabel","Copy "+t.reference);}}function _e(a,e){if(a&1&&(ei(0,"africanies-chip",34),MI(1),gc()),a&2){let t=e.$implicit,n=XE();Qf("variant",n.statusVariant(t.status)),Qy(),Ic(" ",t.status," ");}}function be(a,e){if(a&1&&(ei(0,"africanies-chip",34),MI(1),gc()),a&2){let t=e.$implicit;Qf("variant",t.mode==="sfn"?"export":"import"),Qy(),Ic(" ",t.mode.toUpperCase()," ");}}function Ce(a,e){if(a&1&&(ei(0,"span",35),MI(1),gc()),a&2){let t=e.$implicit,n=XE();Qy(),Ic(" ",n.formatUsd(t.valueUsd)," ");}}function Se(a,e){if(a&1&&Zf(0,"africanies-content-stack",36),a&2){let t=e.$implicit,n=XE();Qf("title",t.packagedBy.name)("subtitle",t.packagedBy.email)("extraLine",n.formatStamp(t.packagedBy.at));}}function we(a,e){if(a&1&&Zf(0,"africanies-action-menu",37),a&2){let t=e.$implicit,n=XE();Qf("items",n.rowActions(t))("ariaLabel","Actions for "+t.reference);}}function xe(a,e){if(a&1&&(ei(0,"span",38),MI(1),gc()),a&2){let t=e.$implicit;Qy(),gp(t.destination);}}function Te(a,e){if(a&1&&(ei(0,"span",39),MI(1),gc()),a&2){let t=e.$implicit,n=XE();Qy(),gp(n.formatUsd(t.valueUsd));}}function ve(a,e){if(a&1&&(ei(0,"africanies-chip",34),MI(1),gc()),a&2){let t=e.$implicit;Qf("variant",t.mode==="sfn"?"export":"import"),Qy(),Ic(" ",t.mode==="sfn"?"Export (SFN)":"Import (STN)"," ");}}function De(a,e){if(a&1&&(ei(0,"africanies-chip",34),MI(1),gc()),a&2){let t=e.$implicit,n=XE();Qf("variant",n.statusVariant(t.status)),Qy(),Ic(" ",t.status," ");}}function ke(a,e){if(a&1&&(ei(0,"p",16),MI(1),gc()),a&2){let t=XE();Qy(),Ic(" Last row action: ",t.lastRowAction()," ");}}function Ee(a,e){if(a&1&&(ei(0,"p",17),MI(1),gc()),a&2){let t=XE();Qy(),Ic(" Expanded row: ",t.lastExpandedRow()," ");}}function Ae(a,e){if(a&1&&(ei(0,"p",17),MI(1),gc()),a&2){let t=XE();Qy(),Ic(" ",t.lastExport()," ");}}function Pe(a,e){if(a&1){let t=GE();ei(0,"button",30),tp("click",function(){let d=Gl(t).$implicit,p=XE();return zl(p.accountKind.set(d))}),MI(1),gc();}if(a&2){let t=e.$implicit,n=XE();Qf("variant",n.accountKind()===t?"primary":"secondary"),Qy(),Ic(" ",t," ");}}function Me(a,e){if(a&1&&(ei(0,"span",40),MI(1),gc()),a&2){let t=e.$implicit,n=XE();Qy(),Ic(" ",n.formatDate(t.createdAt)," ");}}function Re(a,e){if(a&1&&Zf(0,"africanies-content-stack",41),a&2){let t=e.$implicit;Qf("title",t.name)("subtitle",t.email);}}function Le(a,e){if(a&1&&Zf(0,"africanies-content-stack",41),a&2){let t=e.$implicit;Qf("title",t.name)("subtitle",t.email);}}function Ie(a,e){if(a&1&&(ei(0,"div",31)(1,"span",42),MI(2),gc(),Zf(3,"africanies-copy",33),gc()),a&2){let t=e.$implicit;Qy(2),gp(t.identifier),Qy(),Qf("value",t.identifier)("ariaLabel","Copy "+t.identifier);}}function Ne(a,e){if(a&1&&(ei(0,"africanies-chip",34),MI(1),gc()),a&2){let t=e.$implicit,n=XE();Qf("variant",n.kycStatusVariant(t.status)),Qy(),Ic(" ",t.status," ");}}function Fe(a,e){if(a&1&&(ei(0,"span",40),MI(1),gc()),a&2){let t=e.$implicit,n=XE();Qy(),Ic(" ",n.formatDate(t.incorpDate)," ");}}function Be(a,e){if(a&1&&(ei(0,"a",43),MI(1),gc()),a&2){let t=e.$implicit;Qf("href",t.website,Hd),Qy(),Ic(" ",t.website.replace("https://","")," ");}}function Ue(a,e){if(a&1&&Zf(0,"africanies-action-menu",37),a&2){let t=e.$implicit,n=XE();Qf("items",n.customerActions(t))("ariaLabel","Actions for "+t.name);}}var de=["In transit","Delivered","Pending","Exception"],me=["Lagos","Accra","Nairobi","Cairo","London"],y=[{name:"Oladotun Adedeji",email:"oladotun.a@africanies.com"},{name:"Ada Okonkwo",email:"ada.o@africanies.com"},{name:"Chinedu Bello",email:"chinedu.b@africanies.com"}],x=["Pending","Approved","Rejected"],N=[{name:"Ada Okonkwo",email:"ada.okonkwo@example.com"},{name:"Chinedu Bello",email:"chinedu.bello@example.com"},{name:"Fatima Yusuf",email:"fatima.yusuf@example.com"}],F=[{name:"Acme Logistics Ltd",email:"ops@acmelogistics.ng"},{name:"Naija Trade Co",email:"hello@naijatrade.co"},{name:"Sahara Imports Plc",email:"contact@saharaimports.com"}],pe=["Ltd","Llc","Plc"],B=["https://acmelogistics.ng","https://naijatrade.co","https://saharaimports.com"],$e=Array.from({length:6},(a,e)=>{let t=N[e%N.length]??N[0];return {id:`USR-${2e3+e}`,createdAt:new Date(Date.UTC(2026,6,4+e,10,12)),name:t.name,email:t.email,attempts:e%4+1,identifier:`NIN-${800100+e}`,status:x[e%x.length]??"Pending",performedBy:y[e%y.length]?.name??"Oladotun Adedeji",companyType:"",incorpNo:"",incorpDate:new Date(Date.UTC(2019,2,12)),website:""}}),Oe=Array.from({length:6},(a,e)=>{let t=F[e%F.length]??F[0];return {id:`BIZ-${3e3+e}`,createdAt:new Date(Date.UTC(2026,5,8+e,9,30)),name:t.name,email:t.email,attempts:e%3+1,identifier:"",status:x[e%x.length]??"Pending",performedBy:y[e%y.length]?.name??"Oladotun Adedeji",companyType:pe[e%pe.length]??"Ltd",incorpNo:`RC-${10400+e}`,incorpDate:new Date(Date.UTC(2018+e%6,3,15)),website:B[e%B.length]??B[0]}}),ze=Array.from({length:28},(a,e)=>{let t=y[e%y.length]??{name:"Oladotun Adedeji",email:"oladotun.a@africanies.com"};return {reference:`${e%2===0?"SFN":"STN"}-${1e3+e}`,status:de[e%de.length]??"Pending",mode:e%2===0?"sfn":"stn",destination:me[e%me.length]??"Lagos",valueUsd:400+e*175,packagedBy:{name:t.name,email:t.email,at:new Date(Date.UTC(2026,7,14,13,4,22+e))}}}),ue=class a{filterDrawer=T(vn);filterQuery=T(dt);route=T(Ee$1);shipping=T(He);lastShippingMode=this.shipping.mode();page=Co(1);pageSize=Co(pt);sort=Co(null);listDemo=Co("ready");lastRowAction=Co(null);lastExpandedRow=Co(null);lastExport=Co(null);filterState=Co(In());refreshing=Co(false);pageLoading=Co(false);modeLoading=Co(false);listKinds=["ready","loading","empty","error"];activeFilterCount=QI(()=>{let e=this.filterState(),t=dn(e,Zr);return Object.keys(t).filter(n=>n!=="page"&&n!=="per_page"&&n!=="size"&&n!=="order").length});rowActions=e=>[{label:"Open",icon:"eye",onClick:()=>this.lastRowAction.set(`Open \xB7 ${e.reference}`)},{label:"Edit",icon:"edit",onClick:()=>this.lastRowAction.set(`Edit \xB7 ${e.reference}`)},{label:"Copy reference",icon:"copy",onClick:()=>this.lastRowAction.set(`Copy \xB7 ${e.reference}`)},{label:"Delete",icon:"trash",danger:true,dividerBefore:true,onClick:()=>this.lastRowAction.set(`Delete \xB7 ${e.reference}`)}];rowTrackBy=e=>e.reference;columns=[{key:"reference",header:"Reference",sortable:true},{key:"status",header:"Status",sortable:true},{key:"mode",header:"Mode"},{key:"destination",header:"Destination",sortable:true},{key:"valueUsd",header:"Value",sortable:true},{key:"packagedBy",header:"Packaged by"},{key:"actions",header:"",width:"3.5rem"}];compactColumns=[{key:"reference",header:"Reference"},{key:"destination",header:"Destination"},{key:"status",header:"Status"}];accountKind=Co("user");accountKinds=["user","business"];userColumns=[{key:"createdAt",header:"Date created",sortable:true},{key:"customer",header:"Customer"},{key:"attempts",header:"Attempts",sortable:true},{key:"identifier",header:"Identifier"},{key:"status",header:"Status",sortable:true},{key:"performedBy",header:"Performed by"},{key:"actions",header:"Action",width:"3.5rem"}];businessColumns=[{key:"createdAt",header:"Date created",sortable:true},{key:"business",header:"Business"},{key:"attempts",header:"Attempts",sortable:true},{key:"companyType",header:"Company type"},{key:"incorpNo",header:"Incorp no"},{key:"incorpDate",header:"Incorp date"},{key:"website",header:"Website"},{key:"status",header:"Status",sortable:true},{key:"actions",header:"Action",width:"3.5rem"}];customerColumns=QI(()=>this.accountKind()==="business"?this.businessColumns:this.userColumns);customerRows=QI(()=>this.accountKind()==="business"?Oe:$e);customerTrackBy=e=>e.id;customersCode=_o;constructor(){this.syncFromUrl(),this.route.queryParamMap.pipe(Q()).subscribe(()=>{this.syncFromUrl();}),mu(()=>{let e=this.shipping.mode();e!==this.lastShippingMode&&(this.lastShippingMode=e,ZI(()=>this.onShippingModeChange()));});}tableCode=Eo;compactCode=Ao;contentStackCode=ko;sortedRows=QI(()=>{let e=this.sort(),t=this.shipping.mode(),n=ze.filter(T=>T.mode===t);if(!e)return n;let d=e.direction==="asc"?1:-1,p=e.key;return n.sort((T,ge)=>{let v=T[p],D=ge[p];return typeof v=="number"&&typeof D=="number"?(v-D)*d:String(v).localeCompare(String(D))*d})});pageRows=QI(()=>{let e=this.pageSize(),t=(this.page()-1)*e;return this.sortedRows().slice(t,t+e)});meta=QI(()=>{let e=this.pageSize(),t=this.sortedRows().length,n=Math.max(1,Math.ceil(t/e)),d=Math.min(this.page(),n);return {current_page:d,per_page:e,total_items:t,total_pages:n,has_next_page:d<n,has_previous_page:d>1}});listState=QI(()=>{if(this.modeLoading())return {data:void 0,isLoading:true,isFetching:true,isError:false,error:null};switch(this.listDemo()){case "loading":return {data:void 0,isLoading:true,isFetching:true,isError:false,error:null};case "empty":return {data:[],isLoading:false,isFetching:false,isError:false,error:null};case "error":return {data:void 0,isLoading:false,isFetching:false,isError:true,error:"Could not load shipments."};default:return {data:this.pageRows(),isLoading:false,isFetching:this.refreshing(),isError:false,error:null}}});setListDemo(e){this.listDemo.set(e);}onSort(e){this.sort.set(e),this.page.set(1),this.filterQuery.setPage(1);}onPageChange(e){this.runPageLoad(()=>this.page.set(e));}onSizeChange(e){this.runPageLoad(()=>{this.pageSize.set(e),this.page.set(1);});}onShippingModeChange(){this.modeLoading()||(this.modeLoading.set(true),this.page.set(1),this.listDemo.set("ready"),setTimeout(()=>this.modeLoading.set(false),500));}runPageLoad(e){this.pageLoading()||(this.pageLoading.set(true),setTimeout(()=>{e(),this.pageLoading.set(false);},500));}openFilters(){this.filterDrawer.open({config:Zr,state:this.filterState(),title:"Filter shipments"}).afterClosed().subscribe(e=>{e?.applied&&(this.filterState.set(e.state),this.page.set(1));});}onRefresh(){this.refreshing()||(this.refreshing.set(true),this.setListDemo("ready"),setTimeout(()=>this.refreshing.set(false),800));}onExport(){this.lastExport.set(`Export clicked \xB7 ${this.pageRows().length} rows on this page`);}onRowExpand(e){this.lastExpandedRow.set(e.expanded?e.row.reference:null);}customerActions=e=>[{label:"Open",icon:"eye",onClick:()=>this.lastRowAction.set(`Open \xB7 ${e.name}`)},{label:"Edit",icon:"edit",onClick:()=>this.lastRowAction.set(`Edit \xB7 ${e.name}`)}];kycStatusVariant(e){switch(e){case "Approved":return "success";case "Pending":return "warning";case "Rejected":return "danger"}}statusVariant(e){switch(e){case "Delivered":return "success";case "In transit":return "import";case "Pending":return "warning";case "Exception":return "danger"}}formatUsd(e){return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(e)}formatDate(e){return new Intl.DateTimeFormat("en-US",{month:"short",day:"numeric",year:"numeric"}).format(e)}formatStamp(e){return new Intl.DateTimeFormat("en-US",{month:"short",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit",hour12:true}).format(e)}syncFromUrl(){let e=this.filterQuery.read(Zr);this.filterState.set(e),this.page.set(e.page??1),this.pageSize.set(e.size??pt);}static \u0275fac=function(t){return new(t||a)};static \u0275cmp=IE({type:a,selectors:[["app-table-page"]],decls:37,vars:25,consts:[[1,"pg-page-enter","flex","flex-col","gap-10"],["eyebrow","Components","title","Table & pagination","description","Presentational data grid with sortable columns, template cells, and optional pager. Loading, empty, and error states render in the body so the toolbar and headers stay available."],["title","Shipments list","hint","Full list pattern: toolbar (refresh / filters / export), custom cells, expandable row details, row action menu, and [meta] for server-style pagination. Refresh spins the button only; page/size and first load show a body spinner. Empty and error keep Filters available.","badge","template cells",3,"code"],[1,"mb-4","flex","flex-wrap","gap-2"],["africanies-button","","type","button","size","sm",3,"variant"],["emptyMessage","No shipments match these filters.",3,"sortChange","refreshClick","filterClick","exportClick","pageChange","sizeChange","rowExpandChange","columns","rows","meta","sort","rowTrackBy","showRefresh","refreshing","loading","error","showFilter","showExport","filterCount"],["africaniesCellDef","reference"],["africaniesCellDef","status"],["africaniesCellDef","mode"],["africaniesCellDef","valueUsd"],["africaniesCellDef","packagedBy"],["africaniesCellDef","actions"],["africaniesRowDetail","Destination"],["africaniesRowDetail","Declared value"],["africaniesRowDetail","Mode"],["africaniesRowDetail","Status"],[1,"mt-3","m-0","text-caption","text-neutral-600","dark:text-neutral-400"],[1,"mt-1","m-0","text-caption","text-neutral-600","dark:text-neutral-400"],["title","Customers \u2014 user vs business","hint","Same table; switch the column set. User: date created, customer, attempts, identifier, status, performed by, action. Business: date created, business, attempts, company type, incorp no, incorp date, website, status, action.","badge","columns",3,"code"],[3,"columns","rows","rowTrackBy"],["africaniesCellDef","createdAt"],["africaniesCellDef","customer"],["africaniesCellDef","business"],["africaniesCellDef","identifier"],["africaniesCellDef","incorpDate"],["africaniesCellDef","website"],["title","Content stack","hint","Stacked title / subtitle / extra line \u2014 use in table cells or detail panels. The row grows to fit.",3,"code"],["title","Oladotun Adedeji","subtitle","oladotun.a@africanies.com","extraLine","Aug 14, 2026, 2:04:22 PM"],["title","Compact / text-only columns","hint","Minimal columns with no toolbar chrome \u2014 good for nested summaries or dense side panels.","muted","",3,"code"],[3,"columns","rows"],["africanies-button","","type","button","size","sm",3,"click","variant"],[1,"flex","items-center","gap-1"],[1,"font-medium","text-ink","dark:text-white"],[3,"value","ariaLabel"],[3,"variant"],[1,"tabular-nums","text-body-sm","text-ink","dark:text-white"],[3,"title","subtitle","extraLine"],[3,"items","ariaLabel"],[1,"font-medium"],[1,"tabular-nums","font-medium"],[1,"whitespace-nowrap","text-body-sm","tabular-nums"],[3,"title","subtitle"],[1,"font-medium","tabular-nums"],["target","_blank","rel","noopener",1,"text-body-sm","text-ink","underline-offset-2","hover:underline","dark:text-white",3,"href"]],template:function(t,n){t&1&&(ei(0,"div",0),Zf(1,"app-page-header",1),ei(2,"app-demo-section",2)(3,"div",3),VE(4,ye,2,2,"button",4,jE),gc(),ei(6,"africanies-table",5),tp("sortChange",function(p){return n.onSort(p)})("refreshClick",function(){return n.onRefresh()})("filterClick",function(){return n.openFilters()})("exportClick",function(){return n.onExport()})("pageChange",function(p){return n.onPageChange(p)})("sizeChange",function(p){return n.onSizeChange(p)})("rowExpandChange",function(p){return n.onRowExpand(p)}),Uf(7,he,4,3,"ng-template",6)(8,_e,2,2,"ng-template",7)(9,be,2,2,"ng-template",8)(10,Ce,2,1,"ng-template",9)(11,Se,1,3,"ng-template",10)(12,we,1,2,"ng-template",11)(13,xe,2,1,"ng-template",12)(14,Te,2,1,"ng-template",13)(15,ve,2,2,"ng-template",14)(16,De,2,2,"ng-template",15),gc(),LE(17,ke,2,1,"p",16),LE(18,Ee,2,1,"p",17),LE(19,Ae,2,1,"p",17),gc(),ei(20,"app-demo-section",18)(21,"div",3),VE(22,Pe,2,2,"button",4,jE),gc(),ei(24,"africanies-table",19),Uf(25,Me,2,1,"ng-template",20)(26,Re,1,2,"ng-template",21)(27,Le,1,2,"ng-template",22)(28,Ie,4,3,"ng-template",23)(29,Ne,2,2,"ng-template",7)(30,Fe,2,1,"ng-template",24)(31,Be,2,2,"ng-template",25)(32,Ue,1,2,"ng-template",11),gc()(),ei(33,"app-demo-section",26),Zf(34,"africanies-content-stack",27),gc(),ei(35,"app-demo-section",28),Zf(36,"africanies-table",29),gc()()),t&2&&(Qy(2),Qf("code",n.tableCode),Qy(2),HE(n.listKinds),Qy(2),Qf("columns",n.columns)("rows",n.listState().data??FI(24,fe))("meta",n.meta())("sort",n.sort())("rowTrackBy",n.rowTrackBy)("showRefresh",true)("refreshing",n.refreshing())("loading",n.listState().isLoading||n.pageLoading())("error",n.listState().error)("showFilter",true)("showExport",true)("filterCount",n.activeFilterCount()),Qy(11),PE(n.lastRowAction()?17:-1),Qy(),PE(n.lastExpandedRow()?18:-1),Qy(),PE(n.lastExport()?19:-1),Qy(),Qf("code",n.customersCode),Qy(2),HE(n.accountKinds),Qy(2),Qf("columns",n.customerColumns())("rows",n.customerRows())("rowTrackBy",n.customerTrackBy),Qy(9),Qf("code",n.contentStackCode),Qy(2),Qf("code",n.compactCode),Qy(),Qf("columns",n.compactColumns)("rows",n.pageRows().slice(0,3)));},dependencies:[Vr,Qt,Xt,yn,wr,Sr,br,Z,b,Ht],encapsulation:2})};
2
+ export{ue as TablePage};
@@ -0,0 +1 @@
1
+ import {a6 as co,a7 as po,a8 as mo,a9 as uo,aa as fo,ab as go,H as Ht}from'./chunk-Cg7brw6x.js';import'./chunk-CZBTrY_H.js';import {b}from'./chunk-Cy-ZOZI8.js';import {T,aO as pt,O as bn,ai as Ke,aP as Y,aQ as Pr,aR as ue,aS as ve,aT as Jc,C as Co,u as QI,I as IE,aU as qt,aV as li,aW as It,aX as ai,aY as si,aZ as pi,e as ei,c as Zf,a as gc,a8 as Ep,a9 as AI,M as MI,aJ as Uf,Q as Qy,d as Qf,ab as vp,i as Ic,f as gp,k as TP,aD as mu,a_ as jr,m as mI,J as zf}from'./main-WEJC3BLT.js';var N=class l{layout=TP.required();sideNav=TP.required();breadcrumbs=TP.required();userName=TP("Jane Doe");userMenuItems=TP.required();notifications=TP.required();collapsed=Co(false);activeId=Co("track");ariaLabel=QI(()=>`${this.layout()==="mobile"?"Mobile":this.layout()==="tablet"?"Tablet":"Desktop"} navigation`);frameClass=QI(()=>{switch(this.layout()){case "mobile":return "h-[35rem] w-full max-w-[375px]";case "tablet":return "h-[32.5rem] w-full max-w-[768px]";default:return "h-[30rem] w-full"}});contentHint=QI(()=>{switch(this.layout()){case "mobile":return "Tap the menu icon to open the side nav drawer. Clock stays in the header; breadcrumbs and Back sit above the content.";case "tablet":return "Same drawer pattern as phone, with more horizontal room and date/time in the header.";default:return "Persistent side rail, header utilities, and centered content with breadcrumbs above the page body."}});constructor(){mu(()=>{let r=this.layout();this.collapsed.set(r==="mobile"),this.activeId.set(r==="desktop"?"home":"track");});}static \u0275fac=function(s){return new(s||l)};static \u0275cmp=IE({type:l,selectors:[["app-shell-viewport-preview"]],inputs:{layout:[1,"layout"],sideNav:[1,"sideNav"],breadcrumbs:[1,"breadcrumbs"],userName:[1,"userName"],userMenuItems:[1,"userMenuItems"],notifications:[1,"notifications"]},decls:8,vars:12,consts:[[1,"mx-auto","overflow-hidden","rounded-xl","border","border-border","bg-white","shadow-sm","dark:border-white/10","dark:bg-ink"],["contentWidth","5xl",3,"layoutPreview","breadcrumbs","userName","userMenuItems","notifications"],["sidenav","",3,"collapsedChange","activeIdChange","items","collapsed","activeId"],[1,"flex","flex-col","gap-1.5"],[1,"m-0","text-body-sm","font-medium","text-ink","dark:text-white"],[1,"m-0","text-caption","text-neutral-600","dark:text-neutral-400"]],template:function(s,e){s&1&&(ei(0,"div",0)(1,"africanies-app-shell",1)(2,"africanies-side-nav",2),Ep("collapsedChange",function(t){return AI(e.collapsed,t)||(e.collapsed=t),t})("activeIdChange",function(t){return AI(e.activeId,t)||(e.activeId=t),t}),gc(),ei(3,"div",3)(4,"p",4),MI(5," Content "),gc(),ei(6,"p",5),MI(7),gc()()()()),s&2&&(mI(e.frameClass()),Qy(),Qf("layoutPreview",e.layout())("breadcrumbs",e.breadcrumbs())("userName",e.userName())("userMenuItems",e.userMenuItems())("notifications",e.notifications()),Qy(),Qf("items",e.sideNav()),vp("collapsed",e.collapsed)("activeId",e.activeId),zf("aria-label",e.ariaLabel()),Qy(5),Ic(" ",e.contentHint()," "));},dependencies:[jr,si],encapsulation:2})};function $(l,r){l&1&&(ei(0,"p",28),MI(1," Local panel Alpha (not tied to the URL). "),gc());}function ee(l,r){l&1&&(ei(0,"p",28),MI(1," Local panel Beta (not tied to the URL). "),gc());}var Q=class l{router=T(pt);confirm=T(bn);toast=T(Ke);url=Y(this.router.events.pipe(Pr(r=>r instanceof ue),ve(()=>this.router.url),Jc(this.router.url)),{initialValue:this.router.url});routeTabId=Co(null);densityId=Co(null);localTabId=Co("alpha");sideCollapsed=Co(false);sideActiveId=Co("track");shellBreadcrumbs=[{id:"home",label:"Home",icon:"home"},{id:"shipments",label:"Shipments"},{id:"track",label:"STN-1042"}];userMenuItems=[{label:"Profile",icon:"user",onClick:()=>{}},{label:"Settings",icon:"cog",onClick:()=>{}},{label:"Log out",icon:"sign-out",danger:true,dividerBefore:true,onClick:()=>this.confirmLogout()}];shellNotifications=[{id:"n1",title:"Shipment STN-1042 delivered",body:"POD captured at Lagos hub.",timestamp:new Date().toISOString()},{id:"n2",title:"Warehouse sync complete",timestamp:new Date(Date.now()-36e5).toISOString(),read:true}];sideNav=[{id:"home",label:"Home",icon:"home"},{id:"shipments",label:"Shipments",icon:"truck",badge:true,children:[{id:"track",label:"Track",icon:"map-marker",badge:true},{id:"create",label:"Create",icon:"plus"}]},{id:"warehouse",label:"Warehouse",icon:"warehouse"},{id:"settings",label:"Settings",icon:"cog"}];routeTabs=[{id:"overview",label:"Overview",icon:"inbox",routerLink:"/components/navigation/overview"},{id:"documents",label:"Documents",icon:"file-add",routerLink:"/components/navigation/documents"},{id:"events",label:"Events",icon:"alarm",routerLink:"/components/navigation/events"}];densitySegments=[{id:"comfortable",label:"Comfortable",routerLink:"/components/navigation/overview",queryParams:{density:"comfortable"}},{id:"compact",label:"Compact",routerLink:"/components/navigation/overview",queryParams:{density:"compact"}},{id:"dense",label:"Dense",routerLink:"/components/navigation/overview",queryParams:{density:"dense"}}];localTabs=[{id:"alpha",label:"Alpha"},{id:"beta",label:"Beta"}];breadcrumbCode=co;routedTabsCode=po;segmentCode=mo;localTabsCode=uo;sideNavCode=fo;appShellCode=go;crumbs=QI(()=>{let r=this.url().split("?")[0]??"",s=r.includes("/documents")?"Documents":r.includes("/events")?"Events":"Overview";return [{id:"home",label:"Home",routerLink:"/overview",icon:"home"},{id:"nav",label:"Navigation",routerLink:"/components/navigation/overview"},{id:"leaf",label:s}]});confirmLogout(){this.confirm.confirm({title:"Log out?",message:"This signs you out of this device and every other session.",confirmLabel:"Log out",danger:true}).subscribe(r=>{r&&this.toast.success("You have been logged out.");});}static \u0275fac=function(s){return new(s||l)};static \u0275cmp=IE({type:l,selectors:[["app-navigation-page"]],decls:34,vars:31,consts:[[1,"pg-page-enter","flex","flex-col","gap-10"],["eyebrow","Components","title","Navigation","description","App chrome and in-page navigation: shell + side nav, breadcrumbs, tabs, and segments. When items set routerLink, the active state follows the URL so refresh and deep links stay in sync."],["title","App shell \u2014 mobile","hint","Phone layout (375px): hamburger opens the side nav as a drawer inside this frame; header stays compact without the clock.","badge","new"],["layout","mobile","userName","Jane Doe",3,"sideNav","breadcrumbs","userMenuItems","notifications"],["title","App shell \u2014 tablet","hint","Tablet layout (768px): same in-frame drawer as mobile, with more room and date/time in the header.","badge","new"],["layout","tablet","userName","Jane Doe",3,"sideNav","breadcrumbs","userMenuItems","notifications"],["title","App shell \u2014 desktop","hint","Desktop layout (1024px+): persistent side rail, full header chrome, centered content. Sample data only \u2014 wire your routes in the product app.","badge","new",3,"code"],["layout","desktop","userName","Jane Doe",3,"sideNav","breadcrumbs","userMenuItems","notifications"],["title","Side nav","hint","Primary product navigation. Collapse to icons; hover reveals labels and nested links. Collapse all appears above the list when a section is open. Set badge: true for a live-update dot.","badge","new",3,"code"],[1,"flex","h-[28rem]","overflow-visible","rounded-xl","border","border-border","dark:border-white/10"],["ariaLabel","Demo portal",3,"collapsedChange","activeIdChange","items","collapsed","activeId"],[1,"flex","min-w-0","flex-1","flex-col","justify-center","gap-2","bg-background-welcome/60","p-6","dark:bg-ink-950/40"],[1,"m-0","text-caption","uppercase","tracking-wide","text-neutral-500"],[1,"m-0","text-heading-3","text-ink","dark:text-white"],[1,"m-0","text-body-sm","text-neutral-600","dark:text-neutral-400"],["title","Breadcrumb","hint","Show where you are in the hierarchy and link back to parent pages. Crumbs follow the active child route here.",3,"code"],[3,"items"],["title","Tabs (routed)","hint","Section tabs that change the URL (child routes). Active tab survives refresh and can be shared as a link.","subtext",`The page does not jump to the top when you switch tabs \u2014 navigation uses scroll: 'manual'. Pass [keepScroll]="false" to use normal router scrolling.`,3,"code"],["ariaLabel","Shipment sections",3,"activeIdChange","items","activeId"],[1,"mt-4"],["title","Segment (routed via query)","hint","Compact pill switcher for view modes (density, status). Here it syncs to ?density= so the choice survives reload.","subtext","Like routed tabs, switching keeps your scroll position instead of jumping to the top.",3,"code"],["ariaLabel","List density",3,"activeIdChange","items","activeId"],[1,"mt-3","m-0","text-body-sm","text-neutral-600","dark:text-neutral-400"],[1,"font-medium","text-ink","dark:text-white"],["title","Tabs (local)","hint","In-page panels with no router \u2014 bind [(activeId)] and render bodies with africaniesTabDef.",3,"code"],["ariaLabel","Local demo tabs",3,"activeIdChange","items","activeId"],["africaniesTabDef","alpha"],["africaniesTabDef","beta"],[1,"m-0","text-body","text-neutral-600","dark:text-neutral-400"]],template:function(s,e){s&1&&(ei(0,"div",0),Zf(1,"app-page-header",1),ei(2,"app-demo-section",2),Zf(3,"app-shell-viewport-preview",3),gc(),ei(4,"app-demo-section",4),Zf(5,"app-shell-viewport-preview",5),gc(),ei(6,"app-demo-section",6),Zf(7,"app-shell-viewport-preview",7),gc(),ei(8,"app-demo-section",8)(9,"div",9)(10,"africanies-side-nav",10),Ep("collapsedChange",function(t){return AI(e.sideCollapsed,t)||(e.sideCollapsed=t),t})("activeIdChange",function(t){return AI(e.sideActiveId,t)||(e.sideActiveId=t),t}),gc(),ei(11,"div",11)(12,"p",12),MI(13," Active "),gc(),ei(14,"p",13),MI(15),gc(),ei(16,"p",14),MI(17),gc()()()(),ei(18,"app-demo-section",15),Zf(19,"africanies-breadcrumb",16),gc(),ei(20,"app-demo-section",17)(21,"africanies-tabs",18),Ep("activeIdChange",function(t){return AI(e.routeTabId,t)||(e.routeTabId=t),t}),gc(),ei(22,"div",19),Zf(23,"router-outlet"),gc()(),ei(24,"app-demo-section",20)(25,"africanies-segment",21),Ep("activeIdChange",function(t){return AI(e.densityId,t)||(e.densityId=t),t}),gc(),ei(26,"p",22),MI(27," Active density from URL: "),ei(28,"span",23),MI(29),gc()()(),ei(30,"app-demo-section",24)(31,"africanies-tabs",25),Ep("activeIdChange",function(t){return AI(e.localTabId,t)||(e.localTabId=t),t}),Uf(32,$,2,0,"ng-template",26)(33,ee,2,0,"ng-template",27),gc()()()),s&2&&(Qy(3),Qf("sideNav",e.sideNav)("breadcrumbs",e.shellBreadcrumbs)("userMenuItems",e.userMenuItems)("notifications",e.shellNotifications),Qy(2),Qf("sideNav",e.sideNav)("breadcrumbs",e.shellBreadcrumbs)("userMenuItems",e.userMenuItems)("notifications",e.shellNotifications),Qy(),Qf("code",e.appShellCode),Qy(),Qf("sideNav",e.sideNav)("breadcrumbs",e.shellBreadcrumbs)("userMenuItems",e.userMenuItems)("notifications",e.shellNotifications),Qy(),Qf("code",e.sideNavCode),Qy(2),Qf("items",e.sideNav),vp("collapsed",e.sideCollapsed)("activeId",e.sideActiveId),Qy(5),Ic(" ",e.sideActiveId()," "),Qy(2),Ic(" ",e.sideCollapsed()?"Rail collapsed \u2014 hover an icon for the label blade.":"Expanded \u2014 open Shipments for nested items."," "),Qy(),Qf("code",e.breadcrumbCode),Qy(),Qf("items",e.crumbs()),Qy(),Qf("code",e.routedTabsCode),Qy(),Qf("items",e.routeTabs),vp("activeId",e.routeTabId),Qy(3),Qf("code",e.segmentCode),Qy(),Qf("items",e.densitySegments),vp("activeId",e.densityId),Qy(4),gp(e.densityId()??"\u2014"),Qy(),Qf("code",e.localTabsCode),Qy(),Qf("items",e.localTabs),vp("activeId",e.localTabId));},dependencies:[N,qt,li,It,ai,si,pi,b,Ht],encapsulation:2})};export{Q as NavigationPage};
@@ -0,0 +1,68 @@
1
+ var r={RxJS:{label:"RxJS",expansion:"Reactive Extensions for JavaScript",description:"Streams, operators, and utilities for async data (HTTP, overlays, router events)."},"Angular signals":{label:"Angular signals",description:"Fine-grained reactive state: signal, computed, input, output, model, and view queries."},"Angular forms":{label:"Angular forms",description:"Reactive forms and the bridge between form controls and custom inputs."},"Angular DI":{label:"Angular DI",expansion:"Dependency Injection",description:"How Angular creates and delivers services, tokens, and configuration to your code."},"Angular routing":{label:"Angular routing",description:"In-app navigation, route params, and URL-driven UI state."},"Angular CDK":{label:"Angular CDK",expansion:"Component Dev Kit",description:"Low-level Angular utilities (overlays, portals, a11y) that UI libraries build on \u2014 not AWS CDK."},"AFRICANIES SDK":{label:"AFRICANIES SDK",expansion:"Software Development Kit",description:"Bootstrap helpers, overlay APIs, and injection tokens shipped with @africanies/africanies-ui."}},a=[{id:"firstValueFrom",title:"firstValueFrom",category:"RxJS",summary:"Turns an Observable into a Promise that resolves with the first emitted value.",detail:"Observables are lazy streams \u2014 they do nothing until something subscribes. Many Angular APIs (HttpClient, overlay `afterClosed`, etc.) return Observables.\n\n`firstValueFrom(obs$)` subscribes once, resolves when the Observable emits its first value, then unsubscribes. Use it inside `async`/`await` when you want promise-style flow in a component method or service.\n\nIf the Observable completes without emitting, it rejects. If you need the last value instead, use `lastValueFrom`.",example:`import { firstValueFrom } from 'rxjs';
2
+
3
+ async load(): Promise<void> {
4
+ const res = await firstValueFrom(this.http.get<Shipment[]>('/shipments'));
5
+ this.rows.set(res.data);
6
+ }`,seeAlso:["Observable","signal","inject"]},{id:"Observable",title:"Observable",category:"RxJS",summary:"A lazy, push-based stream of values over time.",detail:"RxJS Observables power HTTP calls, router events, overlay results, and many Angular internals. You subscribe (or use operators like `pipe`, `map`, `filter`) to react to emissions.\n\nIn modern Angular you often bridge Observables to signals with `toSignal`, or convert a single emission to a Promise with `firstValueFrom` when `async/await` reads clearer.",seeAlso:["firstValueFrom","toSignal","takeUntilDestroyed"]},{id:"lastValueFrom",title:"lastValueFrom",category:"RxJS",summary:"Like firstValueFrom, but waits for the Observable to complete and returns the last emitted value.",detail:"Use when a stream emits multiple values and you only care about the final one (e.g. a scan/reduction). Most Angular service calls only emit once, so `firstValueFrom` is more common.\n\nRejects if the Observable completes without emitting.",seeAlso:["firstValueFrom","Observable"]},{id:"toSignal",title:"toSignal",category:"Angular signals",summary:"Subscribes to an Observable and exposes its latest value as a signal.",detail:"Import from `@angular/core/rxjs-interop`. `toSignal(source$)` returns a `Signal` that updates when the Observable emits.\n\nCommon in routed components: convert `router.events` or `route.queryParamMap` into a signal, then derive UI state with `computed`. Always provide `{ initialValue: \u2026 }` when the stream may not emit synchronously on first render.",example:`import { toSignal } from '@angular/core/rxjs-interop';
7
+
8
+ private readonly url = toSignal(
9
+ this.router.events.pipe(
10
+ filter((e): e is NavigationEnd => e instanceof NavigationEnd),
11
+ map(() => this.router.url),
12
+ startWith(this.router.url),
13
+ ),
14
+ { initialValue: this.router.url },
15
+ );`,seeAlso:["signal","computed","Observable"]},{id:"signal",title:"signal",category:"Angular signals",summary:"Reactive primitive \u2014 call it like a function to read the current value.",detail:"Signals hold mutable state: `const count = signal(0)`, read with `count()`, update with `count.set(3)` or `count.update(n => n + 1)`.\n\nAngular change detection tracks signal reads in templates and `computed`/`effect`, so you often skip manual `ChangeDetectorRef` for local UI state (loading flags, panel open, selected row, etc.).",example:`protected readonly page = signal(1);
16
+ protected readonly loading = signal(false);
17
+
18
+ protected load(): void {
19
+ this.loading.set(true);
20
+ // \u2026
21
+ this.loading.set(false);
22
+ }`,seeAlso:["computed","effect","model"]},{id:"computed",title:"computed",category:"Angular signals",summary:"Derived signal \u2014 recalculates when its dependencies change.",detail:"`computed(() => \u2026)` reads other signals inside the factory and caches the result until a dependency changes.\n\nUse for view-model shaping: map query signals into `AsyncQueryStateModel`, build breadcrumb arrays from a URL signal, or derive stepper progress \u2014 without storing duplicate state.",example:`protected readonly listState = computed((): AsyncQueryStateModel<Shipment[]> => ({
23
+ status: this.isLoading() ? 'loading' : 'success',
24
+ data: this.rows(),
25
+ isFetching: this.isFetching(),
26
+ }));`,seeAlso:["signal","toSignal"]},{id:"effect",title:"effect",category:"Angular signals",summary:"Runs side effects when signals it reads change.",detail:"Use sparingly for syncing signal state to non-Angular APIs (localStorage, third-party widgets). Prefer `computed` for derived data.\n\nEffects run after render; avoid writing signals that the same effect reads unless you guard against loops.",seeAlso:["signal","computed"]},{id:"inject",title:"inject()",category:"Angular DI",summary:"Resolves a service from Angular\u2019s dependency injector.",detail:"Call `inject(MyService)` in a component, directive, pipe, or `runInInjectionContext`. Replaces constructor injection for standalone components and keeps fields grouped near usage.\n\nPlayground snippets use it for SDK services (`FilterDrawerService`, `ToastService`, `ApiClient`, theme helpers, etc.).",example:`private readonly toast = inject(ToastService);
27
+ private readonly api = inject(ApiClient);`,seeAlso:["standalone","provideAfricaniesUiOverlays","DestroyRef"]},{id:"HttpClient",title:"HttpClient",category:"Angular DI",summary:"Angular service for HTTP GET/POST/etc. \u2014 returns Observables.",detail:"Register with `provideHttpClient()` in `app.config.ts`. Methods like `get<T>(url)` return `Observable<T>` \u2014 pipe operators, subscribe, bridge with `toSignal`, or `await firstValueFrom(...)`.\n\nPlayground list demos use `ApiClient` (a typed wrapper); toast snippets show raw `HttpClient` with `withToast()` for automatic success/error toasts.",example:`import { provideHttpClient } from '@angular/common/http';
28
+
29
+ export const appConfig = {
30
+ providers: [provideHttpClient()],
31
+ };`,seeAlso:["Observable","firstValueFrom","inject"]},{id:"standalone",title:"standalone components",category:"Angular DI",summary:"Components that declare their own `imports` instead of an NgModule.",detail:"Set `standalone: true` on `@Component` and list dependencies in `imports: [ButtonComponent, RouterLink, \u2026]`.\n\nThe AFRICANIES SDK ships standalone components. NgModule facades (`AfricaniesFormsModule`, etc.) still exist for one-import ergonomics, but tree-shaking favors direct standalone imports.",seeAlso:["inject","input"]},{id:"input",title:"input()",category:"Angular signals",summary:"Signal-based @Input \u2014 `readonly foo = input(default)`.",detail:'Angular 17+ signal inputs replace `@Input() foo`. Parent binds `[foo]="value"`; child reads `foo()` in templates and class logic.\n\nOptional inputs use `input<string | null>(null)`. Required: `input.required<string>()`. Transform with `{ transform: booleanAttribute }` for attribute coercion.',seeAlso:["model","output","standalone"]},{id:"output",title:"output()",category:"Angular signals",summary:"Signal-based @Output \u2014 `readonly saved = output<Shipment>()`.",detail:'Replaces `@Output() saved = new EventEmitter()`. Parent listens with `(saved)="onSave($event)"`.\n\nEmit with `this.saved.emit(value)`. Outputs are explicit one-way events upward; prefer `model()` when you need two-way binding.',seeAlso:["input","model"]},{id:"model",title:"model()",category:"Angular signals",summary:"Two-way binding \u2014 `[(collapsed)]` on a signal model.",detail:"`readonly collapsed = model(false)` exposes read via `collapsed()` and write via `collapsed.set(\u2026)` / two-way binding from the parent.\n\nUsed in SDK components like `africanies-side-nav` (`[(collapsed)]`, `[(activeId)]`) so hosts can sync rail state without separate input + output pairs.",seeAlso:["input","signal"]},{id:"viewChild",title:"viewChild()",category:"Angular signals",summary:"Query a child component or element from the template as a signal.",detail:'Import from `@angular/core`. `viewChild(MyComponent)` or `viewChild<ElementRef>("input")` returns a signal that updates when the queried target is available.\n\nPrefer over the legacy `@ViewChild` decorator in new code. Use `viewChildren` for multiple matches.',example:`protected readonly table = viewChild(TableComponent);
32
+
33
+ protected focusFirstRow(): void {
34
+ this.table()?.scrollToTop();
35
+ }`,seeAlso:["signal","input"]},{id:"booleanAttribute",title:"booleanAttribute",category:"Angular signals",summary:"Input transform \u2014 coerces HTML attribute strings to true/false.",detail:"Pass as `{ transform: booleanAttribute }` on `input()`. Empty attribute presence becomes `true`; missing attribute becomes `false`.\n\nSDK components use this for flags like `disabled`, `required`, and `muted` so `[disabled]` works without binding a literal `true`.",example:"readonly disabled = input(false, { transform: booleanAttribute });",seeAlso:["input","standalone"]},{id:"FormControl",title:"FormControl",category:"Angular forms",summary:"Single reactive-form field \u2014 value, validators, and disabled state.",detail:'From `@angular/forms`. `new FormControl("", { validators: [Validators.required] })` tracks one control. Bind in templates with `[formControl]` or group several controls in a `FormGroup`.\n\nAFRICANIES form components also work with signal `value` / `(valueChange)` for simpler cases without reactive forms.',example:`readonly email = new FormControl('', {
36
+ nonNullable: true,
37
+ validators: [Validators.email],
38
+ });`,seeAlso:["ControlValueAccessor","signal"]},{id:"ControlValueAccessor",title:"ControlValueAccessor",category:"Angular forms",summary:"Interface that lets a custom input participate in reactive forms.",detail:"Abbreviated CVA in Angular docs. Your component implements `writeValue`, `registerOnChange`, `registerOnTouched`, and optionally `setDisabledState` so Angular forms can read/write the value.\n\nEvery AFRICANIES form control (`africanies-text-input`, `africanies-select`, etc.) implements CVA \u2014 you can use `[formControl]` or two-way `[(value)]` interchangeably.",seeAlso:["FormControl","input","model"]},{id:"takeUntilDestroyed",title:"takeUntilDestroyed",category:"RxJS",summary:"Unsubscribes automatically when the component is destroyed.",detail:"Import from `@angular/core/rxjs-interop`. Pipe overlay or HTTP Observables with `takeUntilDestroyed()` (optionally pass `DestroyRef`) so you do not leak subscriptions when the user navigates away.\n\nPrefer this over manual `Subscription` fields in components.",example:`this.modal
39
+ .open(EditPanel, { data })
40
+ .afterClosed()
41
+ .pipe(takeUntilDestroyed())
42
+ .subscribe((result) => { /* \u2026 */ });`,seeAlso:["Observable","afterClosed","DestroyRef"]},{id:"DestroyRef",title:"DestroyRef",category:"Angular DI",summary:"Token tied to the current injector\u2019s destroy lifecycle.",detail:"Inject `DestroyRef` to register cleanup when a component, directive, or environment injector is torn down.\n\n`takeUntilDestroyed()` uses it under the hood. You can also call `destroyRef.onDestroy(() => \u2026)` for non-Observable cleanup (timers, listeners).",example:`private readonly destroyRef = inject(DestroyRef);
43
+
44
+ constructor() {
45
+ const id = setInterval(() => this.tick(), 1000);
46
+ this.destroyRef.onDestroy(() => clearInterval(id));
47
+ }`,seeAlso:["takeUntilDestroyed","inject"]},{id:"afterClosed",title:"afterClosed()",category:"AFRICANIES SDK",summary:"Observable that emits once when a modal/drawer/filter overlay closes.",detail:"AFRICANIES overlay services (`ModalService`, `DrawerService`, `FilterDrawerService`) return a handle with `.afterClosed()` \u2014 an Observable of the result passed to `ref.close(result)`.\n\nSubscribe (with `takeUntilDestroyed`) or `await firstValueFrom(handle.afterClosed())` to continue flow after the user applies filters or saves a form.",seeAlso:["firstValueFrom","takeUntilDestroyed","OVERLAY_DATA"]},{id:"OVERLAY_DATA",title:"OVERLAY_DATA",category:"AFRICANIES SDK",summary:"Injection token for data passed into a modal/drawer panel component.",detail:"When opening a panel, pass `{ data: { \u2026 } }` in the config. Inside the panel component, `inject(OVERLAY_DATA)` retrieves that payload with full typing.\n\nPair with `inject(AfricaniesOverlayRef)` to close the overlay and return a result.",seeAlso:["afterClosed","inject","provideAfricaniesUiOverlays"]},{id:"AfricaniesOverlayRef",title:"AfricaniesOverlayRef",category:"AFRICANIES SDK",summary:"Handle to close a modal/drawer and pass a result back to the caller.",detail:"Inject inside a panel component opened by `ModalService` or `DrawerService`. Call `this.ref.close(result)` when the user saves or cancels \u2014 the opener receives `result` through `afterClosed()`.\n\nGeneric type parameter types the result: `AfricaniesOverlayRef<EditShipmentResult>`.",example:`protected readonly ref = inject(AfricaniesOverlayRef<Shipment>);
48
+
49
+ protected save(): void {
50
+ this.ref.close(this.draft());
51
+ }`,seeAlso:["OVERLAY_DATA","afterClosed","inject"]},{id:"provideAfricaniesUiOverlays",title:"provideAfricaniesUiOverlays()",category:"AFRICANIES SDK",summary:"Registers modal, drawer, and confirm services at app bootstrap.",detail:"Add to `ApplicationConfig.providers` once. Required before using `ModalService`, `DrawerService`, `ConfirmService`, or `FilterDrawerService`.\n\nAlso pulls in Angular CDK overlay infrastructure used for positioning and backdrop.",example:`export const appConfig: ApplicationConfig = {
52
+ providers: [
53
+ provideRouter(routes),
54
+ provideAfricaniesUiOverlays(),
55
+ provideAfricaniesToasts(),
56
+ ],
57
+ };`,seeAlso:["CDK","inject","afterClosed"]},{id:"provideAfricaniesToasts",title:"provideAfricaniesToasts()",category:"AFRICANIES SDK",summary:"Registers the toast stack host and ToastService.",detail:"Call once in `app.config.ts`. Then inject `ToastService` anywhere to show timed or persistent corner notifications.",seeAlso:["provideAfricaniesUiOverlays","inject"]},{id:"RouterLink",title:"RouterLink",category:"Angular routing",summary:"Directive that navigates without full page reloads.",detail:"Use on `<a routerLink=\"/path\">` or `[routerLink]=\"['/shipments', id]\"` with optional `queryParams`. SDK nav items accept `routerLink` so active state follows the URL. Routed `africanies-tabs` / `africanies-segment` navigate with `{ scroll: 'manual' }` by default (no jump to top); side nav and breadcrumb still use Angular `RouterLink`.",seeAlso:["toSignal","ActivatedRoute","standalone"]},{id:"Router",title:"Router",category:"Angular routing",summary:"Service for imperative navigation and reading the current URL.",detail:"Inject `Router` to call `navigate()`, `navigateByUrl()`, or listen to `router.events`. Pair with `ActivatedRoute` for the active route segment\u2019s params and data.\n\nSDK nav demos use `Router` + `toSignal` to keep breadcrumb/tabs in sync with the URL.",seeAlso:["RouterLink","ActivatedRoute","toSignal"]},{id:"ActivatedRoute",title:"ActivatedRoute",category:"Angular routing",summary:"Snapshot of the route segment this component was loaded under.",detail:"Inject to read `paramMap`, `queryParamMap`, `data`, and child routes. Streams like `route.queryParamMap` pair well with `toSignal` for filter state synced to the URL.\n\nFilter playground snippets deserialize list filters from query params via `ActivatedRoute`.",example:`private readonly route = inject(ActivatedRoute);
58
+
59
+ protected readonly filters = toSignal(
60
+ this.route.queryParamMap.pipe(map((p) => deserializeFilters(p))),
61
+ { initialValue: defaultFilters() },
62
+ );`,seeAlso:["Router","toSignal","RouterLink"]},{id:"CDK",title:"CDK",category:"Angular CDK",match:"CDK",summary:"Angular Component Dev Kit \u2014 building blocks for overlays, portals, and accessibility (package @angular/cdk).",detail:"Not related to AWS CDK. Google\u2019s Angular CDK is a set of unstyled primitives that Material and other UI libraries use.\n\nIn this SDK, the important piece is **overlay**: menus, selects, toasts, tooltips, modals, and drawers attach panels to `document.body` so they are not clipped by parents with `overflow: hidden` (for example a table). You will see imports from `@angular/cdk/overlay` and `@angular/cdk/portal`, plus directives like `cdkConnectedOverlay`.\n\nConsuming apps should import CDK overlay styles once (`@import '@angular/cdk/overlay-prebuilt.css';`) \u2014 see the `@africanies/africanies-ui` README.",example:`import { Overlay } from '@angular/cdk/overlay';
63
+ import { ComponentPortal } from '@angular/cdk/portal';
64
+
65
+ // Toasts and service-driven overlays attach a portal to the overlay stack.
66
+ const overlayRef = this.overlay.create({ \u2026 });
67
+ overlayRef.attach(new ComponentPortal(ToastHostComponent));`,seeAlso:["provideAfricaniesUiOverlays","afterClosed","inject"],links:[{label:"Angular CDK overview",href:"https://material.angular.dev/cdk/categories"},{label:"Overlay API",href:"https://material.angular.dev/cdk/overlay/overview"},{label:"Portal API",href:"https://material.angular.dev/cdk/portal/overview"}]}],o=[...a].map(e=>({id:e.id,match:e.match??e.id})).sort((e,t)=>t.match.length-e.match.length);new Map(a.map(e=>[e.id,e]));var i=["RxJS","Angular signals","Angular forms","Angular DI","Angular routing","Angular CDK","AFRICANIES SDK"];function n(e){return r[e]}function l(e){let t=r[e];return t.expansion?`${t.label} (${t.expansion})`:t.label}function d(e){return `category-${e.toLowerCase().replace(/\s+/g,"-")}`}function u(e){return a.filter(t=>t.category===e)}
68
+ export{a,d,i,l,n,o,u};