/* eslint-disable camelcase */ /* eslint-disable no-shadow */ /* ts-ignore */ import randomColor from "randomcolor"; import { useState, useEffect, useRef, ChangeEvent } from "react"; import Axios from "axios"; import { IselectedOption } from "../atoms/forms/selectBox/SelectBox"; import moment from "moment"; import { TLanguageShort } from "../types/enum"; // @ts-ignore import Resizer from "react-image-file-resizer"; // 한방에 패치 // A X I O S : (http://codeheaven.io/how-to-use-axios-as-your-http-client/) export type IUseFetch = [ any, boolean, boolean, (url: string | undefined) => void ]; const useShouldSave = (updateValue: any[]) => { const isInitialMount = useRef(true); const [shouldSave, setShouldSave] = useState(false); useEffect(() => { if (isInitialMount.current) { isInitialMount.current = false; } else { setShouldSave(true); // Your useEffect code here to be run on update } }, updateValue); return { shouldSave, setShouldSave }; }; const useFetch = (url: string | undefined = ""): IUseFetch => { const [data, setData] = useState([]); const [inUrl, setInUrl] = useState(url); const [isLoading, setIsLoading] = useState(false); const [isError, setIsError] = useState(false); const fetchData = async () => { setIsError(false); try { const result = await Axios(inUrl); setData(result.data); } catch (error) { setIsError(true); } finally { setIsLoading(false); } }; useEffect(() => { fetchData(); }, [inUrl]); // 내부에 STATE URL을 바꾸어서 다시동작 const doGet = (url: string | undefined) => { setIsLoading(true); url && setInUrl(url); }; return [data, isLoading, isError, doGet]; }; // 디바운스 정 function useDebounce(value: any, delay: number) { // State and setters for debounced value const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(handler); }; }, [value]); return debouncedValue; } export interface TUseInput { value: T; onChangeValid: (value: boolean | string) => void; onChange: (foo: T) => void; isValid: any; } export type TUseRedirect = [boolean, string, (url: string) => void]; function useRedirect( inFlag: boolean = false, inUrl: string = "" ): TUseRedirect { const [flag, setFlag] = useState(inFlag); const [url, inSetRedirect] = useState(inUrl); const setRedirect = (redirectUrl: string) => { inSetRedirect(redirectUrl); setFlag(true); }; return [flag, url, setRedirect]; } // 밸리데이션을 포함한 훅 리턴 function useInput( defaultValue: T, defulatValid: boolean | string = "" ): TUseInput { const [value, setValue] = useState(defaultValue); const [isValid, setIsValid] = useState(defulatValid); const onChange = (value: T) => { setValue(value); }; const onChangeValid = (value: boolean | string) => { setIsValid(value); }; return { value, onChange, isValid, onChangeValid }; } // 체크박스yar function useCheckBox(defaultValue: boolean) { const [checked, setChecked] = useState(defaultValue); const onChange = (value: boolean) => { setChecked(value); }; return { checked, onChange }; } // 데이트 픽커 export interface IUseDayPicker { from: Date | null; setFrom: React.Dispatch>; to: Date | null; setTo: React.Dispatch>; entered: Date | null; setEntered: React.Dispatch>; setDate: (date: Date) => void; } function useDayPicker( defaultFrom: Date | null | string, defaultTo: Date | null | string ): IUseDayPicker { let fromTemp: Date | null | string = defaultFrom; let toTemp: Date | null | string = defaultTo; if (typeof defaultFrom === "string") fromTemp = moment(defaultFrom).toDate(); if (typeof defaultTo === "string") toTemp = moment(defaultTo).toDate(); if (typeof fromTemp === "string") throw Error; if (typeof toTemp === "string") throw Error; const [from, setFrom] = useState(fromTemp); const [entered, setEntered] = useState(toTemp); const [to, setTo]: any = useState(toTemp); const setDate = (date: Date) => { setFrom(date); setEntered(date); setTo(date); }; return { from, to, entered, setFrom, setTo, setEntered, setDate }; } // 색상 필커 export interface IUseColor { color: string; setColor: (inInfo: string) => void; setDisplay: (inInfo: boolean) => void; display: boolean; } // NAME SPACE function useColorPicker(defaultValue: string | null): IUseColor { let defaultColor: string = ""; if (!defaultValue) { const temp: any = randomColor(); if (temp instanceof Array) { defaultColor = temp[0]; } } else { defaultColor = defaultValue; } const [color, inSetColor] = useState(defaultColor); const [display, inSetDisplay] = useState(false); const setColor = (value: string) => { inSetColor(value); }; const setDisplay = (value: boolean) => { inSetDisplay(value); }; return { color, setColor, setDisplay, display }; } // 라디오 훅 function useRadio(defaultValue: any = "") { const [value, setValue] = useState(defaultValue); const onChange = (value: any) => { setValue(value); }; return [value, onChange]; } // 스위치 훅 function useSwitch(defaultValue: boolean) { const [checked, setChecked] = useState(defaultValue); const onChange = (value: boolean) => { setChecked(value); }; return { checked, onChange }; } function useDrawer(defaultValue: boolean) { const [open, setOpen] = useState(defaultValue); const onClick = (e: any) => { setOpen(!open); }; return { open, onClick }; } // useRange function useRange(defaultValue: number) { const [value, setValue] = useState(defaultValue); const onChange = (value: any) => { setValue(value); }; return { value, onChange }; } export interface IUseSelect { selectedOption: IselectedOption | null; onChange(foo: IselectedOption): void; } export interface IUseDrawer { onClick: (e: any) => void; open: boolean; } // 셀렉트박스 훅 function useSelect( defaultValue: IselectedOption | null ): IUseSelect { const [selectedOption, setSelectedOption] = useState(defaultValue); const onChange = (value: IselectedOption) => { setSelectedOption(value); }; return { selectedOption, onChange }; } // 투글 훅 function useToggle(defaultValue: boolean): [boolean, any] { const [toggle, setToggle] = useState(defaultValue); const onClick = () => { setToggle(!toggle); }; return [toggle, onClick]; } // 사이드 네비 function useSideNav(): [boolean, any] { let defaultValue = true; const navRecord = localStorage.getItem("JDsideOpen"); defaultValue = navRecord === "Y"; const [isOpen, setOpen] = useState(defaultValue); const onClick = () => { localStorage.setItem("JDsideOpen", isOpen ? "N" : "Y"); setOpen(!isOpen); }; return [isOpen, onClick]; } // 투글 훅 function usePagiNation(defaultValue: number): [number, (page: number) => void] { const [page, inSetPage] = useState(defaultValue); const setPage = (foo: number) => { inSetPage(foo); }; return [page, setPage]; } export interface IUseModal { isOpen: boolean; openModal: (inInfo?: T) => void; closeModal: () => void; info: T; } interface IModalBtn { msg: string; callBackKey: string; } interface IOpenModalInfo { [key: string]: any; trueBtns?: IModalBtn; falseBtns?: IModalBtn; txt?: string; children?: any; callBack?(flag: boolean, callBackKey?: string): void; } // 모달훅 function useModal( defaultValue: boolean = false, defaultInfo: any = {} ): IUseModal { const [isOpen, setIsOpen] = useState(defaultValue); const [info, setInfo] = useState(defaultInfo); const openModal = (inInfo?: any) => { setIsOpen(true); setInfo(inInfo); }; const closeModal = () => { setIsOpen(false); }; return { isOpen, openModal, closeModal, info }; } export let CURRENT_LANG: TLanguageShort = "kr"; // 언어가 결합된 LANG 함수 export let LANG: (key: string, key2?: string) => any = key => { return; }; // 해당 언어를 찾음 export const JDlang = ( lang: TLanguageShort, langSet: any, key: string, key2?: string ) => { // @ts-ignore if (!langSet[lang]) return ""; // @ts-ignore if (!langSet[lang][key]) return ""; // @ts-ignore if (key2) { // @ts-ignore if (!langSet[lang][key][key2]) return; // @ts-ignore return langSet[lang][key][key2]; } // @ts-ignore return langSet[lang][key]; }; const useLang = (defaultLang: TLanguageShort, langSet: any) => { const [currentLang, setCurrentLang] = useState(defaultLang); const changeLang = (lang: TLanguageShort) => { CURRENT_LANG = lang; setCurrentLang(lang); }; // 언어와 셋을 결합한 함수로 셋팅함 LANG = JDlang.bind(JDlang, currentLang, langSet); return { currentLang, changeLang }; }; // 이미지업로더 export interface IuseImageUploaderOP { file?: any | null; uploading?: boolean; onChangeFile?(event: React.ChangeEvent): void; } export interface IuseImageUploader { file?: any | null; uploading: boolean; isError: boolean; onChangeFile(event: React.ChangeEvent): void; setFile: React.Dispatch; option?: IuseImageUploaderOption; } export interface IuseImageUploaderOption { resizeMaxWidth?: number; resizeMaxHeight?: number; quality?: number; } export type IUploadImg = (uriOrFile: any, fileName?: string, fileType?: string) => Promise // 이미지 업로더 const useImageUploader = ( uploadImg: IUploadImg, defaultFile?: any | null, propOption?: IuseImageUploaderOption, ): IuseImageUploader => { if (defaultFile && defaultFile.tags) { defaultFile.tags.forEach((tag: any) => { delete tag.__typename; }); delete defaultFile.__typename; } const [file, setFile] = useState(defaultFile); const [uploading, setUploading] = useState(false); const [isError, setIsError] = useState(false); const DEFAULT_IMAGEUP_LOADER_OPTION: IuseImageUploaderOption = { quality: 100, resizeMaxHeight: 500, resizeMaxWidth: 500 }; let option = propOption || DEFAULT_IMAGEUP_LOADER_OPTION; const onChangeFile = async ( event: React.ChangeEvent ) => { event.persist(); if (event) { setUploading(true); const { target: { name, value, files, validity } }: ChangeEvent = event as ChangeEvent; if (validity && files && files.length === 1) { const file = files[0]; if (file) { // 이미지인경우 리사이즈 해서 업로드 if (!file.type.includes("video")) { Resizer.imageFileResizer( file, option.resizeMaxWidth, option.resizeMaxHeight, "JPEG", option.quality, 0, async (uri: any) => { uploadImg(uri, file.name, file.type); }, "blob" ); } else { // 비디오인경우 try { uploadImg(file); setFile(file); } catch { setIsError(true); } finally { setUploading(false); } } } } } }; return { file, uploading, isError, onChangeFile, setFile, option: propOption }; }; export default { useInput, useCheckBox, useRadio, useSwitch, useSelect, useToggle, useFetch, useModal, useSideNav, useRange, useDebounce, useDrawer, useLang, useShouldSave, useColorPicker, useDayPicker, usePagiNation, useRedirect }; export { useInput, useCheckBox, useRadio, useSwitch, useSelect, useToggle, useFetch, useModal, useSideNav, useRange, useDebounce, useDrawer, useLang, useShouldSave, useColorPicker, useDayPicker, usePagiNation, useRedirect };