@qlover/create-app 0.3.1 → 0.3.3

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 (75) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/configs/_common/.github/workflows/general-check.yml +17 -29
  3. package/configs/_common/.github/workflows/{release.yml.template → release.yml} +16 -51
  4. package/package.json +3 -3
  5. package/templates/pack-app/fe-config.json +30 -1
  6. package/templates/pack-app/package.json +45 -32
  7. package/templates/pack-app/tsconfig.test.json +1 -1
  8. package/templates/react-app/config/Identifier.I18n.ts +878 -0
  9. package/templates/react-app/config/app.router.json +7 -7
  10. package/templates/react-app/config/common.ts +7 -4
  11. package/templates/react-app/config/theme.json +7 -88
  12. package/templates/react-app/package.json +9 -4
  13. package/templates/react-app/postcss.config.js +1 -2
  14. package/templates/react-app/public/locales/en/common.json +118 -1
  15. package/templates/react-app/public/locales/zh/common.json +118 -1
  16. package/templates/react-app/src/App.tsx +14 -2
  17. package/templates/react-app/src/base/cases/RequestLogger.ts +3 -4
  18. package/templates/react-app/src/base/cases/RequestStatusCatcher.ts +3 -2
  19. package/templates/react-app/src/base/services/I18nService.ts +31 -3
  20. package/templates/react-app/src/base/services/ProcesserService.ts +3 -2
  21. package/templates/react-app/src/core/IOC.ts +15 -9
  22. package/templates/react-app/src/core/bootstrap.ts +42 -53
  23. package/templates/react-app/src/core/bootstraps/PrintBootstrap.ts +14 -0
  24. package/templates/react-app/src/core/bootstraps/index.ts +36 -7
  25. package/templates/react-app/src/core/globals.ts +4 -6
  26. package/templates/react-app/src/core/registers/RegisterApi.ts +2 -5
  27. package/templates/react-app/src/core/registers/RegisterCommon.ts +38 -28
  28. package/templates/react-app/src/core/registers/RegisterControllers.ts +5 -10
  29. package/templates/react-app/src/core/registers/RegisterGlobals.ts +15 -14
  30. package/templates/react-app/src/core/registers/index.ts +27 -12
  31. package/templates/react-app/src/main.tsx +1 -1
  32. package/templates/react-app/src/pages/404.tsx +1 -1
  33. package/templates/react-app/src/pages/500.tsx +1 -1
  34. package/templates/react-app/src/pages/auth/Login.tsx +128 -36
  35. package/templates/react-app/src/pages/base/About.tsx +5 -2
  36. package/templates/react-app/src/pages/base/ErrorIdentifier.tsx +38 -19
  37. package/templates/react-app/src/pages/base/Executor.tsx +447 -29
  38. package/templates/react-app/src/pages/base/Home.tsx +99 -93
  39. package/templates/react-app/src/pages/base/JSONStorage.tsx +47 -38
  40. package/templates/react-app/src/pages/base/Layout.tsx +5 -2
  41. package/templates/react-app/src/pages/base/Request.tsx +90 -208
  42. package/templates/react-app/src/pages/base/components/BaseHeader.tsx +13 -5
  43. package/templates/react-app/src/styles/css/page.css +11 -0
  44. package/templates/react-app/src/styles/css/tailwind.css +5 -0
  45. package/templates/react-app/src/styles/css/themes/_default.css +200 -0
  46. package/templates/react-app/src/styles/css/themes/dark.css +154 -0
  47. package/templates/react-app/src/styles/css/themes/index.css +3 -0
  48. package/templates/react-app/src/styles/css/themes/pink.css +160 -0
  49. package/templates/react-app/src/uikit/components/LanguageSwitcher.tsx +56 -0
  50. package/templates/react-app/src/uikit/components/Loading.tsx +27 -21
  51. package/templates/react-app/src/uikit/components/ThemeSwitcher.tsx +63 -13
  52. package/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +1 -1
  53. package/templates/react-app/src/uikit/controllers/RouterController.ts +3 -3
  54. package/templates/react-app/src/uikit/controllers/UserController.ts +1 -1
  55. package/templates/react-app/tailwind.config.js +1 -15
  56. package/templates/react-app/vite.config.ts +9 -3
  57. package/templates/react-app/lib/tailwind/root10px.js +0 -178
  58. package/templates/react-app/lib/tailwind/theme-generator.js +0 -238
  59. package/templates/react-app/public/locales/en/about.json +0 -3
  60. package/templates/react-app/public/locales/en/executor.json +0 -6
  61. package/templates/react-app/public/locales/en/home.json +0 -10
  62. package/templates/react-app/public/locales/en/jsonStorage.json +0 -11
  63. package/templates/react-app/public/locales/en/login.json +0 -7
  64. package/templates/react-app/public/locales/en/request.json +0 -15
  65. package/templates/react-app/public/locales/zh/about.json +0 -3
  66. package/templates/react-app/public/locales/zh/executor.json +0 -7
  67. package/templates/react-app/public/locales/zh/home.json +0 -10
  68. package/templates/react-app/public/locales/zh/jsonStorage.json +0 -11
  69. package/templates/react-app/public/locales/zh/login.json +0 -8
  70. package/templates/react-app/public/locales/zh/request.json +0 -15
  71. package/templates/react-app/src/base/port/InversifyIocInterface.ts +0 -9
  72. package/templates/react-app/src/uikit/styles/css/page.css +0 -3
  73. package/templates/react-app/src/uikit/styles/css/tailwind.css +0 -3
  74. /package/templates/react-app/config/{ErrorIdentifier.ts → Identifier.Error.ts} +0 -0
  75. /package/templates/react-app/src/{uikit/styles → styles}/css/index.css +0 -0
@@ -1,28 +1,33 @@
1
1
  import { useState } from 'react';
2
+ import { Form, Input, Button } from 'antd';
3
+ import { UserOutlined, LockOutlined, GoogleOutlined } from '@ant-design/icons';
2
4
  import { IOC } from '@/core/IOC';
3
5
  import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
4
6
  import { RouterController } from '@/uikit/controllers/RouterController';
5
7
  import { UserController } from '@/uikit/controllers/UserController';
6
- import AppConfig from '@/core/AppConfig';
7
8
  import { useSliceStore } from '@qlover/slice-store-react';
8
9
 
10
+ interface LoginFormData {
11
+ email: string;
12
+ password: string;
13
+ }
14
+
9
15
  export default function Login() {
10
16
  const { t } = useBaseRoutePage();
11
17
  const userController = IOC(UserController);
18
+ const AppConfig = IOC('AppConfig');
12
19
  useSliceStore(userController);
13
-
14
- const [email, setEmail] = useState(AppConfig.loginUser);
15
- const [password, setPassword] = useState(AppConfig.loginPassword);
16
20
  const [loading, setLoading] = useState(false);
17
21
 
18
- const handleLogin = async () => {
22
+ const handleLogin = async (values: LoginFormData) => {
19
23
  try {
20
24
  setLoading(true);
21
- await userController.login({ username: email, password });
22
- // Redirect or show success message
25
+ await userController.login({
26
+ username: values.email,
27
+ password: values.password
28
+ });
23
29
  IOC(RouterController).replaceToHome();
24
30
  } catch (error) {
25
- // Handle login error
26
31
  console.error(error);
27
32
  } finally {
28
33
  setLoading(false);
@@ -30,37 +35,124 @@ export default function Login() {
30
35
  };
31
36
 
32
37
  return (
33
- <div className="min-h-screen bg-gray-100 py-6 flex flex-col justify-center sm:py-12">
34
- <div className="relative py-3 sm:max-w-xl sm:mx-auto">
35
- <div className="bg-white shadow-lg rounded-lg px-8 py-6">
36
- <h1 className="text-base font-bold text-center text-gray-800 mb-8">
37
- {t('login')}
38
- </h1>
39
- <div className="space-y-6">
40
- <input
41
- type="email"
42
- value={email}
43
- onChange={(e) => setEmail(e.target.value)}
44
- placeholder={t('email')}
45
- className="w-full px-4 py-2 border rounded-lg"
46
- />
47
- <input
48
- type="password"
49
- value={password}
50
- onChange={(e) => setPassword(e.target.value)}
51
- placeholder={t('password')}
52
- className="w-full px-4 py-2 border rounded-lg"
53
- />
54
- <button
55
- onClick={handleLogin}
56
- className="w-full px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors duration-200"
57
- disabled={loading}
38
+ <div className="flex min-h-screen text-xs1 bg-primary">
39
+ {/* Left side - Brand section */}
40
+ <div className="hidden lg:flex lg:w-1/2 bg-secondary p-12 flex-col">
41
+ <div className="flex items-center gap-3 mb-12">
42
+ <div className="w-10 h-10 bg-brand rounded-lg"></div>
43
+ <span className="text-2xl font-semibold text-text">
44
+ {AppConfig.appName}
45
+ </span>
46
+ </div>
47
+ <h1 className="text-4xl font-bold text-text mb-4">
48
+ Welcome back to the future of learning
49
+ </h1>
50
+ <p className="text-text-secondary text-lg mb-8">
51
+ Unlock personalized AI-powered learning experiences designed to
52
+ accelerate your knowledge journey.
53
+ </p>
54
+ <div className="space-y-4">
55
+ <FeatureItem
56
+ icon="🎯"
57
+ text="AI-powered personalized learning paths"
58
+ />
59
+ <FeatureItem icon="🎯" text="Smart content recommendations" />
60
+ <FeatureItem icon="📊" text="Real-time progress tracking" />
61
+ </div>
62
+ </div>
63
+
64
+ {/* Right side - Login form */}
65
+ <div className="w-full lg:w-1/2 p-8 sm:p-12 flex items-center justify-center">
66
+ <div className="w-full max-w-[420px]">
67
+ <h2 className="text-2xl font-semibold mb-2 text-text">
68
+ {t('Sign in to your account')}
69
+ </h2>
70
+ <p className="text-text-secondary mb-8">
71
+ Enter your credentials to access your dashboard
72
+ </p>
73
+
74
+ <Form
75
+ name="login"
76
+ initialValues={{
77
+ email: AppConfig.loginUser,
78
+ password: AppConfig.loginPassword
79
+ }}
80
+ onFinish={handleLogin}
81
+ layout="vertical"
82
+ className="space-y-4"
83
+ >
84
+ <Form.Item
85
+ name="email"
86
+ rules={[{ required: true, message: 'Please input your email!' }]}
58
87
  >
59
- {loading ? 'Loading...' : t('login')}
60
- </button>
61
- </div>
88
+ <Input
89
+ prefix={<UserOutlined className="text-text-tertiary" />}
90
+ placeholder={t('email')}
91
+ className="h-12 text-base bg-secondary border-border"
92
+ />
93
+ </Form.Item>
94
+
95
+ <Form.Item
96
+ name="password"
97
+ rules={[
98
+ { required: true, message: 'Please input your password!' }
99
+ ]}
100
+ >
101
+ <Input.Password
102
+ prefix={<LockOutlined />}
103
+ placeholder={t('password')}
104
+ className="h-12 text-base"
105
+ />
106
+ </Form.Item>
107
+
108
+ <div className="flex justify-end">
109
+ <a href="#" className="text-brand hover:text-brand-hover">
110
+ {t('Forgot your password?')}
111
+ </a>
112
+ </div>
113
+
114
+ <Form.Item>
115
+ <Button
116
+ type="primary"
117
+ htmlType="submit"
118
+ loading={loading}
119
+ className="w-full h-12 text-base"
120
+ >
121
+ {t('Sign In')}
122
+ </Button>
123
+ </Form.Item>
124
+
125
+ <div className="text-center text-text-tertiary my-4">
126
+ or continue with
127
+ </div>
128
+
129
+ <Button icon={<GoogleOutlined />} className="w-full h-12 text-base">
130
+ Sign in with Google
131
+ </Button>
132
+
133
+ <div className="text-center mt-6">
134
+ <span className="text-text-tertiary">
135
+ Don't have an account?{' '}
136
+ </span>
137
+ <a href="#" className="text-brand hover:text-brand-hover">
138
+ Create one here
139
+ </a>
140
+ </div>
141
+ </Form>
62
142
  </div>
63
143
  </div>
64
144
  </div>
65
145
  );
66
146
  }
147
+
148
+ // Helper component for feature items
149
+ function FeatureItem({ icon, text }: { icon: string; text: string }) {
150
+ return (
151
+ <div className="flex items-center gap-3 text-text">
152
+ <div className="w-8 h-8 bg-elevated rounded-lg flex items-center justify-center">
153
+ {icon}
154
+ </div>
155
+ <span>{text}</span>
156
+ </div>
157
+ );
158
+ }
@@ -1,11 +1,14 @@
1
1
  import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
2
+ import * as i18nKeys from '@config/Identifier.I18n';
2
3
 
3
4
  export default function About() {
4
5
  const { t } = useBaseRoutePage();
5
6
  return (
6
- <div className="min-h-screen bg-gray-100 py-6 flex flex-col justify-center sm:py-12">
7
+ <div className="min-h-screen bg-primary py-6 flex flex-col justify-center sm:py-12">
7
8
  <div className="relative py-3 sm:max-w-xl sm:mx-auto">
8
- <h1 className="text-2xl font-bold text-center">{t('title')}</h1>
9
+ <h1 className="text-2xl font-bold text-center text-text">
10
+ {t(i18nKeys.PAGE_ABOUT_TITLE)}
11
+ </h1>
9
12
  </div>
10
13
  </div>
11
14
  );
@@ -1,38 +1,57 @@
1
+ import { Button } from 'antd';
1
2
  import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
2
- import * as ErrorIdentifierList from '@config/ErrorIdentifier';
3
+ import * as ErrorIdentifierList from '@config/Identifier.Error';
4
+ import * as i18nKeys from '@config/Identifier.I18n';
3
5
 
4
6
  export default function ErrorIdentifier() {
5
7
  const { t } = useBaseRoutePage();
6
8
 
7
9
  return (
8
- <div className="min-h-screen bg-gray-100/90 py-8 px-4 sm:px-6 lg:px-8">
9
- <div className="max-w-3xl mx-auto">
10
- <div className="bg-white shadow-lg rounded-lg overflow-hidden">
11
- <div className="bg-gradient-to-r from-blue-500 to-purple-600 px-6 py-4">
12
- <h1 className="text-2xl font-bold text-white">
13
- {t('errorIdentifier')}
10
+ <div className="min-h-screen bg-primary py-8 px-4 sm:px-6 lg:px-8">
11
+ <div className="max-w-4xl mx-auto space-y-6">
12
+ {/* Header Section */}
13
+ <section className="py-8">
14
+ <div className="text-center">
15
+ <h1 className="text-4xl md:text-5xl font-bold mb-6 text-text">
16
+ {t(i18nKeys.PAGE_ERROR_IDENTIFIER_MAIN_TITLE)}
14
17
  </h1>
15
- <p className="text-blue-100 mt-1">
16
- Identifier From: '@config/ErrorIdentifier'
18
+ <p className="text-xl text-text-secondary mb-8">
19
+ {t(i18nKeys.PAGE_ERROR_IDENTIFIER_SOURCE_DESCRIPTION)}
17
20
  </p>
18
21
  </div>
22
+ </section>
19
23
 
20
- <div className="divide-y divide-gray-200">
21
- {Object.entries(ErrorIdentifierList).map(([key, value]) => (
22
- <div
23
- key={key}
24
- className="px-6 py-4 flex flex-col sm:flex-row sm:items-center hover:bg-gray-50"
25
- >
26
- <span className="font-medium text-gray-700 mr-3 min-w-[200px]">
24
+ {/* Error Identifier List */}
25
+ <div className="grid gap-4">
26
+ {Object.entries(ErrorIdentifierList).map(([key, value]) => (
27
+ <div
28
+ key={key}
29
+ className="bg-secondary shadow sm:rounded-lg p-6 border border-border hover:bg-elevated transition-colors duration-200"
30
+ >
31
+ <div className="flex flex-col sm:flex-row sm:items-center justify-between">
32
+ <span className="font-medium text-text mb-2 sm:mb-0">
27
33
  {key}
28
34
  </span>
29
- <span className="mt-1 sm:mt-0 text-gray-600 bg-gray-100 px-3 py-1 rounded-md">
35
+ <span className="text-sm text-text-secondary bg-primary px-3 py-1 rounded-md">
30
36
  {t(value)}
31
37
  </span>
32
38
  </div>
33
- ))}
34
- </div>
39
+ </div>
40
+ ))}
35
41
  </div>
42
+
43
+ {/* Call to Action Section */}
44
+ <section className="py-8 text-center">
45
+ <h2 className="text-2xl font-bold mb-4 text-text">
46
+ {t(i18nKeys.PAGE_ERROR_IDENTIFIER_HELP_TITLE)}
47
+ </h2>
48
+ <p className="text-lg text-text-secondary mb-6">
49
+ {t(i18nKeys.PAGE_ERROR_IDENTIFIER_HELP_DESCRIPTION)}
50
+ </p>
51
+ <Button type="primary" size="large">
52
+ {t(i18nKeys.PAGE_ERROR_IDENTIFIER_CONTACT_SUPPORT)}
53
+ </Button>
54
+ </section>
36
55
  </div>
37
56
  </div>
38
57
  );