@qlover/create-app 0.7.7 → 0.7.9
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/CHANGELOG.md +121 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/templates/next-app/build/generateLocales.ts +1 -1
- package/dist/templates/next-app/config/IOCIdentifier.ts +15 -2
- package/dist/templates/next-app/config/Identifier/common.error.ts +7 -0
- package/dist/templates/next-app/config/Identifier/page.home.ts +7 -0
- package/dist/templates/next-app/config/i18n/HomeI18n .ts +22 -0
- package/dist/templates/next-app/config/theme.ts +1 -0
- package/dist/templates/next-app/package.json +5 -5
- package/dist/templates/next-app/public/locales/{en/common.json → en.json} +3 -1
- package/dist/templates/next-app/public/locales/{zh/common.json → zh.json} +3 -1
- package/dist/templates/next-app/src/app/[locale]/layout.tsx +8 -26
- package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +9 -18
- package/dist/templates/next-app/src/app/[locale]/login/page.tsx +28 -24
- package/dist/templates/next-app/src/app/[locale]/page.tsx +105 -100
- package/dist/templates/next-app/src/base/cases/DialogHandler.ts +92 -0
- package/dist/templates/next-app/src/base/cases/NavigateBridge.ts +16 -0
- package/dist/templates/next-app/src/base/cases/PageParams.ts +74 -0
- package/dist/templates/next-app/src/base/cases/RouterService.ts +35 -0
- package/dist/templates/next-app/src/base/cases/ServerAuth.ts +17 -0
- package/dist/templates/next-app/src/base/cases/ServerErrorHandler.ts +27 -0
- package/dist/templates/next-app/src/base/port/IOCInterface.ts +24 -0
- package/dist/templates/next-app/src/base/port/ParamsHandlerInterface.ts +11 -0
- package/dist/templates/next-app/src/base/port/RouterInterface.ts +11 -0
- package/dist/templates/next-app/src/base/port/ServerAuthInterface.ts +3 -0
- package/dist/templates/next-app/src/base/port/ServerInterface.ts +12 -0
- package/dist/templates/next-app/src/base/types/PageProps.ts +9 -0
- package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +2 -39
- package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +78 -0
- package/dist/templates/next-app/src/core/clientIoc/ClientIOC.ts +37 -0
- package/dist/templates/next-app/src/core/{IocRegisterImpl.ts → clientIoc/ClientIOCRegister.ts} +20 -23
- package/dist/templates/next-app/src/core/globals.ts +3 -0
- package/dist/templates/next-app/src/core/serverIoc/ServerIOC.ts +52 -0
- package/dist/templates/next-app/src/core/serverIoc/ServerIOCRegister.ts +63 -0
- package/dist/templates/next-app/src/i18n/request.ts +1 -2
- package/dist/templates/next-app/src/i18n/routing.ts +3 -3
- package/dist/templates/next-app/src/middleware.ts +6 -3
- package/dist/templates/next-app/src/styles/css/antd-themes/_default.css +12 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/dark.css +26 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/pink.css +16 -0
- package/dist/templates/next-app/src/styles/css/page.css +4 -3
- package/dist/templates/next-app/src/styles/css/themes/_default.css +1 -0
- package/dist/templates/next-app/src/styles/css/themes/dark.css +1 -0
- package/dist/templates/next-app/src/styles/css/themes/pink.css +1 -0
- package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +14 -14
- package/dist/templates/next-app/src/uikit/components/BaseLayout.tsx +27 -0
- package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +13 -1
- package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +5 -0
- package/dist/templates/next-app/src/uikit/components/LanguageSwitcher.tsx +49 -21
- package/dist/templates/next-app/src/uikit/components/LogoutButton.tsx +34 -0
- package/dist/templates/next-app/src/uikit/components/ThemeSwitcher.tsx +92 -35
- package/dist/templates/next-app/src/uikit/context/IOCContext.ts +9 -2
- package/package.json +1 -1
- package/dist/templates/next-app/plugins/eslint-plugin-testid.mjs +0 -94
- package/dist/templates/next-app/plugins/generateLocalesPlugin.ts +0 -33
- package/dist/templates/next-app/src/core/IOC.ts +0 -58
- package/dist/templates/next-app/src/server/getServerI18n.ts +0 -26
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type BootstrapContextValue,
|
|
3
|
+
type BootstrapExecutorPlugin,
|
|
4
|
+
type IOCContainerInterface,
|
|
5
|
+
type IOCFunctionInterface,
|
|
6
|
+
type LoggerInterface
|
|
7
|
+
} from '@qlover/corekit-bridge';
|
|
8
|
+
import { AsyncExecutor, type ExecutorPlugin } from '@qlover/fe-corekit';
|
|
9
|
+
import { I, type IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
10
|
+
import type { ServerInterface } from '@/base/port/ServerInterface';
|
|
11
|
+
import { ServerIOC } from '../serverIoc/ServerIOC';
|
|
12
|
+
|
|
13
|
+
export interface BootstrapServerResult {
|
|
14
|
+
locale: string;
|
|
15
|
+
messages: Record<string, string>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface BootstrapServerContextValue extends BootstrapContextValue {
|
|
19
|
+
locale: string;
|
|
20
|
+
messages: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class BootstrapServer implements ServerInterface {
|
|
24
|
+
protected executor: AsyncExecutor;
|
|
25
|
+
protected root: Record<string, unknown> = {};
|
|
26
|
+
protected IOC: IOCFunctionInterface<
|
|
27
|
+
IOCIdentifierMapServer,
|
|
28
|
+
IOCContainerInterface
|
|
29
|
+
>;
|
|
30
|
+
readonly logger: LoggerInterface;
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
const serverIOC = ServerIOC.create();
|
|
34
|
+
const ioc = serverIOC.create();
|
|
35
|
+
const logger = ioc(I.Logger);
|
|
36
|
+
|
|
37
|
+
this.executor = new AsyncExecutor();
|
|
38
|
+
this.IOC = ioc;
|
|
39
|
+
this.logger = logger;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getIOC(): IOCFunctionInterface<IOCIdentifierMapServer, IOCContainerInterface>;
|
|
43
|
+
getIOC<T extends keyof IOCIdentifierMapServer>(
|
|
44
|
+
identifier: T
|
|
45
|
+
): IOCIdentifierMapServer[T];
|
|
46
|
+
getIOC(
|
|
47
|
+
identifier?: keyof IOCIdentifierMapServer
|
|
48
|
+
):
|
|
49
|
+
| IOCFunctionInterface<IOCIdentifierMapServer, IOCContainerInterface>
|
|
50
|
+
| IOCIdentifierMapServer[keyof IOCIdentifierMapServer] {
|
|
51
|
+
if (identifier === undefined) {
|
|
52
|
+
return this.IOC;
|
|
53
|
+
}
|
|
54
|
+
return this.IOC(identifier);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @override
|
|
59
|
+
*/
|
|
60
|
+
use(
|
|
61
|
+
plugin:
|
|
62
|
+
| BootstrapExecutorPlugin
|
|
63
|
+
| BootstrapExecutorPlugin[]
|
|
64
|
+
| ((
|
|
65
|
+
ioc: IOCFunctionInterface<
|
|
66
|
+
IOCIdentifierMapServer,
|
|
67
|
+
IOCContainerInterface
|
|
68
|
+
>
|
|
69
|
+
) => BootstrapExecutorPlugin)
|
|
70
|
+
): this {
|
|
71
|
+
if (typeof plugin === 'function') {
|
|
72
|
+
plugin = plugin(this.IOC);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
this.executor.use(plugin as ExecutorPlugin<unknown>);
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createIOCFunction,
|
|
3
|
+
type IOCContainerInterface,
|
|
4
|
+
type IOCFunctionInterface
|
|
5
|
+
} from '@qlover/corekit-bridge';
|
|
6
|
+
import { InversifyContainer } from '@/base/cases/InversifyContainer';
|
|
7
|
+
import type { IOCInterface } from '@/base/port/IOCInterface';
|
|
8
|
+
import { ClientIOCRegister } from './ClientIOCRegister';
|
|
9
|
+
import { appConfig } from '../globals';
|
|
10
|
+
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
11
|
+
|
|
12
|
+
export class ClientIOC
|
|
13
|
+
implements IOCInterface<IOCIdentifierMap, IOCContainerInterface>
|
|
14
|
+
{
|
|
15
|
+
protected ioc: IOCFunctionInterface<
|
|
16
|
+
IOCIdentifierMap,
|
|
17
|
+
IOCContainerInterface
|
|
18
|
+
> | null = null;
|
|
19
|
+
|
|
20
|
+
create(): IOCFunctionInterface<IOCIdentifierMap, IOCContainerInterface> {
|
|
21
|
+
if (this.ioc) {
|
|
22
|
+
return this.ioc;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.ioc = createIOCFunction<IOCIdentifierMap>(new InversifyContainer());
|
|
26
|
+
|
|
27
|
+
const register = new ClientIOCRegister({
|
|
28
|
+
appConfig: appConfig
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
register.register(this.ioc.implemention!, this.ioc);
|
|
32
|
+
|
|
33
|
+
return this.ioc;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const clientIOC = new ClientIOC();
|
package/dist/templates/next-app/src/core/{IocRegisterImpl.ts → clientIoc/ClientIOCRegister.ts}
RENAMED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { IOCIdentifier as I } from '@config/IOCIdentifier';
|
|
2
|
+
import { RouterService } from '@/base/cases/RouterService';
|
|
3
|
+
import type { IocRegisterOptions } from '@/base/port/IOCInterface';
|
|
2
4
|
import { I18nService } from '@/base/services/I18nService';
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import type {
|
|
5
|
+
import { UserService } from '@/base/services/UserService';
|
|
6
|
+
import { dialogHandler, logger, JSON } from '../globals';
|
|
7
|
+
import type {
|
|
8
|
+
IOCContainerInterface,
|
|
9
|
+
IOCManagerInterface,
|
|
10
|
+
IOCRegisterInterface
|
|
11
|
+
} from '@qlover/corekit-bridge';
|
|
6
12
|
|
|
7
|
-
export class
|
|
13
|
+
export class ClientIOCRegister
|
|
14
|
+
implements IOCRegisterInterface<IOCContainerInterface, IocRegisterOptions>
|
|
15
|
+
{
|
|
8
16
|
constructor(protected options: IocRegisterOptions) {}
|
|
9
17
|
|
|
10
18
|
/**
|
|
@@ -14,13 +22,13 @@ export class IocRegisterImpl implements IOCRegister {
|
|
|
14
22
|
*
|
|
15
23
|
* @param ioc - IOC container
|
|
16
24
|
*/
|
|
17
|
-
protected registerGlobals(ioc:
|
|
25
|
+
protected registerGlobals(ioc: IOCContainerInterface): void {
|
|
18
26
|
const { appConfig } = this.options;
|
|
19
27
|
ioc.bind(I.JSONSerializer, JSON);
|
|
20
28
|
ioc.bind(I.Logger, logger);
|
|
21
29
|
ioc.bind(I.AppConfig, appConfig);
|
|
22
30
|
// ioc.bind(I.EnvConfigInterface, appConfig);
|
|
23
|
-
|
|
31
|
+
ioc.bind(I.DialogHandler, dialogHandler);
|
|
24
32
|
// ioc.bind(I.UIDialogInterface, dialogHandler);
|
|
25
33
|
// ioc.bind(I.AntdStaticApiInterface, dialogHandler);
|
|
26
34
|
// ioc.bind(I.LocalStorage, globals.localStorage);
|
|
@@ -38,20 +46,9 @@ export class IocRegisterImpl implements IOCRegister {
|
|
|
38
46
|
*
|
|
39
47
|
* @param ioc
|
|
40
48
|
*/
|
|
41
|
-
protected registerImplement(ioc:
|
|
49
|
+
protected registerImplement(ioc: IOCContainerInterface): void {
|
|
42
50
|
ioc.bind(I.I18nServiceInterface, new I18nService());
|
|
43
|
-
|
|
44
|
-
// I.RouteServiceInterface,
|
|
45
|
-
// new RouteService(
|
|
46
|
-
// ioc.get(NavigateBridge),
|
|
47
|
-
// ioc.get(I.I18nServiceInterface),
|
|
48
|
-
// {
|
|
49
|
-
// routes: useLocaleRoutes ? baseRoutes : baseNoLocaleRoutes,
|
|
50
|
-
// logger: ioc.get(I.Logger),
|
|
51
|
-
// hasLocalRoutes: useLocaleRoutes
|
|
52
|
-
// }
|
|
53
|
-
// )
|
|
54
|
-
// );
|
|
51
|
+
ioc.bind(I.RouterServiceInterface, ioc.get(RouterService));
|
|
55
52
|
// ioc.bind(
|
|
56
53
|
// I.ThemeService,
|
|
57
54
|
// new ThemeService({
|
|
@@ -61,14 +58,14 @@ export class IocRegisterImpl implements IOCRegister {
|
|
|
61
58
|
// );
|
|
62
59
|
// ioc.bind(I.I18nKeyErrorPlugin, ioc.get(I18nKeyErrorPlugin));
|
|
63
60
|
// ioc.bind(I.ProcesserExecutorInterface, ioc.get(ProcesserExecutor));
|
|
64
|
-
|
|
61
|
+
ioc.bind(I.UserServiceInterface, ioc.get(UserService));
|
|
65
62
|
// ioc.bind(I.RequestCatcherInterface, ioc.get(RequestStatusCatcher));
|
|
66
63
|
// ioc.bind(I.ExecutorPageBridgeInterface, ioc.get(ExecutorPageBridge));
|
|
67
64
|
// ioc.bind(I.JSONStoragePageInterface, ioc.get(JSONStoragePageBridge));
|
|
68
65
|
// ioc.bind(I.RequestPageBridgeInterface, ioc.get(RequestPageBridge));
|
|
69
66
|
}
|
|
70
67
|
|
|
71
|
-
protected registerCommon(_ioc:
|
|
68
|
+
protected registerCommon(_ioc: IOCContainerInterface): void {
|
|
72
69
|
// const { appConfig } = this.options;
|
|
73
70
|
// const logger = ioc.get(I.Logger);
|
|
74
71
|
// const feApiRequestCommonPlugin = new RequestCommonPlugin({
|
|
@@ -90,8 +87,8 @@ export class IocRegisterImpl implements IOCRegister {
|
|
|
90
87
|
* @override
|
|
91
88
|
*/
|
|
92
89
|
register(
|
|
93
|
-
ioc:
|
|
94
|
-
_manager: IOCManagerInterface<
|
|
90
|
+
ioc: IOCContainerInterface,
|
|
91
|
+
_manager: IOCManagerInterface<IOCContainerInterface>
|
|
95
92
|
): void {
|
|
96
93
|
this.registerGlobals(ioc);
|
|
97
94
|
this.registerCommon(ioc);
|
|
@@ -3,9 +3,12 @@ import { ColorFormatter, ConsoleHandler, Logger } from '@qlover/corekit-bridge';
|
|
|
3
3
|
import { JSONSerializer } from '@qlover/fe-corekit';
|
|
4
4
|
import { loggerStyles } from '@config/common';
|
|
5
5
|
import { AppConfig } from '@/base/cases/AppConfig';
|
|
6
|
+
import { DialogHandler } from '@/base/cases/DialogHandler';
|
|
6
7
|
|
|
7
8
|
export const appConfig = new AppConfig();
|
|
8
9
|
|
|
10
|
+
export const dialogHandler = new DialogHandler();
|
|
11
|
+
|
|
9
12
|
/**
|
|
10
13
|
* Global logger
|
|
11
14
|
*/
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createIOCFunction,
|
|
3
|
+
type IOCContainerInterface,
|
|
4
|
+
type IOCFunctionInterface
|
|
5
|
+
} from '@qlover/corekit-bridge';
|
|
6
|
+
import { AppConfig } from '@/base/cases/AppConfig';
|
|
7
|
+
import { InversifyContainer } from '@/base/cases/InversifyContainer';
|
|
8
|
+
import type { IOCInterface } from '@/base/port/IOCInterface';
|
|
9
|
+
import { ServerIOCRegister } from './ServerIOCRegister';
|
|
10
|
+
import type { IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
11
|
+
|
|
12
|
+
export class ServerIOC
|
|
13
|
+
implements IOCInterface<IOCIdentifierMapServer, IOCContainerInterface>
|
|
14
|
+
{
|
|
15
|
+
static instance: ServerIOC | null = null;
|
|
16
|
+
|
|
17
|
+
protected ioc: IOCFunctionInterface<
|
|
18
|
+
IOCIdentifierMapServer,
|
|
19
|
+
IOCContainerInterface
|
|
20
|
+
> | null = null;
|
|
21
|
+
|
|
22
|
+
static create(): ServerIOC {
|
|
23
|
+
if (this.instance) {
|
|
24
|
+
return this.instance;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
this.instance = new ServerIOC();
|
|
28
|
+
|
|
29
|
+
return this.instance;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
create(): IOCFunctionInterface<
|
|
33
|
+
IOCIdentifierMapServer,
|
|
34
|
+
IOCContainerInterface
|
|
35
|
+
> {
|
|
36
|
+
if (this.ioc) {
|
|
37
|
+
return this.ioc;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.ioc = createIOCFunction<IOCIdentifierMapServer>(
|
|
41
|
+
new InversifyContainer()
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const register = new ServerIOCRegister({
|
|
45
|
+
appConfig: new AppConfig()
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
register.register(this.ioc.implemention!, this.ioc);
|
|
49
|
+
|
|
50
|
+
return this.ioc;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConsoleHandler,
|
|
3
|
+
Logger,
|
|
4
|
+
TimestampFormatter,
|
|
5
|
+
type IOCContainerInterface,
|
|
6
|
+
type IOCManagerInterface,
|
|
7
|
+
type IOCRegisterInterface
|
|
8
|
+
} from '@qlover/corekit-bridge';
|
|
9
|
+
import { IOCIdentifier as I } from '@config/IOCIdentifier';
|
|
10
|
+
import type { IocRegisterOptions } from '@/base/port/IOCInterface';
|
|
11
|
+
|
|
12
|
+
export class ServerIOCRegister
|
|
13
|
+
implements IOCRegisterInterface<IOCContainerInterface, IocRegisterOptions>
|
|
14
|
+
{
|
|
15
|
+
constructor(protected options: IocRegisterOptions) {}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Register globals
|
|
19
|
+
*
|
|
20
|
+
* 一般用于注册全局
|
|
21
|
+
*
|
|
22
|
+
* @param ioc - IOC container
|
|
23
|
+
*/
|
|
24
|
+
protected registerGlobals(ioc: IOCContainerInterface): void {
|
|
25
|
+
const { appConfig } = this.options;
|
|
26
|
+
ioc.bind(I.AppConfig, appConfig);
|
|
27
|
+
ioc.bind(
|
|
28
|
+
I.Logger,
|
|
29
|
+
new Logger({
|
|
30
|
+
handlers: new ConsoleHandler(
|
|
31
|
+
new TimestampFormatter({
|
|
32
|
+
localeOptions: {
|
|
33
|
+
year: '2-digit',
|
|
34
|
+
month: '2-digit',
|
|
35
|
+
day: '2-digit',
|
|
36
|
+
hour: '2-digit',
|
|
37
|
+
minute: '2-digit',
|
|
38
|
+
second: '2-digit'
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
),
|
|
42
|
+
silent: false,
|
|
43
|
+
level: appConfig.env === 'development' ? 'debug' : 'info'
|
|
44
|
+
})
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
protected registerImplement(_ioc: IOCContainerInterface): void {}
|
|
49
|
+
|
|
50
|
+
protected registerCommon(_ioc: IOCContainerInterface): void {}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @override
|
|
54
|
+
*/
|
|
55
|
+
register(
|
|
56
|
+
ioc: IOCContainerInterface,
|
|
57
|
+
_manager: IOCManagerInterface<IOCContainerInterface>
|
|
58
|
+
): void {
|
|
59
|
+
this.registerGlobals(ioc);
|
|
60
|
+
this.registerCommon(ioc);
|
|
61
|
+
this.registerImplement(ioc);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -16,7 +16,6 @@ export default getRequestConfig(async ({ requestLocale }) => {
|
|
|
16
16
|
// Dynamically import the translation messages for the selected locale
|
|
17
17
|
return {
|
|
18
18
|
locale,
|
|
19
|
-
messages: (await import(`../../public/locales/${locale}
|
|
20
|
-
.default
|
|
19
|
+
messages: (await import(`../../public/locales/${locale}.json`)).default
|
|
21
20
|
};
|
|
22
21
|
});
|
|
@@ -15,8 +15,11 @@ export const config = {
|
|
|
15
15
|
matcher: [
|
|
16
16
|
'/', // Match the root path explicitly
|
|
17
17
|
|
|
18
|
-
// Match all paths except for
|
|
19
|
-
//
|
|
20
|
-
|
|
18
|
+
// Match all paths except for:
|
|
19
|
+
// - API routes
|
|
20
|
+
// - Next.js internals (_next/*)
|
|
21
|
+
// - Static files (*.svg, *.png, *.jpg, *.jpeg, *.gif, *.ico)
|
|
22
|
+
// - Other static assets and special files
|
|
23
|
+
'/((?!api|_next|.*\\.(?:svg|png|jpg|jpeg|gif|ico)|favicon.ico|sitemap.xml|sitemap-0.xml).*)'
|
|
21
24
|
]
|
|
22
25
|
};
|
|
@@ -236,4 +236,16 @@ html,
|
|
|
236
236
|
--fe-message-info-color: var(--fe-color-primary);
|
|
237
237
|
--fe-message-loading-color: var(--fe-color-primary);
|
|
238
238
|
}
|
|
239
|
+
|
|
240
|
+
.ant-dropdown-css-var {
|
|
241
|
+
/* Control Variables - Default Theme */
|
|
242
|
+
--fe-control-outline-width: 2px;
|
|
243
|
+
--fe-control-interactive-size: 16px;
|
|
244
|
+
--fe-control-item-bg-hover: rgba(0, 0, 0, 0.04);
|
|
245
|
+
--fe-control-item-bg-active: #e6f4ff;
|
|
246
|
+
--fe-control-item-bg-active-hover: #bae0ff;
|
|
247
|
+
--fe-control-item-bg-active-disabled: rgba(0, 0, 0, 0.15);
|
|
248
|
+
--fe-control-tmp-outline: rgba(0, 0, 0, 0.02);
|
|
249
|
+
--fe-control-outline: rgba(96, 165, 250, 0.1); /* blue-400 with 0.1 opacity */
|
|
250
|
+
}
|
|
239
251
|
}
|
|
@@ -175,4 +175,30 @@
|
|
|
175
175
|
0.85
|
|
176
176
|
); /* 确保文字在深色背景上清晰可见 */
|
|
177
177
|
}
|
|
178
|
+
.ant-dropdown-css-var {
|
|
179
|
+
/* Control Variables - Dark Theme */
|
|
180
|
+
--fe-control-outline-width: 2px;
|
|
181
|
+
--fe-control-interactive-size: 16px;
|
|
182
|
+
--fe-control-item-bg-hover: rgba(255, 255, 255, 0.08);
|
|
183
|
+
--fe-control-item-bg-active: rgba(
|
|
184
|
+
96,
|
|
185
|
+
165,
|
|
186
|
+
250,
|
|
187
|
+
0.2
|
|
188
|
+
); /* blue-400 with 0.2 opacity */
|
|
189
|
+
--fe-control-item-bg-active-hover: rgba(
|
|
190
|
+
96,
|
|
191
|
+
165,
|
|
192
|
+
250,
|
|
193
|
+
0.3
|
|
194
|
+
); /* blue-400 with 0.3 opacity */
|
|
195
|
+
--fe-control-item-bg-active-disabled: rgba(255, 255, 255, 0.15);
|
|
196
|
+
--fe-control-tmp-outline: rgba(255, 255, 255, 0.02);
|
|
197
|
+
--fe-control-outline: rgba(
|
|
198
|
+
96,
|
|
199
|
+
165,
|
|
200
|
+
250,
|
|
201
|
+
0.1
|
|
202
|
+
); /* blue-400 with 0.1 opacity */
|
|
203
|
+
}
|
|
178
204
|
}
|
|
@@ -201,4 +201,20 @@
|
|
|
201
201
|
0 9px 28px 8px rgba(244, 114, 182, 0.05);
|
|
202
202
|
--fe-modal-mask-bg: rgba(244, 114, 182, 0.45);
|
|
203
203
|
}
|
|
204
|
+
.ant-dropdown-css-var {
|
|
205
|
+
/* Control Variables - Pink Theme */
|
|
206
|
+
--fe-control-outline-width: 2px;
|
|
207
|
+
--fe-control-interactive-size: 16px;
|
|
208
|
+
--fe-control-item-bg-hover: rgba(0, 0, 0, 0.04);
|
|
209
|
+
--fe-control-item-bg-active: #fce7f3; /* pink-100 */
|
|
210
|
+
--fe-control-item-bg-active-hover: #fbcfe8; /* pink-200 */
|
|
211
|
+
--fe-control-item-bg-active-disabled: rgba(0, 0, 0, 0.15);
|
|
212
|
+
--fe-control-tmp-outline: rgba(0, 0, 0, 0.02);
|
|
213
|
+
--fe-control-outline: rgba(
|
|
214
|
+
244,
|
|
215
|
+
114,
|
|
216
|
+
182,
|
|
217
|
+
0.1
|
|
218
|
+
); /* pink-400 with 0.1 opacity */
|
|
219
|
+
}
|
|
204
220
|
}
|
|
@@ -11,9 +11,10 @@
|
|
|
11
11
|
--color-secondary: rgba(var(--color-bg-secondary));
|
|
12
12
|
--color-elevated: rgba(var(--color-bg-elevated));
|
|
13
13
|
--color-text: rgba(var(--text-primary));
|
|
14
|
+
--color-text-hover: rgba(var(--text-primary-hover));
|
|
14
15
|
--color-text-secondary: rgba(var(--text-secondary));
|
|
15
16
|
--color-text-tertiary: rgba(var(--text-tertiary));
|
|
16
|
-
--color-border: rgba(var(--color-border));
|
|
17
|
-
--color-brand: rgba(var(--color-brand));
|
|
18
|
-
--color-brand-hover: rgba(var(--color-brand-hover));
|
|
17
|
+
--color-c-border: rgba(var(--color-border));
|
|
18
|
+
--color-c-brand: rgba(var(--color-brand));
|
|
19
|
+
--color-c-brand-hover: rgba(var(--color-brand-hover));
|
|
19
20
|
}
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import Link from 'next/link';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
5
|
+
import { useIOC } from '@/uikit/hook/useIOC';
|
|
6
6
|
import { LanguageSwitcher } from './LanguageSwitcher';
|
|
7
|
+
import { LogoutButton } from './LogoutButton';
|
|
7
8
|
import { ThemeSwitcher } from './ThemeSwitcher';
|
|
8
9
|
|
|
9
|
-
export function BaseHeader() {
|
|
10
|
+
export function BaseHeader(props: { showLogoutButton?: boolean }) {
|
|
11
|
+
const { showLogoutButton } = props;
|
|
12
|
+
const appConfig = useIOC(IOCIdentifier.AppConfig);
|
|
13
|
+
const i18nService = useIOC(IOCIdentifier.I18nServiceInterface);
|
|
14
|
+
|
|
10
15
|
return (
|
|
11
16
|
<header
|
|
12
|
-
data-testid="
|
|
13
|
-
className="h-14 bg-secondary border-b border-border sticky top-0 z-50"
|
|
17
|
+
data-testid="BaseHeader"
|
|
18
|
+
className="h-14 bg-secondary border-b border-c-border sticky top-0 z-50"
|
|
14
19
|
>
|
|
15
20
|
<div className="flex items-center justify-between h-full px-4 mx-auto max-w-7xl">
|
|
16
21
|
<div className="flex items-center">
|
|
@@ -18,23 +23,18 @@ export function BaseHeader() {
|
|
|
18
23
|
href="/"
|
|
19
24
|
className="flex items-center hover:opacity-80 transition-opacity"
|
|
20
25
|
>
|
|
21
|
-
{/* <img
|
|
22
|
-
data-testid="base-header-logo"
|
|
23
|
-
src={IOC(PublicAssetsPath).getPath('/logo.svg')}
|
|
24
|
-
alt="logo"
|
|
25
|
-
className="h-8 w-auto"
|
|
26
|
-
/> */}
|
|
27
26
|
<span
|
|
28
27
|
data-testid="base-header-app-name"
|
|
29
28
|
className="ml-2 text-lg font-semibold text-text"
|
|
30
29
|
>
|
|
31
|
-
{
|
|
30
|
+
{appConfig.appName}
|
|
32
31
|
</span>
|
|
33
32
|
</Link>
|
|
34
33
|
</div>
|
|
35
|
-
<div className="flex items-center gap-
|
|
36
|
-
<LanguageSwitcher />
|
|
34
|
+
<div className="flex items-center gap-2">
|
|
35
|
+
<LanguageSwitcher i18nService={i18nService} />
|
|
37
36
|
<ThemeSwitcher />
|
|
37
|
+
{showLogoutButton && <LogoutButton />}
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
40
|
</header>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseHeader } from './BaseHeader';
|
|
2
|
+
import type { HTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
export interface BaseLayoutProps extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
showLogoutButton?: boolean;
|
|
6
|
+
mainProps?: HTMLAttributes<HTMLElement>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function BaseLayout({
|
|
10
|
+
children,
|
|
11
|
+
showLogoutButton,
|
|
12
|
+
mainProps,
|
|
13
|
+
...props
|
|
14
|
+
}: BaseLayoutProps) {
|
|
15
|
+
return (
|
|
16
|
+
<div
|
|
17
|
+
data-testid="BaseLayout"
|
|
18
|
+
className="flex flex-col min-h-screen"
|
|
19
|
+
{...props}
|
|
20
|
+
>
|
|
21
|
+
<BaseHeader showLogoutButton={showLogoutButton} />
|
|
22
|
+
<main className="flex flex-1 flex-col bg-primary" {...mainProps}>
|
|
23
|
+
{children}
|
|
24
|
+
</main>
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import '@ant-design/v5-patch-for-react-19';
|
|
3
|
+
import { useRouter } from 'next/navigation';
|
|
4
|
+
import { useLocale } from 'next-intl';
|
|
3
5
|
import { useEffect } from 'react';
|
|
6
|
+
import { I } from '@config/IOCIdentifier';
|
|
7
|
+
import { NavigateBridge } from '@/base/cases/NavigateBridge';
|
|
4
8
|
import { BootstrapClient } from '@/core/bootstraps/BootstrapClient';
|
|
9
|
+
import { clientIOC } from '@/core/clientIoc/ClientIOC';
|
|
5
10
|
import { IOCContext } from '../context/IOCContext';
|
|
6
11
|
|
|
7
12
|
export function BootstrapsProvider(props: { children: React.ReactNode }) {
|
|
8
|
-
const IOC =
|
|
13
|
+
const IOC = clientIOC.create();
|
|
14
|
+
const locale = useLocale();
|
|
15
|
+
const router = useRouter();
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
IOC(I.RouterServiceInterface).setLocale(locale);
|
|
19
|
+
IOC(NavigateBridge).setUIBridge(router);
|
|
20
|
+
}, [locale, router, IOC]);
|
|
9
21
|
|
|
10
22
|
useEffect(() => {
|
|
11
23
|
if (typeof window !== 'undefined') {
|
|
@@ -3,6 +3,8 @@ import '@ant-design/v5-patch-for-react-19';
|
|
|
3
3
|
import { AntdRegistry } from '@ant-design/nextjs-registry';
|
|
4
4
|
import { AntdThemeProvider } from '@brain-toolkit/antd-theme-override/react';
|
|
5
5
|
import { ThemeProvider } from 'next-themes';
|
|
6
|
+
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
7
|
+
import { clientIOC } from '@/core/clientIoc/ClientIOC';
|
|
6
8
|
import { BootstrapsProvider } from './BootstrapsProvider';
|
|
7
9
|
import type { CommonThemeConfig } from '@config/theme';
|
|
8
10
|
|
|
@@ -23,10 +25,13 @@ export function ComboProvider(props: {
|
|
|
23
25
|
}) {
|
|
24
26
|
const { themeConfig, children } = props;
|
|
25
27
|
|
|
28
|
+
const IOC = clientIOC.create();
|
|
29
|
+
|
|
26
30
|
return (
|
|
27
31
|
<AntdThemeProvider
|
|
28
32
|
data-testid="ComboProvider"
|
|
29
33
|
theme={themeConfig.antdTheme}
|
|
34
|
+
staticApi={IOC(IOCIdentifier.DialogHandler)}
|
|
30
35
|
>
|
|
31
36
|
<ThemeProvider
|
|
32
37
|
themes={themeConfig.supportedThemes as unknown as string[]}
|