apps/web: add download file feature

This commit is contained in:
vchikalkin 2023-11-27 15:56:44 +03:00
parent ca521cbc22
commit 0606a999ea
6 changed files with 69 additions and 14 deletions

View File

@ -77,11 +77,20 @@ export async function getDocumentTypes({ pageUrlParams }: Input) {
.then((res) => res);
}
export async function getDocuments({ pageUrlParams }: Input) {
const url = createUrl({ ...pageUrlParams, route: '/documents' });
return api
.get(url)
.res<t.ResponseDocuments>((res) => res.json())
.then((res) => res);
}
export async function uploadDocument({
pageUrlParams,
document,
formData,
}: Input & { document: Pick<t.Document, 'documentTypeId'>; formData: FormData }) {
}: Input & { document: Pick<t.DocumentType, 'documentTypeId'>; formData: FormData }) {
const url = createUrl({
...pageUrlParams,
route: '/document',

View File

@ -11,16 +11,24 @@ export type MetaObject = {
type Value = any;
export type Document = {
export type DocumentType = {
documentTypeId: string;
name: string;
};
export type Document = {
documentId: string;
documentTypeId: string;
href: string;
name: string;
};
export type ResponseGetData = Record<string, Value>;
export type ResponseMetaData = Record<string, MetaObject>;
export type ResponseConfig = { title: string };
export type ResponseConditions = string;
export type ResponseDocumentTypes = Document[];
export type ResponseDocumentTypes = DocumentType[];
export type ResponseDocuments = Document[];
export type HttpError = {
errors: string[];

View File

@ -30,8 +30,9 @@ export default async function Page(pageProps: PageProps) {
apiIUS.getMetaData({ pageUrlParams }),
apiIUS.getConfig({ pageUrlParams }),
apiIUS.getDocumentTypes({ pageUrlParams }),
]).then(([data, metaData, { title }, documentTypes]) => {
const props = { data, documentTypes, metaData, pageUrlParams, title };
apiIUS.getDocuments({ pageUrlParams }),
]).then(([data, metaData, { title }, documentTypes, documents]) => {
const props = { data, documentTypes, documents, metaData, pageUrlParams, title };
return <Form {...props} />;
});

View File

@ -1,10 +1,41 @@
import { FormContext } from './context/form-context';
import type { Props } from './types';
import type { Document } from '@/api/ius/types';
import type * as IUS from '@/api/ius/types';
import { getUrls } from '@/config/urls';
import { ArrowDownTrayIcon } from '@heroicons/react/24/solid';
import Link from 'next/link';
import { useContext } from 'react';
import { Heading, InputFile } from 'ui';
function File({ documentTypeId, name }: Document) {
const { URL_IUS } = getUrls();
type DownloadDocumentProps = Pick<FileProps, 'document'>;
function DownloadDocument({ document }: DownloadDocumentProps) {
return document ? (
<Link
href={URL_IUS + document?.href}
target="_blank"
rel="noopener noreferrer"
className="text-primary-600 h-10 px-5 py-2.5 text-sm font-medium hover:underline"
>
<div className="flex flex-row items-center gap-1">
<ArrowDownTrayIcon className="h-4 w-4" />
Скачать
</div>
</Link>
) : (
false
);
}
type FileProps = {
readonly document: IUS.Document | undefined;
readonly documentType: IUS.DocumentType;
};
function File({ document, documentType }: FileProps) {
const { documentTypeId, name } = documentType;
const { formFiles, setFormFiles } = useContext(FormContext);
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
@ -17,20 +48,25 @@ function File({ documentTypeId, name }: Document) {
};
return (
<div key={documentTypeId} className="flex flex-col">
<div key={documentTypeId} className="flex flex-col gap-1">
<label className="mb-2 block text-sm font-normal text-gray-900">{name}:</label>
<InputFile onChange={handleFileChange} />
<DownloadDocument document={document} />
</div>
);
}
export function Files({ documentTypes }: Props) {
export function Files({ documentTypes, documents }: 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} />
{documentTypes.map((documentType) => (
<File
key={documentType.documentTypeId}
documentType={documentType}
document={documents.find((x) => x.documentTypeId === documentType.documentTypeId)}
/>
))}
</div>
</div>

View File

@ -1,4 +1,4 @@
import type { Document } from '@/api/ius/types';
import type { DocumentType } from '@/api/ius/types';
import type { PageUrlParams } from '@/utils/url';
import type { PropsWithChildren } from 'react';
import { createContext, useMemo, useState } from 'react';
@ -6,7 +6,7 @@ import { createContext, useMemo, useState } from 'react';
type FormStatus = 'pending' | 'edit' | 'success' | 'error';
type FormState = { status: FormStatus; text?: string };
type FormFile = Document & { file: File };
type FormFile = DocumentType & { file: File };
type ContextType = {
readonly formFiles: FormFile[];

View File

@ -3,7 +3,8 @@ import type { PageUrlParams } from '@/utils/url';
export type Props = {
readonly data: IUS.ResponseGetData;
documentTypes: IUS.ResponseDocumentTypes;
readonly documentTypes: IUS.ResponseDocumentTypes;
readonly documents: IUS.ResponseDocuments;
readonly metaData: IUS.ResponseMetaData;
readonly pageUrlParams: PageUrlParams;
readonly title: string;