apps/web: add files upload feature
This commit is contained in:
parent
71d7a696f1
commit
ca521cbc22
@ -67,3 +67,29 @@ export async function retract({ pageUrlParams, payload }: Input) {
|
|||||||
.then((res) => res)
|
.then((res) => res)
|
||||||
.catch((error: WretchError) => error.json as t.HttpValidationError);
|
.catch((error: WretchError) => error.json as t.HttpValidationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getDocumentTypes({ pageUrlParams }: Input) {
|
||||||
|
const url = createUrl({ ...pageUrlParams, route: '/documenttypes' });
|
||||||
|
|
||||||
|
return api
|
||||||
|
.get(url)
|
||||||
|
.res<t.ResponseDocumentTypes>((res) => res.json())
|
||||||
|
.then((res) => res);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function uploadDocument({
|
||||||
|
pageUrlParams,
|
||||||
|
document,
|
||||||
|
formData,
|
||||||
|
}: Input & { document: Pick<t.Document, 'documentTypeId'>; formData: FormData }) {
|
||||||
|
const url = createUrl({
|
||||||
|
...pageUrlParams,
|
||||||
|
route: '/document',
|
||||||
|
urlSearchParams: { ...pageUrlParams.urlSearchParams, ...document },
|
||||||
|
});
|
||||||
|
|
||||||
|
return fetch(urls.URL_IUS + url, {
|
||||||
|
body: formData,
|
||||||
|
method: 'POST',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -11,10 +11,16 @@ export type MetaObject = {
|
|||||||
|
|
||||||
type Value = any;
|
type Value = any;
|
||||||
|
|
||||||
|
export type Document = {
|
||||||
|
documentTypeId: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type ResponseGetData = Record<string, Value>;
|
export type ResponseGetData = Record<string, Value>;
|
||||||
export type ResponseMetaData = Record<string, MetaObject>;
|
export type ResponseMetaData = Record<string, MetaObject>;
|
||||||
export type ResponseConfig = { title: string };
|
export type ResponseConfig = { title: string };
|
||||||
export type ResponseConditions = string;
|
export type ResponseConditions = string;
|
||||||
|
export type ResponseDocumentTypes = Document[];
|
||||||
|
|
||||||
export type HttpError = {
|
export type HttpError = {
|
||||||
errors: string[];
|
errors: string[];
|
||||||
|
|||||||
@ -29,8 +29,9 @@ export default async function Page(pageProps: PageProps) {
|
|||||||
apiIUS.getData({ pageUrlParams }),
|
apiIUS.getData({ pageUrlParams }),
|
||||||
apiIUS.getMetaData({ pageUrlParams }),
|
apiIUS.getMetaData({ pageUrlParams }),
|
||||||
apiIUS.getConfig({ pageUrlParams }),
|
apiIUS.getConfig({ pageUrlParams }),
|
||||||
]).then(([data, metaData, { title }]) => {
|
apiIUS.getDocumentTypes({ pageUrlParams }),
|
||||||
const props = { data, metaData, pageUrlParams, title };
|
]).then(([data, metaData, { title }, documentTypes]) => {
|
||||||
|
const props = { data, documentTypes, metaData, pageUrlParams, title };
|
||||||
|
|
||||||
return <Form {...props} />;
|
return <Form {...props} />;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,16 +1,85 @@
|
|||||||
|
/* eslint-disable react/jsx-curly-newline */
|
||||||
/* eslint-disable no-negated-condition */
|
/* eslint-disable no-negated-condition */
|
||||||
import { FormContext } from './context/form-context';
|
import { FormContext } from './context/form-context';
|
||||||
import * as apiIus from '@/api/ius/query';
|
import * as apiIus from '@/api/ius/query';
|
||||||
import { useFormStore } from '@/store/ius/form';
|
import { useFormStore } from '@/store/ius/form';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
import { pick } from 'radash';
|
||||||
|
import { useCallback } from 'react';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { Button } from 'ui';
|
import { Button } from 'ui';
|
||||||
|
|
||||||
|
const ERROR_UPLOAD_DOCUMENT = 'Произошла ошибка при загрузке документов';
|
||||||
|
|
||||||
export function Buttons() {
|
export function Buttons() {
|
||||||
const { reset, resetValidation, setValidation, values } = useFormStore();
|
const { reset, resetValidation, setValidation, values } = useFormStore();
|
||||||
const { pageUrlParams, setFormStatus } = useContext(FormContext);
|
const { formFiles, pageUrlParams, setFormState } = useContext(FormContext);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const handleSave = useCallback(() => {
|
||||||
|
apiIus.save({ pageUrlParams, payload: values }).then((res) => {
|
||||||
|
if (typeof res !== 'boolean') {
|
||||||
|
setTimeout(() => {
|
||||||
|
setFormState({ status: 'edit' });
|
||||||
|
}, 300);
|
||||||
|
Object.keys(res.errors).forEach((name) => {
|
||||||
|
const elementValidation = res?.errors?.[name];
|
||||||
|
if (elementValidation)
|
||||||
|
setValidation({ message: elementValidation[0] ?? '', name, valid: false });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setFormState({ status: 'success' });
|
||||||
|
setTimeout(() => {
|
||||||
|
router.refresh();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [pageUrlParams, router, setFormState, setValidation, values]);
|
||||||
|
|
||||||
|
const handleUploadFiles = useCallback(() => {
|
||||||
|
setFormState({ status: 'pending' });
|
||||||
|
resetValidation();
|
||||||
|
const uploadFiles = formFiles.map((formFile) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', formFile.file);
|
||||||
|
const document = pick(formFile, ['documentTypeId']);
|
||||||
|
|
||||||
|
return apiIus.uploadDocument({
|
||||||
|
document,
|
||||||
|
formData,
|
||||||
|
pageUrlParams,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return Promise.allSettled(uploadFiles).catch(() => {
|
||||||
|
setFormState({ status: 'error', text: ERROR_UPLOAD_DOCUMENT });
|
||||||
|
throw new Error(ERROR_UPLOAD_DOCUMENT);
|
||||||
|
});
|
||||||
|
}, [formFiles, pageUrlParams, resetValidation, setFormState]);
|
||||||
|
|
||||||
|
const handleRetract = useCallback(() => {
|
||||||
|
setFormState({ status: 'pending' });
|
||||||
|
resetValidation();
|
||||||
|
apiIus.retract({ pageUrlParams, payload: values }).then((res) => {
|
||||||
|
if (typeof res !== 'boolean') {
|
||||||
|
setTimeout(() => {
|
||||||
|
setFormState({ status: 'edit' });
|
||||||
|
}, 300);
|
||||||
|
Object.keys(res.errors).forEach((name) => {
|
||||||
|
const elementValidation = res?.errors?.[name];
|
||||||
|
if (elementValidation)
|
||||||
|
setValidation({ message: elementValidation[0] ?? '', name, valid: false });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setFormState({ status: 'success' });
|
||||||
|
setTimeout(() => {
|
||||||
|
router.refresh();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [pageUrlParams, resetValidation, router, setFormState, setValidation, values]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 gap-2 gap-x-4 md:grid-cols-3">
|
<div className="grid grid-cols-1 gap-2 gap-x-4 md:grid-cols-3">
|
||||||
<Button
|
<Button
|
||||||
@ -21,57 +90,10 @@ export function Buttons() {
|
|||||||
>
|
>
|
||||||
Отмена
|
Отмена
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button intent="outline-secondary" onClick={() => handleRetract()}>
|
||||||
intent="outline-secondary"
|
|
||||||
onClick={() => {
|
|
||||||
setFormStatus('pending');
|
|
||||||
resetValidation();
|
|
||||||
apiIus.retract({ pageUrlParams, payload: values }).then((res) => {
|
|
||||||
if (typeof res !== 'boolean') {
|
|
||||||
setTimeout(() => {
|
|
||||||
setFormStatus('edit');
|
|
||||||
}, 300);
|
|
||||||
Object.keys(res.errors).forEach((name) => {
|
|
||||||
const elementValidation = res?.errors?.[name];
|
|
||||||
if (elementValidation)
|
|
||||||
setValidation({ message: elementValidation[0] ?? '', name, valid: false });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setFormStatus('success');
|
|
||||||
setTimeout(() => {
|
|
||||||
router.refresh();
|
|
||||||
}, 600);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Возврат на доработку
|
Возврат на доработку
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button onClick={() => handleUploadFiles().then(() => handleSave())}>Сохранить</Button>
|
||||||
onClick={() => {
|
|
||||||
setFormStatus('pending');
|
|
||||||
resetValidation();
|
|
||||||
apiIus.save({ pageUrlParams, payload: values }).then((res) => {
|
|
||||||
if (typeof res !== 'boolean') {
|
|
||||||
setTimeout(() => {
|
|
||||||
setFormStatus('edit');
|
|
||||||
}, 300);
|
|
||||||
Object.keys(res.errors).forEach((name) => {
|
|
||||||
const elementValidation = res?.errors?.[name];
|
|
||||||
if (elementValidation)
|
|
||||||
setValidation({ message: elementValidation[0] ?? '', name, valid: false });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setFormStatus('success');
|
|
||||||
setTimeout(() => {
|
|
||||||
router.refresh();
|
|
||||||
}, 600);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Сохранить
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
38
apps/web/components/Form/Files.tsx
Normal file
38
apps/web/components/Form/Files.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { FormContext } from './context/form-context';
|
||||||
|
import type { Props } from './types';
|
||||||
|
import type { Document } from '@/api/ius/types';
|
||||||
|
import { useContext } from 'react';
|
||||||
|
import { Heading, InputFile } from 'ui';
|
||||||
|
|
||||||
|
function File({ documentTypeId, name }: Document) {
|
||||||
|
const { formFiles, setFormFiles } = useContext(FormContext);
|
||||||
|
|
||||||
|
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (event.target.files) {
|
||||||
|
setFormFiles([
|
||||||
|
...formFiles.filter((x) => x.documentTypeId !== documentTypeId),
|
||||||
|
{ documentTypeId, file: event.target.files[0], name },
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={documentTypeId} className="flex flex-col">
|
||||||
|
<label className="mb-2 block text-sm font-normal text-gray-900">{name}:</label>
|
||||||
|
<InputFile onChange={handleFileChange} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Files({ documentTypes }: Props) {
|
||||||
|
return (
|
||||||
|
<div className="grid gap-4">
|
||||||
|
<Heading className="text-sms">Документы</Heading>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
{documentTypes.map((document) => (
|
||||||
|
<File key={document.documentTypeId} {...document} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import { FormContext } from './context/form-context';
|
import { FormContext } from './context/form-context';
|
||||||
import { CheckCircleIcon } from '@heroicons/react/24/solid';
|
import { CheckCircleIcon, XCircleIcon } from '@heroicons/react/24/solid';
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { Background, LoadingSpinner } from 'ui';
|
import { Background, LoadingSpinner } from 'ui';
|
||||||
@ -15,21 +15,30 @@ function OverlayWrapper({ children }: PropsWithChildren) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
export function Overlay() {
|
export function Overlay() {
|
||||||
const { formStatus } = useContext(FormContext);
|
const { formState } = useContext(FormContext);
|
||||||
|
const { status, text } = formState;
|
||||||
|
|
||||||
if (formStatus === 'pending')
|
if (status === 'pending')
|
||||||
return (
|
return (
|
||||||
<OverlayWrapper>
|
<OverlayWrapper>
|
||||||
{LoadingSpinner} <p className="font-medium">Загрузка...</p>
|
{LoadingSpinner} <p className="font-medium">Загрузка...</p>
|
||||||
</OverlayWrapper>
|
</OverlayWrapper>
|
||||||
);
|
);
|
||||||
if (formStatus === 'success')
|
if (status === 'success')
|
||||||
return (
|
return (
|
||||||
<OverlayWrapper>
|
<OverlayWrapper>
|
||||||
<CheckCircleIcon className="h-10 w-10 fill-green-500" title="OK" />{' '}
|
<CheckCircleIcon className="h-10 w-10 fill-green-500" title="OK" />{' '}
|
||||||
<p className="font-medium">Данные сохранены</p>
|
<p className="font-medium">Данные сохранены</p>
|
||||||
</OverlayWrapper>
|
</OverlayWrapper>
|
||||||
);
|
);
|
||||||
|
if (status === 'error') {
|
||||||
|
return (
|
||||||
|
<OverlayWrapper>
|
||||||
|
<XCircleIcon className="h-10 w-10 fill-red-500" title="Error" />{' '}
|
||||||
|
<p className="font-medium">{text}</p>
|
||||||
|
</OverlayWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,19 @@
|
|||||||
|
import type { Document } from '@/api/ius/types';
|
||||||
import type { PageUrlParams } from '@/utils/url';
|
import type { PageUrlParams } from '@/utils/url';
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { createContext, useMemo, useState } from 'react';
|
import { createContext, useMemo, useState } from 'react';
|
||||||
|
|
||||||
type FormStatus = 'pending' | 'edit' | 'success';
|
type FormStatus = 'pending' | 'edit' | 'success' | 'error';
|
||||||
|
type FormState = { status: FormStatus; text?: string };
|
||||||
|
|
||||||
|
type FormFile = Document & { file: File };
|
||||||
|
|
||||||
type ContextType = {
|
type ContextType = {
|
||||||
readonly formStatus: FormStatus;
|
readonly formFiles: FormFile[];
|
||||||
|
readonly formState: FormState;
|
||||||
readonly pageUrlParams: PageUrlParams;
|
readonly pageUrlParams: PageUrlParams;
|
||||||
readonly setFormStatus: (status: FormStatus) => void;
|
readonly setFormFiles: (files: FormFile[]) => void;
|
||||||
|
readonly setFormState: (formState: FormState) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FormContext = createContext<ContextType>({} as ContextType);
|
export const FormContext = createContext<ContextType>({} as ContextType);
|
||||||
@ -16,10 +22,11 @@ export function FormContextProvider({
|
|||||||
children,
|
children,
|
||||||
...initialData
|
...initialData
|
||||||
}: PropsWithChildren & Pick<ContextType, 'pageUrlParams'>) {
|
}: PropsWithChildren & Pick<ContextType, 'pageUrlParams'>) {
|
||||||
const [formStatus, setFormStatus] = useState<FormStatus>('edit');
|
const [formState, setFormState] = useState<FormState>({ status: 'edit' });
|
||||||
|
const [formFiles, setFormFiles] = useState<FormFile[]>([]);
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
() => ({ ...initialData, formStatus, setFormStatus }),
|
() => ({ ...initialData, formFiles, formState, setFormFiles, setFormState }),
|
||||||
[formStatus, initialData]
|
[formFiles, formState, initialData]
|
||||||
);
|
);
|
||||||
|
|
||||||
return <FormContext.Provider value={value}>{children}</FormContext.Provider>;
|
return <FormContext.Provider value={value}>{children}</FormContext.Provider>;
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
import { Buttons } from './Buttons';
|
import { Buttons } from './Buttons';
|
||||||
import { FormContext, FormContextProvider } from './context/form-context';
|
import { FormContext, FormContextProvider } from './context/form-context';
|
||||||
import { Elements } from './Elements';
|
import { Elements } from './Elements';
|
||||||
|
import { Files } from './Files';
|
||||||
import { Header } from './Header';
|
import { Header } from './Header';
|
||||||
import { Overlay } from './Overlay';
|
import { Overlay } from './Overlay';
|
||||||
import type { Props } from './types';
|
import type { Props } from './types';
|
||||||
@ -20,6 +21,8 @@ function Content(props: Props) {
|
|||||||
<Header title={title} link={'/ius' + createUrl({ ...pageUrlParams, route: '/conditions' })} />
|
<Header title={title} link={'/ius' + createUrl({ ...pageUrlParams, route: '/conditions' })} />
|
||||||
<Elements {...props} />
|
<Elements {...props} />
|
||||||
<Divider />
|
<Divider />
|
||||||
|
<Files {...props} />
|
||||||
|
<Divider />
|
||||||
<Buttons />
|
<Buttons />
|
||||||
</Background>
|
</Background>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import type { ResponseGetData, ResponseMetaData } from '@/api/ius/types';
|
import type * as IUS from '@/api/ius/types';
|
||||||
import type { PageUrlParams } from '@/utils/url';
|
import type { PageUrlParams } from '@/utils/url';
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
readonly data: ResponseGetData;
|
readonly data: IUS.ResponseGetData;
|
||||||
readonly metaData: ResponseMetaData;
|
documentTypes: IUS.ResponseDocumentTypes;
|
||||||
|
readonly metaData: IUS.ResponseMetaData;
|
||||||
readonly pageUrlParams: PageUrlParams;
|
readonly pageUrlParams: PageUrlParams;
|
||||||
readonly title: string;
|
readonly title: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -24,7 +24,7 @@ const nextConfig = {
|
|||||||
outputFileTracingRoot: path.join(__dirname, '../../'),
|
outputFileTracingRoot: path.join(__dirname, '../../'),
|
||||||
},
|
},
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
transpilePackages: ['ui'],
|
transpilePackages: ['ui', 'radash'],
|
||||||
async rewrites() {
|
async rewrites() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,7 +10,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^2.0.18",
|
"@heroicons/react": "^2.0.18",
|
||||||
"next": "^14.0.1",
|
"next": "^14.0.3",
|
||||||
|
"radash": "^11.0.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"tsconfig": "*",
|
"tsconfig": "*",
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
export type PageProps = {
|
export type PageProps = {
|
||||||
params: { slug: string };
|
params: { slug: string };
|
||||||
searchParams: string | string[][] | Record<string, string>;
|
searchParams: Record<string, string>;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import type { PageProps } from '@/types/page';
|
import type { PageProps } from '@/types/page';
|
||||||
|
|
||||||
export function getPageUrlParams({ params, searchParams }: PageProps) {
|
export function getPageUrlParams({ params, searchParams }: PageProps) {
|
||||||
return { path: `/${params.slug}`, urlSearchParams: new URLSearchParams(searchParams) };
|
return { path: `/${params.slug}`, urlSearchParams: searchParams };
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PageUrlParams = ReturnType<typeof getPageUrlParams>;
|
export type PageUrlParams = ReturnType<typeof getPageUrlParams>;
|
||||||
|
|||||||
@ -21,3 +21,15 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
|
|||||||
export const InputNumber = forwardRef<HTMLInputElement, InputProps>((props, ref) => (
|
export const InputNumber = forwardRef<HTMLInputElement, InputProps>((props, ref) => (
|
||||||
<Input ref={ref} type="number" {...props} />
|
<Input ref={ref} type="number" {...props} />
|
||||||
));
|
));
|
||||||
|
|
||||||
|
export const InputFile = forwardRef<HTMLInputElement, InputProps>((props, ref) => (
|
||||||
|
<input
|
||||||
|
{...props}
|
||||||
|
ref={ref}
|
||||||
|
type="file"
|
||||||
|
className="file:bg-primary-50 file:text-primary-500 hover:file:bg-primary-100 block w-full text-sm
|
||||||
|
text-slate-500 file:mr-4 file:rounded-sm file:border-0
|
||||||
|
file:px-4 file:py-2 file:text-sm
|
||||||
|
file:font-semibold hover:file:cursor-pointer"
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|||||||
113
yarn.lock
113
yarn.lock
@ -574,10 +574,10 @@
|
|||||||
"@jridgewell/resolve-uri" "^3.1.0"
|
"@jridgewell/resolve-uri" "^3.1.0"
|
||||||
"@jridgewell/sourcemap-codec" "^1.4.14"
|
"@jridgewell/sourcemap-codec" "^1.4.14"
|
||||||
|
|
||||||
"@next/env@14.0.1":
|
"@next/env@14.0.3":
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-14.0.1.tgz#7d03c9042c205a320aef2ea3f83c2d16b6825563"
|
resolved "https://registry.yarnpkg.com/@next/env/-/env-14.0.3.tgz#9a58b296e7ae04ffebce8a4e5bd0f87f71de86bd"
|
||||||
integrity sha512-Ms8ZswqY65/YfcjrlcIwMPD7Rg/dVjdLapMcSHG26W6O67EJDF435ShW4H4LXi1xKO1oRc97tLXUpx8jpLe86A==
|
integrity sha512-7xRqh9nMvP5xrW4/+L0jgRRX+HoNRGnfJpD+5Wq6/13j3dsdzxO3BCXn7D3hMqsDb+vjZnJq+vI7+EtgrYZTeA==
|
||||||
|
|
||||||
"@next/eslint-plugin-next@^13.5.4":
|
"@next/eslint-plugin-next@^13.5.4":
|
||||||
version "13.5.6"
|
version "13.5.6"
|
||||||
@ -586,50 +586,50 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
glob "7.1.7"
|
glob "7.1.7"
|
||||||
|
|
||||||
"@next/swc-darwin-arm64@14.0.1":
|
"@next/swc-darwin-arm64@14.0.3":
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.1.tgz#75a5f872c4077ecd536d7496bc24f3d312d5dcd0"
|
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.3.tgz#b1a0440ffbf69056451947c4aea5b6d887e9fbbc"
|
||||||
integrity sha512-JyxnGCS4qT67hdOKQ0CkgFTp+PXub5W1wsGvIq98TNbF3YEIN7iDekYhYsZzc8Ov0pWEsghQt+tANdidITCLaw==
|
integrity sha512-64JbSvi3nbbcEtyitNn2LEDS/hcleAFpHdykpcnrstITFlzFgB/bW0ER5/SJJwUPj+ZPY+z3e+1jAfcczRLVGw==
|
||||||
|
|
||||||
"@next/swc-darwin-x64@14.0.1":
|
"@next/swc-darwin-x64@14.0.3":
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.1.tgz#7d8498fc680cc8b4d5181bee336818c63779bc5e"
|
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.3.tgz#48b527ef7eb5dbdcaf62fd107bc3a78371f36f09"
|
||||||
integrity sha512-625Z7bb5AyIzswF9hvfZWa+HTwFZw+Jn3lOBNZB87lUS0iuCYDHqk3ujuHCkiyPtSC0xFBtYDLcrZ11mF/ap3w==
|
integrity sha512-RkTf+KbAD0SgYdVn1XzqE/+sIxYGB7NLMZRn9I4Z24afrhUpVJx6L8hsRnIwxz3ERE2NFURNliPjJ2QNfnWicQ==
|
||||||
|
|
||||||
"@next/swc-linux-arm64-gnu@14.0.1":
|
"@next/swc-linux-arm64-gnu@14.0.3":
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.1.tgz#184286794e67bed192de7dbb10d7f040c996f965"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.3.tgz#0a36475a38b2855ab8ea0fe8b56899bc90184c0f"
|
||||||
integrity sha512-iVpn3KG3DprFXzVHM09kvb//4CNNXBQ9NB/pTm8LO+vnnnaObnzFdS5KM+w1okwa32xH0g8EvZIhoB3fI3mS1g==
|
integrity sha512-3tBWGgz7M9RKLO6sPWC6c4pAw4geujSwQ7q7Si4d6bo0l6cLs4tmO+lnSwFp1Tm3lxwfMk0SgkJT7EdwYSJvcg==
|
||||||
|
|
||||||
"@next/swc-linux-arm64-musl@14.0.1":
|
"@next/swc-linux-arm64-musl@14.0.3":
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.1.tgz#e8121b860ebc97a8d2a9113e5a42878430e749d5"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.3.tgz#25328a9f55baa09fde6364e7e47ade65c655034f"
|
||||||
integrity sha512-mVsGyMxTLWZXyD5sen6kGOTYVOO67lZjLApIj/JsTEEohDDt1im2nkspzfV5MvhfS7diDw6Rp/xvAQaWZTv1Ww==
|
integrity sha512-v0v8Kb8j8T23jvVUWZeA2D8+izWspeyeDGNaT2/mTHWp7+37fiNfL8bmBWiOmeumXkacM/AB0XOUQvEbncSnHA==
|
||||||
|
|
||||||
"@next/swc-linux-x64-gnu@14.0.1":
|
"@next/swc-linux-x64-gnu@14.0.3":
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.1.tgz#cdc4276b11a10c892fd1cb7dd31e024064db9c3b"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.3.tgz#594b747e3c8896b2da67bba54fcf8a6b5a410e5e"
|
||||||
integrity sha512-wMqf90uDWN001NqCM/auRl3+qVVeKfjJdT9XW+RMIOf+rhUzadmYJu++tp2y+hUbb6GTRhT+VjQzcgg/QTD9NQ==
|
integrity sha512-VM1aE1tJKLBwMGtyBR21yy+STfl0MapMQnNrXkxeyLs0GFv/kZqXS5Jw/TQ3TSUnbv0QPDf/X8sDXuMtSgG6eg==
|
||||||
|
|
||||||
"@next/swc-linux-x64-musl@14.0.1":
|
"@next/swc-linux-x64-musl@14.0.3":
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.1.tgz#4a194a484ceb34fd370e8d1af571493859fb2542"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.3.tgz#a02da58fc6ecad8cf5c5a2a96a7f6030ec7f6215"
|
||||||
integrity sha512-ol1X1e24w4j4QwdeNjfX0f+Nza25n+ymY0T2frTyalVczUmzkVD7QGgPTZMHfR1aLrO69hBs0G3QBYaj22J5GQ==
|
integrity sha512-64EnmKy18MYFL5CzLaSuUn561hbO1Gk16jM/KHznYP3iCIfF9e3yULtHaMy0D8zbHfxset9LTOv6cuYKJgcOxg==
|
||||||
|
|
||||||
"@next/swc-win32-arm64-msvc@14.0.1":
|
"@next/swc-win32-arm64-msvc@14.0.3":
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.1.tgz#71923debee50f98ef166b28cdb3ad7e7463e6598"
|
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.3.tgz#bf2be23d3ba2ebd0d4a9376a31f783efdb677b48"
|
||||||
integrity sha512-WEmTEeWs6yRUEnUlahTgvZteh5RJc4sEjCQIodJlZZ5/VJwVP8p2L7l6VhzQhT4h7KvLx/Ed4UViBdne6zpIsw==
|
integrity sha512-WRDp8QrmsL1bbGtsh5GqQ/KWulmrnMBgbnb+59qNTW1kVi1nG/2ndZLkcbs2GX7NpFLlToLRMWSQXmPzQm4tog==
|
||||||
|
|
||||||
"@next/swc-win32-ia32-msvc@14.0.1":
|
"@next/swc-win32-ia32-msvc@14.0.3":
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.1.tgz#b8f46da899c279fd65db76f0951849290c480ef9"
|
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.3.tgz#839f8de85a4bf2c3c69242483ab87cb916427551"
|
||||||
integrity sha512-oFpHphN4ygAgZUKjzga7SoH2VGbEJXZa/KL8bHCAwCjDWle6R1SpiGOdUdA8EJ9YsG1TYWpzY6FTbUA+iAJeww==
|
integrity sha512-EKffQeqCrj+t6qFFhIFTRoqb2QwX1mU7iTOvMyLbYw3QtqTw9sMwjykyiMlZlrfm2a4fA84+/aeW+PMg1MjuTg==
|
||||||
|
|
||||||
"@next/swc-win32-x64-msvc@14.0.1":
|
"@next/swc-win32-x64-msvc@14.0.3":
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.1.tgz#be3dd8b3729ec51c99ff04b51e2b235756d02b6e"
|
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.3.tgz#27b623612b1d0cea6efe0a0d31aa1a335fc99647"
|
||||||
integrity sha512-FFp3nOJ/5qSpeWT0BZQ+YE1pSMk4IMpkME/1DwKBwhg4mJLB9L+6EXuJi4JEwaJdl5iN+UUlmUD3IsR1kx5fAg==
|
integrity sha512-ERhKPSJ1vQrPiwrs15Pjz/rvDHZmkmvbf/BjPN/UCOI++ODftT0GtasDPi0j+y6PPJi5HsXw+dpRaXUaw4vjuQ==
|
||||||
|
|
||||||
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
|
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
|
||||||
version "5.1.1-v1"
|
version "5.1.1-v1"
|
||||||
@ -4100,12 +4100,12 @@ netmask@^2.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
|
resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
|
||||||
integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
|
integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
|
||||||
|
|
||||||
next@^14.0.1:
|
next@^14.0.3:
|
||||||
version "14.0.1"
|
version "14.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/next/-/next-14.0.1.tgz#1375d94c5dc7af730234af48401be270e975cb22"
|
resolved "https://registry.yarnpkg.com/next/-/next-14.0.3.tgz#8d801a08eaefe5974203d71092fccc463103a03f"
|
||||||
integrity sha512-s4YaLpE4b0gmb3ggtmpmV+wt+lPRuGtANzojMQ2+gmBpgX9w5fTbjsy6dXByBuENsdCX5pukZH/GxdFgO62+pA==
|
integrity sha512-AbYdRNfImBr3XGtvnwOxq8ekVCwbFTv/UJoLwmaX89nk9i051AEY4/HAWzU0YpaTDw8IofUpmuIlvzWF13jxIw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@next/env" "14.0.1"
|
"@next/env" "14.0.3"
|
||||||
"@swc/helpers" "0.5.2"
|
"@swc/helpers" "0.5.2"
|
||||||
busboy "1.6.0"
|
busboy "1.6.0"
|
||||||
caniuse-lite "^1.0.30001406"
|
caniuse-lite "^1.0.30001406"
|
||||||
@ -4113,15 +4113,15 @@ next@^14.0.1:
|
|||||||
styled-jsx "5.1.1"
|
styled-jsx "5.1.1"
|
||||||
watchpack "2.4.0"
|
watchpack "2.4.0"
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@next/swc-darwin-arm64" "14.0.1"
|
"@next/swc-darwin-arm64" "14.0.3"
|
||||||
"@next/swc-darwin-x64" "14.0.1"
|
"@next/swc-darwin-x64" "14.0.3"
|
||||||
"@next/swc-linux-arm64-gnu" "14.0.1"
|
"@next/swc-linux-arm64-gnu" "14.0.3"
|
||||||
"@next/swc-linux-arm64-musl" "14.0.1"
|
"@next/swc-linux-arm64-musl" "14.0.3"
|
||||||
"@next/swc-linux-x64-gnu" "14.0.1"
|
"@next/swc-linux-x64-gnu" "14.0.3"
|
||||||
"@next/swc-linux-x64-musl" "14.0.1"
|
"@next/swc-linux-x64-musl" "14.0.3"
|
||||||
"@next/swc-win32-arm64-msvc" "14.0.1"
|
"@next/swc-win32-arm64-msvc" "14.0.3"
|
||||||
"@next/swc-win32-ia32-msvc" "14.0.1"
|
"@next/swc-win32-ia32-msvc" "14.0.3"
|
||||||
"@next/swc-win32-x64-msvc" "14.0.1"
|
"@next/swc-win32-x64-msvc" "14.0.3"
|
||||||
|
|
||||||
no-case@^2.2.0, no-case@^2.3.2:
|
no-case@^2.2.0, no-case@^2.3.2:
|
||||||
version "2.3.2"
|
version "2.3.2"
|
||||||
@ -4669,6 +4669,11 @@ queue-microtask@^1.2.2:
|
|||||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||||
|
|
||||||
|
radash@^11.0.0:
|
||||||
|
version "11.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/radash/-/radash-11.0.0.tgz#925698e94b554336fc159c253ac33a9a49881835"
|
||||||
|
integrity sha512-CRWxTFTDff0IELGJ/zz58yY4BDgyI14qSM5OLNKbCItJrff7m7dXbVF0kWYVCXQtPb3SXIVhXvAImH6eT7VLSg==
|
||||||
|
|
||||||
rambda@^7.4.0:
|
rambda@^7.4.0:
|
||||||
version "7.5.0"
|
version "7.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/rambda/-/rambda-7.5.0.tgz#1865044c59bc0b16f63026c6e5a97e4b1bbe98fe"
|
resolved "https://registry.yarnpkg.com/rambda/-/rambda-7.5.0.tgz#1865044c59bc0b16f63026c6e5a97e4b1bbe98fe"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user