Initial commit
This commit is contained in:
commit
fa30c04815
117 changed files with 33513 additions and 0 deletions
19
src/common/const.ts
Normal file
19
src/common/const.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
export const DEFAULT_API_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
|
||||
|
||||
export const DEFAULT_API_DATE_FORMAT = 'yyyy-MM-dd';
|
||||
|
||||
export const DEFAULT_DATE_FORMAT = 'dd/MM/yyyy HH:mm';
|
||||
|
||||
export const MAX_TABLE_ROWS = 15;
|
||||
|
||||
export const VALIDATION_MESSAGES = {
|
||||
required: (name: string) => `${name} cannot be blank`,
|
||||
invalidEmail: () => 'Email address is invalid',
|
||||
passwordConfirmation: () => 'Passwords do not match',
|
||||
min: (name: string, min: number) => `${name} must be at least ${min}`,
|
||||
};
|
||||
|
||||
export const BACK_TO_PAGE = 'prevPage';
|
||||
export const BACK_TO_SEARCH = 'prevSearch';
|
||||
export const RETURN_TO = 'returnTo';
|
||||
export const RICH_EDITOR_DEFAULT_TAB = 'richEditorTab';
|
||||
1
src/common/index.ts
Normal file
1
src/common/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export { isTouched, addParamsToLink } from './util';
|
||||
39
src/common/types.ts
Normal file
39
src/common/types.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
export interface ImageApiData {
|
||||
data: {
|
||||
id: number;
|
||||
fileId: number;
|
||||
name: string;
|
||||
isMain: boolean;
|
||||
url: string;
|
||||
smallUrl: string;
|
||||
mediumUrl: string;
|
||||
originalFileId: number;
|
||||
mediumFileId: number;
|
||||
smallFileId: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ImageMediaData {
|
||||
id: number;
|
||||
fileId: number;
|
||||
name: string;
|
||||
isMain: boolean;
|
||||
url: string;
|
||||
smallUrl: string;
|
||||
mediumUrl: string;
|
||||
originalFileId: number;
|
||||
mediumFileId: number;
|
||||
smallFileId: number;
|
||||
smallFile?: {
|
||||
id: number;
|
||||
name: string;
|
||||
url: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type ImageUploaderValue = File | string | ImageMediaData;
|
||||
|
||||
export type Breadcrumb = {
|
||||
label: string;
|
||||
href: string;
|
||||
};
|
||||
17
src/common/util/add-params-to-link.ts
Normal file
17
src/common/util/add-params-to-link.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import urlcat from 'urlcat';
|
||||
import { BACK_TO_PAGE, BACK_TO_SEARCH, RETURN_TO, RICH_EDITOR_DEFAULT_TAB } from '../const';
|
||||
|
||||
type UrlParams = {
|
||||
currentPage?: number;
|
||||
prevSearch?: string;
|
||||
returnTo?: [string, number | string];
|
||||
richEditorTab?: string;
|
||||
};
|
||||
export function addParamsToLink(url: string, params: UrlParams) {
|
||||
return urlcat(url, {
|
||||
[BACK_TO_PAGE]: params.currentPage,
|
||||
[BACK_TO_SEARCH]: params.prevSearch,
|
||||
[RETURN_TO]: params.returnTo?.join(':'),
|
||||
[RICH_EDITOR_DEFAULT_TAB]: params.richEditorTab,
|
||||
});
|
||||
}
|
||||
2
src/common/util/index.ts
Normal file
2
src/common/util/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export { isTouched } from './is-touched';
|
||||
export { addParamsToLink } from './add-params-to-link';
|
||||
6
src/common/util/is-touched.ts
Normal file
6
src/common/util/is-touched.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { get } from 'lodash';
|
||||
import { FormState } from 'react-hook-form';
|
||||
|
||||
export function isTouched<T>(formState: FormState<T>, fieldName: keyof T | string) {
|
||||
return formState.isSubmitted || get(formState.touchedFields, fieldName);
|
||||
}
|
||||
92
src/common/util/show-toast.tsx
Normal file
92
src/common/util/show-toast.tsx
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { Transition } from '@headlessui/react';
|
||||
import { XCircleIcon, CheckCircleIcon } from '@heroicons/react/outline';
|
||||
import { XIcon } from '@heroicons/react/solid';
|
||||
|
||||
export enum ToastType {
|
||||
Success = 'success',
|
||||
Error = 'error',
|
||||
}
|
||||
|
||||
export const showToast = (text: string, type?: ToastType) => {
|
||||
switch (type) {
|
||||
case ToastType.Error:
|
||||
toast.custom(
|
||||
(t) => (
|
||||
<Transition
|
||||
show={t.visible}
|
||||
as={Fragment}
|
||||
enter="transform ease-out duration-300 transition"
|
||||
enterFrom="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
|
||||
enterTo="translate-y-0 opacity-100 sm:translate-x-0"
|
||||
leave="transition ease-in duration-100"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="max-w-sm w-full bg-white shadow-lg rounded-lg pointer-events-auto ring-1 ring-black ring-opacity-5 overflow-hidden">
|
||||
<div className="p-4">
|
||||
<div className="flex items-start">
|
||||
<div className="flex-shrink-0">
|
||||
<XCircleIcon className="h-6 w-6 text-red-400" aria-hidden="true" />
|
||||
</div>
|
||||
<div className="ml-3 w-0 flex-1 pt-0.5">
|
||||
<p className="text-sm font-medium text-gray-900">{text}</p>
|
||||
</div>
|
||||
<div className="ml-4 flex-shrink-0 flex">
|
||||
<button
|
||||
className="bg-white rounded-md inline-flex text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||
onClick={() => toast.dismiss(t.id)}
|
||||
>
|
||||
<span className="sr-only">Close</span>
|
||||
<XIcon className="h-5 w-5" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
),
|
||||
{ position: 'top-right' },
|
||||
);
|
||||
break;
|
||||
default:
|
||||
toast.custom(
|
||||
(t) => (
|
||||
<Transition
|
||||
show={t.visible}
|
||||
as={Fragment}
|
||||
enter="transform ease-out duration-300 transition"
|
||||
enterFrom="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
|
||||
enterTo="translate-y-0 opacity-100 sm:translate-x-0"
|
||||
leave="transition ease-in duration-100"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="max-w-sm w-full bg-white shadow-lg rounded-lg pointer-events-auto ring-1 ring-black ring-opacity-5 overflow-hidden">
|
||||
<div className="p-4">
|
||||
<div className="flex items-start">
|
||||
<div className="flex-shrink-0">
|
||||
<CheckCircleIcon className="h-6 w-6 text-primary" aria-hidden="true" />
|
||||
</div>
|
||||
<div className="ml-3 w-0 flex-1 pt-0.5">
|
||||
<p className="text-sm font-medium text-gray-900">{text}</p>
|
||||
</div>
|
||||
<div className="ml-4 flex-shrink-0 flex">
|
||||
<button
|
||||
className="bg-white rounded-md inline-flex text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||
onClick={() => toast.dismiss(t.id)}
|
||||
>
|
||||
<span className="sr-only">Close</span>
|
||||
<XIcon className="h-5 w-5" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
),
|
||||
{ position: 'top-right' },
|
||||
);
|
||||
}
|
||||
};
|
||||
Reference in a new issue