@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.
- package/README.md +8 -0
- package/cjs/index.js +2437 -3204
- package/cjs/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
- package/cjs/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/cjs/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/cjs/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/cjs/src/guidelines/componentRule/componentRule.instruction.md +732 -0
- package/cjs/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
- package/cjs/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/cjs/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
- package/cjs/src/guidelines/framework/framework.instruction.md +1112 -0
- package/cjs/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
- package/cjs/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
- package/cjs/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
- package/cjs/src/guidelines/modelService/modelService.instruction.md +935 -0
- package/cjs/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
- package/cjs/src/guidelines/modelStore/modelStore.instruction.md +591 -0
- package/cjs/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
- package/cjs/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
- package/cjs/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/cjs/src/guidelines/modelView/modelView.instruction.md +1005 -0
- package/cjs/src/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/cjs/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
- package/cjs/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
- package/cjs/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
- package/cjs/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/cjs/src/templates/module/__model__.dictionary.js +4 -5
- package/esm/index.js +2524 -3286
- package/esm/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
- package/esm/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/esm/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/esm/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/esm/src/guidelines/componentRule/componentRule.instruction.md +732 -0
- package/esm/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
- package/esm/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/esm/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
- package/esm/src/guidelines/framework/framework.instruction.md +1112 -0
- package/esm/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
- package/esm/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
- package/esm/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
- package/esm/src/guidelines/modelService/modelService.instruction.md +935 -0
- package/esm/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
- package/esm/src/guidelines/modelStore/modelStore.instruction.md +591 -0
- package/esm/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
- package/esm/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
- package/esm/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/esm/src/guidelines/modelView/modelView.instruction.md +1005 -0
- package/esm/src/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/esm/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
- package/esm/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
- package/esm/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
- package/esm/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/esm/src/templates/module/__model__.dictionary.js +4 -5
- package/package.json +3 -1
- package/src/guideline/guideline.command.d.ts +7 -0
- package/src/guideline/guideline.prompt.d.ts +15 -0
- package/src/guideline/guideline.runner.d.ts +5 -0
- package/src/guideline/guideline.script.d.ts +6 -0
- package/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
- package/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/src/guidelines/componentRule/componentRule.instruction.md +732 -0
- package/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
- package/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
- package/src/guidelines/framework/framework.instruction.md +1112 -0
- package/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
- package/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
- package/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
- package/src/guidelines/modelService/modelService.instruction.md +935 -0
- package/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
- package/src/guidelines/modelStore/modelStore.instruction.md +591 -0
- package/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
- package/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
- package/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/src/guidelines/modelView/modelView.instruction.md +1005 -0
- package/src/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
- package/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
- package/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
- package/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/src/module/module.command.d.ts +6 -8
- package/src/module/module.prompt.d.ts +2 -15
- package/src/module/module.request.d.ts +22 -18
- package/src/module/module.runner.d.ts +4 -20
- package/src/module/module.script.d.ts +6 -7
- package/src/scalar/scalar.command.d.ts +7 -0
- package/src/scalar/scalar.prompt.d.ts +23 -0
- package/src/scalar/scalar.runner.d.ts +13 -0
- package/src/scalar/scalar.script.d.ts +6 -0
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -47
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -128
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -42
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -50
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -41
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -51
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -43
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -60
- package/cjs/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -54
- package/cjs/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
- package/cjs/src/templates/app/app/[lang]/admin/layout.js +0 -54
- package/cjs/src/templates/app/app/[lang]/admin/page.js +0 -63
- package/cjs/src/templates/app/app/csr.js +0 -34
- package/cjs/src/templates/app/app/index.html.template +0 -13
- package/cjs/src/templates/app/app/layout.js +0 -38
- package/cjs/src/templates/app/capacitor.config.ts.template +0 -8
- package/cjs/src/templates/app/env/env.client.debug.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.develop.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.local.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.main.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.testing.ts.template +0 -7
- package/cjs/src/templates/app/env/env.server.debug.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.develop.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.local.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.main.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.testing.ts.template +0 -7
- package/cjs/src/templates/app/lib/setting/Setting.Template.js +0 -57
- package/cjs/src/templates/app/lib/setting/Setting.Unit.js +0 -38
- package/cjs/src/templates/app/lib/setting/Setting.Util.js +0 -34
- package/cjs/src/templates/app/lib/setting/Setting.View.js +0 -51
- package/cjs/src/templates/app/lib/setting/Setting.Zone.js +0 -80
- package/cjs/src/templates/app/lib/setting/index.js +0 -61
- package/cjs/src/templates/app/lib/summary/Summary.Template.js +0 -43
- package/cjs/src/templates/app/lib/summary/Summary.Unit.js +0 -38
- package/cjs/src/templates/app/lib/summary/Summary.Util.js +0 -33
- package/cjs/src/templates/app/lib/summary/Summary.View.js +0 -51
- package/cjs/src/templates/app/lib/summary/Summary.Zone.js +0 -62
- package/cjs/src/templates/app/lib/summary/index.js +0 -67
- package/cjs/src/templates/app/lib/user/User.Template.js +0 -65
- package/cjs/src/templates/app/lib/user/User.Unit.js +0 -38
- package/cjs/src/templates/app/lib/user/User.Util.js +0 -94
- package/cjs/src/templates/app/lib/user/User.View.js +0 -66
- package/cjs/src/templates/app/lib/user/User.Zone.js +0 -74
- package/cjs/src/templates/app/lib/user/index.js +0 -61
- package/cjs/src/templates/app/page.test.ts.template +0 -10
- package/cjs/src/templates/app/playwright.config.ts.template +0 -6
- package/cjs/src/templates/app/postcss.config.js.template +0 -10
- package/cjs/src/templates/app/public/manifest.json.template +0 -67
- package/cjs/src/templates/app/tsconfig.json.template +0 -22
- package/cjs/src/templates/app/tsconfig.spec.json.template +0 -7
- package/cjs/src/templates/app/ui/Footer.js +0 -67
- package/cjs/src/templates/app/ui/MainHeader.js +0 -131
- package/cjs/src/templates/crudPages/[__model__Id]/edit/page.js +0 -73
- package/cjs/src/templates/crudPages/[__model__Id]/page.js +0 -83
- package/cjs/src/templates/crudPages/new/page.js +0 -70
- package/cjs/src/templates/crudPages/page.js +0 -71
- package/cjs/src/templates/libRoot/.gitignore.template +0 -15
- package/cjs/src/templates/libRoot/env/env.server.example.ts.template +0 -7
- package/cjs/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
- package/cjs/src/templates/libRoot/lib/setting/Setting.Template.js +0 -57
- package/cjs/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -38
- package/cjs/src/templates/libRoot/lib/setting/Setting.Util.js +0 -34
- package/cjs/src/templates/libRoot/lib/setting/Setting.View.js +0 -51
- package/cjs/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -80
- package/cjs/src/templates/libRoot/lib/setting/index.js +0 -61
- package/cjs/src/templates/libRoot/lib/summary/Summary.Template.js +0 -43
- package/cjs/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -38
- package/cjs/src/templates/libRoot/lib/summary/Summary.Util.js +0 -33
- package/cjs/src/templates/libRoot/lib/summary/Summary.View.js +0 -51
- package/cjs/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -62
- package/cjs/src/templates/libRoot/lib/summary/index.js +0 -67
- package/cjs/src/templates/libRoot/lib/user/User.Template.js +0 -65
- package/cjs/src/templates/libRoot/lib/user/User.Unit.js +0 -38
- package/cjs/src/templates/libRoot/lib/user/User.Util.js +0 -94
- package/cjs/src/templates/libRoot/lib/user/User.View.js +0 -66
- package/cjs/src/templates/libRoot/lib/user/User.Zone.js +0 -74
- package/cjs/src/templates/libRoot/lib/user/index.js +0 -61
- package/cjs/src/templates/libRoot/package.json.template +0 -4
- package/cjs/src/templates/libRoot/tsconfig.json.template +0 -13
- package/cjs/src/templates/libRoot/tsconfig.spec.json.template +0 -7
- package/cjs/src/templates/localDev/docker-compose.yaml.template +0 -36
- package/cjs/src/templates/module/__Model__.Template.js +0 -54
- package/cjs/src/templates/module/__Model__.Unit.js +0 -42
- package/cjs/src/templates/module/__Model__.Util.js +0 -70
- package/cjs/src/templates/module/__Model__.View.js +0 -48
- package/cjs/src/templates/module/__Model__.Zone.js +0 -83
- package/cjs/src/templates/module/index.js +0 -61
- package/cjs/src/templates/pkgRoot/tsconfig.json.template +0 -15
- package/cjs/src/templates/workspaceRoot/.env.template +0 -20
- package/cjs/src/templates/workspaceRoot/.gitignore.template +0 -118
- package/cjs/src/templates/workspaceRoot/.prettierignore.template +0 -10
- package/cjs/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
- package/cjs/src/templates/workspaceRoot/.swcrc.template +0 -9
- package/cjs/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
- package/cjs/src/templates/workspaceRoot/README.md.template +0 -37
- package/cjs/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
- package/cjs/src/templates/workspaceRoot/package.json.template +0 -43
- package/cjs/src/templates/workspaceRoot/tsconfig.json.template +0 -29
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -27
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -108
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -22
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -30
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -21
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -31
- package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -23
- package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -40
- package/esm/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -34
- package/esm/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
- package/esm/src/templates/app/app/[lang]/admin/layout.js +0 -34
- package/esm/src/templates/app/app/[lang]/admin/page.js +0 -43
- package/esm/src/templates/app/app/csr.js +0 -14
- package/esm/src/templates/app/app/index.html.template +0 -13
- package/esm/src/templates/app/app/layout.js +0 -18
- package/esm/src/templates/app/capacitor.config.ts.template +0 -8
- package/esm/src/templates/app/env/env.client.debug.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.develop.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.local.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.main.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.testing.ts.template +0 -7
- package/esm/src/templates/app/env/env.server.debug.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.develop.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.local.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.main.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.testing.ts.template +0 -7
- package/esm/src/templates/app/lib/setting/Setting.Template.js +0 -37
- package/esm/src/templates/app/lib/setting/Setting.Unit.js +0 -18
- package/esm/src/templates/app/lib/setting/Setting.Util.js +0 -14
- package/esm/src/templates/app/lib/setting/Setting.View.js +0 -31
- package/esm/src/templates/app/lib/setting/Setting.Zone.js +0 -60
- package/esm/src/templates/app/lib/setting/index.js +0 -41
- package/esm/src/templates/app/lib/summary/Summary.Template.js +0 -23
- package/esm/src/templates/app/lib/summary/Summary.Unit.js +0 -18
- package/esm/src/templates/app/lib/summary/Summary.Util.js +0 -13
- package/esm/src/templates/app/lib/summary/Summary.View.js +0 -31
- package/esm/src/templates/app/lib/summary/Summary.Zone.js +0 -42
- package/esm/src/templates/app/lib/summary/index.js +0 -47
- package/esm/src/templates/app/lib/user/User.Template.js +0 -45
- package/esm/src/templates/app/lib/user/User.Unit.js +0 -18
- package/esm/src/templates/app/lib/user/User.Util.js +0 -74
- package/esm/src/templates/app/lib/user/User.View.js +0 -46
- package/esm/src/templates/app/lib/user/User.Zone.js +0 -54
- package/esm/src/templates/app/lib/user/index.js +0 -41
- package/esm/src/templates/app/page.test.ts.template +0 -10
- package/esm/src/templates/app/playwright.config.ts.template +0 -6
- package/esm/src/templates/app/postcss.config.js.template +0 -10
- package/esm/src/templates/app/public/manifest.json.template +0 -67
- package/esm/src/templates/app/tsconfig.json.template +0 -22
- package/esm/src/templates/app/tsconfig.spec.json.template +0 -7
- package/esm/src/templates/app/ui/Footer.js +0 -47
- package/esm/src/templates/app/ui/MainHeader.js +0 -111
- package/esm/src/templates/crudPages/[__model__Id]/edit/page.js +0 -53
- package/esm/src/templates/crudPages/[__model__Id]/page.js +0 -63
- package/esm/src/templates/crudPages/new/page.js +0 -50
- package/esm/src/templates/crudPages/page.js +0 -51
- package/esm/src/templates/libRoot/.gitignore.template +0 -15
- package/esm/src/templates/libRoot/env/env.server.example.ts.template +0 -7
- package/esm/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
- package/esm/src/templates/libRoot/lib/setting/Setting.Template.js +0 -37
- package/esm/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -18
- package/esm/src/templates/libRoot/lib/setting/Setting.Util.js +0 -14
- package/esm/src/templates/libRoot/lib/setting/Setting.View.js +0 -31
- package/esm/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -60
- package/esm/src/templates/libRoot/lib/setting/index.js +0 -41
- package/esm/src/templates/libRoot/lib/summary/Summary.Template.js +0 -23
- package/esm/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -18
- package/esm/src/templates/libRoot/lib/summary/Summary.Util.js +0 -13
- package/esm/src/templates/libRoot/lib/summary/Summary.View.js +0 -31
- package/esm/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -42
- package/esm/src/templates/libRoot/lib/summary/index.js +0 -47
- package/esm/src/templates/libRoot/lib/user/User.Template.js +0 -45
- package/esm/src/templates/libRoot/lib/user/User.Unit.js +0 -18
- package/esm/src/templates/libRoot/lib/user/User.Util.js +0 -74
- package/esm/src/templates/libRoot/lib/user/User.View.js +0 -46
- package/esm/src/templates/libRoot/lib/user/User.Zone.js +0 -54
- package/esm/src/templates/libRoot/lib/user/index.js +0 -41
- package/esm/src/templates/libRoot/package.json.template +0 -4
- package/esm/src/templates/libRoot/tsconfig.json.template +0 -13
- package/esm/src/templates/libRoot/tsconfig.spec.json.template +0 -7
- package/esm/src/templates/localDev/docker-compose.yaml.template +0 -36
- package/esm/src/templates/module/__Model__.Template.js +0 -34
- package/esm/src/templates/module/__Model__.Unit.js +0 -22
- package/esm/src/templates/module/__Model__.Util.js +0 -50
- package/esm/src/templates/module/__Model__.View.js +0 -28
- package/esm/src/templates/module/__Model__.Zone.js +0 -63
- package/esm/src/templates/module/index.js +0 -41
- package/esm/src/templates/pkgRoot/tsconfig.json.template +0 -15
- package/esm/src/templates/workspaceRoot/.env.template +0 -20
- package/esm/src/templates/workspaceRoot/.gitignore.template +0 -118
- package/esm/src/templates/workspaceRoot/.prettierignore.template +0 -10
- package/esm/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
- package/esm/src/templates/workspaceRoot/.swcrc.template +0 -9
- package/esm/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
- package/esm/src/templates/workspaceRoot/README.md.template +0 -37
- package/esm/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
- package/esm/src/templates/workspaceRoot/package.json.template +0 -43
- package/esm/src/templates/workspaceRoot/tsconfig.json.template +0 -29
- package/src/application/application.prompt.d.ts +0 -2
- package/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.d.ts +0 -10
- package/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(user)/layout.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/layout.d.ts +0 -9
- package/src/templates/app/app/[lang]/admin/layout.d.ts +0 -9
- package/src/templates/app/app/[lang]/admin/page.d.ts +0 -9
- package/src/templates/app/app/csr.d.ts +0 -9
- package/src/templates/app/app/layout.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Template.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Unit.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Util.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.View.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Zone.d.ts +0 -9
- package/src/templates/app/lib/setting/index.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Template.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Unit.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Util.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.View.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Zone.d.ts +0 -9
- package/src/templates/app/lib/summary/index.d.ts +0 -9
- package/src/templates/app/lib/user/User.Template.d.ts +0 -9
- package/src/templates/app/lib/user/User.Unit.d.ts +0 -9
- package/src/templates/app/lib/user/User.Util.d.ts +0 -9
- package/src/templates/app/lib/user/User.View.d.ts +0 -9
- package/src/templates/app/lib/user/User.Zone.d.ts +0 -9
- package/src/templates/app/lib/user/index.d.ts +0 -9
- package/src/templates/app/ui/Footer.d.ts +0 -9
- package/src/templates/app/ui/MainHeader.d.ts +0 -10
- package/src/templates/crudPages/[__model__Id]/edit/page.d.ts +0 -11
- package/src/templates/crudPages/[__model__Id]/page.d.ts +0 -11
- package/src/templates/crudPages/new/page.d.ts +0 -11
- package/src/templates/crudPages/page.d.ts +0 -11
- package/src/templates/libRoot/lib/setting/Setting.Template.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.Unit.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.Util.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.View.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.Zone.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/index.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Template.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Unit.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Util.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.View.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Zone.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/index.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Template.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Unit.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Util.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.View.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Zone.d.ts +0 -9
- package/src/templates/libRoot/lib/user/index.d.ts +0 -9
- package/src/templates/module/__Model__.Template.d.ts +0 -11
- package/src/templates/module/__Model__.Unit.d.ts +0 -11
- package/src/templates/module/__Model__.Util.d.ts +0 -11
- package/src/templates/module/__Model__.View.d.ts +0 -11
- package/src/templates/module/__Model__.Zone.d.ts +0 -11
- package/src/templates/module/index.d.ts +0 -11
|
@@ -0,0 +1,732 @@
|
|
|
1
|
+
# Component Rule Instruction for Akan.js Framework
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
1. [Component Architecture](#component-architecture)
|
|
6
|
+
2. [Component Types](#component-types)
|
|
7
|
+
3. [File Naming Conventions](#file-naming-conventions)
|
|
8
|
+
4. [CSS Rule with TailwindCSS and DaisyUI](#css-rule-with-tailwindcss-and-daisyui)
|
|
9
|
+
5. [Utility Functions](#utility-functions)
|
|
10
|
+
6. [Best Practices](#best-practices)
|
|
11
|
+
7. [Complete Examples](#complete-examples)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Component Architecture
|
|
16
|
+
|
|
17
|
+
Akan.js framework uses a modular component architecture that separates UI elements by responsibility. Each feature or model in your application should follow a consistent pattern with standardized component types.
|
|
18
|
+
|
|
19
|
+
### Core Structure
|
|
20
|
+
|
|
21
|
+
Every component in Akan.js follows this fundamental structure:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { clsx } from "@akanjs/client";
|
|
25
|
+
import { ModelType } from "@your-app/client";
|
|
26
|
+
|
|
27
|
+
interface ComponentProps {
|
|
28
|
+
className?: string;
|
|
29
|
+
// Feature-specific props
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const Component = ({ className, ...props }: ComponentProps) => {
|
|
33
|
+
return <div className={clsx("base-classes", className)}>{/* Component content */}</div>;
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Directory Organization
|
|
38
|
+
|
|
39
|
+
Features are organized in a consistent structure:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
{apps,libs}/
|
|
43
|
+
└── project-name/
|
|
44
|
+
└── lib/
|
|
45
|
+
└── feature-name/
|
|
46
|
+
├── FeatureName.Unit.tsx
|
|
47
|
+
├── FeatureName.View.tsx
|
|
48
|
+
├── FeatureName.Template.tsx
|
|
49
|
+
├── FeatureName.Util.tsx
|
|
50
|
+
├── FeatureName.Zone.tsx
|
|
51
|
+
├── featureName.constant.ts
|
|
52
|
+
├── featureName.service.ts
|
|
53
|
+
├── featureName.signal.ts
|
|
54
|
+
├── featureName.store.ts
|
|
55
|
+
└── index.ts
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Component Types
|
|
61
|
+
|
|
62
|
+
Akan.js components are categorized into five main types, each with a specific responsibility:
|
|
63
|
+
|
|
64
|
+
### 1. Unit Components (\*.Unit.tsx)
|
|
65
|
+
|
|
66
|
+
- **Purpose**: Display individual items in lists or cards
|
|
67
|
+
- **Responsibility**: Compact display of model data
|
|
68
|
+
- **Props**: Model data + navigation/action props
|
|
69
|
+
- **Example Usage**: List items, cards, thumbnails
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
export const Card = ({ model, href }: ModelProps<"model", ModelType>) => {
|
|
73
|
+
return (
|
|
74
|
+
<Link href={href} className="rounded-lg shadow-sm hover:shadow-lg">
|
|
75
|
+
<div className="p-4">
|
|
76
|
+
<h3 className="font-medium">{model.title}</h3>
|
|
77
|
+
<p className="opacity-75">{model.description}</p>
|
|
78
|
+
</div>
|
|
79
|
+
</Link>
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 2. View Components (\*.View.tsx)
|
|
85
|
+
|
|
86
|
+
- **Purpose**: Display detailed model information
|
|
87
|
+
- **Responsibility**: Comprehensive view of a single model
|
|
88
|
+
- **Props**: Full model object and contextual data
|
|
89
|
+
- **Example Usage**: Detail pages, modals with complete model information
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
export const General = ({ model, className }: { model: ModelType; className?: string }) => {
|
|
93
|
+
return (
|
|
94
|
+
<div className={clsx("space-y-4 p-4", className)}>
|
|
95
|
+
<h1 className="text-2xl font-bold">{model.title}</h1>
|
|
96
|
+
<div className="flex gap-2 text-sm opacity-75">
|
|
97
|
+
<span>{model.category}</span>
|
|
98
|
+
<span>{new Date(model.createdAt).toLocaleDateString()}</span>
|
|
99
|
+
</div>
|
|
100
|
+
<p className="whitespace-pre-wrap">{model.content}</p>
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 3. Template Components (\*.Template.tsx)
|
|
107
|
+
|
|
108
|
+
- **Purpose**: Create/edit forms for models
|
|
109
|
+
- **Responsibility**: Input gathering and form state management
|
|
110
|
+
- **Props**: Form state handlers (typically from store)
|
|
111
|
+
- **Example Usage**: Create/edit forms, wizards, step-by-step flows
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
export const General = () => {
|
|
115
|
+
const form = st.use.modelForm();
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<div className="space-y-4">
|
|
119
|
+
<div>
|
|
120
|
+
<label className="text-sm opacity-75">Title</label>
|
|
121
|
+
<Input
|
|
122
|
+
value={form.title ?? ""}
|
|
123
|
+
onChange={st.do.setTitleOnModel}
|
|
124
|
+
placeholder="Enter title"
|
|
125
|
+
className="w-full rounded-md p-2"
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
<div>
|
|
130
|
+
<label className="text-sm opacity-75">Content</label>
|
|
131
|
+
<Input.TextArea
|
|
132
|
+
value={form.content ?? ""}
|
|
133
|
+
onChange={st.do.setContentOnModel}
|
|
134
|
+
placeholder="Enter content"
|
|
135
|
+
className="h-32 w-full rounded-md p-2"
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 4. Util Components (\*.Util.tsx)
|
|
144
|
+
|
|
145
|
+
- **Purpose**: Utility components specific to a feature
|
|
146
|
+
- **Responsibility**: Feature-specific UI helpers, buttons, toolbars
|
|
147
|
+
- **Props**: Action handlers, contextual data
|
|
148
|
+
- **Example Usage**: Toolbars, statistics, insights, action buttons
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
export const Toolbar = ({ model, className }: { model: ModelType; className?: string }) => {
|
|
152
|
+
return (
|
|
153
|
+
<div className={clsx("flex gap-2", className)}>
|
|
154
|
+
<Button onClick={() => st.do.duplicateModel(model.id)}>Duplicate</Button>
|
|
155
|
+
<Button variant="danger" onClick={() => st.do.deleteModel(model.id)}>
|
|
156
|
+
Delete
|
|
157
|
+
</Button>
|
|
158
|
+
</div>
|
|
159
|
+
);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export const Stats = ({ summary }: { summary: ModelSummary }) => {
|
|
163
|
+
return (
|
|
164
|
+
<div className="grid grid-cols-3 gap-4">
|
|
165
|
+
<div className="bg-base-100 rounded-lg p-3">
|
|
166
|
+
<div className="text-sm opacity-75">Total</div>
|
|
167
|
+
<div className="text-xl font-medium">{summary.total}</div>
|
|
168
|
+
</div>
|
|
169
|
+
<div className="bg-base-100 rounded-lg p-3">
|
|
170
|
+
<div className="text-sm opacity-75">Active</div>
|
|
171
|
+
<div className="text-xl font-medium">{summary.active}</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
};
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 5. Zone Components (\*.Zone.tsx)
|
|
179
|
+
|
|
180
|
+
- **Purpose**: Container components with data loading
|
|
181
|
+
- **Responsibility**: Data fetching, layout, and wiring components together
|
|
182
|
+
- **Props**: Initialization data, query parameters
|
|
183
|
+
- **Example Usage**: Pages, sections, data-driven layout areas
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
export const List = ({
|
|
187
|
+
init,
|
|
188
|
+
query,
|
|
189
|
+
className,
|
|
190
|
+
}: {
|
|
191
|
+
init: ClientInit<"model">;
|
|
192
|
+
query?: QueryParams;
|
|
193
|
+
className?: string;
|
|
194
|
+
}) => {
|
|
195
|
+
return (
|
|
196
|
+
<Load.Units
|
|
197
|
+
init={init}
|
|
198
|
+
query={query}
|
|
199
|
+
className={className}
|
|
200
|
+
renderItem={(model: ModelType) => <Model.Unit.Card key={model.id} model={model} href={`/model/${model.id}`} />}
|
|
201
|
+
renderEmpty={() => <div>No items found</div>}
|
|
202
|
+
/>
|
|
203
|
+
);
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export const Admin = ({ init, query }: { init: ClientInit<"model">; query?: QueryParams }) => {
|
|
207
|
+
return (
|
|
208
|
+
<Data.ListContainer
|
|
209
|
+
init={init}
|
|
210
|
+
query={query}
|
|
211
|
+
sliceName="model"
|
|
212
|
+
renderItem={Model.Unit.Card}
|
|
213
|
+
renderTemplate={Model.Template.General}
|
|
214
|
+
renderView={(model: ModelType) => <Model.View.General model={model} />}
|
|
215
|
+
columns={["title", "status", "createdAt"]}
|
|
216
|
+
actions={(model) => ["edit", "delete", "view"]}
|
|
217
|
+
/>
|
|
218
|
+
);
|
|
219
|
+
};
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## File Naming Conventions
|
|
225
|
+
|
|
226
|
+
Akan.js uses a strict naming convention to maintain consistency:
|
|
227
|
+
|
|
228
|
+
- **Model Components**:
|
|
229
|
+
|
|
230
|
+
- `{Model}.Unit.tsx` - Card/list item components
|
|
231
|
+
- `{Model}.View.tsx` - Detailed view components
|
|
232
|
+
- `{Model}.Template.tsx` - Form/edit components
|
|
233
|
+
- `{Model}.Util.tsx` - Utility components
|
|
234
|
+
- `{Model}.Zone.tsx` - Container components
|
|
235
|
+
|
|
236
|
+
- **Model Logic**:
|
|
237
|
+
|
|
238
|
+
- `{model}.constant.ts` - Types, GraphQL schema, enums
|
|
239
|
+
- `{model}.service.ts` - Business logic and database operations
|
|
240
|
+
- `{model}.signal.ts` - Client state management and API calls
|
|
241
|
+
- `{model}.store.ts` - Zustand store definitions
|
|
242
|
+
- `{model}.dictionary.ts` - i18n strings
|
|
243
|
+
- `{model}.document.ts` - Mongoose database schema
|
|
244
|
+
|
|
245
|
+
- **UI Components**:
|
|
246
|
+
- `ui/**/*.tsx` - Reusable UI components
|
|
247
|
+
- `ui/Button.tsx`, `ui/Card.tsx`, etc.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## CSS Rule with TailwindCSS and DaisyUI
|
|
252
|
+
|
|
253
|
+
Akan.js uses TailwindCSS with DaisyUI for styling. Follow these guidelines:
|
|
254
|
+
|
|
255
|
+
### 1. Class Management
|
|
256
|
+
|
|
257
|
+
Always use `clsx` for conditional and composite classes:
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
import { clsx } from "@akanjs/client";
|
|
261
|
+
|
|
262
|
+
className={clsx(
|
|
263
|
+
"base-classes",
|
|
264
|
+
condition && "conditional-class",
|
|
265
|
+
variant === "primary" ? "primary-class" : "secondary-class",
|
|
266
|
+
className // Always include passed className for composition
|
|
267
|
+
)}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### 2. Color System
|
|
271
|
+
|
|
272
|
+
Use DaisyUI's theme colors instead of hardcoded values. This ensures theme consistency and dark/light mode compatibility:
|
|
273
|
+
|
|
274
|
+
```tsx
|
|
275
|
+
// Good - uses theme colors
|
|
276
|
+
className = "bg-primary text-base-100";
|
|
277
|
+
|
|
278
|
+
// Bad - uses hardcoded colors
|
|
279
|
+
className = "bg-[#C33C32] text-[#FFFFFF]";
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
DaisyUI provides semantic colors:
|
|
283
|
+
|
|
284
|
+
- `primary`, `secondary`, `accent` - Brand colors
|
|
285
|
+
- `base-100` through `base-900` - Background/text variants
|
|
286
|
+
- `info`, `success`, `warning`, `error` - Status colors
|
|
287
|
+
|
|
288
|
+
### 3. Responsive Design
|
|
289
|
+
|
|
290
|
+
Use Tailwind's responsive prefixes:
|
|
291
|
+
|
|
292
|
+
```tsx
|
|
293
|
+
<div className="flex-col md:flex-row">
|
|
294
|
+
<div className="w-full md:w-1/2 lg:w-1/3">Responsive width</div>
|
|
295
|
+
<div className="hidden lg:block">Only visible on large screens</div>
|
|
296
|
+
</div>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### 4. Animation
|
|
300
|
+
|
|
301
|
+
Use Tailwind animation classes with transitions:
|
|
302
|
+
|
|
303
|
+
```tsx
|
|
304
|
+
<div className="transition-all duration-300 hover:scale-105">
|
|
305
|
+
Hover effect
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<div className="animate-pulse">Loading indicator</div>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### 5. Component Styling
|
|
312
|
+
|
|
313
|
+
Use DaisyUI components for consistent UIs:
|
|
314
|
+
|
|
315
|
+
```tsx
|
|
316
|
+
<button className="btn btn-primary btn-sm">Primary Button</button>
|
|
317
|
+
|
|
318
|
+
<div className="card bg-base-200 shadow-md">
|
|
319
|
+
<div className="card-body">
|
|
320
|
+
<h2 className="card-title">Card Title</h2>
|
|
321
|
+
<p>Card content</p>
|
|
322
|
+
</div>
|
|
323
|
+
</div>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Utility Functions
|
|
329
|
+
|
|
330
|
+
Akan.js provides several utility modules for common frontend tasks:
|
|
331
|
+
|
|
332
|
+
### 1. Cookie Management (`@akanjs/client/cookie`)
|
|
333
|
+
|
|
334
|
+
```tsx
|
|
335
|
+
import { getCookie, setCookie, removeCookie } from "@akanjs/client";
|
|
336
|
+
|
|
337
|
+
// Setting cookies
|
|
338
|
+
setCookie("session", "token123");
|
|
339
|
+
|
|
340
|
+
// Getting cookies
|
|
341
|
+
const session = getCookie("session");
|
|
342
|
+
|
|
343
|
+
// Authentication helpers
|
|
344
|
+
const user = getMe();
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### 2. Storage Utilities (`@akanjs/client/storage`)
|
|
348
|
+
|
|
349
|
+
Cross-platform storage that works in both web and mobile:
|
|
350
|
+
|
|
351
|
+
```tsx
|
|
352
|
+
import { storage } from "@akanjs/client";
|
|
353
|
+
|
|
354
|
+
// Store data
|
|
355
|
+
await storage.setItem("key", "value");
|
|
356
|
+
|
|
357
|
+
// Retrieve data
|
|
358
|
+
const value = await storage.getItem("key");
|
|
359
|
+
|
|
360
|
+
// Remove data
|
|
361
|
+
await storage.removeItem("key");
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### 3. Device Capabilities (`@akanjs/client/device`)
|
|
365
|
+
|
|
366
|
+
```tsx
|
|
367
|
+
import { device } from "@akanjs/client";
|
|
368
|
+
|
|
369
|
+
// Initialize device
|
|
370
|
+
await device.init();
|
|
371
|
+
|
|
372
|
+
// Haptic feedback
|
|
373
|
+
device.vibrate("medium");
|
|
374
|
+
|
|
375
|
+
// Keyboard control
|
|
376
|
+
device.keyboard.show();
|
|
377
|
+
device.keyboard.hide();
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### 4. Routing (`@akanjs/client/router`)
|
|
381
|
+
|
|
382
|
+
```tsx
|
|
383
|
+
import { router } from "@akanjs/client";
|
|
384
|
+
|
|
385
|
+
// Navigation
|
|
386
|
+
router.push("/dashboard");
|
|
387
|
+
router.replace("/login");
|
|
388
|
+
router.back();
|
|
389
|
+
|
|
390
|
+
// With query parameters
|
|
391
|
+
router.push("/search", { q: "term" });
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### 5. CSS Utilities (`@akanjs/client/types`)
|
|
395
|
+
|
|
396
|
+
```tsx
|
|
397
|
+
import { clsx } from "@akanjs/client";
|
|
398
|
+
|
|
399
|
+
// Combining class names
|
|
400
|
+
const className = clsx("base-class", isActive && "active-class", variant === "large" ? "text-lg" : "text-sm");
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Best Practices
|
|
406
|
+
|
|
407
|
+
1. **Separation of Concerns**
|
|
408
|
+
|
|
409
|
+
- Keep business logic in signal/store files
|
|
410
|
+
- Keep UI rendering in component files
|
|
411
|
+
- Use Zone components to wire everything together
|
|
412
|
+
|
|
413
|
+
2. **Component Composition**
|
|
414
|
+
|
|
415
|
+
- Break complex UIs into smaller components
|
|
416
|
+
- Use composition over inheritance
|
|
417
|
+
- Always accept and forward `className` prop
|
|
418
|
+
|
|
419
|
+
3. **Performance**
|
|
420
|
+
|
|
421
|
+
- Use `React.memo` for frequently re-rendered components
|
|
422
|
+
- Avoid inline function definitions in render methods
|
|
423
|
+
- Use useMemo/useCallback for expensive computations
|
|
424
|
+
|
|
425
|
+
4. **Accessibility**
|
|
426
|
+
|
|
427
|
+
- Include proper ARIA attributes
|
|
428
|
+
- Ensure keyboard navigation works
|
|
429
|
+
- Maintain sufficient color contrast
|
|
430
|
+
|
|
431
|
+
5. **Type Safety**
|
|
432
|
+
|
|
433
|
+
- Define clear interfaces for all component props
|
|
434
|
+
- Leverage TypeScript's discriminated unions where appropriate
|
|
435
|
+
- Use model types from constants files
|
|
436
|
+
|
|
437
|
+
6. **State Management**
|
|
438
|
+
- Use framework-provided state utilities (signals, stores)
|
|
439
|
+
- Keep global state minimal and focused
|
|
440
|
+
- Follow the Akan.js state pattern (store + signal)
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Complete Examples
|
|
445
|
+
|
|
446
|
+
### Full Model Module Components
|
|
447
|
+
|
|
448
|
+
Here's a complete example of components for a "Product" feature:
|
|
449
|
+
|
|
450
|
+
#### Product.Unit.tsx
|
|
451
|
+
|
|
452
|
+
```tsx
|
|
453
|
+
import { clsx, ModelProps } from "@akanjs/client";
|
|
454
|
+
import { cnst } from "@app/client";
|
|
455
|
+
import { Image, Link } from "@util/ui";
|
|
456
|
+
|
|
457
|
+
export const Card = ({ product, href }: ModelProps<"product", cnst.Product>) => {
|
|
458
|
+
return (
|
|
459
|
+
<Link href={href} className="animate-fadeIn flex rounded-lg shadow-sm duration-300 hover:shadow-lg">
|
|
460
|
+
<div className="p-4">
|
|
461
|
+
<h3 className="font-medium">{product.name}</h3>
|
|
462
|
+
<div className="text-primary">${product.price.toFixed(2)}</div>
|
|
463
|
+
{product.image && <Image src={product.image.url} className="h-32 w-full rounded object-cover" />}
|
|
464
|
+
<p className="text-sm opacity-75">{product.description}</p>
|
|
465
|
+
</div>
|
|
466
|
+
</Link>
|
|
467
|
+
);
|
|
468
|
+
};
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
#### Product.View.tsx
|
|
472
|
+
|
|
473
|
+
```tsx
|
|
474
|
+
import { clsx } from "@akanjs/client";
|
|
475
|
+
import { cnst } from "@app/client";
|
|
476
|
+
import { Button, Image } from "@util/ui";
|
|
477
|
+
|
|
478
|
+
interface ProductViewProps {
|
|
479
|
+
className?: string;
|
|
480
|
+
product: cnst.Product;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export const General = ({ className, product }: ProductViewProps) => {
|
|
484
|
+
return (
|
|
485
|
+
<div className={clsx("animate-fadeIn space-y-6", className)}>
|
|
486
|
+
<div className="flex flex-col gap-6 md:flex-row">
|
|
487
|
+
{product.image && (
|
|
488
|
+
<div className="w-full md:w-1/2">
|
|
489
|
+
<Image src={product.image.url} className="w-full rounded-lg object-cover" />
|
|
490
|
+
</div>
|
|
491
|
+
)}
|
|
492
|
+
|
|
493
|
+
<div className="w-full space-y-4 md:w-1/2">
|
|
494
|
+
<h1 className="text-3xl font-bold">{product.name}</h1>
|
|
495
|
+
<div className="text-primary text-xl font-medium">${product.price.toFixed(2)}</div>
|
|
496
|
+
<p className="whitespace-pre-wrap">{product.description}</p>
|
|
497
|
+
<div className="flex gap-2">
|
|
498
|
+
<Button variant="primary">Add to Cart</Button>
|
|
499
|
+
<Button variant="outline">Save for Later</Button>
|
|
500
|
+
</div>
|
|
501
|
+
</div>
|
|
502
|
+
</div>
|
|
503
|
+
|
|
504
|
+
<div>
|
|
505
|
+
<h2 className="mb-2 text-xl font-medium">Specifications</h2>
|
|
506
|
+
<div className="grid grid-cols-2 gap-2">
|
|
507
|
+
{product.specifications.map((spec, idx) => (
|
|
508
|
+
<div key={idx} className="flex justify-between border-b p-2">
|
|
509
|
+
<span className="font-medium">{spec.name}</span>
|
|
510
|
+
<span>{spec.value}</span>
|
|
511
|
+
</div>
|
|
512
|
+
))}
|
|
513
|
+
</div>
|
|
514
|
+
</div>
|
|
515
|
+
</div>
|
|
516
|
+
);
|
|
517
|
+
};
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
#### Product.Template.tsx
|
|
521
|
+
|
|
522
|
+
```tsx
|
|
523
|
+
"use client";
|
|
524
|
+
import { clsx } from "@akanjs/client";
|
|
525
|
+
import { st } from "@app/client";
|
|
526
|
+
import { Button, Input, Upload } from "@util/ui";
|
|
527
|
+
import { AiOutlinePlus } from "react-icons/ai";
|
|
528
|
+
|
|
529
|
+
export const General = () => {
|
|
530
|
+
const productForm = st.use.productForm();
|
|
531
|
+
|
|
532
|
+
return (
|
|
533
|
+
<div className="space-y-6">
|
|
534
|
+
<div>
|
|
535
|
+
<label className="mb-1 block text-sm opacity-75">Product Name</label>
|
|
536
|
+
<Input
|
|
537
|
+
value={productForm.name ?? ""}
|
|
538
|
+
onChange={st.do.setNameOnProduct}
|
|
539
|
+
placeholder="Enter product name"
|
|
540
|
+
className="w-full rounded-md p-2"
|
|
541
|
+
/>
|
|
542
|
+
</div>
|
|
543
|
+
|
|
544
|
+
<div>
|
|
545
|
+
<label className="mb-1 block text-sm opacity-75">Price</label>
|
|
546
|
+
<Input
|
|
547
|
+
type="number"
|
|
548
|
+
value={productForm.price?.toString() ?? ""}
|
|
549
|
+
onChange={(value) => st.do.setPriceOnProduct(Number(value))}
|
|
550
|
+
placeholder="0.00"
|
|
551
|
+
className="w-full rounded-md p-2"
|
|
552
|
+
/>
|
|
553
|
+
</div>
|
|
554
|
+
|
|
555
|
+
<div>
|
|
556
|
+
<label className="mb-1 block text-sm opacity-75">Description</label>
|
|
557
|
+
<Input.TextArea
|
|
558
|
+
value={productForm.description ?? ""}
|
|
559
|
+
onChange={st.do.setDescriptionOnProduct}
|
|
560
|
+
placeholder="Product description"
|
|
561
|
+
className="h-32 w-full rounded-md p-2"
|
|
562
|
+
/>
|
|
563
|
+
</div>
|
|
564
|
+
|
|
565
|
+
<div>
|
|
566
|
+
<label className="mb-1 block text-sm opacity-75">Product Image</label>
|
|
567
|
+
<Upload.Image
|
|
568
|
+
aspectRatio={[1, 1]}
|
|
569
|
+
type="crop"
|
|
570
|
+
styleType="square"
|
|
571
|
+
protoFile={productForm.image}
|
|
572
|
+
onRemove={() => st.do.setImageOnProduct(null)}
|
|
573
|
+
renderEmpty={() => (
|
|
574
|
+
<div className="border-base-200 bg-base-100 flex h-48 w-full items-center justify-center rounded-xl border drop-shadow-xl duration-300 hover:opacity-50">
|
|
575
|
+
<div>
|
|
576
|
+
<AiOutlinePlus className="text-primary text-6xl font-bold opacity-60" />
|
|
577
|
+
<p className="text-base-300 text-center text-xs">Upload Image</p>
|
|
578
|
+
</div>
|
|
579
|
+
</div>
|
|
580
|
+
)}
|
|
581
|
+
renderComplete={(file) => (
|
|
582
|
+
<div className="h-48 w-full rounded-md">
|
|
583
|
+
<Image file={file} className="size-full rounded-md object-cover" />
|
|
584
|
+
</div>
|
|
585
|
+
)}
|
|
586
|
+
onSave={(file) => st.do.uploadImageOnProduct([file] as unknown as FileList)}
|
|
587
|
+
/>
|
|
588
|
+
</div>
|
|
589
|
+
</div>
|
|
590
|
+
);
|
|
591
|
+
};
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
#### Product.Util.tsx
|
|
595
|
+
|
|
596
|
+
```tsx
|
|
597
|
+
"use client";
|
|
598
|
+
import { ModelDashboardProps } from "@akanjs/client";
|
|
599
|
+
import { getQueryMap } from "@akanjs/constant";
|
|
600
|
+
import { cnst, st } from "@app/client";
|
|
601
|
+
import { Data } from "@shared/ui";
|
|
602
|
+
import { Button } from "@util/ui";
|
|
603
|
+
|
|
604
|
+
export const Stat = ({
|
|
605
|
+
className,
|
|
606
|
+
summary,
|
|
607
|
+
sliceName = "product",
|
|
608
|
+
queryMap = getQueryMap(cnst.ProductSummary),
|
|
609
|
+
}: ModelDashboardProps<cnst.Summary>) => {
|
|
610
|
+
return (
|
|
611
|
+
<Data.Dashboard
|
|
612
|
+
className={className}
|
|
613
|
+
summary={summary}
|
|
614
|
+
sliceName={sliceName}
|
|
615
|
+
queryMap={queryMap}
|
|
616
|
+
columns={["totalProducts", "inStock", "outOfStock"]}
|
|
617
|
+
/>
|
|
618
|
+
);
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
export const AddToCart = ({ productId, className }: { productId: string; className?: string }) => {
|
|
622
|
+
return (
|
|
623
|
+
<Button className={clsx("bg-primary text-white", className)} onClick={() => st.do.addToCart(productId)}>
|
|
624
|
+
Add to Cart
|
|
625
|
+
</Button>
|
|
626
|
+
);
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
export const PriceFilter = ({
|
|
630
|
+
onChange,
|
|
631
|
+
value,
|
|
632
|
+
}: {
|
|
633
|
+
onChange: (range: [number, number]) => void;
|
|
634
|
+
value: [number, number];
|
|
635
|
+
}) => {
|
|
636
|
+
return (
|
|
637
|
+
<div className="space-y-2">
|
|
638
|
+
<div className="flex justify-between text-sm">
|
|
639
|
+
<span>Min: ${value[0]}</span>
|
|
640
|
+
<span>Max: ${value[1]}</span>
|
|
641
|
+
</div>
|
|
642
|
+
<div className="flex gap-4">
|
|
643
|
+
<input
|
|
644
|
+
type="range"
|
|
645
|
+
min="0"
|
|
646
|
+
max="1000"
|
|
647
|
+
value={value[0]}
|
|
648
|
+
onChange={(e) => onChange([Number(e.target.value), value[1]])}
|
|
649
|
+
className="range range-xs range-primary"
|
|
650
|
+
/>
|
|
651
|
+
<input
|
|
652
|
+
type="range"
|
|
653
|
+
min="0"
|
|
654
|
+
max="1000"
|
|
655
|
+
value={value[1]}
|
|
656
|
+
onChange={(e) => onChange([value[0], Number(e.target.value)])}
|
|
657
|
+
className="range range-xs range-primary"
|
|
658
|
+
/>
|
|
659
|
+
</div>
|
|
660
|
+
</div>
|
|
661
|
+
);
|
|
662
|
+
};
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
#### Product.Zone.tsx
|
|
666
|
+
|
|
667
|
+
```tsx
|
|
668
|
+
"use client";
|
|
669
|
+
import { ModelsProps } from "@akanjs/client";
|
|
670
|
+
import { ClientInit, ClientView } from "@akanjs/signal";
|
|
671
|
+
import { cnst, Product } from "@app/client";
|
|
672
|
+
import { Data, Load } from "@shared/ui";
|
|
673
|
+
|
|
674
|
+
export const Admin = ({ sliceName = "product", init, query }: ModelsProps<cnst.Product>) => {
|
|
675
|
+
return (
|
|
676
|
+
<Data.ListContainer
|
|
677
|
+
init={init}
|
|
678
|
+
query={query}
|
|
679
|
+
sliceName={sliceName}
|
|
680
|
+
renderItem={Product.Unit.Card}
|
|
681
|
+
renderDashboard={Product.Util.Stat}
|
|
682
|
+
renderTemplate={Product.Template.General}
|
|
683
|
+
renderTitle={(product) => product.name}
|
|
684
|
+
renderView={(product) => <Product.View.General product={product} />}
|
|
685
|
+
columns={["name", "price", "status", "createdAt"]}
|
|
686
|
+
actions={(product) => ["edit", "remove", "view"]}
|
|
687
|
+
/>
|
|
688
|
+
);
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
export const Catalog = ({
|
|
692
|
+
className,
|
|
693
|
+
init,
|
|
694
|
+
query,
|
|
695
|
+
}: {
|
|
696
|
+
className?: string;
|
|
697
|
+
init: ClientInit<"product", cnst.Product>;
|
|
698
|
+
query?: Record<string, any>;
|
|
699
|
+
}) => {
|
|
700
|
+
return (
|
|
701
|
+
<div className={className}>
|
|
702
|
+
<div className="flex flex-col gap-6 md:flex-row">
|
|
703
|
+
<div className="w-full md:w-1/4">
|
|
704
|
+
<Product.Util.Filters />
|
|
705
|
+
</div>
|
|
706
|
+
|
|
707
|
+
<div className="w-full md:w-3/4">
|
|
708
|
+
<Load.Units
|
|
709
|
+
init={init}
|
|
710
|
+
query={query}
|
|
711
|
+
renderItem={(product) => (
|
|
712
|
+
<Product.Unit.Card key={product.id} href={`/products/${product.id}`} product={product} />
|
|
713
|
+
)}
|
|
714
|
+
renderEmpty={() => <div className="p-8 text-center">No products found matching your criteria</div>}
|
|
715
|
+
renderList={(products) => (
|
|
716
|
+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
|
717
|
+
{products.map((product) => (
|
|
718
|
+
<Product.Unit.Card key={product.id} href={`/products/${product.id}`} product={product} />
|
|
719
|
+
))}
|
|
720
|
+
</div>
|
|
721
|
+
)}
|
|
722
|
+
/>
|
|
723
|
+
</div>
|
|
724
|
+
</div>
|
|
725
|
+
</div>
|
|
726
|
+
);
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
export const View = ({ view }: { view: ClientView<"product", cnst.Product> }) => {
|
|
730
|
+
return <Load.View view={view} renderView={(product) => <Product.View.General product={product} />} />;
|
|
731
|
+
};
|
|
732
|
+
```
|