@akanjs/cli 0.0.142 → 0.0.144

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 (349) hide show
  1. package/README.md +8 -0
  2. package/cjs/index.js +2437 -3204
  3. package/cjs/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
  4. package/cjs/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
  5. package/cjs/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
  6. package/cjs/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
  7. package/cjs/src/guidelines/componentRule/componentRule.instruction.md +732 -0
  8. package/cjs/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
  9. package/cjs/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
  10. package/cjs/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
  11. package/cjs/src/guidelines/framework/framework.instruction.md +1112 -0
  12. package/cjs/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
  13. package/cjs/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
  14. package/cjs/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
  15. package/cjs/src/guidelines/modelService/modelService.instruction.md +935 -0
  16. package/cjs/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
  17. package/cjs/src/guidelines/modelStore/modelStore.instruction.md +591 -0
  18. package/cjs/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
  19. package/cjs/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
  20. package/cjs/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
  21. package/cjs/src/guidelines/modelView/modelView.instruction.md +1005 -0
  22. package/cjs/src/guidelines/modelZone/modelZone.instruction.md +528 -0
  23. package/cjs/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
  24. package/cjs/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
  25. package/cjs/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
  26. package/cjs/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
  27. package/cjs/src/templates/module/__model__.dictionary.js +4 -5
  28. package/esm/index.js +2524 -3286
  29. package/esm/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
  30. package/esm/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
  31. package/esm/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
  32. package/esm/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
  33. package/esm/src/guidelines/componentRule/componentRule.instruction.md +732 -0
  34. package/esm/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
  35. package/esm/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
  36. package/esm/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
  37. package/esm/src/guidelines/framework/framework.instruction.md +1112 -0
  38. package/esm/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
  39. package/esm/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
  40. package/esm/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
  41. package/esm/src/guidelines/modelService/modelService.instruction.md +935 -0
  42. package/esm/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
  43. package/esm/src/guidelines/modelStore/modelStore.instruction.md +591 -0
  44. package/esm/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
  45. package/esm/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
  46. package/esm/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
  47. package/esm/src/guidelines/modelView/modelView.instruction.md +1005 -0
  48. package/esm/src/guidelines/modelZone/modelZone.instruction.md +528 -0
  49. package/esm/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
  50. package/esm/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
  51. package/esm/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
  52. package/esm/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
  53. package/esm/src/templates/module/__model__.dictionary.js +4 -5
  54. package/package.json +3 -1
  55. package/src/guideline/guideline.command.d.ts +7 -0
  56. package/src/guideline/guideline.prompt.d.ts +15 -0
  57. package/src/guideline/guideline.runner.d.ts +5 -0
  58. package/src/guideline/guideline.script.d.ts +6 -0
  59. package/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
  60. package/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
  61. package/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
  62. package/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
  63. package/src/guidelines/componentRule/componentRule.instruction.md +732 -0
  64. package/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
  65. package/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
  66. package/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
  67. package/src/guidelines/framework/framework.instruction.md +1112 -0
  68. package/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
  69. package/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
  70. package/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
  71. package/src/guidelines/modelService/modelService.instruction.md +935 -0
  72. package/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
  73. package/src/guidelines/modelStore/modelStore.instruction.md +591 -0
  74. package/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
  75. package/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
  76. package/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
  77. package/src/guidelines/modelView/modelView.instruction.md +1005 -0
  78. package/src/guidelines/modelZone/modelZone.instruction.md +528 -0
  79. package/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
  80. package/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
  81. package/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
  82. package/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
  83. package/src/module/module.command.d.ts +6 -8
  84. package/src/module/module.prompt.d.ts +2 -15
  85. package/src/module/module.request.d.ts +22 -18
  86. package/src/module/module.runner.d.ts +4 -20
  87. package/src/module/module.script.d.ts +6 -7
  88. package/src/scalar/scalar.command.d.ts +7 -0
  89. package/src/scalar/scalar.prompt.d.ts +23 -0
  90. package/src/scalar/scalar.runner.d.ts +13 -0
  91. package/src/scalar/scalar.script.d.ts +6 -0
  92. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -47
  93. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -128
  94. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -42
  95. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -50
  96. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -41
  97. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -51
  98. package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -43
  99. package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -60
  100. package/cjs/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -54
  101. package/cjs/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
  102. package/cjs/src/templates/app/app/[lang]/admin/layout.js +0 -54
  103. package/cjs/src/templates/app/app/[lang]/admin/page.js +0 -63
  104. package/cjs/src/templates/app/app/csr.js +0 -34
  105. package/cjs/src/templates/app/app/index.html.template +0 -13
  106. package/cjs/src/templates/app/app/layout.js +0 -38
  107. package/cjs/src/templates/app/capacitor.config.ts.template +0 -8
  108. package/cjs/src/templates/app/env/env.client.debug.ts.template +0 -7
  109. package/cjs/src/templates/app/env/env.client.develop.ts.template +0 -7
  110. package/cjs/src/templates/app/env/env.client.local.ts.template +0 -7
  111. package/cjs/src/templates/app/env/env.client.main.ts.template +0 -7
  112. package/cjs/src/templates/app/env/env.client.testing.ts.template +0 -7
  113. package/cjs/src/templates/app/env/env.server.debug.ts.template +0 -15
  114. package/cjs/src/templates/app/env/env.server.develop.ts.template +0 -15
  115. package/cjs/src/templates/app/env/env.server.local.ts.template +0 -15
  116. package/cjs/src/templates/app/env/env.server.main.ts.template +0 -15
  117. package/cjs/src/templates/app/env/env.server.testing.ts.template +0 -7
  118. package/cjs/src/templates/app/lib/setting/Setting.Template.js +0 -57
  119. package/cjs/src/templates/app/lib/setting/Setting.Unit.js +0 -38
  120. package/cjs/src/templates/app/lib/setting/Setting.Util.js +0 -34
  121. package/cjs/src/templates/app/lib/setting/Setting.View.js +0 -51
  122. package/cjs/src/templates/app/lib/setting/Setting.Zone.js +0 -80
  123. package/cjs/src/templates/app/lib/setting/index.js +0 -61
  124. package/cjs/src/templates/app/lib/summary/Summary.Template.js +0 -43
  125. package/cjs/src/templates/app/lib/summary/Summary.Unit.js +0 -38
  126. package/cjs/src/templates/app/lib/summary/Summary.Util.js +0 -33
  127. package/cjs/src/templates/app/lib/summary/Summary.View.js +0 -51
  128. package/cjs/src/templates/app/lib/summary/Summary.Zone.js +0 -62
  129. package/cjs/src/templates/app/lib/summary/index.js +0 -67
  130. package/cjs/src/templates/app/lib/user/User.Template.js +0 -65
  131. package/cjs/src/templates/app/lib/user/User.Unit.js +0 -38
  132. package/cjs/src/templates/app/lib/user/User.Util.js +0 -94
  133. package/cjs/src/templates/app/lib/user/User.View.js +0 -66
  134. package/cjs/src/templates/app/lib/user/User.Zone.js +0 -74
  135. package/cjs/src/templates/app/lib/user/index.js +0 -61
  136. package/cjs/src/templates/app/page.test.ts.template +0 -10
  137. package/cjs/src/templates/app/playwright.config.ts.template +0 -6
  138. package/cjs/src/templates/app/postcss.config.js.template +0 -10
  139. package/cjs/src/templates/app/public/manifest.json.template +0 -67
  140. package/cjs/src/templates/app/tsconfig.json.template +0 -22
  141. package/cjs/src/templates/app/tsconfig.spec.json.template +0 -7
  142. package/cjs/src/templates/app/ui/Footer.js +0 -67
  143. package/cjs/src/templates/app/ui/MainHeader.js +0 -131
  144. package/cjs/src/templates/crudPages/[__model__Id]/edit/page.js +0 -73
  145. package/cjs/src/templates/crudPages/[__model__Id]/page.js +0 -83
  146. package/cjs/src/templates/crudPages/new/page.js +0 -70
  147. package/cjs/src/templates/crudPages/page.js +0 -71
  148. package/cjs/src/templates/libRoot/.gitignore.template +0 -15
  149. package/cjs/src/templates/libRoot/env/env.server.example.ts.template +0 -7
  150. package/cjs/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
  151. package/cjs/src/templates/libRoot/lib/setting/Setting.Template.js +0 -57
  152. package/cjs/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -38
  153. package/cjs/src/templates/libRoot/lib/setting/Setting.Util.js +0 -34
  154. package/cjs/src/templates/libRoot/lib/setting/Setting.View.js +0 -51
  155. package/cjs/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -80
  156. package/cjs/src/templates/libRoot/lib/setting/index.js +0 -61
  157. package/cjs/src/templates/libRoot/lib/summary/Summary.Template.js +0 -43
  158. package/cjs/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -38
  159. package/cjs/src/templates/libRoot/lib/summary/Summary.Util.js +0 -33
  160. package/cjs/src/templates/libRoot/lib/summary/Summary.View.js +0 -51
  161. package/cjs/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -62
  162. package/cjs/src/templates/libRoot/lib/summary/index.js +0 -67
  163. package/cjs/src/templates/libRoot/lib/user/User.Template.js +0 -65
  164. package/cjs/src/templates/libRoot/lib/user/User.Unit.js +0 -38
  165. package/cjs/src/templates/libRoot/lib/user/User.Util.js +0 -94
  166. package/cjs/src/templates/libRoot/lib/user/User.View.js +0 -66
  167. package/cjs/src/templates/libRoot/lib/user/User.Zone.js +0 -74
  168. package/cjs/src/templates/libRoot/lib/user/index.js +0 -61
  169. package/cjs/src/templates/libRoot/package.json.template +0 -4
  170. package/cjs/src/templates/libRoot/tsconfig.json.template +0 -13
  171. package/cjs/src/templates/libRoot/tsconfig.spec.json.template +0 -7
  172. package/cjs/src/templates/localDev/docker-compose.yaml.template +0 -36
  173. package/cjs/src/templates/module/__Model__.Template.js +0 -54
  174. package/cjs/src/templates/module/__Model__.Unit.js +0 -42
  175. package/cjs/src/templates/module/__Model__.Util.js +0 -70
  176. package/cjs/src/templates/module/__Model__.View.js +0 -48
  177. package/cjs/src/templates/module/__Model__.Zone.js +0 -83
  178. package/cjs/src/templates/module/index.js +0 -61
  179. package/cjs/src/templates/pkgRoot/tsconfig.json.template +0 -15
  180. package/cjs/src/templates/workspaceRoot/.env.template +0 -20
  181. package/cjs/src/templates/workspaceRoot/.gitignore.template +0 -118
  182. package/cjs/src/templates/workspaceRoot/.prettierignore.template +0 -10
  183. package/cjs/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
  184. package/cjs/src/templates/workspaceRoot/.swcrc.template +0 -9
  185. package/cjs/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
  186. package/cjs/src/templates/workspaceRoot/README.md.template +0 -37
  187. package/cjs/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
  188. package/cjs/src/templates/workspaceRoot/package.json.template +0 -43
  189. package/cjs/src/templates/workspaceRoot/tsconfig.json.template +0 -29
  190. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -27
  191. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -108
  192. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -22
  193. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -30
  194. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -21
  195. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -31
  196. package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -23
  197. package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -40
  198. package/esm/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -34
  199. package/esm/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
  200. package/esm/src/templates/app/app/[lang]/admin/layout.js +0 -34
  201. package/esm/src/templates/app/app/[lang]/admin/page.js +0 -43
  202. package/esm/src/templates/app/app/csr.js +0 -14
  203. package/esm/src/templates/app/app/index.html.template +0 -13
  204. package/esm/src/templates/app/app/layout.js +0 -18
  205. package/esm/src/templates/app/capacitor.config.ts.template +0 -8
  206. package/esm/src/templates/app/env/env.client.debug.ts.template +0 -7
  207. package/esm/src/templates/app/env/env.client.develop.ts.template +0 -7
  208. package/esm/src/templates/app/env/env.client.local.ts.template +0 -7
  209. package/esm/src/templates/app/env/env.client.main.ts.template +0 -7
  210. package/esm/src/templates/app/env/env.client.testing.ts.template +0 -7
  211. package/esm/src/templates/app/env/env.server.debug.ts.template +0 -15
  212. package/esm/src/templates/app/env/env.server.develop.ts.template +0 -15
  213. package/esm/src/templates/app/env/env.server.local.ts.template +0 -15
  214. package/esm/src/templates/app/env/env.server.main.ts.template +0 -15
  215. package/esm/src/templates/app/env/env.server.testing.ts.template +0 -7
  216. package/esm/src/templates/app/lib/setting/Setting.Template.js +0 -37
  217. package/esm/src/templates/app/lib/setting/Setting.Unit.js +0 -18
  218. package/esm/src/templates/app/lib/setting/Setting.Util.js +0 -14
  219. package/esm/src/templates/app/lib/setting/Setting.View.js +0 -31
  220. package/esm/src/templates/app/lib/setting/Setting.Zone.js +0 -60
  221. package/esm/src/templates/app/lib/setting/index.js +0 -41
  222. package/esm/src/templates/app/lib/summary/Summary.Template.js +0 -23
  223. package/esm/src/templates/app/lib/summary/Summary.Unit.js +0 -18
  224. package/esm/src/templates/app/lib/summary/Summary.Util.js +0 -13
  225. package/esm/src/templates/app/lib/summary/Summary.View.js +0 -31
  226. package/esm/src/templates/app/lib/summary/Summary.Zone.js +0 -42
  227. package/esm/src/templates/app/lib/summary/index.js +0 -47
  228. package/esm/src/templates/app/lib/user/User.Template.js +0 -45
  229. package/esm/src/templates/app/lib/user/User.Unit.js +0 -18
  230. package/esm/src/templates/app/lib/user/User.Util.js +0 -74
  231. package/esm/src/templates/app/lib/user/User.View.js +0 -46
  232. package/esm/src/templates/app/lib/user/User.Zone.js +0 -54
  233. package/esm/src/templates/app/lib/user/index.js +0 -41
  234. package/esm/src/templates/app/page.test.ts.template +0 -10
  235. package/esm/src/templates/app/playwright.config.ts.template +0 -6
  236. package/esm/src/templates/app/postcss.config.js.template +0 -10
  237. package/esm/src/templates/app/public/manifest.json.template +0 -67
  238. package/esm/src/templates/app/tsconfig.json.template +0 -22
  239. package/esm/src/templates/app/tsconfig.spec.json.template +0 -7
  240. package/esm/src/templates/app/ui/Footer.js +0 -47
  241. package/esm/src/templates/app/ui/MainHeader.js +0 -111
  242. package/esm/src/templates/crudPages/[__model__Id]/edit/page.js +0 -53
  243. package/esm/src/templates/crudPages/[__model__Id]/page.js +0 -63
  244. package/esm/src/templates/crudPages/new/page.js +0 -50
  245. package/esm/src/templates/crudPages/page.js +0 -51
  246. package/esm/src/templates/libRoot/.gitignore.template +0 -15
  247. package/esm/src/templates/libRoot/env/env.server.example.ts.template +0 -7
  248. package/esm/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
  249. package/esm/src/templates/libRoot/lib/setting/Setting.Template.js +0 -37
  250. package/esm/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -18
  251. package/esm/src/templates/libRoot/lib/setting/Setting.Util.js +0 -14
  252. package/esm/src/templates/libRoot/lib/setting/Setting.View.js +0 -31
  253. package/esm/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -60
  254. package/esm/src/templates/libRoot/lib/setting/index.js +0 -41
  255. package/esm/src/templates/libRoot/lib/summary/Summary.Template.js +0 -23
  256. package/esm/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -18
  257. package/esm/src/templates/libRoot/lib/summary/Summary.Util.js +0 -13
  258. package/esm/src/templates/libRoot/lib/summary/Summary.View.js +0 -31
  259. package/esm/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -42
  260. package/esm/src/templates/libRoot/lib/summary/index.js +0 -47
  261. package/esm/src/templates/libRoot/lib/user/User.Template.js +0 -45
  262. package/esm/src/templates/libRoot/lib/user/User.Unit.js +0 -18
  263. package/esm/src/templates/libRoot/lib/user/User.Util.js +0 -74
  264. package/esm/src/templates/libRoot/lib/user/User.View.js +0 -46
  265. package/esm/src/templates/libRoot/lib/user/User.Zone.js +0 -54
  266. package/esm/src/templates/libRoot/lib/user/index.js +0 -41
  267. package/esm/src/templates/libRoot/package.json.template +0 -4
  268. package/esm/src/templates/libRoot/tsconfig.json.template +0 -13
  269. package/esm/src/templates/libRoot/tsconfig.spec.json.template +0 -7
  270. package/esm/src/templates/localDev/docker-compose.yaml.template +0 -36
  271. package/esm/src/templates/module/__Model__.Template.js +0 -34
  272. package/esm/src/templates/module/__Model__.Unit.js +0 -22
  273. package/esm/src/templates/module/__Model__.Util.js +0 -50
  274. package/esm/src/templates/module/__Model__.View.js +0 -28
  275. package/esm/src/templates/module/__Model__.Zone.js +0 -63
  276. package/esm/src/templates/module/index.js +0 -41
  277. package/esm/src/templates/pkgRoot/tsconfig.json.template +0 -15
  278. package/esm/src/templates/workspaceRoot/.env.template +0 -20
  279. package/esm/src/templates/workspaceRoot/.gitignore.template +0 -118
  280. package/esm/src/templates/workspaceRoot/.prettierignore.template +0 -10
  281. package/esm/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
  282. package/esm/src/templates/workspaceRoot/.swcrc.template +0 -9
  283. package/esm/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
  284. package/esm/src/templates/workspaceRoot/README.md.template +0 -37
  285. package/esm/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
  286. package/esm/src/templates/workspaceRoot/package.json.template +0 -43
  287. package/esm/src/templates/workspaceRoot/tsconfig.json.template +0 -29
  288. package/src/application/application.prompt.d.ts +0 -2
  289. package/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.d.ts +0 -9
  290. package/src/templates/app/app/[lang]/(__appName__)/(public)/page.d.ts +0 -9
  291. package/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.d.ts +0 -9
  292. package/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.d.ts +0 -9
  293. package/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.d.ts +0 -10
  294. package/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.d.ts +0 -9
  295. package/src/templates/app/app/[lang]/(__appName__)/(user)/layout.d.ts +0 -9
  296. package/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.d.ts +0 -9
  297. package/src/templates/app/app/[lang]/(__appName__)/layout.d.ts +0 -9
  298. package/src/templates/app/app/[lang]/admin/layout.d.ts +0 -9
  299. package/src/templates/app/app/[lang]/admin/page.d.ts +0 -9
  300. package/src/templates/app/app/csr.d.ts +0 -9
  301. package/src/templates/app/app/layout.d.ts +0 -9
  302. package/src/templates/app/lib/setting/Setting.Template.d.ts +0 -9
  303. package/src/templates/app/lib/setting/Setting.Unit.d.ts +0 -9
  304. package/src/templates/app/lib/setting/Setting.Util.d.ts +0 -9
  305. package/src/templates/app/lib/setting/Setting.View.d.ts +0 -9
  306. package/src/templates/app/lib/setting/Setting.Zone.d.ts +0 -9
  307. package/src/templates/app/lib/setting/index.d.ts +0 -9
  308. package/src/templates/app/lib/summary/Summary.Template.d.ts +0 -9
  309. package/src/templates/app/lib/summary/Summary.Unit.d.ts +0 -9
  310. package/src/templates/app/lib/summary/Summary.Util.d.ts +0 -9
  311. package/src/templates/app/lib/summary/Summary.View.d.ts +0 -9
  312. package/src/templates/app/lib/summary/Summary.Zone.d.ts +0 -9
  313. package/src/templates/app/lib/summary/index.d.ts +0 -9
  314. package/src/templates/app/lib/user/User.Template.d.ts +0 -9
  315. package/src/templates/app/lib/user/User.Unit.d.ts +0 -9
  316. package/src/templates/app/lib/user/User.Util.d.ts +0 -9
  317. package/src/templates/app/lib/user/User.View.d.ts +0 -9
  318. package/src/templates/app/lib/user/User.Zone.d.ts +0 -9
  319. package/src/templates/app/lib/user/index.d.ts +0 -9
  320. package/src/templates/app/ui/Footer.d.ts +0 -9
  321. package/src/templates/app/ui/MainHeader.d.ts +0 -10
  322. package/src/templates/crudPages/[__model__Id]/edit/page.d.ts +0 -11
  323. package/src/templates/crudPages/[__model__Id]/page.d.ts +0 -11
  324. package/src/templates/crudPages/new/page.d.ts +0 -11
  325. package/src/templates/crudPages/page.d.ts +0 -11
  326. package/src/templates/libRoot/lib/setting/Setting.Template.d.ts +0 -9
  327. package/src/templates/libRoot/lib/setting/Setting.Unit.d.ts +0 -9
  328. package/src/templates/libRoot/lib/setting/Setting.Util.d.ts +0 -9
  329. package/src/templates/libRoot/lib/setting/Setting.View.d.ts +0 -9
  330. package/src/templates/libRoot/lib/setting/Setting.Zone.d.ts +0 -9
  331. package/src/templates/libRoot/lib/setting/index.d.ts +0 -9
  332. package/src/templates/libRoot/lib/summary/Summary.Template.d.ts +0 -9
  333. package/src/templates/libRoot/lib/summary/Summary.Unit.d.ts +0 -9
  334. package/src/templates/libRoot/lib/summary/Summary.Util.d.ts +0 -9
  335. package/src/templates/libRoot/lib/summary/Summary.View.d.ts +0 -9
  336. package/src/templates/libRoot/lib/summary/Summary.Zone.d.ts +0 -9
  337. package/src/templates/libRoot/lib/summary/index.d.ts +0 -9
  338. package/src/templates/libRoot/lib/user/User.Template.d.ts +0 -9
  339. package/src/templates/libRoot/lib/user/User.Unit.d.ts +0 -9
  340. package/src/templates/libRoot/lib/user/User.Util.d.ts +0 -9
  341. package/src/templates/libRoot/lib/user/User.View.d.ts +0 -9
  342. package/src/templates/libRoot/lib/user/User.Zone.d.ts +0 -9
  343. package/src/templates/libRoot/lib/user/index.d.ts +0 -9
  344. package/src/templates/module/__Model__.Template.d.ts +0 -11
  345. package/src/templates/module/__Model__.Unit.d.ts +0 -11
  346. package/src/templates/module/__Model__.Util.d.ts +0 -11
  347. package/src/templates/module/__Model__.View.d.ts +0 -11
  348. package/src/templates/module/__Model__.Zone.d.ts +0 -11
  349. package/src/templates/module/index.d.ts +0 -11
@@ -0,0 +1,1005 @@
1
+ # Akan.js Model.View.tsx Implementation Guide
2
+
3
+ ## Purpose and Role of Model.View.tsx Files in the Akan.js Architecture
4
+
5
+ Model.View.tsx files serve as specialized server components within the Akan.js framework that provide comprehensive presentation layers for domain models. They fulfill several critical roles:
6
+
7
+ - **Complete Data Visualization**: Present full, detailed views of domain entities
8
+ - **Page-Level Components**: Serve as primary content components for application pages
9
+ - **Consistent Representation**: Ensure uniform presentation of domain models
10
+ - **Server-Side Optimization**: Leverage Next.js server components for performance
11
+ - **Cross-Component Integration**: Provide view components that integrate with the broader component ecosystem
12
+
13
+ In the Akan.js component hierarchy, View components sit between high-level Zones (layout containers) and lower-level Units (list items/cards), providing comprehensive representations of domain models.
14
+
15
+ ## Core Principles of Model.View.tsx Components
16
+
17
+ 1. **Server-First Architecture**: View components are server components, optimized for static rendering
18
+ 2. **Presentation Focus**: Concentrate solely on displaying data, not managing state or handling interactions
19
+ 3. **Model-Centric Design**: Build around domain model structures (`cnst.Model`)
20
+ 4. **Composition-Based**: Composed of smaller, focused components for different aspects of the model
21
+ 5. **Responsive UI**: Adapt to different screen sizes and viewport conditions
22
+ 6. **Accessibility**: Follow best practices for screen readers and keyboard navigation
23
+ 7. **No Client-Side Hooks**: Avoid `useState`, `useEffect`, and other client-side React hooks
24
+
25
+ ## File Structure and Component Organization
26
+
27
+ ### Location and Naming Convention
28
+
29
+ ```
30
+ apps/
31
+ app-name/
32
+ lib/
33
+ feature-name/
34
+ FeatureName.View.tsx # PascalCase for file and component names
35
+ ```
36
+
37
+ ### Component Structure
38
+
39
+ A typical Model.View.tsx file exports multiple component variations:
40
+
41
+ ```tsx
42
+ import { clsx } from "clsx";
43
+ import { cnst } from "@your-lib/client";
44
+ import { Card, Section } from "@util/ui";
45
+
46
+ // Basic view interface
47
+ export interface ProductViewProps {
48
+ product: cnst.Product;
49
+ className?: string;
50
+ }
51
+
52
+ // General view (default/standard view)
53
+ export const General = ({ product, className }: ProductViewProps) => (
54
+ <div className={clsx("animate-fadeIn space-y-6", className)}>
55
+ <h1 className="text-2xl font-bold">{product.name}</h1>
56
+ <div className="flex gap-4">
57
+ <div className="w-2/3">
58
+ <h2 className="mb-2 text-xl">Description</h2>
59
+ <p>{product.description}</p>
60
+ {/* More product details */}
61
+ </div>
62
+ <div className="w-1/3">
63
+ <Card className="p-4">
64
+ <h3 className="mb-2 text-lg font-medium">Summary</h3>
65
+ <div className="space-y-2">
66
+ <div className="flex justify-between">
67
+ <span>Price:</span>
68
+ <span className="font-bold">{product.price.toLocaleString()} KRW</span>
69
+ </div>
70
+ <div className="flex justify-between">
71
+ <span>In Stock:</span>
72
+ <span>{product.inStock ? "Yes" : "No"}</span>
73
+ </div>
74
+ </div>
75
+ </Card>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ );
80
+
81
+ // Specialized views for different contexts
82
+ export const Dashboard = ({ product }: ProductViewProps) => (
83
+ <Section title={product.name} className="dashboard-view">
84
+ {/* Dashboard-specific presentation */}
85
+ </Section>
86
+ );
87
+
88
+ export const Printable = ({ product }: ProductViewProps) => (
89
+ <div className="print-only">{/* Print-optimized view */}</div>
90
+ );
91
+ ```
92
+
93
+ ## Props Design and Interfaces
94
+
95
+ Model.View components use consistent prop interfaces that follow these patterns:
96
+
97
+ ```tsx
98
+ // Basic pattern
99
+ export interface ProductViewProps {
100
+ product: cnst.Product; // The primary model object
101
+ className?: string; // For styling customization
102
+ }
103
+
104
+ // With additional configuration options
105
+ export interface OrderViewProps {
106
+ order: cnst.Order;
107
+ className?: string;
108
+ showDetails?: boolean; // Optional display configuration
109
+ highlightStatus?: boolean;
110
+ }
111
+
112
+ // With variant/type discrimination
113
+ export type InvoiceViewProps =
114
+ | { invoice: cnst.Invoice; variant: "summary"; className?: string }
115
+ | { invoice: cnst.Invoice; variant: "detailed"; showPayments: boolean; className?: string };
116
+
117
+ export const Invoice = (props: InvoiceViewProps) => {
118
+ if (props.variant === "summary") {
119
+ return <InvoiceSummary invoice={props.invoice} className={props.className} />;
120
+ } else {
121
+ return <InvoiceDetailed invoice={props.invoice} showPayments={props.showPayments} className={props.className} />;
122
+ }
123
+ };
124
+ ```
125
+
126
+ ## Component Variations and Specialized Views
127
+
128
+ Model.View components typically include multiple variations for different use cases:
129
+
130
+ 1. **General**: Standard, complete view of the model
131
+ 2. **Summary/Dashboard**: Condensed view with key information
132
+ 3. **Detailed**: Expanded view with all available information
133
+ 4. **Print/Export**: View optimized for printing or exporting
134
+ 5. **Specialized**: Context-specific views (admin, customer, etc.)
135
+
136
+ Example implementation:
137
+
138
+ ```tsx
139
+ // General view (standard)
140
+ export const General = ({ project }: ProjectViewProps) => (
141
+ <div className="project-view">
142
+ <h1>{project.name}</h1>
143
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2">{/* Project information organized in a grid */}</div>
144
+ </div>
145
+ );
146
+
147
+ // Timeline view (specialized)
148
+ export const Timeline = ({ project }: ProjectViewProps) => (
149
+ <div className="project-timeline">{/* Timeline visualization of project milestones */}</div>
150
+ );
151
+
152
+ // Financial view (specialized)
153
+ export const Financial = ({ project }: ProjectViewProps) => (
154
+ <div className="project-financials">{/* Financial breakdown and charts */}</div>
155
+ );
156
+ ```
157
+
158
+ ## Integration with Other Akan.js Components
159
+
160
+ Model.View components work seamlessly with other components in the Akan.js ecosystem:
161
+
162
+ ### Used in Pages
163
+
164
+ ```tsx
165
+ // app/products/[id]/page.tsx
166
+ import { Product } from "@shared/client";
167
+
168
+ export default async function ProductPage({ params }: { params: { id: string } }) {
169
+ const product = await getProductById(params.id);
170
+
171
+ return (
172
+ <div className="container mx-auto py-8">
173
+ <Product.View.General product={product} />
174
+ </div>
175
+ );
176
+ }
177
+ ```
178
+
179
+ ### Used in Utils (Client Components)
180
+
181
+ ```tsx
182
+ // Product.Util.tsx
183
+ "use client";
184
+ import { useState } from "react";
185
+ import { Product } from "@shared/client";
186
+ import { cnst, st } from "@shared/client";
187
+
188
+ export const ProductViewer = ({ productId }: { productId: string }) => {
189
+ const product = st.use.product(productId);
190
+ const [view, setView] = useState<"general" | "specifications">("general");
191
+
192
+ if (!product) return <div>Loading...</div>;
193
+
194
+ return (
195
+ <div>
196
+ <div className="tabs mb-4">
197
+ <button className={`tab ${view === "general" ? "tab-active" : ""}`} onClick={() => setView("general")}>
198
+ General
199
+ </button>
200
+ <button
201
+ className={`tab ${view === "specifications" ? "tab-active" : ""}`}
202
+ onClick={() => setView("specifications")}
203
+ >
204
+ Specifications
205
+ </button>
206
+ </div>
207
+
208
+ {view === "general" ? (
209
+ <Product.View.General product={product} />
210
+ ) : (
211
+ <Product.View.Specifications product={product} />
212
+ )}
213
+ </div>
214
+ );
215
+ };
216
+ ```
217
+
218
+ ### Used in Zones (Layout Containers)
219
+
220
+ ```tsx
221
+ // Product.Zone.tsx
222
+ "use client";
223
+ import { useState } from "react";
224
+ import { Product } from "@shared/client";
225
+ import { cnst, st } from "@shared/client";
226
+ import { Zone } from "@util/ui";
227
+
228
+ export const ProductManagerZone = () => {
229
+ const products = st.use.productList();
230
+ const [selectedProduct, setSelectedProduct] = useState<cnst.Product | null>(null);
231
+
232
+ return (
233
+ <Zone title="Product Management">
234
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
235
+ <div className="lg:col-span-1">
236
+ <Zone.Section title="Products">
237
+ {/* Product list for selection */}
238
+ {products.map((product) => (
239
+ <button key={product.id} onClick={() => setSelectedProduct(product)} className="mb-2 w-full text-left">
240
+ <Product.Unit.Abstract product={product} />
241
+ </button>
242
+ ))}
243
+ </Zone.Section>
244
+ </div>
245
+
246
+ <div className="lg:col-span-2">
247
+ <Zone.Section title="Selected Product">
248
+ {selectedProduct ? (
249
+ <Product.View.General product={selectedProduct} />
250
+ ) : (
251
+ <div className="py-8 text-center text-gray-500">Select a product to view details</div>
252
+ )}
253
+ </Zone.Section>
254
+ </div>
255
+ </div>
256
+ </Zone>
257
+ );
258
+ };
259
+ ```
260
+
261
+ ## Server Component Considerations
262
+
263
+ Model.View.tsx files are server components and must follow these constraints:
264
+
265
+ 1. **No Client-Side Hooks**:
266
+
267
+ - No `useState`, `useEffect`, `useRef`, etc.
268
+ - No `useRouter` or other Next.js client hooks
269
+ - No browser APIs (`window`, `localStorage`, etc.)
270
+
271
+ 2. **No Event Handlers**:
272
+
273
+ - No `onClick`, `onChange`, or other event handlers
274
+ - No form submission handling
275
+
276
+ 3. **No "use client" Directive**:
277
+
278
+ - The file should not include the "use client" directive
279
+
280
+ 4. **Static Props Only**:
281
+ - Props should be static and not depend on client-side state
282
+ - Data should be passed in explicitly through props
283
+
284
+ If you need interactivity, wrap the View component in a client component (typically in a Util.tsx file).
285
+
286
+ ## Best Practices for Effective View Components
287
+
288
+ ### 1. Consistent Layout Structure
289
+
290
+ ```tsx
291
+ export const General = ({ invoice }: InvoiceViewProps) => (
292
+ <div className="space-y-8">
293
+ {/* Header section */}
294
+ <div className="flex items-center justify-between">
295
+ <h1 className="text-2xl font-bold">Invoice #{invoice.number}</h1>
296
+ <div className="badge badge-lg">{invoice.status}</div>
297
+ </div>
298
+
299
+ {/* Metadata section */}
300
+ <div className="grid grid-cols-2 gap-4 rounded-lg bg-gray-50 p-4">
301
+ <div>
302
+ <h2 className="text-sm text-gray-500">Client</h2>
303
+ <p className="font-medium">{invoice.client.name}</p>
304
+ </div>
305
+ <div>
306
+ <h2 className="text-sm text-gray-500">Issue Date</h2>
307
+ <p className="font-medium">{formatDate(invoice.issueDate)}</p>
308
+ </div>
309
+ {/* More metadata fields */}
310
+ </div>
311
+
312
+ {/* Main content section */}
313
+ <div>
314
+ <h2 className="mb-4 text-xl font-semibold">Line Items</h2>
315
+ <table className="w-full">{/* Table content */}</table>
316
+ </div>
317
+
318
+ {/* Summary section */}
319
+ <div className="flex justify-end">
320
+ <div className="w-64 space-y-2">
321
+ <div className="flex justify-between">
322
+ <span>Subtotal:</span>
323
+ <span>{formatCurrency(invoice.subtotal)}</span>
324
+ </div>
325
+ {/* More summary rows */}
326
+ <div className="flex justify-between border-t pt-2 text-lg font-bold">
327
+ <span>Total:</span>
328
+ <span>{formatCurrency(invoice.total)}</span>
329
+ </div>
330
+ </div>
331
+ </div>
332
+ </div>
333
+ );
334
+ ```
335
+
336
+ ### 2. Responsive Design
337
+
338
+ ```tsx
339
+ export const General = ({ product }: ProductViewProps) => (
340
+ <div className="animate-fadeIn">
341
+ <div className="flex flex-col gap-6 lg:flex-row">
342
+ {/* Images - full width on mobile, 40% on desktop */}
343
+ <div className="w-full lg:w-2/5">
344
+ {product.images && product.images.length > 0 ? (
345
+ <div className="relative aspect-square overflow-hidden rounded-lg">
346
+ <Image src={product.images[0].url} alt={product.name} fill className="object-cover" />
347
+ </div>
348
+ ) : (
349
+ <div className="flex aspect-square items-center justify-center rounded-lg bg-gray-200">
350
+ <span className="text-gray-400">No image available</span>
351
+ </div>
352
+ )}
353
+ </div>
354
+
355
+ {/* Product info - full width on mobile, 60% on desktop */}
356
+ <div className="w-full lg:w-3/5">
357
+ <h1 className="text-xl font-bold md:text-2xl lg:text-3xl">{product.name}</h1>
358
+ <div className="text-primary mt-2 text-lg font-medium md:text-xl">{formatCurrency(product.price)}</div>
359
+
360
+ {/* Responsive grid for specifications */}
361
+ <div className="mt-6 grid grid-cols-1 gap-4 md:grid-cols-2">
362
+ {product.specifications.map((spec) => (
363
+ <div key={spec.id} className="border-b pb-2">
364
+ <span className="text-sm text-gray-500">{spec.name}:</span>
365
+ <div>{spec.value}</div>
366
+ </div>
367
+ ))}
368
+ </div>
369
+ </div>
370
+ </div>
371
+ </div>
372
+ );
373
+ ```
374
+
375
+ ### 3. Conditional Rendering for Edge Cases
376
+
377
+ ```tsx
378
+ export const General = ({ order }: OrderViewProps) => (
379
+ <div className="order-view">
380
+ <h1 className="text-2xl font-bold">Order #{order.number}</h1>
381
+
382
+ {/* Handle missing customer information */}
383
+ <div className="mt-4">
384
+ <h2 className="text-lg font-medium">Customer</h2>
385
+ {order.customer ? (
386
+ <div className="mt-2">
387
+ <p>{order.customer.name}</p>
388
+ <p>{order.customer.email}</p>
389
+ <p>{order.customer.phone || "No phone provided"}</p>
390
+ </div>
391
+ ) : (
392
+ <p className="text-gray-500 italic">Customer information not available</p>
393
+ )}
394
+ </div>
395
+
396
+ {/* Handle empty item lists */}
397
+ <div className="mt-6">
398
+ <h2 className="text-lg font-medium">Items</h2>
399
+ {order.items && order.items.length > 0 ? (
400
+ <table className="mt-2 w-full">{/* Table content */}</table>
401
+ ) : (
402
+ <p className="mt-2 text-gray-500 italic">No items in this order</p>
403
+ )}
404
+ </div>
405
+
406
+ {/* Conditional sections based on order status */}
407
+ {order.status === "delivered" && (
408
+ <div className="mt-6 rounded-lg bg-green-50 p-4">
409
+ <h2 className="text-lg font-medium text-green-800">Delivery Information</h2>
410
+ <p className="mt-2">Delivered on: {formatDate(order.deliveryDate)}</p>
411
+ {order.signedBy && <p>Signed by: {order.signedBy}</p>}
412
+ </div>
413
+ )}
414
+ </div>
415
+ );
416
+ ```
417
+
418
+ ### 4. Component Composition for Complex Views
419
+
420
+ ```tsx
421
+ // Helper components for complex views
422
+ const OrderHeader = ({ order }: { order: cnst.Order }) => (
423
+ <div className="flex items-center justify-between">
424
+ <h1 className="text-2xl font-bold">Order #{order.number}</h1>
425
+ <StatusBadge status={order.status} />
426
+ </div>
427
+ );
428
+
429
+ const StatusBadge = ({ status }: { status: string }) => {
430
+ const statusStyles = {
431
+ pending: "bg-yellow-100 text-yellow-800",
432
+ processing: "bg-blue-100 text-blue-800",
433
+ shipped: "bg-purple-100 text-purple-800",
434
+ delivered: "bg-green-100 text-green-800",
435
+ cancelled: "bg-red-100 text-red-800",
436
+ };
437
+
438
+ return (
439
+ <span className={`rounded-full px-3 py-1 text-sm font-medium ${statusStyles[status] || "bg-gray-100"}`}>
440
+ {status}
441
+ </span>
442
+ );
443
+ };
444
+
445
+ const OrderItems = ({ items }: { items: cnst.OrderItem[] }) => (
446
+ <div className="mt-6">
447
+ <h2 className="mb-2 text-lg font-medium">Items</h2>
448
+ <div className="overflow-hidden rounded-lg border">
449
+ {items.map((item, index) => (
450
+ <div
451
+ key={item.id}
452
+ className={clsx("flex items-center justify-between p-4", index < items.length - 1 && "border-b")}
453
+ >
454
+ <div className="flex items-center">
455
+ {item.product.image && (
456
+ <div className="mr-4 h-12 w-12">
457
+ <Image src={item.product.image} alt={item.product.name} width={48} height={48} />
458
+ </div>
459
+ )}
460
+ <div>
461
+ <div className="font-medium">{item.product.name}</div>
462
+ <div className="text-sm text-gray-500">Qty: {item.quantity}</div>
463
+ </div>
464
+ </div>
465
+ <div className="text-right">
466
+ <div>{formatCurrency(item.price)}</div>
467
+ <div className="text-sm text-gray-500">{formatCurrency(item.price * item.quantity)}</div>
468
+ </div>
469
+ </div>
470
+ ))}
471
+ </div>
472
+ </div>
473
+ );
474
+
475
+ // Main component combining the pieces
476
+ export const General = ({ order }: OrderViewProps) => (
477
+ <div className="space-y-6">
478
+ <OrderHeader order={order} />
479
+ <CustomerSection customer={order.customer} />
480
+ <OrderItems items={order.items} />
481
+ <ShippingSection shipping={order.shipping} />
482
+ <PaymentSection payment={order.payment} />
483
+ <TotalsSection totals={order.totals} />
484
+ </div>
485
+ );
486
+ ```
487
+
488
+ ## How to Use Model.View.tsx in Pages, Utils and Zones
489
+
490
+ ### In Pages (Server Components)
491
+
492
+ ```tsx
493
+ // app/orders/[id]/page.tsx
494
+ import { Order } from "@shared/client";
495
+ import { getOrderById } from "@shared/lib/order/order.service";
496
+
497
+ export default async function OrderPage({ params }: { params: { id: string } }) {
498
+ const order = await getOrderById(params.id);
499
+
500
+ return (
501
+ <div className="container mx-auto py-8">
502
+ <Order.View.General order={order} />
503
+ </div>
504
+ );
505
+ }
506
+ ```
507
+
508
+ ### In Utils (Client Components)
509
+
510
+ ```tsx
511
+ // Order.Util.tsx
512
+ "use client";
513
+ import { useState } from "react";
514
+ import { Order } from "@shared/client";
515
+ import { st } from "@shared/client";
516
+
517
+ export const OrderViewer = ({ orderId }: { orderId: string }) => {
518
+ const order = st.use.order(orderId);
519
+ const [view, setView] = useState<"general" | "items" | "shipping">("general");
520
+
521
+ if (!order) return <div className="animate-pulse">Loading...</div>;
522
+
523
+ return (
524
+ <div>
525
+ <div className="tabs mb-4">
526
+ <button className={`tab ${view === "general" ? "tab-active" : ""}`} onClick={() => setView("general")}>
527
+ Overview
528
+ </button>
529
+ <button className={`tab ${view === "items" ? "tab-active" : ""}`} onClick={() => setView("items")}>
530
+ Items
531
+ </button>
532
+ <button className={`tab ${view === "shipping" ? "tab-active" : ""}`} onClick={() => setView("shipping")}>
533
+ Shipping
534
+ </button>
535
+ </div>
536
+
537
+ {view === "general" && <Order.View.General order={order} />}
538
+ {view === "items" && <Order.View.Items order={order} />}
539
+ {view === "shipping" && <Order.View.Shipping order={order} />}
540
+
541
+ <div className="mt-6 flex justify-end space-x-2">
542
+ <button className="btn btn-outline" onClick={() => st.do.printOrder(orderId)}>
543
+ Print
544
+ </button>
545
+ {order.status === "pending" && (
546
+ <button className="btn btn-primary" onClick={() => st.do.processOrder(orderId)}>
547
+ Process Order
548
+ </button>
549
+ )}
550
+ </div>
551
+ </div>
552
+ );
553
+ };
554
+ ```
555
+
556
+ ### In Zones (Layout Containers)
557
+
558
+ ```tsx
559
+ // Dashboard.Zone.tsx
560
+ "use client";
561
+ import { useState, useEffect } from "react";
562
+ import { Order, Product } from "@shared/client";
563
+ import { sig } from "@shared/client";
564
+ import { Zone, Tabs } from "@util/ui";
565
+
566
+ export const AnalyticsDashboard = () => {
567
+ const [data, setData] = useState(null);
568
+ const [loading, setLoading] = useState(true);
569
+
570
+ useEffect(() => {
571
+ const loadData = async () => {
572
+ setLoading(true);
573
+ try {
574
+ const dashboardData = await sig.analytics.getDashboardData();
575
+ setData(dashboardData);
576
+ } catch (error) {
577
+ console.error("Failed to load dashboard data", error);
578
+ } finally {
579
+ setLoading(false);
580
+ }
581
+ };
582
+
583
+ loadData();
584
+ }, []);
585
+
586
+ if (loading) return <div className="animate-pulse">Loading dashboard...</div>;
587
+ if (!data) return <div>Failed to load dashboard data</div>;
588
+
589
+ return (
590
+ <Zone title="Business Analytics">
591
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
592
+ <Zone.Section title="Recent Orders">
593
+ {data.recentOrders.map((order) => (
594
+ <div key={order.id} className="mb-4">
595
+ <Order.View.Summary order={order} />
596
+ </div>
597
+ ))}
598
+ </Zone.Section>
599
+
600
+ <Zone.Section title="Top Products">
601
+ {data.topProducts.map((product) => (
602
+ <div key={product.id} className="mb-4">
603
+ <Product.View.Performance product={product} />
604
+ </div>
605
+ ))}
606
+ </Zone.Section>
607
+ </div>
608
+
609
+ <Zone.Section title="Sales Overview">
610
+ <SalesChart data={data.salesData} />
611
+ </Zone.Section>
612
+ </Zone>
613
+ );
614
+ };
615
+ ```
616
+
617
+ ## Common Patterns and Advanced Techniques
618
+
619
+ ### 1. Status-Based Visualizations
620
+
621
+ ```tsx
622
+ export const StatusSummary = ({ project }: ProjectViewProps) => {
623
+ // Determine color based on status
624
+ const statusColor =
625
+ {
626
+ planning: "bg-blue-100 text-blue-800",
627
+ active: "bg-green-100 text-green-800",
628
+ onHold: "bg-yellow-100 text-yellow-800",
629
+ completed: "bg-purple-100 text-purple-800",
630
+ cancelled: "bg-red-100 text-red-800",
631
+ }[project.status] || "bg-gray-100 text-gray-800";
632
+
633
+ // Calculate progress percentage
634
+ const progress = (project.completedTasks / (project.totalTasks || 1)) * 100;
635
+
636
+ return (
637
+ <div className="rounded-lg border p-4">
638
+ <div className="mb-4 flex items-center justify-between">
639
+ <h2 className="text-lg font-bold">{project.name}</h2>
640
+ <span className={`rounded-full px-3 py-1 text-sm font-medium ${statusColor}`}>{project.status}</span>
641
+ </div>
642
+
643
+ <div className="space-y-2">
644
+ <div className="flex justify-between text-sm">
645
+ <span>Progress</span>
646
+ <span>{Math.round(progress)}%</span>
647
+ </div>
648
+ <div className="h-2.5 w-full rounded-full bg-gray-200">
649
+ <div className="h-2.5 rounded-full bg-blue-600" style={{ width: `${progress}%` }}></div>
650
+ </div>
651
+ </div>
652
+
653
+ <div className="mt-4 grid grid-cols-2 gap-4 text-center">
654
+ <div>
655
+ <div className="text-sm text-gray-500">Tasks</div>
656
+ <div className="font-bold">
657
+ {project.completedTasks}/{project.totalTasks}
658
+ </div>
659
+ </div>
660
+ <div>
661
+ <div className="text-sm text-gray-500">Due Date</div>
662
+ <div className="font-bold">{formatDate(project.dueDate)}</div>
663
+ </div>
664
+ </div>
665
+ </div>
666
+ );
667
+ };
668
+ ```
669
+
670
+ ### 2. Hierarchical Data Display
671
+
672
+ ```tsx
673
+ export const OrgChart = ({ department }: DepartmentViewProps) => {
674
+ // Recursive component for displaying a department and its subdepartments
675
+ const DepartmentNode = ({ dept, level = 0 }: { dept: cnst.Department; level: number }) => (
676
+ <div className={`pl-${level * 6}`}>
677
+ <div className="my-1 flex items-center rounded border p-2">
678
+ <div className="font-bold">{dept.name}</div>
679
+ <div className="ml-2 text-sm text-gray-500">({dept.employeeCount} employees)</div>
680
+ </div>
681
+
682
+ {dept.subdepartments?.map((subdept) => <DepartmentNode key={subdept.id} dept={subdept} level={level + 1} />)}
683
+ </div>
684
+ );
685
+
686
+ return (
687
+ <div className="department-hierarchy">
688
+ <h2 className="mb-4 text-xl font-bold">Organization Structure</h2>
689
+ <DepartmentNode dept={department} level={0} />
690
+ </div>
691
+ );
692
+ };
693
+ ```
694
+
695
+ ### 3. Multi-Section Views with Tabs
696
+
697
+ ```tsx
698
+ export const Product = ({ product }: ProductViewProps) => (
699
+ <div className="product-view">
700
+ <h1 className="mb-6 text-2xl font-bold">{product.name}</h1>
701
+
702
+ <div className="tabs tabs-boxed mb-6">
703
+ <a className="tab tab-active">Overview</a>
704
+ <a className="tab">Specifications</a>
705
+ <a className="tab">Reviews</a>
706
+ </div>
707
+
708
+ <div className="tab-content">
709
+ {/* Overview section - active by default */}
710
+ <div className="space-y-4">
711
+ <div className="flex flex-col gap-6 md:flex-row">
712
+ {/* Product image */}
713
+ <div className="md:w-1/2">
714
+ {product.image && (
715
+ <div className="aspect-square overflow-hidden rounded-lg">
716
+ <Image src={product.image} alt={product.name} fill className="object-contain" />
717
+ </div>
718
+ )}
719
+ </div>
720
+
721
+ {/* Product details */}
722
+ <div className="md:w-1/2">
723
+ <div className="text-primary text-xl font-bold">{formatCurrency(product.price)}</div>
724
+
725
+ <div className="mt-4">
726
+ <h2 className="mb-2 text-lg font-medium">Description</h2>
727
+ <p>{product.description}</p>
728
+ </div>
729
+
730
+ <div className="mt-4">
731
+ <h2 className="mb-2 text-lg font-medium">Features</h2>
732
+ <ul className="list-disc space-y-1 pl-5">
733
+ {product.features?.map((feature, index) => <li key={index}>{feature}</li>)}
734
+ </ul>
735
+ </div>
736
+ </div>
737
+ </div>
738
+ </div>
739
+
740
+ {/* Other tab contents would be here but hidden initially */}
741
+ </div>
742
+ </div>
743
+ );
744
+ ```
745
+
746
+ ## Performance Optimization Strategies
747
+
748
+ ### 1. Optimize Images and Media
749
+
750
+ ```tsx
751
+ import { Image } from "@util/ui"; // Optimized image component
752
+
753
+ export const General = ({ product }: ProductViewProps) => (
754
+ <div className="product-view">
755
+ {product.image && (
756
+ <Image
757
+ src={product.image}
758
+ alt={product.name}
759
+ width={600}
760
+ height={600}
761
+ sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
762
+ priority={false}
763
+ loading="lazy"
764
+ className="h-auto w-full rounded-lg object-contain"
765
+ />
766
+ )}
767
+ {/* Rest of the product view */}
768
+ </div>
769
+ );
770
+ ```
771
+
772
+ ### 2. Conditional Rendering for Complex Content
773
+
774
+ ```tsx
775
+ export const Dashboard = ({ project }: ProjectViewProps) => (
776
+ <div className="project-dashboard">
777
+ {/* Always render essential information */}
778
+ <div className="mb-6">
779
+ <h1 className="text-2xl font-bold">{project.name}</h1>
780
+ <div className="mt-2 flex gap-2">
781
+ <span className={`badge ${getStatusBadgeClass(project.status)}`}>{project.status}</span>
782
+ <span className="text-sm text-gray-500">Due: {formatDate(project.dueDate)}</span>
783
+ </div>
784
+ </div>
785
+
786
+ {/* Only render charts if project has tasks */}
787
+ {project.tasks?.length > 0 && (
788
+ <div className="mb-6">
789
+ <h2 className="mb-2 text-lg font-medium">Progress Overview</h2>
790
+ <ProgressChart tasks={project.tasks} />
791
+ </div>
792
+ )}
793
+
794
+ {/* Only render team section if project has team members */}
795
+ {project.team?.length > 0 && (
796
+ <div className="mb-6">
797
+ <h2 className="mb-2 text-lg font-medium">Team</h2>
798
+ <div className="flex flex-wrap gap-2">
799
+ {project.team.map((member) => (
800
+ <TeamMemberBadge key={member.id} member={member} />
801
+ ))}
802
+ </div>
803
+ </div>
804
+ )}
805
+ </div>
806
+ );
807
+ ```
808
+
809
+ ### 3. Chunking Large Data Displays
810
+
811
+ ```tsx
812
+ export const OrderList = ({ orders }: { orders: cnst.Order[] }) => (
813
+ <div className="space-y-6">
814
+ <h2 className="text-xl font-bold">Orders ({orders.length})</h2>
815
+
816
+ {/* Group orders by month for better organization */}
817
+ {Object.entries(groupByMonth(orders)).map(([month, monthOrders]) => (
818
+ <div key={month}>
819
+ <h3 className="mb-2 text-lg font-medium">{month}</h3>
820
+ <div className="space-y-2">
821
+ {monthOrders.map((order) => (
822
+ <Order.View.Summary key={order.id} order={order} />
823
+ ))}
824
+ </div>
825
+ </div>
826
+ ))}
827
+ </div>
828
+ );
829
+
830
+ // Helper function to group orders by month
831
+ function groupByMonth(orders: cnst.Order[]) {
832
+ return orders.reduce((groups, order) => {
833
+ const month = new Date(order.createdAt).toLocaleString("default", { month: "long", year: "numeric" });
834
+ if (!groups[month]) groups[month] = [];
835
+ groups[month].push(order);
836
+ return groups;
837
+ }, {});
838
+ }
839
+ ```
840
+
841
+ ## Troubleshooting and Common Issues
842
+
843
+ ### 1. "useState is not defined" or "use client" Error
844
+
845
+ **Problem**: Server component using client-side hooks
846
+
847
+ ```tsx
848
+ // ❌ Error: This is a server component that's using client-side hooks
849
+ export const ProductView = ({ product }) => {
850
+ const [expanded, setExpanded] = useState(false);
851
+ // ...
852
+ };
853
+ ```
854
+
855
+ **Solution**: Move interactive elements to client components
856
+
857
+ ```tsx
858
+ // ✅ Server component (View.tsx) - pure presentation
859
+ export const ProductView = ({ product, expanded = false }) => (
860
+ <div>
861
+ <h1>{product.name}</h1>
862
+ {expanded && <div className="mt-4">{/* Additional details */}</div>}
863
+ </div>
864
+ );
865
+
866
+ // In a separate Util.tsx file (client component)
867
+ ("use client");
868
+ import { useState } from "react";
869
+ import { Product } from "@your-lib/client";
870
+
871
+ export const ExpandableProduct = ({ product }) => {
872
+ const [expanded, setExpanded] = useState(false);
873
+
874
+ return (
875
+ <div>
876
+ <Product.View.ProductView product={product} expanded={expanded} />
877
+ <button onClick={() => setExpanded(!expanded)}>{expanded ? "Show Less" : "Show More"}</button>
878
+ </div>
879
+ );
880
+ };
881
+ ```
882
+
883
+ ### 2. Missing or Undefined Data
884
+
885
+ **Problem**: Trying to access properties on potentially undefined data
886
+
887
+ ```tsx
888
+ // ❌ Error: Cannot read properties of undefined (reading 'name')
889
+ export const CustomerView = ({ order }) => (
890
+ <div>
891
+ <h2>Customer</h2>
892
+ <p>{order.customer.name}</p> // Error if customer is undefined
893
+ <p>{order.customer.email}</p>
894
+ </div>
895
+ );
896
+ ```
897
+
898
+ **Solution**: Add proper null checks and fallbacks
899
+
900
+ ```tsx
901
+ // ✅ With proper null checks
902
+ export const CustomerView = ({ order }) => (
903
+ <div>
904
+ <h2>Customer</h2>
905
+ {order.customer ? (
906
+ <>
907
+ <p>{order.customer.name}</p>
908
+ <p>{order.customer.email || "No email provided"}</p>
909
+ </>
910
+ ) : (
911
+ <p className="text-gray-500 italic">No customer information available</p>
912
+ )}
913
+ </div>
914
+ );
915
+ ```
916
+
917
+ ### 3. Layout Shifts Due to Conditional Rendering
918
+
919
+ **Problem**: Content jumps when conditional elements render
920
+
921
+ **Solution**: Use fixed-height placeholders or layout containers
922
+
923
+ ```tsx
924
+ export const ProductDetails = ({ product }: ProductViewProps) => (
925
+ <div className="product-details">
926
+ {/* Images - maintain consistent height */}
927
+ <div className="aspect-square overflow-hidden rounded-lg bg-gray-100">
928
+ {product.image ? (
929
+ <Image src={product.image} alt={product.name} fill className="object-cover" />
930
+ ) : (
931
+ <div className="flex h-full items-center justify-center">
932
+ <span className="text-gray-400">No image available</span>
933
+ </div>
934
+ )}
935
+ </div>
936
+
937
+ {/* Product information with consistent spacing */}
938
+ <div className="mt-4 min-h-[200px]">
939
+ <h1 className="text-xl font-bold">{product.name}</h1>
940
+ <div className="text-primary mt-2 font-bold">{formatCurrency(product.price)}</div>
941
+
942
+ <div className="mt-4 h-[100px] overflow-auto">
943
+ {product.description ? (
944
+ <p>{product.description}</p>
945
+ ) : (
946
+ <p className="text-gray-500 italic">No description available</p>
947
+ )}
948
+ </div>
949
+ </div>
950
+ </div>
951
+ );
952
+ ```
953
+
954
+ ### 4. Over-Fetching Data in Nested Views
955
+
956
+ **Problem**: Nested components causing excessive data fetching
957
+
958
+ **Solution**: Pass only required data from parent to child components
959
+
960
+ ```tsx
961
+ // Parent component passes only necessary data
962
+ export const OrderView = ({ order }: OrderViewProps) => (
963
+ <div className="order-view">
964
+ <h1>Order #{order.number}</h1>
965
+
966
+ <div className="mt-6">
967
+ <h2>Customer</h2>
968
+ <CustomerSummary customer={order.customer} />
969
+ </div>
970
+
971
+ <div className="mt-6">
972
+ <h2>Items</h2>
973
+ {order.items.map((item) => (
974
+ <OrderItemRow
975
+ key={item.id}
976
+ productName={item.product.name}
977
+ quantity={item.quantity}
978
+ price={item.price}
979
+ // Only pass needed fields, not the entire product object
980
+ />
981
+ ))}
982
+ </div>
983
+ </div>
984
+ );
985
+ ```
986
+
987
+ ## Conclusion
988
+
989
+ Model.View.tsx components are a fundamental building block in the Akan.js component architecture, providing consistent, reusable presentation layers for domain models. By following the guidelines in this document, you'll create View components that:
990
+
991
+ - Provide comprehensive visual representations of domain models
992
+ - Work seamlessly with other components in the Akan.js ecosystem
993
+ - Leverage the performance benefits of Next.js server components
994
+ - Are maintainable, scalable, and follow consistent patterns
995
+
996
+ Remember the key principles:
997
+
998
+ 1. Focus on presentation, not interaction
999
+ 2. Follow server component constraints
1000
+ 3. Organize in logical component variations
1001
+ 4. Design for reuse across pages, Utils, and Zones
1002
+ 5. Handle edge cases and provide fallbacks
1003
+ 6. Optimize for performance and accessibility
1004
+
1005
+ With these principles in mind, your Model.View.tsx components will provide a solid foundation for your Akan.js application's user interface.