Compare commits

..

11 Commits

Author SHA1 Message Date
3bf64aebce Merge pull request 'feature/create-place' (#8) from feature/create-place into develop
Reviewed-on: http://10.244.188.80:30210/behnam/diapal-panel/pulls/8
2023-05-30 13:07:56 +00:00
d77b4ffddb [REF]: remove extra logs 2023-05-30 16:03:00 +03:00
6da3051038 closes#157@2h
[FEAT]: add business logic for create a new place
2023-05-30 16:01:23 +03:00
ea8bcae9df [REF]: refactor statemenagement caching options 2023-05-30 13:46:52 +03:00
84e2a186b9 closes#156@4.5h
[FEAT]: complete ui and ui logic of create place
2023-05-30 13:36:36 +03:00
85a6bc9fb7 refs#156@1.5h
[FEAT]: add input place name and place type select box for ui of create place
2023-05-29 19:40:24 +03:00
b25c3f2064 Merge pull request 'refactor/qrcode' (#7) from refactor/qrcode into develop
Reviewed-on: http://10.244.188.80:30210/behnam/diapal-panel/pulls/7
2023-05-29 15:06:07 +00:00
dc02c847e5 [REF]: refactor qr code to return qr code id 2023-05-29 18:04:09 +03:00
c8cc39d72f closes#174@15m
[REF]: refactor qrcode to return just id of the qrcode
2023-05-29 18:00:33 +03:00
4ee74afd9b Merge pull request 'closes#176@20m' (#6) from debug/response-interceptor into develop
Reviewed-on: http://10.244.188.80:30210/behnam/diapal-panel/pulls/6
2023-05-29 14:51:02 +00:00
c9a25069d8 closes#176@20m
[DEB]: debug expired access token and handle refresh token to navigate to the login page
2023-05-29 17:41:20 +03:00
63 changed files with 881 additions and 81 deletions

View File

@ -3,3 +3,5 @@
npm run test && npm run lint
npm run test && npm run lint
npm run test && npm run lint
npm run test && npm run lint

View File

@ -2,9 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<title>Dipal admin panel</title>
</head>
<body>
<div id="root"></div>

View File

@ -14,12 +14,14 @@
},
"dependencies": {
"@reduxjs/toolkit": "^1.9.3",
"@types/react-select": "^5.0.1",
"axios": "^1.3.4",
"qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-router-dom": "^6.9.0",
"react-select": "^5.7.3",
"swr": "^2.1.5"
},
"devDependencies": {

View File

@ -0,0 +1,11 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg" fill="#fff" stroke="#fff">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier">
<path fill="#fff" d="M288 896h448q32 0 32 32t-32 32H288q-32 0-32-32t32-32z"/>
<path fill="#fff" d="M800 416a288 288 0 10-576 0c0 118.144 94.528 272.128 288 456.576C705.472 688.128 800 534.144 800 416zM512 960C277.312 746.688 160 565.312 160 416a352 352 0 01704 0c0 149.312-117.312 330.688-352 544z"/>
<path fill="#fff" d="M544 384h96a32 32 0 110 64h-96v96a32 32 0 01-64 0v-96h-96a32 32 0 010-64h96v-96a32 32 0 0164 0v96z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 915 B

View File

@ -1,7 +1,7 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 2H6C5.46957 2 4.96086 2.21071 4.58579 2.58579C4.21071 2.96086 4 3.46957 4 4V20C4 20.5304 4.21071 21.0391 4.58579 21.4142C4.96086 21.7893 5.46957 22 6 22H18C18.5304 22 19.0391 21.7893 19.4142 21.4142C19.7893 21.0391 20 20.5304 20 20V8L14 2Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 2V8H20" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16 13H8" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16 17H8" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10 9H9H8" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg fill="#fff" width="197px" height="197px" viewBox="-2.08 -2.08 20.16 20.16" id="add-user-16px" xmlns="http://www.w3.org/2000/svg" stroke="#fff">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <path id="Path_179" data-name="Path 179" d="M29.991,8a4,4,0,1,0-4-4A4,4,0,0,0,29.991,8Zm0-7a3,3,0,1,1-3,3A3,3,0,0,1,29.991,1ZM31,15.5a.5.5,0,0,1-.5.5h-7A1.5,1.5,0,0,1,22,14.5,4.505,4.505,0,0,1,26.5,10h4a.5.5,0,0,1,0,1h-4A3.5,3.5,0,0,0,23,14.5a.5.5,0,0,0,.5.5h7A.5.5,0,0,1,31,15.5Zm7-3a.5.5,0,0,1-.5.5H35v2.5a.5.5,0,0,1-1,0V13H31.5a.5.5,0,0,1,0-1H34V9.5a.5.5,0,0,1,1,0V12h2.5A.5.5,0,0,1,38,12.5Z" transform="translate(-22)"/> </g>
</svg>

Before

Width:  |  Height:  |  Size: 841 B

After

Width:  |  Height:  |  Size: 928 B

14
public/logo.svg Normal file
View File

@ -0,0 +1,14 @@
<svg width="445" height="186" viewBox="0 0 445 186" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="118.419" y="4.99276" width="56.5023" height="56.5023" rx="28.2512" fill="url(#paint0_linear_10465_270914)" stroke="white" stroke-width="8.01452"/>
<path d="M47.4671 183.432H0.200012V50.0942H47.8577C61.2696 50.0942 72.8151 52.7636 82.4942 58.1023C92.1733 63.3976 99.6172 71.015 104.826 80.9545C110.078 90.8941 112.703 102.787 112.703 116.633C112.703 130.522 110.078 142.458 104.826 152.441C99.6172 162.424 92.1299 170.085 82.364 175.424C72.6415 180.762 61.0092 183.432 47.4671 183.432ZM28.391 159.277H46.2952C54.6288 159.277 61.6385 157.802 67.3245 154.85C73.0538 151.855 77.3508 147.233 80.2155 140.982C83.1236 134.689 84.5776 126.572 84.5776 116.633C84.5776 106.78 83.1236 98.7285 80.2155 92.4783C77.3508 86.2281 73.0755 81.6273 67.3896 78.6758C61.7036 75.7243 54.6939 74.2486 46.3603 74.2486H28.391V159.277Z" fill="white"/>
<path d="M133.065 183.432V83.4286H160.801V183.432H133.065Z" fill="white"/>
<path d="M195.415 183.432V50.0942H248.021C258.134 50.0942 266.75 52.0257 273.868 55.8887C280.987 59.7082 286.412 65.0252 290.145 71.8397C293.921 78.6107 295.809 86.4235 295.809 95.2779C295.809 104.132 293.899 111.945 290.08 118.716C286.26 125.487 280.726 130.761 273.478 134.537C266.273 138.313 257.548 140.201 247.305 140.201H213.775V117.609H242.748C248.173 117.609 252.644 116.676 256.16 114.81C259.719 112.9 262.366 110.274 264.103 106.932C265.882 103.546 266.772 99.6617 266.772 95.2779C266.772 90.8507 265.882 86.9877 264.103 83.689C262.366 80.3469 259.719 77.7643 256.16 75.9414C252.6 74.075 248.086 73.1418 242.617 73.1418H223.606V183.432H195.415Z" fill="white"/>
<path d="M339.43 185.32C333.05 185.32 327.364 184.213 322.373 181.999C317.381 179.742 313.431 176.422 310.523 172.038C307.659 167.611 306.226 162.099 306.226 155.501C306.226 149.945 307.246 145.279 309.286 141.503C311.326 137.727 314.104 134.689 317.62 132.388C321.136 130.088 325.129 128.352 329.599 127.18C334.113 126.008 338.844 125.183 343.792 124.706C349.609 124.098 354.296 123.534 357.855 123.013C361.415 122.449 363.997 121.624 365.603 120.539C367.209 119.454 368.012 117.848 368.012 115.721V115.331C368.012 111.207 366.71 108.017 364.106 105.76C361.545 103.503 357.899 102.374 353.168 102.374C348.176 102.374 344.205 103.481 341.253 105.695C338.302 107.865 336.349 110.6 335.394 113.898L309.742 111.815C311.044 105.738 313.605 100.486 317.424 96.0592C321.244 91.5885 326.17 88.1596 332.204 85.7724C338.28 83.3418 345.312 82.1265 353.298 82.1265C358.854 82.1265 364.171 82.7775 369.249 84.0796C374.371 85.3818 378.906 87.4001 382.856 90.1345C386.849 92.869 389.996 96.3847 392.297 100.682C394.597 104.935 395.747 110.035 395.747 115.982V183.432H369.444V169.564H368.663C367.057 172.689 364.909 175.445 362.217 177.833C359.526 180.176 356.293 182.021 352.517 183.367C348.741 184.669 344.378 185.32 339.43 185.32ZM347.373 166.179C351.453 166.179 355.056 165.376 358.181 163.77C361.306 162.12 363.758 159.907 365.538 157.129C367.317 154.351 368.207 151.204 368.207 147.688V137.076C367.339 137.64 366.146 138.161 364.626 138.639C363.151 139.073 361.48 139.485 359.613 139.876C357.747 140.223 355.881 140.548 354.014 140.852C352.148 141.113 350.455 141.351 348.936 141.568C345.681 142.046 342.838 142.805 340.407 143.847C337.976 144.889 336.088 146.299 334.743 148.079C333.397 149.815 332.724 151.985 332.724 154.59C332.724 158.366 334.092 161.252 336.826 163.249C339.604 165.202 343.12 166.179 347.373 166.179Z" fill="white"/>
<path d="M445 50.0942V183.432H417.265V50.0942H445Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_10465_270914" x1="146.67" y1="9.00002" x2="146.67" y2="57.4878" gradientUnits="userSpaceOnUse">
<stop stop-color="#0092DF"/>
<stop offset="1" stop-color="#003EDF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -7,7 +7,7 @@ const getPlacesRO = (placesResponse: GetPlacesResponse): GetPlacesRO => {
id: placeResponse._id,
placeType: placeResponse.place_type,
name: placeResponse.name,
parentId: placeResponse.place_type,
parentId: placeResponse.parent_id,
availableServices: placeResponse.available_services,
createdAt: placeResponse.createdAt,
updatedAt: placeResponse.updatedAt,

View File

@ -0,0 +1,45 @@
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
import { apiUrls } from '~/driven/utils/configs/appConfig';
import {
ICreatePlaceLogicMaker,
createPlaceArguments,
} from '~/driving/application/core/places/create-place/model/submiCreatePlace';
const createPlacesDto = (newPlace: createPlaceArguments) => ({
place_type: newPlace.placeType,
parent_id: newPlace.parentId || null,
name: newPlace.placeName,
});
const createPlaceAdapter = (
userAdmin: AdminUserModel | null,
updateAccessToken: (newAccessToken: string) => void,
navigateToAuth: () => void,
): ICreatePlaceLogicMaker => {
const url = apiUrls.core.createPlace;
const httpHandler = async (newPlace: createPlaceArguments) => {
const httpProvider = new HTTPPovider(
{
accessToken: (userAdmin && userAdmin?.adminUserData.accessToken) || null,
refreshToken: (userAdmin && userAdmin?.adminUserData.refreshToken) || null,
},
updateAccessToken,
navigateToAuth,
);
const dto = createPlacesDto(newPlace);
const options: HttpOptionsType = {
url,
method: 'POST',
data: dto,
};
return await httpProvider.request<string>(options);
};
return {
httpHandler,
};
};
export default createPlaceAdapter;

View File

@ -46,7 +46,6 @@ export class HTTPPovider {
async request<R>(customOptions: HttpOptionsType) {
const axiosInstance = this.handleRequestInterceptor();
this.responseIncepter(axiosInstance);
const response = await axiosInstance<ApiGlobalResponseObject<R>>(customOptions);
if (!response) throw new Error(staticMessages.service.errors[500]);
@ -69,12 +68,11 @@ export class HTTPPovider {
}
private responseIncepter(axiosInstance: AxiosInstance) {
axiosInstance.interceptors.response.use(
return axiosInstance.interceptors.response.use(
(response) => response,
(error) => {
const originalRequest = error.config;
if (error.response.status === 401 && error.response.message === 'Unauthorized') {
if (error.response.status === 401 && error.response.data.message === 'Unauthorized') {
const newAccessToken = this.refreshAccessToken().then(() => {
originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
return axios(originalRequest);

View File

@ -10,6 +10,9 @@ export default class SwrBoundary implements StateManagementProvider {
isLoading: boolean;
error?: string | undefined;
} {
return useSwr(key, httpHandler);
return useSwr(key, httpHandler, {
revalidateOnFocus: false,
errorRetryCount: 3,
});
}
}

View File

@ -0,0 +1,18 @@
import React, { PropsWithChildren } from 'react';
export interface IInputWrapper {
title: string;
className?: string;
}
export default function InputWrapper(props: PropsWithChildren<IInputWrapper>) {
const { children, title, className } = props;
return (
<div className={`flex flex-col ${className}`}>
<label className='mb-1 text-txt-second text-xs' htmlFor={title}>
{title}
</label>
{children}
</div>
);
}

View File

@ -0,0 +1,34 @@
/* eslint-disable import/no-extraneous-dependencies */
import React from 'react';
import Select from 'react-select';
import InputWrapper, { IInputWrapper } from '../input-wrapper/InputWrapper';
interface IInputBox<ValueType> extends IInputWrapper {
name: string;
state: {
value: { value: ValueType; label: string };
options: { value: ValueType; label: string }[];
setValue: (newValue: ValueType, label: string) => void;
isLoading?: boolean;
};
}
export default function InputBox<ValueType>(props: IInputBox<ValueType>) {
const { title, className, name, state } = props;
const { setValue, value, options } = state;
return (
<InputWrapper title={title} className={className}>
<Select
classNamePrefix='select'
defaultValue={value}
value={value}
isLoading={state.isLoading}
onChange={(newValue) => newValue && newValue.value && setValue(newValue.value, newValue.label)}
isSearchable
name={name}
options={options}
className='text-txt-medium'
/>
</InputWrapper>
);
}

View File

@ -1,4 +1,5 @@
import React from 'react';
import InputWrapper from '../input-wrapper/InputWrapper';
export type SetStateInputMethod<NameType> = (name: NameType, newValue: string) => void;
@ -25,10 +26,7 @@ export default function SimpleInput<NameType>(props: ISimpleInput<NameType>) {
};
return (
<div className={`flex flex-col ${className}`}>
<label className='mb-1 text-txt-second text-xs' htmlFor={title}>
{title}
</label>
<InputWrapper title={title} className={className}>
<input
value={state}
onChange={handleInputChange}
@ -36,6 +34,6 @@ export default function SimpleInput<NameType>(props: ISimpleInput<NameType>) {
className='bg-bg-gray h-11 rounded-lg focus:outline-0 px-2 text-txt-medium w-full'
id={title}
/>
</div>
</InputWrapper>
);
}

View File

@ -9,6 +9,7 @@ export const appConfig = {
export const routes = {
usersList: '/',
createUser: '/create-user',
createPlace: '/create-place',
authentication: '/auth',
};
@ -23,6 +24,11 @@ export const routesData = {
icon: icons.createUser,
title: staticMessages.global.createUser,
},
createPlace: {
path: routes.createPlace,
icon: icons.createPlace,
title: staticMessages.global.createPlace,
},
};
const baseApiUrl = ENVs.apiOrigin;
@ -34,6 +40,7 @@ export const apiUrls = {
createUserAccount: `${baseApiUrl}${ENVs.apiCreateUserAccount}`,
createUserProfile: `${baseApiUrl}${ENVs.apiCreateUserProfile}`,
createMember: `${baseApiUrl}${ENVs.apiCreateMember}`,
createPlace: `${baseApiUrl}${ENVs.apiCreatePlace}`,
},
generic: {
authPhonenumber: `${ENVs.apiAuthOrigin}${ENVs.apiAuthPhonenumber}`,

View File

@ -5,5 +5,6 @@ export const icons = {
logoBlack: `${baseIconsUrl}logo-black.svg`,
users: `${baseIconsUrl}users.svg`,
createUser: `${baseIconsUrl}createuser.svg`,
createPlace: `${baseIconsUrl}createplace.svg`,
qrcode: `${baseIconsUrl}qrcode.png`,
};

View File

@ -10,4 +10,5 @@ export const ENVs = {
apiQr: process.env.VITE_API_QR,
apiCreateUserProfile: process.env.VITE_API_USERS_PROFILE,
apiCreateMember: process.env.VITE_API_CREATE_MEMBER,
apiCreatePlace: process.env.VITE_API_PLACES,
};

View File

@ -4,6 +4,7 @@ export const staticMessages = {
input: 'please fill all inputs correctly',
phonenumber: 'please fill the valid number',
otp: 'please fill the otp fields correctly',
inputPlace: 'place type and name of place is necessary',
},
users: 'Users',
submit: 'Submit',
@ -13,9 +14,12 @@ export const staticMessages = {
title: 'title',
status: 'Status',
placeType: 'Place Type',
placeParentId: 'Parent id',
address: 'Address',
qrCode: 'qrCode',
createUser: 'Create user',
createPlace: 'Create place',
PlaceName: 'Place name',
phonenumber: 'Phone Number',
enterPanel: 'Enter to Panel',
enterPhoneNumber: 'Enter your phone number',
@ -23,15 +27,29 @@ export const staticMessages = {
success: {
createUser: 'user created successfully',
createMember: 'member created successfully',
createPlace: 'place created successfully',
},
and: 'and',
canUseFor: 'can use for',
oneTime: 'one time',
multipleTimes: 'multiple times',
},
placeTypes: {
continent: 'Continent',
country: 'Country',
state: 'State',
region: 'Region',
city: 'City',
district: 'District',
street: 'Street',
building: 'Building',
section: 'Section',
floor: 'Floor',
flat: 'Flat',
},
service: {
errors: {
500: 'server not respond please try again later!',
500: 'there is a problem with connecting to the server please try again later!',
401: 'Authentication error!',
},
},

View File

@ -1,7 +1,10 @@
import StateManagementService from '~/driven/boundaries/state-management';
import StorageService from '~/driven/boundaries/storage-boundary';
import { NavigateFunction } from 'react-router-dom';
import { QrPlace } from '~/business-logic/core/places/common/entity/placeEntity';
import { ITableRowInfra } from '~/driving/application/core/common/table-row/infra/protocols';
import { appConfig, routes } from '../configs/appConfig';
import { staticMessages } from '../constants/staticMessages';
import { errorHandlingStateTypes, UIErrorHandling } from './protocols/globalHelpersProtocols';
import { IUserContext } from './contexts/userContext';
@ -48,3 +51,13 @@ export const navigateToAuth = (userCtx: IUserContext, navigate: NavigateFunction
setUser(null);
navigate(routes.authentication);
};
export const returnPlacesDetailsMessage = (dep: { QrCodeData: QrPlace; rowData: ITableRowInfra['rowData'] }) => {
const { QrCodeData, rowData } = dep;
const placeType = rowData.rowItemsTitle[1];
const placeTitle = rowData.rowItemsTitle[0];
const isOneTime = !QrCodeData.oneTime ? staticMessages.global.multipleTimes : staticMessages.global.oneTime;
const message = `${placeType} ${placeTitle} ${staticMessages.global.and} ${staticMessages.global.canUseFor} ${isOneTime}`;
return message;
};

View File

@ -1,10 +1,10 @@
/* eslint-disable react/no-unused-prop-types */
/* eslint-disable import/no-extraneous-dependencies */
import React, { useState } from 'react';
import { QrPlace } from '~/business-logic/core/places/common/entity/placeEntity';
import Modal from '~/driven/utils/components/modal/Modal';
import { icons } from '~/driven/utils/constants/assertUrls';
import { QRCodeCanvas } from 'qrcode.react';
import { staticMessages } from '~/driven/utils/constants/staticMessages';
import { ITableRowInfra } from '../../../infra/protocols';
interface IRowItemProp {
@ -14,13 +14,13 @@ interface IRowItemProp {
rowData: ITableRowInfra['rowData'];
}
function QrCodeReader(props: { QrCodeData: QrPlace; rowData: ITableRowInfra['rowData'] }) {
const { QrCodeData, rowData } = props;
const placeType = rowData.rowItemsTitle[1];
const placeTitle = rowData.rowItemsTitle[0];
const isOneTime = !QrCodeData.oneTime ? staticMessages.global.multipleTimes : staticMessages.global.oneTime;
const returnQrCodeIdMessage = (dep: { QrCodeData: QrPlace }) => {
const { QrCodeData } = dep;
const message = `${placeType} ${placeTitle} ${staticMessages.global.and} ${staticMessages.global.canUseFor} ${isOneTime}`;
return QrCodeData.id;
};
function QrCodeReader(props: { QrCodeData: QrPlace; rowData: ITableRowInfra['rowData'] }) {
const message = returnQrCodeIdMessage(props);
return <QRCodeCanvas id='qrCode' value={message} size={150} bgColor='#fff' level='H' />;
}

View File

@ -1,19 +1,16 @@
/* eslint-disable consistent-return */
/* eslint-disable no-underscore-dangle */
import React from 'react';
import getPlaces from '~/business-logic/core/places/get-places';
import getPlacesAdapter from '~/driven/adapters/get-places-adapter/getPlacesAdapter';
import PlacesModel from '~/business-logic/core/places/common/model/placesModel';
import { prepareStateManagementForVM } from '~/driven/utils/helpers/globalHelpers';
import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator';
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
import { apiUrls } from '~/driven/utils/configs/appConfig';
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
import { QrPlace } from '~/business-logic/core/places/common/entity/placeEntity';
import PlacesListView from '../view/PlacesListView';
import usePlacesListVM from '../viewmodel/placesListVM';
import placesListModel from '../model/placesListModel';
import getPlaces from '~/business-logic/core/places/get-places';
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
import getPlacesAdapter from '~/driven/adapters/get-places-adapter/getPlacesAdapter';
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
import { apiUrls } from '~/driven/utils/configs/appConfig';
import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator';
import { prepareStateManagementForVM } from '~/driven/utils/helpers/globalHelpers';
import PlacesModel from '~/business-logic/core/places/common/model/placesModel';
import placesListModel from '../../places-list/model/placesListModel';
type QrCodeResponse = {
one_time: false;
@ -40,13 +37,7 @@ const prepareTheLogicForModel = () => {
return { getingPlacesLogic, url };
};
export interface IPlacesListProps {
selectedRowId: string;
setSelectedRowId: React.Dispatch<React.SetStateAction<string>>;
}
export default function PlacessList(props: IPlacesListProps) {
const { selectedRowId, setSelectedRowId } = props;
const useGetPlaceList = () => {
const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater();
const getQrCodes = async () => {
@ -81,9 +72,8 @@ export default function PlacessList(props: IPlacesListProps) {
};
const placesModel = async () => await placesListModel(getPlacesWithQrLogic);
const useGetPlacesList = prepareStateManagementForVM<PlacesModel>(url, placesModel);
const { placesData } = usePlacesListVM({
useGetPlacesList,
});
return <PlacesListView placesList={placesData} selectedRowId={selectedRowId} setSelectedRowId={setSelectedRowId} />;
}
return useGetPlacesList;
};
export default useGetPlaceList;

View File

@ -0,0 +1,3 @@
import CreatePlace from './infra/CreatePlace';
export default CreatePlace;

View File

@ -0,0 +1,30 @@
import React from 'react';
import createPlaceAdapter from '~/driven/adapters/create-place-adapter/createPlaceAdapter';
import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator';
import CreatePlaceView from '../view/CreatePlaceView';
import useCreatePlaceVm from '../viewmodel/createPlaceVM';
import createPlaceModel from '../model/createPlaceModel';
export default function CreatePlace() {
const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater();
const { user } = userData;
const createPlaceDrivenAdapter = createPlaceAdapter(user, accessTokenUpdateHandler, notLoginAuth);
const { inputOptions, createPlace } = createPlaceModel(createPlaceDrivenAdapter);
const { formStateData, inputStateHandlers, selectBoxOptions, handleSubmitCreatePlaceForm } = useCreatePlaceVm({
getInputOptions: inputOptions,
createPlaceModel: createPlace,
});
return (
<CreatePlaceView
handleSubmitCreatePlaceForm={handleSubmitCreatePlaceForm}
inputOptions={{
parentId: selectBoxOptions.parentIdsOptions,
placeType: selectBoxOptions.placeTypesOptions,
isParentIdLoading: selectBoxOptions.isParentIdLoading,
}}
formStateData={formStateData}
inputStateHandlers={inputStateHandlers}
/>
);
}

View File

@ -0,0 +1,20 @@
import { CreatePlaceType } from './protocols';
import getValidOptionsOfSelectBox from './getValidOptionsOfSelectBox';
import createPlaceLogicMaker, { ICreatePlaceLogicMaker } from './submiCreatePlace';
type ICreatePlaceModel = ICreatePlaceLogicMaker;
const createPlaceModel = (depenedencies: ICreatePlaceModel): CreatePlaceType => {
const { getPlacesTypeOptionsOfSelectBox, getValidParentIdsOptionsOfSelectBox } = getValidOptionsOfSelectBox;
const { createPlace } = createPlaceLogicMaker(depenedencies);
return {
createPlace,
inputOptions: {
getPlaceType: getPlacesTypeOptionsOfSelectBox,
getParentIds: getValidParentIdsOptionsOfSelectBox,
},
};
};
export default createPlaceModel;

View File

@ -0,0 +1,66 @@
import Places from '~/business-logic/core/places/common/entity/placeEntity';
import PlacesModel from '~/business-logic/core/places/common/model/placesModel';
import { staticMessages } from '~/driven/utils/constants/staticMessages';
import { placeTypes } from '../view/protocol';
export const placeTypeTuple: ReadonlyArray<`${placeTypes}`> = [
placeTypes.continent,
placeTypes.country,
placeTypes.state,
placeTypes.region,
placeTypes.city,
placeTypes.district,
placeTypes.street,
placeTypes.building,
placeTypes.section,
placeTypes.floor,
placeTypes.flat,
];
const makeOptionsOfSelectBoxForParentIds = (places: Places[], currentPlaceType: `${placeTypes}`) => {
const currentPlaceTypeIndex = placeTypeTuple.indexOf(currentPlaceType);
if (currentPlaceTypeIndex === -1) throw new Error();
const placesValidToShow = places.reduce((prevVal, currentVal) => {
const placeListItemIndex = placeTypeTuple.indexOf(currentVal.placeType as `${placeTypes}`);
if (!currentVal.parentId) return prevVal;
if (placeListItemIndex === -1) return prevVal;
if (placeListItemIndex > currentPlaceTypeIndex) return prevVal;
const label = `${currentVal.placeType} ${currentVal.name}`;
return [...prevVal, { value: currentVal.parentId, label }];
}, <{ value: string; label: string }[]>[]);
return placesValidToShow;
};
const getValidParentIdsOptionsOfSelectBox = (
currentPlaceType: `${placeTypes}`,
placesList: PlacesModel,
): { value: string; label: string }[] => {
try {
if (!placesList) throw new Error();
const places = placesList.getData();
if (!places.length) throw new Error();
const placesOptionsValidToShow = makeOptionsOfSelectBoxForParentIds(places, currentPlaceType);
return placesOptionsValidToShow;
} catch (_error) {
return [];
}
};
const getPlacesTypeOptionsOfSelectBox = () => {
return Object.keys(placeTypes).map((placeTypeKey) => {
const key = placeTypeKey as keyof typeof placeTypes;
return { value: placeTypes[key], label: staticMessages.placeTypes[placeTypes[key]] };
});
};
export default {
getValidParentIdsOptionsOfSelectBox,
getPlacesTypeOptionsOfSelectBox,
};

View File

@ -0,0 +1,3 @@
import createPlaceModel from './createPlaceModel';
export default createPlaceModel;

View File

@ -0,0 +1,20 @@
import PlacesModel from '~/business-logic/core/places/common/model/placesModel';
import { placeTypes } from '../view/protocol';
import { createPlaceArguments } from './submiCreatePlace';
export type CreatePlaceType = {
createPlace: (placeData: createPlaceArguments) => Promise<string>;
inputOptions: {
getPlaceType: () => {
value: placeTypes;
label: string;
}[];
getParentIds: (
currentPlaceType: `${placeTypes}`,
placesList: PlacesModel,
) => {
value: string;
label: string;
}[];
};
};

View File

@ -0,0 +1,24 @@
import { placeTypes } from '../view/protocol';
export type createPlaceArguments = {
placeType: `${placeTypes}`;
placeName: string;
parentId: string;
};
export interface ICreatePlaceLogicMaker {
httpHandler: (placeData: createPlaceArguments) => Promise<string>;
}
const createPlaceLogicMaker = (depenedencies: ICreatePlaceLogicMaker) => {
const { httpHandler } = depenedencies;
const createPlace = async (placeData: createPlaceArguments) => {
return await httpHandler(placeData);
};
return {
createPlace,
};
};
export default createPlaceLogicMaker;

View File

@ -0,0 +1,61 @@
import React from 'react';
import SimpleInput from '~/driven/utils/components/inputs/simple-input/SimpleInput';
import InputBox from '~/driven/utils/components/inputs/select-box/InputBox';
import { staticMessages } from '~/driven/utils/constants/staticMessages';
import PrimaryButton from '~/driven/utils/components/buttons/primary-button/PrimaryButton';
import Notification from '~/driven/utils/components/Notification/Notification';
import { ICreatePlaceProps } from './protocol';
export default function CreatePlaceView(props: ICreatePlaceProps) {
const { formStateData, inputStateHandlers, inputOptions, handleSubmitCreatePlaceForm } = props;
const { formState, error, setError } = formStateData;
return (
<>
{Boolean(error.message) && (
<Notification
message={error.message}
type={error.type}
onCloseCallback={() => setError({ message: '', type: 'error' })}
/>
)}
<form onSubmit={handleSubmitCreatePlaceForm} className='p-4 py-6 flex flex-wrap w-full gap-4'>
<SimpleInput
inputData={{
name: staticMessages.global.PlaceName,
title: staticMessages.global.PlaceName,
}}
stateHanlder={{
state: formState.placeName,
setState: inputStateHandlers.name,
}}
className='mb-4 w-[48%] px-2'
/>
<InputBox
name={staticMessages.global.placeType}
state={{
value: { value: formState.placeTypes, label: staticMessages.placeTypes[formState.placeTypes] },
setValue: inputStateHandlers.placeType,
options: inputOptions.placeType,
}}
title={staticMessages.global.placeType}
className='mb-4 w-[48%] px-2 border-1 border-txt-medium text-txt-medium'
/>
<InputBox
name={staticMessages.global.placeParentId}
state={{
value: { value: formState.parentId.value, label: formState.parentId.label },
setValue: inputStateHandlers.parentId,
options: inputOptions.parentId,
isLoading: inputOptions.isParentIdLoading,
}}
title={staticMessages.global.placeParentId}
className='mb-4 w-[48%] px-2 border-1 border-txt-medium text-txt-medium'
/>
<div className='w-full'>
<PrimaryButton onClick={() => null} title={staticMessages.global.submit} />
</div>
</form>
</>
);
}

View File

@ -0,0 +1,53 @@
export enum placeTypes {
continent = 'continent',
country = 'country',
state = 'state',
region = 'region',
city = 'city',
district = 'district',
street = 'street',
building = 'building',
section = 'section',
floor = 'floor',
flat = 'flat',
}
export type PlaceFormState = {
placeName: string;
placeTypes: `${placeTypes}`;
parentId: { value: string; label: string };
};
export interface ICreatePlaceProps {
handleSubmitCreatePlaceForm: (e: React.FormEvent) => Promise<void>;
formStateData: {
formState: PlaceFormState;
error: {
message: string;
type: 'error' | 'success';
};
setError: React.Dispatch<
React.SetStateAction<{
message: string;
type: 'error' | 'success';
}>
>;
setFormState: React.Dispatch<React.SetStateAction<PlaceFormState>>;
};
inputStateHandlers: {
name: (_name: string, newValue: string) => void;
placeType: (newValue: `${placeTypes}`) => void;
parentId: (newValue: string, label: string) => void;
};
inputOptions: {
placeType: {
value: placeTypes;
label: string;
}[];
parentId: {
value: string;
label: string;
}[];
isParentIdLoading: boolean;
};
}

View File

@ -0,0 +1,97 @@
import { useCallback, useEffect, useMemo, useState } from 'react';
import { AxiosError } from 'axios';
import { staticMessages } from '~/driven/utils/constants/staticMessages';
import useGetPlaceList from '../../common/hooks/useGetPlaceList';
import { PlaceFormState, placeTypes } from '../view/protocol';
import { createPlaceArguments } from '../model/submiCreatePlace';
import { ICreatePlaceVm, initialPlaceFormState } from './protocols';
const onChangeInputStateHandlers = (setFormState: React.Dispatch<React.SetStateAction<PlaceFormState>>) => {
const handleNameSetState = (_name: string, newValue: string) =>
setFormState((prev) => ({ ...prev, placeName: newValue }));
const handlePlaceTypeSetState = (newValue: `${placeTypes}`) =>
setFormState((prev) => ({ ...prev, placeTypes: newValue }));
const handleParentIdSetState = (newValue: string, label: string) =>
setFormState((prev) => ({ ...prev, parentId: { value: newValue, label } }));
return {
handleNameSetState,
handlePlaceTypeSetState,
handleParentIdSetState,
};
};
const resetParentIdOnChangePlaceType = (setFormState: React.Dispatch<React.SetStateAction<PlaceFormState>>) => {
setFormState((prev) => ({ ...prev, parentId: { label: '', value: '' } }));
};
const useCreatePlaceVm = (dependencies: ICreatePlaceVm) => {
const { getInputOptions, createPlaceModel } = dependencies;
const { getParentIds, getPlaceType } = getInputOptions;
const [formState, setFormState] = useState<PlaceFormState>(initialPlaceFormState);
const [error, setError] = useState<{ message: string; type: 'error' | 'success' }>({ message: '', type: 'error' });
const { handleNameSetState, handleParentIdSetState, handlePlaceTypeSetState } = useMemo(
() => onChangeInputStateHandlers(setFormState),
[],
);
const handleSubmitCreatePlaceForm = async (e: React.FormEvent) => {
e.preventDefault();
try {
const { parentId, placeName, placeTypes: placeType } = formState;
if (!placeName || !placeName) throw new Error(staticMessages.global.errors.inputPlace);
const newPlaceData: createPlaceArguments = {
parentId: parentId.value,
placeName,
placeType,
};
const response = await createPlaceModel(newPlaceData);
if (!response) throw new Error(staticMessages.service.errors[500]);
setError({
message: staticMessages.global.success.createPlace,
type: 'success',
});
} catch (errorExc) {
if (errorExc instanceof AxiosError) {
setError({ message: errorExc.response?.data?.description, type: 'error' });
} else if (errorExc instanceof Error) {
setError({ message: errorExc.message, type: 'error' });
}
}
};
useEffect(() => resetParentIdOnChangePlaceType(setFormState), [formState.placeTypes]);
const getPlaceList = useCallback(() => useGetPlaceList()(), []);
const places = getPlaceList();
const placeTypesOptions = useMemo(() => getPlaceType(), []);
const parentIdsOptions = useMemo(() => {
if (!places.data) return [];
return getParentIds(formState.placeTypes, places.data);
}, [formState.placeTypes, places]);
return {
handleSubmitCreatePlaceForm,
formStateData: {
formState,
error,
setError,
setFormState,
},
inputStateHandlers: {
name: handleNameSetState,
parentId: handleParentIdSetState,
placeType: handlePlaceTypeSetState,
},
selectBoxOptions: {
placeTypesOptions,
parentIdsOptions,
isParentIdLoading: places.isLoading,
},
};
};
export default useCreatePlaceVm;

View File

@ -0,0 +1,14 @@
import { CreatePlaceType } from '../model/protocols';
import { createPlaceArguments } from '../model/submiCreatePlace';
import { PlaceFormState, placeTypes } from '../view/protocol';
export const initialPlaceFormState: PlaceFormState = {
placeTypes: placeTypes.continent,
placeName: '',
parentId: { value: '', label: '' },
};
export interface ICreatePlaceVm {
getInputOptions: CreatePlaceType['inputOptions'];
createPlaceModel: (placeData: createPlaceArguments) => Promise<string>;
}

View File

@ -0,0 +1,22 @@
/* eslint-disable consistent-return */
/* eslint-disable no-underscore-dangle */
import React from 'react';
import PlacesListView from '../view/PlacesListView';
import usePlacesListVM from '../viewmodel/placesListVM';
import useGetPlaceList from '../../common/hooks/useGetPlaceList';
export interface IPlacesListProps {
selectedRowId: string;
setSelectedRowId: React.Dispatch<React.SetStateAction<string>>;
}
export default function PlacessList(props: IPlacesListProps) {
const { selectedRowId, setSelectedRowId } = props;
const useGetPlacesList = useGetPlaceList();
const { placesData } = usePlacesListVM({
useGetPlacesList,
});
return <PlacesListView placesList={placesData} selectedRowId={selectedRowId} setSelectedRowId={setSelectedRowId} />;
}

View File

@ -1,10 +1,10 @@
import React, { useMemo } from 'react';
import { staticMessages } from '~/driven/utils/constants/staticMessages';
import Loading from '~/driven/utils/components/loading/Loading';
import TableRow from '../../common/table-row';
import TableRow from '../../../common/table-row';
import { IPlacesListProps } from './protocols';
export default function UsersListView(props: IPlacesListProps) {
export default function PlacesListView(props: IPlacesListProps) {
const { selectedRowId, setSelectedRowId, placesList } = props;
const rows = useMemo(() => {

View File

@ -2,7 +2,7 @@ import { INewUserData } from '~/business-logic/core/users/create-user/create-acc
import { SetStateInputMethod } from '~/driven/utils/components/inputs/simple-input/SimpleInput';
export default interface ICreateUserViewProps {
onSubmit: (e: React.FormEvent) => void;
onSubmit: (e: React.FormEvent) => Promise<void>;
stateHandler: {
inputStates: INewUserData;
inputsSetStates: SetStateInputMethod<keyof INewUserData>;

View File

@ -3,7 +3,7 @@ import React, { useMemo } from 'react';
import { staticMessages } from '~/driven/utils/constants/staticMessages';
import Users from '~/business-logic/core/users/common/entity/entity';
import Loading from '~/driven/utils/components/loading/Loading';
import TableRow from '../../common/table-row';
import TableRow from '../../../common/table-row';
import { IUserListProps } from './protocols';
export default function UsersListView(props: IUserListProps) {

View File

@ -19,7 +19,7 @@ export default function Sidebar() {
isCurrentPage.pathname === routesData[key].path ? 'bg-primary-300' : ''
}`}
>
<img src={routesData[key].icon} alt='page icon' className='mr-2' />
<img src={routesData[key].icon} alt='page icon' className='mr-2 w-6 h-6' />
<div>{routesData[key].title}</div>
</Link>
);

View File

@ -5,6 +5,7 @@ import CreateUser from '../pages/CreateUser';
import MainPageLayout from '../pages/layouts/MainPageLayout';
import AuthenticationPage from '../pages/Authentication';
import UserLoginLayout from '../pages/layouts/UserLoginLayout';
import CreatePlacePage from '../pages/CreatePlacePage';
export default function Router() {
const location = useLocation();
@ -14,6 +15,7 @@ export default function Router() {
<Route element={<MainPageLayout />}>
<Route index element={<Home />} />
<Route path={routes.createUser} element={<CreateUser />} />
<Route path={routes.createPlace} element={<CreatePlacePage />} />
</Route>
<Route element={<UserLoginLayout />}>
<Route path={routes.authentication} element={<AuthenticationPage />} />

View File

@ -0,0 +1,13 @@
import React from 'react';
import PageTitle from '~/driven/utils/components/page-title/pageTitle';
import { staticMessages } from '~/driven/utils/constants/staticMessages';
import CreatePlace from '~/driving/application/core/places/create-place';
export default function CreatePlacePage() {
return (
<>
<PageTitle className='px-4 py-5' title={staticMessages.global.createPlace} />
<CreatePlace />
</>
);
}

View File

@ -1,7 +1,7 @@
import React from 'react';
import PageTitle from '~/driven/utils/components/page-title/pageTitle';
import { staticMessages } from '~/driven/utils/constants/staticMessages';
import CreateUser from '~/driving/application/core/create-user';
import CreateUser from '~/driving/application/core/users/create-user';
export default function CreateUserPage() {
return (

View File

@ -8,8 +8,8 @@ import PageTitle from '~/driven/utils/components/page-title/pageTitle';
import { apiUrls } from '~/driven/utils/configs/appConfig';
import { staticMessages } from '~/driven/utils/constants/staticMessages';
import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator';
import PlacesList from '~/driving/application/core/places-list';
import UsersList from '~/driving/application/core/users-list';
import PlacesList from '~/driving/application/core/places/places-list';
import UsersList from '~/driving/application/core/users/users-list';
export default function index() {
const [selectedUserRowId, setSelectedUserRowId] = useState<string>('');

230
yarn.lock
View File

@ -197,7 +197,7 @@
dependencies:
"@babel/types" "^7.18.6"
"@babel/helper-module-imports@^7.21.4":
"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.21.4":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz#ac88b2f76093637489e718a90cec6cf8a9b029af"
integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==
@ -1078,6 +1078,13 @@
resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
"@babel/runtime@^7.12.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
version "7.22.3"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.3.tgz#0a7fce51d43adbf0f7b517a71f4c3aaca92ebcbb"
integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ==
dependencies:
regenerator-runtime "^0.13.11"
"@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.21.0"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz"
@ -1149,6 +1156,39 @@
resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
"@emotion/babel-plugin@^11.11.0":
version "11.11.0"
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c"
integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==
dependencies:
"@babel/helper-module-imports" "^7.16.7"
"@babel/runtime" "^7.18.3"
"@emotion/hash" "^0.9.1"
"@emotion/memoize" "^0.8.1"
"@emotion/serialize" "^1.1.2"
babel-plugin-macros "^3.1.0"
convert-source-map "^1.5.0"
escape-string-regexp "^4.0.0"
find-root "^1.1.0"
source-map "^0.5.7"
stylis "4.2.0"
"@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0":
version "11.11.0"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff"
integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==
dependencies:
"@emotion/memoize" "^0.8.1"
"@emotion/sheet" "^1.2.2"
"@emotion/utils" "^1.2.1"
"@emotion/weak-memoize" "^0.3.1"
stylis "4.2.0"
"@emotion/hash@^0.9.1":
version "0.9.1"
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43"
integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==
"@emotion/is-prop-valid@^1.1.0":
version "1.2.0"
resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz"
@ -1161,6 +1201,41 @@
resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz"
integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==
"@emotion/memoize@^0.8.1":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17"
integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
"@emotion/react@^11.8.1":
version "11.11.0"
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.0.tgz#408196b7ef8729d8ad08fc061b03b046d1460e02"
integrity sha512-ZSK3ZJsNkwfjT3JpDAWJZlrGD81Z3ytNDsxw1LKq1o+xkmO5pnWfr6gmCC8gHEFf3nSSX/09YrG67jybNPxSUw==
dependencies:
"@babel/runtime" "^7.18.3"
"@emotion/babel-plugin" "^11.11.0"
"@emotion/cache" "^11.11.0"
"@emotion/serialize" "^1.1.2"
"@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
"@emotion/utils" "^1.2.1"
"@emotion/weak-memoize" "^0.3.1"
hoist-non-react-statics "^3.3.1"
"@emotion/serialize@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51"
integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==
dependencies:
"@emotion/hash" "^0.9.1"
"@emotion/memoize" "^0.8.1"
"@emotion/unitless" "^0.8.1"
"@emotion/utils" "^1.2.1"
csstype "^3.0.2"
"@emotion/sheet@^1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec"
integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==
"@emotion/stylis@^0.8.4":
version "0.8.5"
resolved "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz"
@ -1171,6 +1246,26 @@
resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz"
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
"@emotion/unitless@^0.8.1":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3"
integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==
"@emotion/use-insertion-effect-with-fallbacks@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963"
integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==
"@emotion/utils@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4"
integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==
"@emotion/weak-memoize@^0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6"
integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==
"@esbuild/android-arm64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz#cf91e86df127aa3d141744edafcba0abdc577d23"
@ -1313,6 +1408,18 @@
resolved "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz"
integrity sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==
"@floating-ui/core@^1.2.6":
version "1.2.6"
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.2.6.tgz#d21ace437cc919cdd8f1640302fa8851e65e75c0"
integrity sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg==
"@floating-ui/dom@^1.0.1":
version "1.2.9"
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.2.9.tgz#b9ed1c15d30963419a6736f1b7feb350dd49c603"
integrity sha512-sosQxsqgxMNkV3C+3UqTS6LxP7isRLwX8WMepp843Rb3/b0Wz8+MdUkxJksByip3C2WwLugLHN1b4ibn//zKwQ==
dependencies:
"@floating-ui/core" "^1.2.6"
"@humanwhocodes/config-array@^0.11.8":
version "0.11.8"
resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz"
@ -1795,6 +1902,11 @@
resolved "https://registry.npmjs.org/@types/node/-/node-18.15.1.tgz"
integrity sha512-U2TWca8AeHSmbpi314QBESRk7oPjSZjDsR+c+H4ECC1l+kFgpZf8Ydhv3SJpPy51VyZHHqxlb6mTTqYNNRVAIw==
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
"@types/prettier@^2.1.5":
version "2.7.2"
resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz"
@ -1812,6 +1924,20 @@
dependencies:
"@types/react" "*"
"@types/react-select@^5.0.1":
version "5.0.1"
resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-5.0.1.tgz#04fc85edd34a72675a0ab56ad4c30428aab0e444"
integrity sha512-h5Im0AP0dr4AVeHtrcvQrLV+gmPa7SA0AGdxl2jOhtwiE6KgXBFSogWw8az32/nusE6AQHlCOHQWjP1S/+oMWA==
dependencies:
react-select "*"
"@types/react-transition-group@^4.4.0":
version "4.4.6"
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.6.tgz#18187bcda5281f8e10dfc48f0943e2fdf4f75e2e"
integrity sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^18.0.27":
version "18.0.28"
resolved "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz"
@ -2224,6 +2350,15 @@ babel-plugin-jest-hoist@^29.5.0:
"@types/babel__core" "^7.1.14"
"@types/babel__traverse" "^7.0.6"
babel-plugin-macros@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1"
integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==
dependencies:
"@babel/runtime" "^7.12.5"
cosmiconfig "^7.0.0"
resolve "^1.19.0"
babel-plugin-polyfill-corejs2@^0.3.3:
version "0.3.3"
resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz"
@ -2498,7 +2633,7 @@ confusing-browser-globals@^1.0.10:
resolved "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz"
integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==
convert-source-map@^1.6.0, convert-source-map@^1.7.0:
convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.9.0"
resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz"
integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
@ -2515,6 +2650,17 @@ core-js-compat@^3.25.1:
dependencies:
browserslist "^4.21.5"
cosmiconfig@^7.0.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6"
integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==
dependencies:
"@types/parse-json" "^4.0.0"
import-fresh "^3.2.1"
parse-json "^5.0.0"
path-type "^4.0.0"
yaml "^1.10.0"
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
@ -2714,6 +2860,14 @@ dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9:
resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz"
integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==
dom-helpers@^5.0.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
dependencies:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"
domexception@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz"
@ -3228,6 +3382,11 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
find-root@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
find-up@^4.0.0, find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz"
@ -3470,7 +3629,7 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@ -4421,6 +4580,11 @@ makeerror@1.0.12:
dependencies:
tmpl "1.0.5"
memoize-one@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
@ -4676,7 +4840,7 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
parse-json@^5.2.0:
parse-json@^5.0.0, parse-json@^5.2.0:
version "5.2.0"
resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz"
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
@ -4846,7 +5010,7 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.5"
prop-types@^15.8.1:
prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -4875,6 +5039,11 @@ pure-rand@^6.0.0:
resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz"
integrity sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==
qrcode.react@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-3.1.0.tgz#5c91ddc0340f768316fbdb8fff2765134c2aecd8"
integrity sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==
querystringify@^2.1.1:
version "2.2.0"
resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz"
@ -4945,6 +5114,31 @@ react-router@6.9.0:
dependencies:
"@remix-run/router" "1.4.0"
react-select@*, react-select@^5.7.3:
version "5.7.3"
resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.7.3.tgz#fa0dc9a23cad6ff3871ad3829f6083a4b54961a2"
integrity sha512-z8i3NCuFFWL3w27xq92rBkVI2onT0jzIIPe480HlBjXJ3b5o6Q+Clp4ydyeKrj9DZZ3lrjawwLC5NGl0FSvUDg==
dependencies:
"@babel/runtime" "^7.12.0"
"@emotion/cache" "^11.4.0"
"@emotion/react" "^11.8.1"
"@floating-ui/dom" "^1.0.1"
"@types/react-transition-group" "^4.4.0"
memoize-one "^6.0.0"
prop-types "^15.6.0"
react-transition-group "^4.3.0"
use-isomorphic-layout-effect "^1.1.2"
react-transition-group@^4.3.0:
version "4.4.5"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
dependencies:
"@babel/runtime" "^7.5.5"
dom-helpers "^5.0.1"
loose-envify "^1.4.0"
prop-types "^15.6.2"
react@^18.2.0:
version "18.2.0"
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
@ -5089,6 +5283,15 @@ resolve@^1.1.7, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.1:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
resolve@^1.19.0:
version "1.22.2"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
dependencies:
is-core-module "^2.11.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
resolve@^2.0.0-next.4:
version "2.0.0-next.4"
resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz"
@ -5218,6 +5421,11 @@ source-map-support@0.5.13:
buffer-from "^1.0.0"
source-map "^0.6.0"
source-map@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
@ -5350,6 +5558,11 @@ styled-components@^5.3.8:
shallowequal "^1.1.0"
supports-color "^5.5.0"
stylis@4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51"
integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==
supports-color@^5.3.0, supports-color@^5.5.0:
version "5.5.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
@ -5596,6 +5809,11 @@ url-parse@^1.5.3:
querystringify "^2.1.1"
requires-port "^1.0.0"
use-isomorphic-layout-effect@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb"
integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==
use-sync-external-store@^1.0.0, use-sync-external-store@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz"
@ -5768,7 +5986,7 @@ yallist@^4.0.0:
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml@^1.10.2:
yaml@^1.10.0, yaml@^1.10.2:
version "1.10.2"
resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==