From 7c0f5978405b82253eddbfbaa59d38d967b7ae68 Mon Sep 17 00:00:00 2001 From: "S.Gromov" Date: Thu, 7 May 2026 22:13:26 +0300 Subject: [PATCH] =?UTF-8?q?chore:=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=B8=D0=BD=D1=84=D1=80=D0=B0=D1=81=D1=82=D1=80?= =?UTF-8?q?=D1=83=D0=BA=D1=82=D1=83=D1=80=D1=83=20Mantine=20=D0=B8=20?= =?UTF-8?q?=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - добавлен алиас infra и обновлены импорты Mantine - настроены тема, цветовая схема и CSS-переменные Mantine - добавлен переключатель цветовой схемы на главный экран - обновлены шаблоны бизнес- и infra-модулей под фабрики - добавлена команда генерации Petstore API и исключён generated-код из Biome - обновлены JSDoc-комментарии React-компонентов --- .env.example | 3 + .../business/{{name.kebabCase}}/index.ts | 6 +- .../types/{{name.kebabCase}}-api.type.ts | 4 + .../types/{{name.kebabCase}}-deps.type.ts | 4 + .../types/{{name.kebabCase}}-factory.type.ts | 7 + .../types/{{name.kebabCase}}.type.ts | 11 +- .../{{name.kebabCase}}.business.tsx | 20 --- .../{{name.kebabCase}}.factory.ts | 8 ++ .../{{name.kebabCase}}/index.ts | 0 .../styles/{{name.kebabCase}}.module.css | 0 .../types/{{name.kebabCase}}.type.ts | 0 .../{{name.kebabCase}}.infra.tsx | 0 .../styles/{{name.kebabCase}}.module.css | 2 - biome.json | 3 +- package.json | 1 + src/app/layout.tsx | 18 ++- src/app/page.tsx | 7 + .../mantine/config/color-scheme.config.ts | 4 + src/infra/mantine/config/dark-theme.config.ts | 12 ++ .../mantine/config/light-theme.config.ts | 12 ++ .../mantine-css-variables-resolver.config.ts | 52 +++++++ .../mantine/config/mantine-theme.config.ts | 56 ++++++++ src/infra/mantine/index.ts | 5 + .../mantine/providers/mantine-provider.tsx | 39 ++++++ .../mantine/types/mantine-provider.type.ts | 8 ++ .../ui/mantine-color-scheme-script.tsx | 22 +++ .../ui/mantine-color-scheme-switch.tsx | 127 ++++++++++++++++++ src/infrastructure/mantine/index.ts | 1 - .../mantine/mantine-provider.tsx | 11 -- src/screens/home/home.screen.tsx | 8 +- tsconfig.json | 2 +- 31 files changed, 402 insertions(+), 51 deletions(-) create mode 100644 .templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-api.type.ts create mode 100644 .templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-deps.type.ts create mode 100644 .templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-factory.type.ts delete mode 100644 .templates/business/{{name.kebabCase}}/{{name.kebabCase}}.business.tsx create mode 100644 .templates/business/{{name.kebabCase}}/{{name.kebabCase}}.factory.ts rename .templates/{infrastructure => infra}/{{name.kebabCase}}/index.ts (100%) rename .templates/{business => infra}/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css (100%) rename .templates/{infrastructure => infra}/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts (100%) rename .templates/{infrastructure => infra}/{{name.kebabCase}}/{{name.kebabCase}}.infra.tsx (100%) delete mode 100644 .templates/infrastructure/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css create mode 100644 src/infra/mantine/config/color-scheme.config.ts create mode 100644 src/infra/mantine/config/dark-theme.config.ts create mode 100644 src/infra/mantine/config/light-theme.config.ts create mode 100644 src/infra/mantine/config/mantine-css-variables-resolver.config.ts create mode 100644 src/infra/mantine/config/mantine-theme.config.ts create mode 100644 src/infra/mantine/index.ts create mode 100644 src/infra/mantine/providers/mantine-provider.tsx create mode 100644 src/infra/mantine/types/mantine-provider.type.ts create mode 100644 src/infra/mantine/ui/mantine-color-scheme-script.tsx create mode 100644 src/infra/mantine/ui/mantine-color-scheme-switch.tsx delete mode 100644 src/infrastructure/mantine/index.ts delete mode 100644 src/infrastructure/mantine/mantine-provider.tsx diff --git a/.env.example b/.env.example index adb7788..3d6081b 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,5 @@ # Базовый URL приложения NEXT_PUBLIC_APP_URL=http://localhost:3000 + +# Базовый URL локального Swagger Petstore API +NEXT_PUBLIC_PET_STORE_API_URL=http://localhost:8080/api/v3 diff --git a/.templates/business/{{name.kebabCase}}/index.ts b/.templates/business/{{name.kebabCase}}/index.ts index 6c47526..44c1485 100644 --- a/.templates/business/{{name.kebabCase}}/index.ts +++ b/.templates/business/{{name.kebabCase}}/index.ts @@ -1 +1,5 @@ -export { {{name.pascalCase}}Business } from './{{name.kebabCase}}.business' +export { {{name.camelCase}}Factory } from './{{name.kebabCase}}.factory'; +export type { {{name.pascalCase}} } from './types/{{name.kebabCase}}.type'; +export type { {{name.pascalCase}}Api } from './types/{{name.kebabCase}}-api.type'; +export type { {{name.pascalCase}}Deps } from './types/{{name.kebabCase}}-deps.type'; +export type { {{name.pascalCase}}Factory } from './types/{{name.kebabCase}}-factory.type'; diff --git a/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-api.type.ts b/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-api.type.ts new file mode 100644 index 0000000..e031f81 --- /dev/null +++ b/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-api.type.ts @@ -0,0 +1,4 @@ +/** + * Публичный API бизнес-модуля {{name.pascalCase}}. + */ +export type {{name.pascalCase}}Api = Record; diff --git a/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-deps.type.ts b/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-deps.type.ts new file mode 100644 index 0000000..7109eb3 --- /dev/null +++ b/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-deps.type.ts @@ -0,0 +1,4 @@ +/** + * Зависимости бизнес-модуля {{name.pascalCase}}. + */ +export type {{name.pascalCase}}Deps = Record; diff --git a/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-factory.type.ts b/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-factory.type.ts new file mode 100644 index 0000000..ba675cb --- /dev/null +++ b/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}-factory.type.ts @@ -0,0 +1,7 @@ +import type { {{name.pascalCase}}Api } from './{{name.kebabCase}}-api.type'; +import type { {{name.pascalCase}}Deps } from './{{name.kebabCase}}-deps.type'; + +/** + * Фабрика публичного API бизнес-модуля {{name.pascalCase}}. + */ +export type {{name.pascalCase}}Factory = (deps: {{name.pascalCase}}Deps) => {{name.pascalCase}}Api; diff --git a/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts b/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts index 59561c1..edcdee4 100644 --- a/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts +++ b/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts @@ -1,11 +1,4 @@ -import type { HTMLAttributes } from 'react' - /** - * Параметры бизнес-модуля {{name.pascalCase}}. + * Доменная сущность {{name.pascalCase}}. */ -export type {{name.pascalCase}}BusinessParams = {} - -/** HTML-атрибуты корневого элемента. */ -type RootAttrs = HTMLAttributes - -export type {{name.pascalCase}}BusinessProps = RootAttrs & {{name.pascalCase}}BusinessParams +export type {{name.pascalCase}} = Record; diff --git a/.templates/business/{{name.kebabCase}}/{{name.kebabCase}}.business.tsx b/.templates/business/{{name.kebabCase}}/{{name.kebabCase}}.business.tsx deleted file mode 100644 index a29fefc..0000000 --- a/.templates/business/{{name.kebabCase}}/{{name.kebabCase}}.business.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import cl from 'clsx' -import type { {{name.pascalCase}}BusinessProps } from './types/{{name.kebabCase}}.type' -import styles from './styles/{{name.kebabCase}}.module.css' - -/** - * <Назначение бизнес-модуля {{name.pascalCase}} в 1 строке>. - * - * Используется для: - * - <сценарий 1> - * - <сценарий 2> - */ -export const {{name.pascalCase}}Business = (props: {{name.pascalCase}}BusinessProps) => { - const { children, className, ...htmlAttr } = props - - return ( -
- {children} -
- ) -} diff --git a/.templates/business/{{name.kebabCase}}/{{name.kebabCase}}.factory.ts b/.templates/business/{{name.kebabCase}}/{{name.kebabCase}}.factory.ts new file mode 100644 index 0000000..8dbe15c --- /dev/null +++ b/.templates/business/{{name.kebabCase}}/{{name.kebabCase}}.factory.ts @@ -0,0 +1,8 @@ +import type { {{name.pascalCase}}Factory } from './types/{{name.kebabCase}}-factory.type'; + +/** + * Создаёт публичный API бизнес-модуля {{name.pascalCase}}. + */ +export const {{name.camelCase}}Factory: {{name.pascalCase}}Factory = () => { + return {}; +}; diff --git a/.templates/infrastructure/{{name.kebabCase}}/index.ts b/.templates/infra/{{name.kebabCase}}/index.ts similarity index 100% rename from .templates/infrastructure/{{name.kebabCase}}/index.ts rename to .templates/infra/{{name.kebabCase}}/index.ts diff --git a/.templates/business/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css b/.templates/infra/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css similarity index 100% rename from .templates/business/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css rename to .templates/infra/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css diff --git a/.templates/infrastructure/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts b/.templates/infra/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts similarity index 100% rename from .templates/infrastructure/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts rename to .templates/infra/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts diff --git a/.templates/infrastructure/{{name.kebabCase}}/{{name.kebabCase}}.infra.tsx b/.templates/infra/{{name.kebabCase}}/{{name.kebabCase}}.infra.tsx similarity index 100% rename from .templates/infrastructure/{{name.kebabCase}}/{{name.kebabCase}}.infra.tsx rename to .templates/infra/{{name.kebabCase}}/{{name.kebabCase}}.infra.tsx diff --git a/.templates/infrastructure/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css b/.templates/infrastructure/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css deleted file mode 100644 index c3a2af6..0000000 --- a/.templates/infrastructure/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css +++ /dev/null @@ -1,2 +0,0 @@ -.root { -} diff --git a/biome.json b/biome.json index 026c7af..b3411e8 100644 --- a/biome.json +++ b/biome.json @@ -13,7 +13,8 @@ "!.next", "!dist", "!build", - "!.templates" + "!.templates", + "!src/infrastructure/**/generated" ] }, "formatter": { diff --git a/package.json b/package.json index 45eb815..226e508 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "biome check", "format": "biome format --write", "sprite": "svg-sprites", + "codegen:pet-store-api": "npx @gromlab/api-codegen@latest -i http://localhost:8080/api/v3/openapi.json -o src/infrastructure/pet-store-api/generated -n pet-store-api.generated", "predev": "svg-sprites", "prebuild": "svg-sprites" }, diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 315becc..5c7e848 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,8 +1,11 @@ import '@mantine/core/styles.css'; import 'shared/styles/global.css'; -import { ColorSchemeScript } from '@mantine/core'; -import { MantineProvider } from 'infrastructure/mantine'; +import { + MantineColorSchemeScript, + MantineProvider, + mantineHtmlProps, +} from 'infra/mantine'; import type { Metadata } from 'next'; import type { PropsWithChildren } from 'react'; @@ -31,11 +34,18 @@ export const metadata: Metadata = { }, }; +/** + * Корневой layout приложения Next.js. + * + * Используется для: + * - подключения провайдеров приложения + * - установки базовой HTML-структуры всех страниц + */ export default function RootLayout({ children }: PropsWithChildren) { return ( - + - + diff --git a/src/app/page.tsx b/src/app/page.tsx index c03abe3..76c1671 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -6,6 +6,13 @@ export const metadata: Metadata = { description: 'Главная страница приложения', }; +/** + * Страница главного маршрута приложения. + * + * Используется для: + * - отображения главного экрана в корневом маршруте + * - композиции контента главной страницы + */ export default function HomePage() { return ; } diff --git a/src/infra/mantine/config/color-scheme.config.ts b/src/infra/mantine/config/color-scheme.config.ts new file mode 100644 index 0000000..bc9a8f8 --- /dev/null +++ b/src/infra/mantine/config/color-scheme.config.ts @@ -0,0 +1,4 @@ +import type { MantineColorScheme } from '@mantine/core'; + +export const MANTINE_COLOR_SCHEME_STORAGE_KEY = 'app-color-scheme'; +export const MANTINE_DEFAULT_COLOR_SCHEME: MantineColorScheme = 'auto'; diff --git a/src/infra/mantine/config/dark-theme.config.ts b/src/infra/mantine/config/dark-theme.config.ts new file mode 100644 index 0000000..4a13b98 --- /dev/null +++ b/src/infra/mantine/config/dark-theme.config.ts @@ -0,0 +1,12 @@ +export const darkTheme = { + primary: '#60a5fa', + background: '#0f172a', + backgroundHover: '#1e293b', + surface: '#111827', + text: '#f8fafc', + textSecondary: '#cbd5e1', + border: '#334155', + error: '#ff6b6b', + success: '#69db7c', + warning: '#ffd43b', +} as const; diff --git a/src/infra/mantine/config/light-theme.config.ts b/src/infra/mantine/config/light-theme.config.ts new file mode 100644 index 0000000..4a9d926 --- /dev/null +++ b/src/infra/mantine/config/light-theme.config.ts @@ -0,0 +1,12 @@ +export const lightTheme = { + primary: '#2563eb', + background: '#ffffff', + backgroundHover: '#f8fafc', + surface: '#ffffff', + text: '#111827', + textSecondary: '#64748b', + border: '#e2e8f0', + error: '#e03131', + success: '#2f9e44', + warning: '#e67700', +} as const; diff --git a/src/infra/mantine/config/mantine-css-variables-resolver.config.ts b/src/infra/mantine/config/mantine-css-variables-resolver.config.ts new file mode 100644 index 0000000..86be773 --- /dev/null +++ b/src/infra/mantine/config/mantine-css-variables-resolver.config.ts @@ -0,0 +1,52 @@ +import type { CSSVariablesResolver } from '@mantine/core'; +import { darkTheme } from './dark-theme.config'; +import { lightTheme } from './light-theme.config'; + +type ThemePalette = { + primary: string; + background: string; + backgroundHover: string; + surface: string; + text: string; + textSecondary: string; + border: string; + error: string; + success: string; + warning: string; +}; + +type ThemeCssVariables = { + '--color-primary': string; + '--color-bg': string; + '--color-bg-hover': string; + '--color-surface': string; + '--color-text': string; + '--color-text-secondary': string; + '--color-border': string; + '--color-error': string; + '--color-success': string; + '--color-warning': string; +}; + +const getThemeCssVariables = (theme: ThemePalette): ThemeCssVariables => { + return { + '--color-primary': theme.primary, + '--color-bg': theme.background, + '--color-bg-hover': theme.backgroundHover, + '--color-surface': theme.surface, + '--color-text': theme.text, + '--color-text-secondary': theme.textSecondary, + '--color-border': theme.border, + '--color-error': theme.error, + '--color-success': theme.success, + '--color-warning': theme.warning, + }; +}; + +export const mantineCssVariablesResolver: CSSVariablesResolver = () => { + return { + variables: {}, + light: getThemeCssVariables(lightTheme), + dark: getThemeCssVariables(darkTheme), + }; +}; diff --git a/src/infra/mantine/config/mantine-theme.config.ts b/src/infra/mantine/config/mantine-theme.config.ts new file mode 100644 index 0000000..af37179 --- /dev/null +++ b/src/infra/mantine/config/mantine-theme.config.ts @@ -0,0 +1,56 @@ +import type { MantineColorsTuple, MantineThemeOverride } from '@mantine/core'; +import { createTheme, virtualColor } from '@mantine/core'; +import { darkTheme } from './dark-theme.config'; +import { lightTheme } from './light-theme.config'; + +const brandLightColors = [ + '#eff6ff', + '#dbeafe', + '#bfdbfe', + '#93c5fd', + '#60a5fa', + '#3b82f6', + '#2563eb', + '#1d4ed8', + '#1e40af', + '#1e3a8a', +] satisfies MantineColorsTuple; + +const brandDarkColors = [ + '#dbeafe', + '#bfdbfe', + '#93c5fd', + '#60a5fa', + '#3b82f6', + '#2563eb', + '#1d4ed8', + '#1e40af', + '#1e3a8a', + '#172554', +] satisfies MantineColorsTuple; + +export const mantineTheme: MantineThemeOverride = createTheme({ + black: darkTheme.background, + white: lightTheme.background, + primaryColor: 'brand', + primaryShade: { light: 6, dark: 4 }, + defaultRadius: 'md', + autoContrast: true, + cursorType: 'pointer', + colors: { + brand: virtualColor({ + name: 'brand', + light: 'brandLight', + dark: 'brandDark', + }), + brandLight: brandLightColors, + brandDark: brandDarkColors, + }, + fontFamily: + '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', + headings: { + fontFamily: + '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', + fontWeight: '700', + }, +}); diff --git a/src/infra/mantine/index.ts b/src/infra/mantine/index.ts new file mode 100644 index 0000000..63b6d59 --- /dev/null +++ b/src/infra/mantine/index.ts @@ -0,0 +1,5 @@ +export { mantineHtmlProps } from '@mantine/core'; + +export { MantineProvider } from './providers/mantine-provider'; +export { MantineColorSchemeScript } from './ui/mantine-color-scheme-script'; +export { MantineColorSchemeSwitch } from './ui/mantine-color-scheme-switch'; diff --git a/src/infra/mantine/providers/mantine-provider.tsx b/src/infra/mantine/providers/mantine-provider.tsx new file mode 100644 index 0000000..eb2e385 --- /dev/null +++ b/src/infra/mantine/providers/mantine-provider.tsx @@ -0,0 +1,39 @@ +'use client'; + +import { + MantineProvider as BaseMantineProvider, + localStorageColorSchemeManager, +} from '@mantine/core'; +import { + MANTINE_COLOR_SCHEME_STORAGE_KEY, + MANTINE_DEFAULT_COLOR_SCHEME, +} from '../config/color-scheme.config'; +import { mantineCssVariablesResolver } from '../config/mantine-css-variables-resolver.config'; +import { mantineTheme } from '../config/mantine-theme.config'; +import type { MantineProviderProps } from '../types/mantine-provider.type'; + +const colorSchemeManager = localStorageColorSchemeManager({ + key: MANTINE_COLOR_SCHEME_STORAGE_KEY, +}); + +/** + * Провайдер темы и цветовой схемы Mantine. + * + * Используется для: + * - подключения глобальной темы Mantine + * - синхронизации цветовой схемы приложения + */ +export const MantineProvider = (props: MantineProviderProps) => { + const { children } = props; + + return ( + + {children} + + ); +}; diff --git a/src/infra/mantine/types/mantine-provider.type.ts b/src/infra/mantine/types/mantine-provider.type.ts new file mode 100644 index 0000000..e3eb49e --- /dev/null +++ b/src/infra/mantine/types/mantine-provider.type.ts @@ -0,0 +1,8 @@ +import type { ReactNode } from 'react'; + +/** + * Пропсы провайдера Mantine UI. + */ +export type MantineProviderProps = { + children: ReactNode; +}; diff --git a/src/infra/mantine/ui/mantine-color-scheme-script.tsx b/src/infra/mantine/ui/mantine-color-scheme-script.tsx new file mode 100644 index 0000000..2f364e8 --- /dev/null +++ b/src/infra/mantine/ui/mantine-color-scheme-script.tsx @@ -0,0 +1,22 @@ +import { ColorSchemeScript } from '@mantine/core'; +import type { ReactNode } from 'react'; +import { + MANTINE_COLOR_SCHEME_STORAGE_KEY, + MANTINE_DEFAULT_COLOR_SCHEME, +} from '../config/color-scheme.config'; + +/** + * Скрипт инициализации цветовой схемы Mantine до гидрации. + * + * Используется для: + * - применения сохраненной цветовой схемы до загрузки React + * - предотвращения мигания темы при первом рендере + */ +export const MantineColorSchemeScript = (): ReactNode => { + return ( + + ); +}; diff --git a/src/infra/mantine/ui/mantine-color-scheme-switch.tsx b/src/infra/mantine/ui/mantine-color-scheme-switch.tsx new file mode 100644 index 0000000..c0fdc14 --- /dev/null +++ b/src/infra/mantine/ui/mantine-color-scheme-switch.tsx @@ -0,0 +1,127 @@ +'use client'; + +import type { MantineColorScheme } from '@mantine/core'; +import { + Center, + SegmentedControl, + useMantineColorScheme, + VisuallyHidden, +} from '@mantine/core'; +import { useMounted } from '@mantine/hooks'; +import type { ReactNode } from 'react'; + +const colorSchemeValues = [ + 'auto', + 'light', + 'dark', +] as const satisfies readonly MantineColorScheme[]; + +type ColorSchemeValue = (typeof colorSchemeValues)[number]; + +const systemThemeLabel = ( +
+ + Системная тема +
+); + +const lightThemeLabel = ( +
+ + Светлая тема +
+); + +const darkThemeLabel = ( +
+ + Темная тема +
+); + +const colorSchemeItems: { label: ReactNode; value: ColorSchemeValue }[] = [ + { label: systemThemeLabel, value: 'auto' }, + { label: lightThemeLabel, value: 'light' }, + { label: darkThemeLabel, value: 'dark' }, +]; + +const isColorSchemeValue = (value: string): value is ColorSchemeValue => { + return colorSchemeValues.some((item) => item === value); +}; + +/** + * Переключатель цветовой схемы Mantine. + * + * Используется для: + * - выбора системной, светлой или темной темы + * - управления пользовательской цветовой схемой приложения + */ +export const MantineColorSchemeSwitch = (): ReactNode => { + const mounted = useMounted(); + const { colorScheme, setColorScheme } = useMantineColorScheme(); + const value = + mounted && isColorSchemeValue(colorScheme) ? colorScheme : 'auto'; + + const handleChange = (nextValue: string): void => { + if (!isColorSchemeValue(nextValue)) { + return; + } + + setColorScheme(nextValue); + }; + + return ( + + ); +}; diff --git a/src/infrastructure/mantine/index.ts b/src/infrastructure/mantine/index.ts deleted file mode 100644 index c248e7a..0000000 --- a/src/infrastructure/mantine/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { MantineProvider } from './mantine-provider'; diff --git a/src/infrastructure/mantine/mantine-provider.tsx b/src/infrastructure/mantine/mantine-provider.tsx deleted file mode 100644 index bab72f2..0000000 --- a/src/infrastructure/mantine/mantine-provider.tsx +++ /dev/null @@ -1,11 +0,0 @@ -'use client'; - -import { MantineProvider as BaseMantineProvider } from '@mantine/core'; -import type { PropsWithChildren } from 'react'; - -/** - * Провайдер Mantine UI. - */ -export const MantineProvider = ({ children }: PropsWithChildren) => { - return {children}; -}; diff --git a/src/screens/home/home.screen.tsx b/src/screens/home/home.screen.tsx index 620c9fc..7a19adc 100644 --- a/src/screens/home/home.screen.tsx +++ b/src/screens/home/home.screen.tsx @@ -1,8 +1,13 @@ import { Container, Image, Stack, Text, Title } from '@mantine/core'; +import { MantineColorSchemeSwitch } from 'infra/mantine'; import styles from './styles/home.module.css'; /** - * Главный экран приложения. + * Главный экран стартовой страницы приложения. + * + * Используется для: + * - отображения приветственного содержимого шаблона + * - предоставления быстрого переключения цветовой схемы */ export const HomeScreen = () => { return ( @@ -18,6 +23,7 @@ export const HomeScreen = () => { /> Добро пожаловать Шаблон приложения на Next.js и TypeScript. + diff --git a/tsconfig.json b/tsconfig.json index 1613e25..0723f11 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,7 +21,7 @@ "paths": { "app/*": ["./src/app/*"], "business/*": ["./src/business/*"], - "infrastructure/*": ["./src/infrastructure/*"], + "infra/*": ["./src/infra/*"], "layouts/*": ["./src/layouts/*"], "screens/*": ["./src/screens/*"], "ui/*": ["./src/ui/*"],