From 117723df8c831117617d20440178fb256f11feb1 Mon Sep 17 00:00:00 2001 From: Loi Phan Date: Wed, 1 Nov 2023 09:49:30 +0700 Subject: [PATCH] Update component and optimized code --- hotel-management/src/commons/styles/Input.ts | 19 ++++++++- .../src/components/Dialog/index.tsx | 4 +- hotel-management/src/components/Search.tsx | 11 ++--- .../src/components/Table/styled.ts | 1 + hotel-management/src/constants/path.ts | 1 + hotel-management/src/constants/variables.ts | 42 ++++++++++++++++++- hotel-management/src/globals/interfaces.ts | 7 +--- hotel-management/src/globals/types.ts | 17 +++++++- hotel-management/src/helpers/utils.ts | 33 +++++++++++---- hotel-management/src/helpers/validators.ts | 18 +++++--- 10 files changed, 124 insertions(+), 29 deletions(-) diff --git a/hotel-management/src/commons/styles/Input.ts b/hotel-management/src/commons/styles/Input.ts index f1350ab..0826c7e 100644 --- a/hotel-management/src/commons/styles/Input.ts +++ b/hotel-management/src/commons/styles/Input.ts @@ -1,10 +1,25 @@ -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; // Styled import CommonInput from './CommonInput'; -const Input = styled.input` +interface IInputTyped { + type?: 'text' | 'checkbox' | 'hidden'; +} + +const Input = styled.input` ${CommonInput} + + ${(props) => + props.type === 'checkbox' && + css` + width: 20px; + height: 20px; + `} `; +Input.defaultProps = { + type: 'text', +}; + export default Input; diff --git a/hotel-management/src/components/Dialog/index.tsx b/hotel-management/src/components/Dialog/index.tsx index 8e73da6..1bedac9 100644 --- a/hotel-management/src/components/Dialog/index.tsx +++ b/hotel-management/src/components/Dialog/index.tsx @@ -7,7 +7,7 @@ import { IDialogProps } from '../../globals/interfaces'; import { StyledBody, StyledDialog, StyledTitle } from './styled'; const Dialog = forwardRef((props, ref) => { - const { title, children, onClose } = props as IDialogProps; + const { title, children, onClose } = props as IDialogProps; return ( | undefined} @@ -17,6 +17,6 @@ const Dialog = forwardRef((props, ref) => { {children} ); -}) as React.FC; +}) as React.FC>; export default Dialog; diff --git a/hotel-management/src/components/Search.tsx b/hotel-management/src/components/Search.tsx index 71538f5..ddc1585 100644 --- a/hotel-management/src/components/Search.tsx +++ b/hotel-management/src/components/Search.tsx @@ -9,24 +9,25 @@ const StyledSearch = styled.input` `; interface ISearch { - setPhoneSearch: React.Dispatch>; + setPlaceHolder: string; + setValueSearch: React.Dispatch>; } -const Search = ({ setPhoneSearch }: ISearch) => { +const Search = ({ setValueSearch, setPlaceHolder }: ISearch) => { const [query, setQuery] = useState(''); useEffect(() => { const timeOut = setTimeout(() => { - setPhoneSearch(query); + setValueSearch(query); }, 500); return () => clearTimeout(timeOut); - }, [setPhoneSearch, query]); + }, [setValueSearch, query]); return ( setQuery(e.target.value)} - placeholder="Search by phone..." + placeholder={setPlaceHolder} /> ); }; diff --git a/hotel-management/src/components/Table/styled.ts b/hotel-management/src/components/Table/styled.ts index 739542f..5e89ff2 100644 --- a/hotel-management/src/components/Table/styled.ts +++ b/hotel-management/src/components/Table/styled.ts @@ -15,6 +15,7 @@ const CommonRow = styled.div` grid-template-columns: ${(props) => props.columns}; column-gap: 10px; align-items: center; + justify-items: center; `; const StyledBody = styled.div` diff --git a/hotel-management/src/constants/path.ts b/hotel-management/src/constants/path.ts index d4bd6b1..2f54b15 100644 --- a/hotel-management/src/constants/path.ts +++ b/hotel-management/src/constants/path.ts @@ -4,3 +4,4 @@ export const ROOM: string = '/room'; export const OTHER_PATH: string = '*'; export const BASE_URL: string = 'https://hotel-management-api.loiphan.com/'; export const USER_PATH = 'users'; +export const ROOM_PATH = 'rooms'; diff --git a/hotel-management/src/constants/variables.ts b/hotel-management/src/constants/variables.ts index d1fc6b2..1c03d65 100644 --- a/hotel-management/src/constants/variables.ts +++ b/hotel-management/src/constants/variables.ts @@ -34,4 +34,44 @@ const USER_PAGE = { ], }; -export { USER_PAGE }; +// prettier-ignore +const ROOM_PAGE = { + ORDERBY_OPTIONS: [ + { + value: 'asc', + label: 'Ascending', + }, + { + value: 'desc', + label: 'Descending', + }, + ], + SORTBY_OPTIONS: [ + { + value: 'id', + label: 'Sort by id', + }, + { + value: 'name', + label: 'Sort by name', + }, + { + value: 'amount', + label: 'Sort by amount', + }, + { + value: 'price', + label: 'Sort by price', + }, + { + value: 'discount', + label: 'Sort by discount', + }, + { + value: 'status', + label: 'Sort by status', + }, + ], +} + +export { USER_PAGE, ROOM_PAGE }; diff --git a/hotel-management/src/globals/interfaces.ts b/hotel-management/src/globals/interfaces.ts index ef16998..2d0726c 100644 --- a/hotel-management/src/globals/interfaces.ts +++ b/hotel-management/src/globals/interfaces.ts @@ -1,6 +1,3 @@ -// Types -import { TUser } from './types'; - interface IMenusContext { openId?: string; close?: () => void; @@ -23,14 +20,14 @@ interface ITableBody { render?: (value: T) => JSX.Element; } -interface IDialogProps { +interface IDialogProps { title?: string; children?: JSX.Element[] | JSX.Element; onClose?: () => void; reload?: boolean; setReload?: React.Dispatch>; ref?: React.MutableRefObject; - user?: TUser | null; + data?: T | null; isAdd?: boolean; } diff --git a/hotel-management/src/globals/types.ts b/hotel-management/src/globals/types.ts index 8514620..3937295 100644 --- a/hotel-management/src/globals/types.ts +++ b/hotel-management/src/globals/types.ts @@ -7,6 +7,16 @@ type TUser = { roomId: string; }; +type TRoom = { + id: string; + name: string; + amount: string; + price: string; + discount: string; + description: string; + status: boolean; +}; + type TStateSchema = { [key: string]: { value?: string; @@ -15,7 +25,11 @@ type TStateSchema = { }; type TKeyValue = { - [key: string]: string | undefined | boolean; + [key: string]: string | undefined | boolean | number; +}; + +export type Test = { + [key: string]: string; }; type TPropValues = 'value' | 'error' | boolean; @@ -37,6 +51,7 @@ type TResponse = { export type { TUser, + TRoom, TStateSchema, TKeyValue, TPropValues, diff --git a/hotel-management/src/helpers/utils.ts b/hotel-management/src/helpers/utils.ts index 6c3b585..bdba669 100644 --- a/hotel-management/src/helpers/utils.ts +++ b/hotel-management/src/helpers/utils.ts @@ -2,7 +2,7 @@ import { invalidFormatMsg } from '../constants/messages'; // Types -import { TKeyValue, TPropValues, TStateSchema, TUser } from '../globals/types'; +import { TKeyValue, TPropValues, TStateSchema, Test } from '../globals/types'; const VALUE = 'value'; const ERROR = 'error'; @@ -47,18 +47,35 @@ const addValidator = ({ validatorFunc, prop, required = true }: TValidator) => { }; }; -const getValueUser = (user: TUser | null = null, prop: string): string => { - if (user) { - return user[prop as keyof TUser]; +const getValueFromObj = (obj: T | null = null): Test => { + let result = {}; + + if (obj) { + for (const key of Object.keys(obj)) { + const tempValue = obj[key as keyof typeof obj]; + const value: string | boolean | number = + typeof tempValue === 'boolean' || + typeof tempValue === 'string' || + typeof tempValue === 'number' + ? tempValue + : ''; + + result = { ...result, [`${key}Value`]: value }; + } } - return ''; + return result; }; -const searchQuery = (phone: string, sort: string, order: string) => { +const searchQuery = ( + columnSearch: string, + phone: string, + sort: string, + order: string, +) => { // prettier-ignore const phoneParams = phone - ? 'phone_like=' + phone + ? `${columnSearch}_like=` + phone : ''; // prettier-ignore @@ -92,7 +109,7 @@ export { isObject, isRequired, getPropValues, - getValueUser, + getValueFromObj, addValidator, searchQuery, VALUE, diff --git a/hotel-management/src/helpers/validators.ts b/hotel-management/src/helpers/validators.ts index 4157039..a971715 100644 --- a/hotel-management/src/helpers/validators.ts +++ b/hotel-management/src/helpers/validators.ts @@ -1,5 +1,5 @@ -const isValidString = (value: string): boolean => { - return /^[a-zA-Z]{4,}(?: [a-zA-Z]+){0,2}$/gm.test(value); +const isValidName = (value: string): boolean => { + return /^[a-zA-Z]{2,}(?: [a-zA-Z]+){0,2}$/gm.test(value); }; const isValidNumber = (value: string): boolean => { @@ -10,8 +10,16 @@ const isValidPhoneNumber = (value: string): boolean => { return /(84|0[3|5|7|8|9])+([0-9]{8})\b/g.test(value); }; -const isValidAddress = (value: string): boolean => { - return value.trim().length >= 10; +const isValidString = (value: string): boolean => { + return value.trim().length >= 5; }; -export { isValidString, isValidNumber, isValidPhoneNumber, isValidAddress }; +const skipCheck = () => true; + +export { + isValidName, + isValidNumber, + isValidPhoneNumber, + isValidString, + skipCheck, +};