@qlover/create-app 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/package.json +4 -4
  3. package/templates/react-app/README.md +311 -120
  4. package/templates/react-app/config/Identifier.I18n.ts +1048 -0
  5. package/templates/react-app/config/app.router.json +7 -7
  6. package/templates/react-app/config/common.ts +13 -0
  7. package/templates/react-app/config/theme.json +7 -88
  8. package/templates/react-app/package.json +11 -5
  9. package/templates/react-app/postcss.config.js +1 -2
  10. package/templates/react-app/public/locales/en/common.json +142 -1
  11. package/templates/react-app/public/locales/zh/common.json +142 -1
  12. package/templates/react-app/src/App.tsx +16 -3
  13. package/templates/react-app/src/base/apis/AiApi.ts +4 -4
  14. package/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +2 -2
  15. package/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +2 -2
  16. package/templates/react-app/src/base/cases/AppConfig.ts +103 -0
  17. package/templates/react-app/src/base/cases/{appError/AppError.ts → AppError.ts} +0 -3
  18. package/templates/react-app/src/base/cases/DialogHandler.ts +86 -0
  19. package/templates/react-app/src/base/cases/RequestLogger.ts +1 -1
  20. package/templates/react-app/src/base/cases/RouterLoader.ts +166 -0
  21. package/templates/react-app/src/base/port/InteractionHubInterface.ts +94 -0
  22. package/templates/react-app/src/base/services/I18nService.ts +50 -3
  23. package/templates/react-app/src/base/services/ProcesserService.ts +0 -1
  24. package/templates/react-app/src/base/types/deprecated-antd.d.ts +60 -0
  25. package/templates/react-app/src/core/IOC.ts +18 -8
  26. package/templates/react-app/src/core/bootstrap.ts +41 -62
  27. package/templates/react-app/src/core/bootstraps/PrintBootstrap.ts +14 -0
  28. package/templates/react-app/src/core/bootstraps/index.ts +36 -7
  29. package/templates/react-app/src/core/globals.ts +8 -1
  30. package/templates/react-app/src/core/registers/RegisterApi.ts +2 -5
  31. package/templates/react-app/src/core/registers/RegisterCommon.ts +38 -29
  32. package/templates/react-app/src/core/registers/RegisterControllers.ts +5 -10
  33. package/templates/react-app/src/core/registers/RegisterGlobals.ts +21 -17
  34. package/templates/react-app/src/core/registers/index.ts +27 -13
  35. package/templates/react-app/src/main.tsx +1 -1
  36. package/templates/react-app/src/pages/404.tsx +1 -1
  37. package/templates/react-app/src/pages/500.tsx +1 -1
  38. package/templates/react-app/src/pages/auth/Login.tsx +128 -36
  39. package/templates/react-app/src/pages/base/About.tsx +118 -2
  40. package/templates/react-app/src/pages/base/ErrorIdentifier.tsx +38 -19
  41. package/templates/react-app/src/pages/base/Executor.tsx +442 -29
  42. package/templates/react-app/src/pages/base/Home.tsx +99 -93
  43. package/templates/react-app/src/pages/base/JSONStorage.tsx +47 -38
  44. package/templates/react-app/src/pages/base/Layout.tsx +5 -2
  45. package/templates/react-app/src/pages/base/Request.tsx +90 -208
  46. package/templates/react-app/src/pages/base/components/BaseHeader.tsx +13 -5
  47. package/templates/react-app/src/styles/css/antd-themes/_default.css +239 -0
  48. package/templates/react-app/src/styles/css/antd-themes/dark.css +176 -0
  49. package/templates/react-app/src/styles/css/antd-themes/index.css +3 -0
  50. package/templates/react-app/src/styles/css/antd-themes/no-context.css +34 -0
  51. package/templates/react-app/src/styles/css/antd-themes/pink.css +199 -0
  52. package/templates/react-app/src/{uikit/styles → styles}/css/index.css +3 -0
  53. package/templates/react-app/src/styles/css/page.css +11 -0
  54. package/templates/react-app/src/styles/css/tailwind.css +5 -0
  55. package/templates/react-app/src/styles/css/themes/_default.css +29 -0
  56. package/templates/react-app/src/styles/css/themes/dark.css +29 -0
  57. package/templates/react-app/src/styles/css/themes/index.css +3 -0
  58. package/templates/react-app/src/styles/css/themes/pink.css +29 -0
  59. package/templates/react-app/src/uikit/components/LanguageSwitcher.tsx +56 -0
  60. package/templates/react-app/src/uikit/components/Loading.tsx +27 -21
  61. package/templates/react-app/src/uikit/components/RouterRenderComponent.tsx +1 -1
  62. package/templates/react-app/src/uikit/components/ThemeSwitcher.tsx +63 -13
  63. package/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +1 -1
  64. package/templates/react-app/src/uikit/controllers/RouterController.ts +1 -1
  65. package/templates/react-app/src/uikit/controllers/UserController.ts +2 -2
  66. package/templates/react-app/tailwind.config.js +1 -15
  67. package/templates/react-app/tsconfig.json +3 -2
  68. package/templates/react-app/tsconfig.node.json +2 -1
  69. package/templates/react-app/vite.config.ts +15 -3
  70. package/templates/react-app/lib/tailwind/root10px.js +0 -178
  71. package/templates/react-app/lib/tailwind/theme-generator.js +0 -238
  72. package/templates/react-app/public/locales/en/about.json +0 -3
  73. package/templates/react-app/public/locales/en/executor.json +0 -6
  74. package/templates/react-app/public/locales/en/home.json +0 -10
  75. package/templates/react-app/public/locales/en/jsonStorage.json +0 -11
  76. package/templates/react-app/public/locales/en/login.json +0 -7
  77. package/templates/react-app/public/locales/en/request.json +0 -15
  78. package/templates/react-app/public/locales/zh/about.json +0 -3
  79. package/templates/react-app/public/locales/zh/executor.json +0 -6
  80. package/templates/react-app/public/locales/zh/home.json +0 -10
  81. package/templates/react-app/public/locales/zh/jsonStorage.json +0 -11
  82. package/templates/react-app/public/locales/zh/login.json +0 -7
  83. package/templates/react-app/public/locales/zh/request.json +0 -15
  84. package/templates/react-app/src/base/cases/router-loader/index.ts +0 -90
  85. package/templates/react-app/src/base/port/InversifyIocInterface.ts +0 -9
  86. package/templates/react-app/src/core/AppConfig.ts +0 -36
  87. package/templates/react-app/src/uikit/styles/css/page.css +0 -3
  88. package/templates/react-app/src/uikit/styles/css/tailwind.css +0 -3
  89. /package/templates/react-app/config/{ErrorIdentifier.ts → Identifier.Error.ts} +0 -0
@@ -1,106 +1,112 @@
1
- import LocaleLink from '@/uikit/components/LocaleLink';
1
+ import { Button } from 'antd';
2
2
  import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
3
-
4
- const navigationItems = [
5
- {
6
- href: '/about',
7
- bgColor: 'bg-blue-50',
8
- hoverColor: 'hover:bg-blue-100',
9
- titleColor: 'text-blue-700',
10
- titleKey: 'about',
11
- descriptionKey: 'about_description'
12
- },
13
- {
14
- href: '/jsonstorage',
15
- bgColor: 'bg-green-50',
16
- hoverColor: 'hover:bg-green-100',
17
- titleColor: 'text-green-700',
18
- titleKey: 'jsonstorage',
19
- descriptionKey: 'jsonstorage_description'
20
- },
21
- {
22
- href: '/request',
23
- bgColor: 'bg-red-50',
24
- hoverColor: 'hover:bg-red-100',
25
- titleColor: 'text-red-700',
26
- titleKey: 'request',
27
- descriptionKey: 'request_description'
28
- },
29
- {
30
- href: '/executor',
31
- bgColor: 'bg-purple-50',
32
- hoverColor: 'hover:bg-purple-100',
33
- titleColor: 'text-purple-700',
34
- titleKey: 'executor',
35
- descriptionKey: 'executor_description'
36
- },
37
- {
38
- href: '/errorIdentifier',
39
- bgColor: 'bg-amber-50',
40
- hoverColor: 'hover:bg-amber-100',
41
- titleColor: 'text-amber-700',
42
- titleKey: 'errorIdentifier',
43
- descriptionKey: 'errorIdentifier_description'
44
- }
45
- ];
3
+ import LocaleLink from '@/uikit/components/LocaleLink';
4
+ import clsx from 'clsx';
5
+ import * as i18nKeys from '@config/Identifier.I18n';
46
6
 
47
7
  export default function Home() {
48
8
  const { t } = useBaseRoutePage();
49
9
 
10
+ const navigationItems = [
11
+ {
12
+ href: '/about',
13
+ bgColor: 'bg-blue-50',
14
+ hoverColor: 'hover:bg-blue-100',
15
+ titleColor: 'text-blue-700',
16
+ titleKey: i18nKeys.PAGE_ABOUT_TITLE,
17
+ descriptionKey: i18nKeys.PAGE_ABOUT_DESCRIPTION
18
+ },
19
+ {
20
+ href: '/jsonstorage',
21
+ bgColor: 'bg-green-50',
22
+ hoverColor: 'hover:bg-green-100',
23
+ titleColor: 'text-green-700',
24
+ titleKey: i18nKeys.PAGE_JSONSTORAGE_TITLE,
25
+ descriptionKey: i18nKeys.PAGE_JSONSTORAGE_DESCRIPTION
26
+ },
27
+ {
28
+ href: '/request',
29
+ bgColor: 'bg-red-50',
30
+ hoverColor: 'hover:bg-red-100',
31
+ titleColor: 'text-red-700',
32
+ titleKey: i18nKeys.PAGE_REQUEST_TITLE,
33
+ descriptionKey: i18nKeys.PAGE_REQUEST_DESCRIPTION
34
+ },
35
+ {
36
+ href: '/executor',
37
+ bgColor: 'bg-purple-50',
38
+ hoverColor: 'hover:bg-purple-100',
39
+ titleColor: 'text-purple-700',
40
+ titleKey: i18nKeys.PAGE_EXECUTOR_TITLE,
41
+ descriptionKey: i18nKeys.PAGE_EXECUTOR_DESCRIPTION
42
+ },
43
+ {
44
+ href: '/errorIdentifier',
45
+ bgColor: 'bg-amber-50',
46
+ hoverColor: 'hover:bg-amber-100',
47
+ titleColor: 'text-amber-700',
48
+ titleKey: i18nKeys.PAGE_ERROR_IDENTIFIER_TITLE,
49
+ descriptionKey: i18nKeys.PAGE_ERROR_IDENTIFIER_DESCRIPTION
50
+ }
51
+ ];
52
+
50
53
  return (
51
- <div className="min-h-screen bg-gray-100/90 py-6 flex flex-col justify-center sm:py-12">
52
- <div className="relative py-3 sm:max-w-xl sm:mx-auto">
53
- <div className="bg-white shadow-lg rounded-lg px-8 py-6">
54
- <h1 className="text-3xl font-bold text-center text-gray-800 mb-8">
55
- {t('welcome')}
54
+ <div className="min-h-screen bg-primary">
55
+ {/* Hero Section */}
56
+ <section className="py-16 px-4">
57
+ <div className="max-w-4xl mx-auto text-center">
58
+ <h1 className="text-4xl md:text-5xl font-bold mb-6 text-text">
59
+ {t(i18nKeys.HOME_WELCOME)}
56
60
  </h1>
61
+ <p className="text-xl text-text-secondary mb-8">
62
+ {t(i18nKeys.HOME_DESCRIPTION)}
63
+ </p>
64
+ </div>
65
+ </section>
57
66
 
58
- <div className="space-y-6">
59
- <div className="text-center text-gray-600 mb-8">
60
- {t('description')}
61
- </div>
62
-
63
- <div className="grid gap-4">
64
- {navigationItems.map((item, index) => (
65
- <LocaleLink
66
- key={index}
67
- href={item.href}
68
- className={`block p-4 ${item.bgColor} rounded-lg ${item.hoverColor} transition-colors duration-200`}
69
- >
70
- <h2
71
- className={`text-xl font-semibold ${item.titleColor} mb-2`}
72
- >
73
- {t(item.titleKey)}
74
- </h2>
75
- <p className="text-gray-600">{t(item.descriptionKey)}</p>
76
- </LocaleLink>
77
- ))}
78
- </div>
67
+ {/* Navigation Grid */}
68
+ <section className="max-w-6xl mx-auto px-4 py-12">
69
+ <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
70
+ {navigationItems.map((item) => (
71
+ <LocaleLink
72
+ key={item.href}
73
+ href={item.href}
74
+ className={clsx(
75
+ 'block rounded-lg p-6',
76
+ 'bg-secondary',
77
+ 'border border-border',
78
+ 'hover:bg-elevated',
79
+ 'transition-colors duration-200'
80
+ )}
81
+ >
82
+ <h3 className={`text-xl font-semibold mb-3 text-text`}>
83
+ {t(item.titleKey)}
84
+ </h3>
85
+ <p className="text-text-secondary mb-4">
86
+ {t(item.descriptionKey)}
87
+ </p>
88
+ <Button type="primary" className="w-full">
89
+ {t(i18nKeys.HOME_EXPLORE)}
90
+ </Button>
91
+ </LocaleLink>
92
+ ))}
93
+ </div>
94
+ </section>
79
95
 
80
- <div className="mt-8 text-center">
81
- <LocaleLink
82
- href="https://github.com/qlover/fe-base"
83
- target="_blank"
84
- rel="noopener noreferrer"
85
- className="inline-flex items-center text-gray-600 hover:text-gray-800"
86
- >
87
- <svg
88
- className="w-5 h-5 mr-2"
89
- fill="currentColor"
90
- viewBox="0 0 24 24"
91
- >
92
- <path
93
- fillRule="evenodd"
94
- d="M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.17 6.839 9.49.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.604-3.369-1.34-3.369-1.34-.454-1.156-1.11-1.464-1.11-1.464-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.578.688.48C19.138 20.167 22 16.418 22 12c0-5.523-4.477-10-10-10z"
95
- clipRule="evenodd"
96
- />
97
- </svg>
98
- Visit GitHub
99
- </LocaleLink>
100
- </div>
101
- </div>
96
+ {/* Call to Action Section */}
97
+ <section className="py-16 px-4 bg-elevated">
98
+ <div className="max-w-4xl mx-auto text-center">
99
+ <h2 className="text-3xl font-bold mb-4 text-text">
100
+ {t(i18nKeys.HOME_GET_STARTED_TITLE)}
101
+ </h2>
102
+ <p className="text-lg text-text-secondary mb-8">
103
+ {t(i18nKeys.HOME_GET_STARTED_DESCRIPTION)}
104
+ </p>
105
+ <Button type="primary" size="large" className="px-8">
106
+ {t(i18nKeys.HOME_GET_STARTED_BUTTON)}
107
+ </Button>
102
108
  </div>
103
- </div>
109
+ </section>
104
110
  </div>
105
111
  );
106
112
  }
@@ -3,29 +3,30 @@ import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
3
3
  import template from 'lodash/template';
4
4
  import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
5
5
  import { useSliceStore } from '@qlover/slice-store-react';
6
+ import { Button, Input } from 'antd';
7
+ import * as i18nKeys from '@config/Identifier.I18n';
6
8
 
7
9
  export default function JSONStorage() {
8
10
  const jsonStorageController = IOC(JSONStorageController);
9
11
  const controllerState = useSliceStore(jsonStorageController);
10
-
11
12
  const { t } = useBaseRoutePage();
12
13
 
13
14
  return (
14
- <div className="min-h-screen bg-gray-100 py-6 flex flex-col justify-center sm:py-12">
15
+ <div className="min-h-screen bg-primary py-6 flex flex-col justify-center sm:py-12">
15
16
  <div className="relative py-3 sm:max-w-xl sm:mx-auto">
16
- <div className="bg-white shadow-lg rounded-lg px-8 py-6">
17
- <h1 className="text-3xl font-bold text-center text-gray-800 mb-8">
18
- {t('title')}
17
+ <div className="bg-secondary shadow-lg rounded-lg px-8 py-6">
18
+ <h1 className="text-3xl font-bold text-center text-text mb-8">
19
+ {t(i18nKeys.PAGE_JSONSTORAGE_MAIN_TITLE)}
19
20
  </h1>
20
21
 
21
22
  <div className="space-y-6">
22
23
  {/* 无过期时间的测试 */}
23
- <div className="p-6 bg-gray-50 rounded-lg">
24
- <h2 className="text-xl font-semibold text-gray-800 mb-4">
25
- {t('title2')}
24
+ <div className="p-6 bg-elevated rounded-lg">
25
+ <h2 className="text-xl font-semibold text-text mb-4">
26
+ {t(i18nKeys.PAGE_JSONSTORAGE_PERMANENT_TITLE)}
26
27
  </h2>
27
- <div className="text-gray-600 mb-4">
28
- {template(t('format.title'))({
28
+ <div className="text-text-secondary mb-4">
29
+ {template(t(i18nKeys.PAGE_JSONSTORAGE_FORMAT_TITLE))({
29
30
  key: 'testKey1',
30
31
  min: 100,
31
32
  max: 9000
@@ -33,16 +34,18 @@ export default function JSONStorage() {
33
34
  </div>
34
35
 
35
36
  <div className="flex flex-col items-center space-y-4">
36
- <button
37
+ <Button
38
+ type="primary"
37
39
  onClick={jsonStorageController.changeRandomTestKey1}
38
- className="px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors duration-200"
39
40
  >
40
- {t('setRandomValue')}
41
- </button>
41
+ {t(i18nKeys.PAGE_JSONSTORAGE_SET_RANDOM)}
42
+ </Button>
42
43
 
43
- <div className="p-4 bg-white rounded-lg w-full text-center">
44
- <span className="text-gray-600">{t('currentValue')}: </span>
45
- <span className="font-semibold text-gray-800">
44
+ <div className="p-4 bg-secondary rounded-lg w-full text-center">
45
+ <span className="text-text-secondary">
46
+ {t(i18nKeys.PAGE_JSONSTORAGE_CURRENT_VALUE)}:{' '}
47
+ </span>
48
+ <span className="font-semibold text-text">
46
49
  {controllerState.testKey1}
47
50
  </span>
48
51
  </div>
@@ -50,12 +53,12 @@ export default function JSONStorage() {
50
53
  </div>
51
54
 
52
55
  {/* 带过期时间的测试 */}
53
- <div className="p-6 bg-gray-50 rounded-lg">
54
- <h2 className="text-xl font-semibold text-gray-800 mb-4">
55
- {t('title3')}
56
+ <div className="p-6 bg-elevated rounded-lg">
57
+ <h2 className="text-xl font-semibold text-text mb-4">
58
+ {t(i18nKeys.PAGE_JSONSTORAGE_EXPIRE_TITLE)}
56
59
  </h2>
57
- <div className="text-gray-600 mb-4">
58
- {template(t('format.title'))({
60
+ <div className="text-text-secondary mb-4">
61
+ {template(t(i18nKeys.PAGE_JSONSTORAGE_FORMAT_TITLE))({
59
62
  key: 'testKey2',
60
63
  min: 100,
61
64
  max: 9000
@@ -64,7 +67,7 @@ export default function JSONStorage() {
64
67
 
65
68
  <div className="flex flex-col items-center space-y-4">
66
69
  <div className="flex items-center space-x-4">
67
- <input
70
+ <Input
68
71
  type="number"
69
72
  value={controllerState.expireTime}
70
73
  onChange={(e) =>
@@ -72,23 +75,27 @@ export default function JSONStorage() {
72
75
  Number(e.target.value)
73
76
  )
74
77
  }
75
- className="px-4 py-2 border rounded-lg w-32"
78
+ className="w-32"
76
79
  min="1000"
77
80
  step="1000"
78
81
  />
79
- <span className="text-gray-600">{t('ms')}</span>
82
+ <span className="text-text-secondary">
83
+ {t(i18nKeys.PAGE_JSONSTORAGE_MS)}
84
+ </span>
80
85
  </div>
81
86
 
82
- <button
87
+ <Button
88
+ type="primary"
83
89
  onClick={jsonStorageController.onChangeRandomTestKey2}
84
- className="px-6 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors duration-200"
85
90
  >
86
- {t('setExpireTime')}
87
- </button>
91
+ {t(i18nKeys.PAGE_JSONSTORAGE_SET_EXPIRE)}
92
+ </Button>
88
93
 
89
- <div className="p-4 bg-white rounded-lg w-full text-center">
90
- <span className="text-gray-600">{t('currentValue')}: </span>
91
- <span className="font-semibold text-gray-800">
94
+ <div className="p-4 bg-secondary rounded-lg w-full text-center">
95
+ <span className="text-text-secondary">
96
+ {t(i18nKeys.PAGE_JSONSTORAGE_CURRENT_VALUE)}:{' '}
97
+ </span>
98
+ <span className="font-semibold text-text">
92
99
  {controllerState.testKey2}
93
100
  </span>
94
101
  </div>
@@ -96,12 +103,12 @@ export default function JSONStorage() {
96
103
  </div>
97
104
 
98
105
  {/* 请求超时时间设置 */}
99
- <div className="p-6 bg-gray-50 rounded-lg">
100
- <h2 className="text-xl font-semibold text-gray-800 mb-4">
101
- {t('title4')}
106
+ <div className="p-6 bg-elevated rounded-lg">
107
+ <h2 className="text-xl font-semibold text-text mb-4">
108
+ {t(i18nKeys.PAGE_JSONSTORAGE_TIMEOUT_TITLE)}
102
109
  </h2>
103
110
  <div className="flex items-center space-x-4">
104
- <input
111
+ <Input
105
112
  type="number"
106
113
  value={controllerState.requestTimeout}
107
114
  onChange={(e) =>
@@ -109,11 +116,13 @@ export default function JSONStorage() {
109
116
  Number(e.target.value)
110
117
  )
111
118
  }
112
- className="px-4 py-2 border rounded-lg w-32"
119
+ className="w-32"
113
120
  min="1000"
114
121
  step="1000"
115
122
  />
116
- <span className="text-gray-600">{t('ms')}</span>
123
+ <span className="text-text-secondary">
124
+ {t(i18nKeys.PAGE_JSONSTORAGE_MS)}
125
+ </span>
117
126
  </div>
118
127
  </div>
119
128
  </div>
@@ -5,10 +5,13 @@ import { ProcessProvider } from '@/uikit/providers/ProcessProvider';
5
5
  export default function Layout() {
6
6
  return (
7
7
  <ProcessProvider>
8
- <div data-testid="basic-layout" className="text-base">
8
+ <div
9
+ data-testid="basic-layout"
10
+ className="text-base min-h-screen bg-primary"
11
+ >
9
12
  <BaseHeader />
10
13
 
11
- <div className="text-black bg-white">
14
+ <div className="text-text bg-primary">
12
15
  <Outlet />
13
16
  </div>
14
17
  </div>