feat: confirm access page and persist redux store

This commit is contained in:
2025-07-24 10:23:53 +04:00
parent d844e82785
commit 27bb7c3ebc
19 changed files with 491 additions and 91 deletions

View File

@ -0,0 +1,16 @@
import PageContainer from "@/components/PageContainer/PageContainer";
import PageItem from "@/components/PageBlock/PageItem";
import Logo from "@/components/Logo/Logo";
import ConfirmAccessForm from "@/components/ConfirmAccessForm/ConfirmAccessForm";
export default function ConfirmAccessPage() {
return (
<PageContainer center>
<PageItem fullScreenMobile>
<Logo title={"Вход с помощью LogiDex ID"} />
<ConfirmAccessForm />
</PageItem>
</PageContainer>
)
}

View File

@ -9,6 +9,7 @@ import Header from "@/components/Header/Header";
import { theme } from "@/theme"; import { theme } from "@/theme";
import "@/app/global.css"; import "@/app/global.css";
import Footer from "@/components/Footer/Footer"; import Footer from "@/components/Footer/Footer";
import ReduxProvider from "@/providers/ReduxProvider";
export const metadata = { export const metadata = {
title: "LogiDex ID", title: "LogiDex ID",
@ -44,9 +45,11 @@ export default function RootLayout({ children }: Props) {
<MantineProvider <MantineProvider
theme={theme} theme={theme}
defaultColorScheme={"auto"}> defaultColorScheme={"auto"}>
<ReduxProvider>
<Header /> <Header />
{children} {children}
<Footer /> <Footer />
</ReduxProvider>
</MantineProvider> </MantineProvider>
</body> </body>
</html> </html>

View File

@ -0,0 +1,44 @@
"use client";
import { FC, useEffect, useState } from "react";
import { redirect } from "next/navigation";
import { useSelector } from "react-redux";
import { Button, Text } from "@mantine/core";
import SERVICES from "@/constants/services";
import { ServiceCode } from "@/enums/ServiceCode";
import { RootState } from "@/lib/store";
import ServiceData from "@/types/ServiceData";
const ConfirmAccessButton: FC = () => {
const serviceCode = useSelector(
(state: RootState) => state.targetService.serviceCode
);
const [serviceData, setServiceData] = useState<ServiceData>();
useEffect(() => {
if (serviceCode === ServiceCode.UNDEFINED) {
redirect("services");
}
setServiceData(SERVICES[serviceCode]);
}, [serviceCode]);
const confirmAccess = () => {};
return (
<>
<Button
onClick={() => confirmAccess()}
variant={"filled"}>
Войти
</Button>
<Text
fz={"h4"}
ta="center">
Сервис {serviceData?.name} получит{" "}
{serviceData?.requiredAccesses}
</Text>
</>
);
};
export default ConfirmAccessButton;

View File

@ -0,0 +1,14 @@
.container {
@media (min-width: 48em) {
max-width: 400px;
}
}
.gray-text {
@mixin dark {
color: #807e7e;
}
@mixin light {
color: gray;
}
}

View File

@ -0,0 +1,22 @@
import { FC } from "react";
import { Stack, Text } from "@mantine/core";
import ConfirmAccessButton from "@/components/ConfirmAccessForm/ConfirmAccessButton";
import styles from "./ConfirmAccessForm.module.css";
const ConfirmAccessForm: FC = () => {
return (
<Stack
align={"center"}
className={styles.container}>
<ConfirmAccessButton />
<Text
className={styles["gray-text"]}
ta="center">
Данные из LogiDex ID передаются в другой сервис и обрабатываются
в соответствии с правилами этого сервиса
</Text>
</Stack>
);
};
export default ConfirmAccessForm;

View File

@ -16,7 +16,7 @@ const Footer = () => {
color: "inherit", color: "inherit",
fontSize: 14, fontSize: 14,
}}> }}>
Help and support Помощь
</Link> </Link>
<Group gap={5}> <Group gap={5}>
<Text style={{ fontSize: 18 }}>©</Text> <Text style={{ fontSize: 18 }}>©</Text>

View File

@ -1,20 +1,50 @@
import Link from "next/link"; "use client";
import { useMemo } from "react";
import { redirect } from "next/navigation";
import { Button, Stack, Title } from "@mantine/core"; import { Button, Stack, Title } from "@mantine/core";
import styles from "@/components/ServicesList/ServicesList.module.css"; import styles from "@/components/ServicesList/ServicesList.module.css";
import TitleWithLines from "@/components/TitleWithLines/TitleWithLines"; import TitleWithLines from "@/components/TitleWithLines/TitleWithLines";
import SERVICES from "@/constants/services";
import { ServiceCode } from "@/enums/ServiceCode";
import { setTargetService } from "@/lib/features/targetService/targetServiceSlice";
import { useAppDispatch } from "@/lib/store";
import ServiceData from "@/types/ServiceData";
const ServicesList = () => { const ServicesList = () => {
const getServiceLink = ( const dispatch = useAppDispatch();
title: string, const services = useMemo(
href: string, () =>
isInDevelopment: boolean = false Object.entries(SERVICES)
) => { .filter(([key]) => key !== ServiceCode.UNDEFINED)
.map(([, value]) => value),
[SERVICES]
);
const onServiceClick = (service: ServiceData) => {
dispatch(setTargetService(service.code));
redirect("confirm-access");
};
const getServiceButton = (service: ServiceData, key: number) => {
return ( return (
<Button <Button
component={Link} key={key}
size={"xl"} size={"xl"}
href={isInDevelopment ? "" : href} onClick={() => onServiceClick(service)}>
disabled={isInDevelopment}> <Stack gap={0}>
<Title order={4}>{service.name}</Title>
</Stack>
</Button>
);
};
const getServiceInDevelopment = (title: string) => {
return (
<Button
size={"xl"}
onClick={() => {}}
disabled>
<Stack gap={0}> <Stack gap={0}>
<Title order={4}>{title}</Title> <Title order={4}>{title}</Title>
</Stack> </Stack>
@ -26,9 +56,9 @@ const ServicesList = () => {
<Stack <Stack
className={styles.container} className={styles.container}
gap={"lg"}> gap={"lg"}>
{getServiceLink("CRM", "https://skirbo.ru/")} {services.map((service, i) => getServiceButton(service, i))}
<TitleWithLines title="Скоро будет" /> <TitleWithLines title="Скоро будет" />
{getServiceLink("Analytics", "", true)} {getServiceInDevelopment("Analytics")}
</Stack> </Stack>
); );
}; };

20
constants/services.ts Normal file
View File

@ -0,0 +1,20 @@
import { ServiceCode } from "@/enums/ServiceCode";
import ServiceData from "@/types/ServiceData";
const SERVICES = {
[ServiceCode.UNDEFINED]: {
code: ServiceCode.UNDEFINED,
name: "undefined",
link: "",
requiredAccesses: "",
},
[ServiceCode.CRM]: {
code: ServiceCode.CRM,
name: "LogiDex CRM",
link: "https://skirbo.ru",
requiredAccesses:
"доступ к учетной записи и сделкам по фулфиллменту",
} as ServiceData,
};
export default SERVICES;

4
enums/ServiceCode.ts Normal file
View File

@ -0,0 +1,4 @@
export enum ServiceCode {
CRM = "crm",
UNDEFINED = "",
}

View File

@ -0,0 +1,8 @@
import { combineReducers } from "@reduxjs/toolkit";
import targetServiceReducer from "@/lib/features/targetService/targetServiceSlice";
const rootReducer = combineReducers({
targetService: targetServiceReducer,
});
export default rootReducer;

View File

@ -0,0 +1,24 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { ServiceCode } from "@/enums/ServiceCode";
interface TargetServiceState {
serviceCode: ServiceCode;
}
const initialState: TargetServiceState = {
serviceCode: ServiceCode.UNDEFINED,
};
export const targetServiceSlice = createSlice({
name: "targetService",
initialState,
reducers: {
setTargetService: (state, action: PayloadAction<ServiceCode>) => {
state.serviceCode = action.payload;
},
},
});
export const { setTargetService } = targetServiceSlice.actions;
export default targetServiceSlice.reducer;

28
lib/store.ts Normal file
View File

@ -0,0 +1,28 @@
import { configureStore } from "@reduxjs/toolkit";
import { useDispatch } from "react-redux";
import { persistReducer, persistStore } from "redux-persist";
import storage from "redux-persist/lib/storage";
import rootReducer from "@/lib/features/rootReducer";
const persistConfig = {
key: "root",
storage,
whitelist: ["targetService"],
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
export const store = configureStore({
reducer: persistedReducer,
middleware: getDefaultMiddleware =>
getDefaultMiddleware({
serializableCheck: false,
}),
});
export const persistor = persistStore(store);
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();

View File

@ -1,5 +1,5 @@
{ {
"name": "mantine-next-template", "name": "logidex-id",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
@ -24,6 +24,7 @@
"@mantine/form": "^8.1.3", "@mantine/form": "^8.1.3",
"@mantine/hooks": "8.1.2", "@mantine/hooks": "8.1.2",
"@next/bundle-analyzer": "^15.3.3", "@next/bundle-analyzer": "^15.3.3",
"@reduxjs/toolkit": "^2.8.2",
"@tabler/icons-react": "^3.34.0", "@tabler/icons-react": "^3.34.0",
"classnames": "^2.5.1", "classnames": "^2.5.1",
"i18n-iso-countries": "^7.14.0", "i18n-iso-countries": "^7.14.0",
@ -32,6 +33,8 @@
"react": "19.1.0", "react": "19.1.0",
"react-dom": "19.1.0", "react-dom": "19.1.0",
"react-imask": "^7.6.1", "react-imask": "^7.6.1",
"react-redux": "^9.2.0",
"redux-persist": "^6.0.0",
"sharp": "^0.34.3" "sharp": "^0.34.3"
}, },
"devDependencies": { "devDependencies": {
@ -48,6 +51,8 @@
"@types/jest": "^29.5.14", "@types/jest": "^29.5.14",
"@types/node": "^22.13.11", "@types/node": "^22.13.11",
"@types/react": "19.1.8", "@types/react": "19.1.8",
"@types/react-redux": "^7.1.34",
"@types/redux-persist": "^4.3.1",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"eslint-config-mantine": "^4.0.3", "eslint-config-mantine": "^4.0.3",

View File

@ -0,0 +1,23 @@
"use client";
import { ReactNode } from "react";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { persistor, store } from "@/lib/store";
type Props = {
children: ReactNode;
};
export default function ReduxProvider({ children }: Props) {
return (
<Provider store={store}>
{" "}
<PersistGate
loading={null}
persistor={persistor}>
{children}
</PersistGate>
</Provider>
);
}

5
redux-persist.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
declare module "redux-persist/lib/storage" {
import { WebStorage } from "redux-persist/es/types";
const localStorage: WebStorage;
export default localStorage;
}

View File

@ -1,5 +0,0 @@
import userEvent from "@testing-library/user-event";
export * from "@testing-library/react";
export { render } from "./render";
export { userEvent };

View File

@ -1,16 +0,0 @@
import { render as testingLibraryRender } from "@testing-library/react";
import { MantineProvider } from "@mantine/core";
import { theme } from "@/theme";
import React from "react";
export function render(ui: React.ReactNode) {
return testingLibraryRender(<>{ui}</>, {
wrapper: ({ children }: { children: React.ReactNode }) => (
<MantineProvider
theme={theme}
env="test">
{children}
</MantineProvider>
),
});
}

10
types/ServiceData.ts Normal file
View File

@ -0,0 +1,10 @@
import { ServiceCode } from "@/enums/ServiceCode";
type ServiceData = {
code: ServiceCode;
name: string;
link: string;
requiredAccesses: string;
}
export default ServiceData;

273
yarn.lock
View File

@ -1404,7 +1404,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.24.4": "@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.24.4, @babel/runtime@npm:^7.9.2":
version: 7.27.6 version: 7.27.6
resolution: "@babel/runtime@npm:7.27.6" resolution: "@babel/runtime@npm:7.27.6"
checksum: 10c0/89726be83f356f511dcdb74d3ea4d873a5f0cf0017d4530cb53aa27380c01ca102d573eff8b8b77815e624b1f8c24e7f0311834ad4fb632c90a770fda00bd4c8 checksum: 10c0/89726be83f356f511dcdb74d3ea4d873a5f0cf0017d4530cb53aa27380c01ca102d573eff8b8b77815e624b1f8c24e7f0311834ad4fb632c90a770fda00bd4c8
@ -2961,6 +2961,28 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@reduxjs/toolkit@npm:^2.8.2":
version: 2.8.2
resolution: "@reduxjs/toolkit@npm:2.8.2"
dependencies:
"@standard-schema/spec": "npm:^1.0.0"
"@standard-schema/utils": "npm:^0.3.0"
immer: "npm:^10.0.3"
redux: "npm:^5.0.1"
redux-thunk: "npm:^3.1.0"
reselect: "npm:^5.1.0"
peerDependencies:
react: ^16.9.0 || ^17.0.0 || ^18 || ^19
react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
peerDependenciesMeta:
react:
optional: true
react-redux:
optional: true
checksum: 10c0/6a7a33bad5f1100340757151ff86ca0c4c248f030ae56ce0e6f1d98b39fa87c8f193e9faa2ebd6d5a4c0416921e9f9f7a2bbdd81156c39f08f6bf5ce70c2b927
languageName: node
linkType: hard
"@sinclair/typebox@npm:^0.27.8": "@sinclair/typebox@npm:^0.27.8":
version: 0.27.8 version: 0.27.8
resolution: "@sinclair/typebox@npm:0.27.8" resolution: "@sinclair/typebox@npm:0.27.8"
@ -2993,6 +3015,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@standard-schema/spec@npm:^1.0.0":
version: 1.0.0
resolution: "@standard-schema/spec@npm:1.0.0"
checksum: 10c0/a1ab9a8bdc09b5b47aa8365d0e0ec40cc2df6437be02853696a0e377321653b0d3ac6f079a8c67d5ddbe9821025584b1fb71d9cc041a6666a96f1fadf2ece15f
languageName: node
linkType: hard
"@standard-schema/utils@npm:^0.3.0":
version: 0.3.0
resolution: "@standard-schema/utils@npm:0.3.0"
checksum: 10c0/6eb74cd13e52d5fc74054df51e37d947ef53f3ab9e02c085665dcca3c38c60ece8d735cebbdf18fbb13c775fbcb9becb3f53109b0e092a63f0f7389ce0993fd0
languageName: node
linkType: hard
"@storybook/builder-webpack5@npm:8.6.14": "@storybook/builder-webpack5@npm:8.6.14":
version: 8.6.14 version: 8.6.14
resolution: "@storybook/builder-webpack5@npm:8.6.14" resolution: "@storybook/builder-webpack5@npm:8.6.14"
@ -3514,6 +3550,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/hoist-non-react-statics@npm:^3.3.0":
version: 3.3.7
resolution: "@types/hoist-non-react-statics@npm:3.3.7"
dependencies:
hoist-non-react-statics: "npm:^3.3.0"
peerDependencies:
"@types/react": "*"
checksum: 10c0/ed8f4e88338f7d021d0f956adf6089d2a12b2e254a03c05292324f2e986d2376eb9efdb8a4f04596823e8fca88c9d06361d20dab4a2a00dc935fb36ac911de55
languageName: node
linkType: hard
"@types/html-minifier-terser@npm:^6.0.0": "@types/html-minifier-terser@npm:^6.0.0":
version: 6.1.0 version: 6.1.0
resolution: "@types/html-minifier-terser@npm:6.1.0" resolution: "@types/html-minifier-terser@npm:6.1.0"
@ -3599,7 +3646,19 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/react@npm:19.1.8": "@types/react-redux@npm:^7.1.34":
version: 7.1.34
resolution: "@types/react-redux@npm:7.1.34"
dependencies:
"@types/hoist-non-react-statics": "npm:^3.3.0"
"@types/react": "npm:*"
hoist-non-react-statics: "npm:^3.3.0"
redux: "npm:^4.0.0"
checksum: 10c0/6750964ec656eb6973b0e4fda787549aee5dbc266a0f0e78fc9efb417b4965c0b060d10b99a7b7fa0c8812b8a0a07d97a1ef46d094bf64fee07144e8bbad781a
languageName: node
linkType: hard
"@types/react@npm:*, @types/react@npm:19.1.8":
version: 19.1.8 version: 19.1.8
resolution: "@types/react@npm:19.1.8" resolution: "@types/react@npm:19.1.8"
dependencies: dependencies:
@ -3608,6 +3667,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/redux-persist@npm:^4.3.1":
version: 4.3.1
resolution: "@types/redux-persist@npm:4.3.1"
dependencies:
redux-persist: "npm:*"
checksum: 10c0/fb02ca069b309fdda4f72afb558e66859bf9c0a70ad9a5eec45a791da0cdaa200e8cd015c82f0efd9d3c94cbd5d32c88e51e025fdd53feb19045d6d258395a54
languageName: node
linkType: hard
"@types/resolve@npm:^1.20.2": "@types/resolve@npm:^1.20.2":
version: 1.20.6 version: 1.20.6
resolution: "@types/resolve@npm:1.20.6" resolution: "@types/resolve@npm:1.20.6"
@ -3636,6 +3704,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/use-sync-external-store@npm:^0.0.6":
version: 0.0.6
resolution: "@types/use-sync-external-store@npm:0.0.6"
checksum: 10c0/77c045a98f57488201f678b181cccd042279aff3da34540ad242f893acc52b358bd0a8207a321b8ac09adbcef36e3236944390e2df4fcedb556ce7bb2a88f2a8
languageName: node
linkType: hard
"@types/yargs-parser@npm:*": "@types/yargs-parser@npm:*":
version: 21.0.3 version: 21.0.3
resolution: "@types/yargs-parser@npm:21.0.3" resolution: "@types/yargs-parser@npm:21.0.3"
@ -7329,6 +7404,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"hoist-non-react-statics@npm:^3.3.0":
version: 3.3.2
resolution: "hoist-non-react-statics@npm:3.3.2"
dependencies:
react-is: "npm:^16.7.0"
checksum: 10c0/fe0889169e845d738b59b64badf5e55fa3cf20454f9203d1eb088df322d49d4318df774828e789898dcb280e8a5521bb59b3203385662ca5e9218a6ca5820e74
languageName: node
linkType: hard
"hookified@npm:^1.10.0": "hookified@npm:^1.10.0":
version: 1.10.0 version: 1.10.0
resolution: "hookified@npm:1.10.0" resolution: "hookified@npm:1.10.0"
@ -7525,6 +7609,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"immer@npm:^10.0.3":
version: 10.1.1
resolution: "immer@npm:10.1.1"
checksum: 10c0/b749e10d137ccae91788f41bd57e9387f32ea6d6ea8fd7eb47b23fd7766681575efc7f86ceef7fe24c3bc9d61e38ff5d2f49c2663b2b0c056e280a4510923653
languageName: node
linkType: hard
"import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": "import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0":
version: 3.3.1 version: 3.3.1
resolution: "import-fresh@npm:3.3.1" resolution: "import-fresh@npm:3.3.1"
@ -8937,6 +9028,62 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"logidex-id@workspace:.":
version: 0.0.0-use.local
resolution: "logidex-id@workspace:."
dependencies:
"@babel/core": "npm:^7.27.4"
"@eslint/js": "npm:^9.29.0"
"@ianvs/prettier-plugin-sort-imports": "npm:^4.4.2"
"@mantine/core": "npm:8.1.2"
"@mantine/form": "npm:^8.1.3"
"@mantine/hooks": "npm:8.1.2"
"@next/bundle-analyzer": "npm:^15.3.3"
"@reduxjs/toolkit": "npm:^2.8.2"
"@storybook/nextjs": "npm:^8.6.8"
"@storybook/react": "npm:^8.6.8"
"@tabler/icons-react": "npm:^3.34.0"
"@testing-library/dom": "npm:^10.4.0"
"@testing-library/jest-dom": "npm:^6.6.3"
"@testing-library/react": "npm:^16.3.0"
"@testing-library/user-event": "npm:^14.6.1"
"@types/eslint-plugin-jsx-a11y": "npm:^6"
"@types/jest": "npm:^29.5.14"
"@types/node": "npm:^22.13.11"
"@types/react": "npm:19.1.8"
"@types/react-redux": "npm:^7.1.34"
"@types/redux-persist": "npm:^4.3.1"
babel-loader: "npm:^10.0.0"
classnames: "npm:^2.5.1"
eslint: "npm:^9.29.0"
eslint-config-mantine: "npm:^4.0.3"
eslint-plugin-jsx-a11y: "npm:^6.10.2"
eslint-plugin-react: "npm:^7.37.5"
i18n-iso-countries: "npm:^7.14.0"
jest: "npm:^30.0.0"
jest-environment-jsdom: "npm:^30.0.0"
libphonenumber-js: "npm:^1.12.10"
next: "npm:15.3.3"
postcss: "npm:^8.5.5"
postcss-preset-mantine: "npm:1.17.0"
postcss-simple-vars: "npm:^7.0.1"
prettier: "npm:^3.5.3"
react: "npm:19.1.0"
react-dom: "npm:19.1.0"
react-imask: "npm:^7.6.1"
react-redux: "npm:^9.2.0"
redux-persist: "npm:^6.0.0"
sharp: "npm:^0.34.3"
storybook: "npm:^8.6.8"
storybook-dark-mode: "npm:^4.0.2"
stylelint: "npm:^16.20.0"
stylelint-config-standard-scss: "npm:^15.0.1"
ts-jest: "npm:^29.4.0"
typescript: "npm:5.8.3"
typescript-eslint: "npm:^8.34.0"
languageName: unknown
linkType: soft
"loose-envify@npm:^1.4.0": "loose-envify@npm:^1.4.0":
version: 1.4.0 version: 1.4.0
resolution: "loose-envify@npm:1.4.0" resolution: "loose-envify@npm:1.4.0"
@ -9051,57 +9198,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"mantine-next-template@workspace:.":
version: 0.0.0-use.local
resolution: "mantine-next-template@workspace:."
dependencies:
"@babel/core": "npm:^7.27.4"
"@eslint/js": "npm:^9.29.0"
"@ianvs/prettier-plugin-sort-imports": "npm:^4.4.2"
"@mantine/core": "npm:8.1.2"
"@mantine/form": "npm:^8.1.3"
"@mantine/hooks": "npm:8.1.2"
"@next/bundle-analyzer": "npm:^15.3.3"
"@storybook/nextjs": "npm:^8.6.8"
"@storybook/react": "npm:^8.6.8"
"@tabler/icons-react": "npm:^3.34.0"
"@testing-library/dom": "npm:^10.4.0"
"@testing-library/jest-dom": "npm:^6.6.3"
"@testing-library/react": "npm:^16.3.0"
"@testing-library/user-event": "npm:^14.6.1"
"@types/eslint-plugin-jsx-a11y": "npm:^6"
"@types/jest": "npm:^29.5.14"
"@types/node": "npm:^22.13.11"
"@types/react": "npm:19.1.8"
babel-loader: "npm:^10.0.0"
classnames: "npm:^2.5.1"
eslint: "npm:^9.29.0"
eslint-config-mantine: "npm:^4.0.3"
eslint-plugin-jsx-a11y: "npm:^6.10.2"
eslint-plugin-react: "npm:^7.37.5"
i18n-iso-countries: "npm:^7.14.0"
jest: "npm:^30.0.0"
jest-environment-jsdom: "npm:^30.0.0"
libphonenumber-js: "npm:^1.12.10"
next: "npm:15.3.3"
postcss: "npm:^8.5.5"
postcss-preset-mantine: "npm:1.17.0"
postcss-simple-vars: "npm:^7.0.1"
prettier: "npm:^3.5.3"
react: "npm:19.1.0"
react-dom: "npm:19.1.0"
react-imask: "npm:^7.6.1"
sharp: "npm:^0.34.3"
storybook: "npm:^8.6.8"
storybook-dark-mode: "npm:^4.0.2"
stylelint: "npm:^16.20.0"
stylelint-config-standard-scss: "npm:^15.0.1"
ts-jest: "npm:^29.4.0"
typescript: "npm:5.8.3"
typescript-eslint: "npm:^8.34.0"
languageName: unknown
linkType: soft
"map-or-similar@npm:^1.5.0": "map-or-similar@npm:^1.5.0":
version: 1.5.0 version: 1.5.0
resolution: "map-or-similar@npm:1.5.0" resolution: "map-or-similar@npm:1.5.0"
@ -10507,7 +10603,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-is@npm:^16.13.1": "react-is@npm:^16.13.1, react-is@npm:^16.7.0":
version: 16.13.1 version: 16.13.1
resolution: "react-is@npm:16.13.1" resolution: "react-is@npm:16.13.1"
checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1 checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1
@ -10538,6 +10634,25 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-redux@npm:^9.2.0":
version: 9.2.0
resolution: "react-redux@npm:9.2.0"
dependencies:
"@types/use-sync-external-store": "npm:^0.0.6"
use-sync-external-store: "npm:^1.4.0"
peerDependencies:
"@types/react": ^18.2.25 || ^19
react: ^18.0 || ^19
redux: ^5.0.0
peerDependenciesMeta:
"@types/react":
optional: true
redux:
optional: true
checksum: 10c0/00d485f9d9219ca1507b4d30dde5f6ff8fb68ba642458f742e0ec83af052f89e65cd668249b99299e1053cc6ad3d2d8ac6cb89e2f70d2ac5585ae0d7fa0ef259
languageName: node
linkType: hard
"react-refresh@npm:^0.14.0": "react-refresh@npm:^0.14.0":
version: 0.14.2 version: 0.14.2
resolution: "react-refresh@npm:0.14.2" resolution: "react-refresh@npm:0.14.2"
@ -10687,6 +10802,40 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"redux-persist@npm:*, redux-persist@npm:^6.0.0":
version: 6.0.0
resolution: "redux-persist@npm:6.0.0"
peerDependencies:
redux: ">4.0.0"
checksum: 10c0/8242d265ab8d28bbc95cf2dc2a05b869eb67aa309b1ed08163c926f3af56dd8eb1ea62118286083461b8ef2024d3b349fd264e5a62a70eb2e74d068c832d5bf2
languageName: node
linkType: hard
"redux-thunk@npm:^3.1.0":
version: 3.1.0
resolution: "redux-thunk@npm:3.1.0"
peerDependencies:
redux: ^5.0.0
checksum: 10c0/21557f6a30e1b2e3e470933247e51749be7f1d5a9620069a3125778675ce4d178d84bdee3e2a0903427a5c429e3aeec6d4df57897faf93eb83455bc1ef7b66fd
languageName: node
linkType: hard
"redux@npm:^4.0.0":
version: 4.2.1
resolution: "redux@npm:4.2.1"
dependencies:
"@babel/runtime": "npm:^7.9.2"
checksum: 10c0/136d98b3d5dbed1cd6279c8c18a6a74c416db98b8a432a46836bdd668475de6279a2d4fd9d1363f63904e00f0678a8a3e7fa532c897163340baf1e71bb42c742
languageName: node
linkType: hard
"redux@npm:^5.0.1":
version: 5.0.1
resolution: "redux@npm:5.0.1"
checksum: 10c0/b10c28357194f38e7d53b760ed5e64faa317cc63de1fb95bc5d9e127fab956392344368c357b8e7a9bedb0c35b111e7efa522210cfdc3b3c75e5074718e9069c
languageName: node
linkType: hard
"reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9": "reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9":
version: 1.0.10 version: 1.0.10
resolution: "reflect.getprototypeof@npm:1.0.10" resolution: "reflect.getprototypeof@npm:1.0.10"
@ -10806,6 +10955,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"reselect@npm:^5.1.0":
version: 5.1.1
resolution: "reselect@npm:5.1.1"
checksum: 10c0/219c30da122980f61853db3aebd173524a2accd4b3baec770e3d51941426c87648a125ca08d8c57daa6b8b086f2fdd2703cb035dd6231db98cdbe1176a71f489
languageName: node
linkType: hard
"resolve-cwd@npm:^3.0.0": "resolve-cwd@npm:^3.0.0":
version: 3.0.0 version: 3.0.0
resolution: "resolve-cwd@npm:3.0.0" resolution: "resolve-cwd@npm:3.0.0"
@ -12701,6 +12857,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"use-sync-external-store@npm:^1.4.0":
version: 1.5.0
resolution: "use-sync-external-store@npm:1.5.0"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/1b8663515c0be34fa653feb724fdcce3984037c78dd4a18f68b2c8be55cc1a1084c578d5b75f158d41b5ddffc2bf5600766d1af3c19c8e329bb20af2ec6f52f4
languageName: node
linkType: hard
"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1":
version: 1.0.2 version: 1.0.2
resolution: "util-deprecate@npm:1.0.2" resolution: "util-deprecate@npm:1.0.2"