diff --git a/hotel-management/src/App.tsx b/hotel-management/src/App.tsx index cb03a8b..96ae698 100644 --- a/hotel-management/src/App.tsx +++ b/hotel-management/src/App.tsx @@ -18,7 +18,9 @@ import { initialState, reducer, } from '@context/UserRoomAvailableContext'; -import { useEffect, useReducer } from 'react'; +import { useEffect, useMemo, useReducer } from 'react'; + +// Services import { getUserNotBooked } from '@service/userServices'; import { getRoomsAvailable } from '@service/roomServices'; @@ -55,16 +57,21 @@ function App() { load(); }, []); + const store = useMemo(() => { + return { roomsAvailable, usersAvailable, dispatch }; + }, [roomsAvailable, usersAvailable]); + return ( - + }> - } /> + } + /> } /> } /> } /> diff --git a/hotel-management/src/commons/styles/Button.ts b/hotel-management/src/commons/styles/Button.ts index 7305ea0..2324d3a 100644 --- a/hotel-management/src/commons/styles/Button.ts +++ b/hotel-management/src/commons/styles/Button.ts @@ -16,10 +16,10 @@ const variations: IVariations = { background-color: var(--danger-btn-color); color: var(--light-text); `, -}; +} as const; interface IButtonStyle { - variations?: keyof IVariations; + variations?: keyof typeof variations; } const Button = styled.button` diff --git a/hotel-management/src/components/ButtonIcon/index.tsx b/hotel-management/src/components/ButtonIcon/index.tsx index 8375518..dff27b0 100644 --- a/hotel-management/src/components/ButtonIcon/index.tsx +++ b/hotel-management/src/components/ButtonIcon/index.tsx @@ -1,92 +1,5 @@ -import { COLOR, SIZE } from '@constant/styles'; import { ReactNode } from 'react'; -import styled, { css } from 'styled-components'; - -interface IStyledButtonIcon { - isHaveChildren: boolean; - style?: { - fontSize?: string; - backgroundColor?: string; - color?: string; - }; - iconStyle?: { - color?: string; - size?: string; - }; -} - -const StyledButtonIcon = styled.button` - background: none; - - padding: 10px; - transition: all 0.2s; - - border: none; - - ${(props) => - props.style?.fontSize && - css` - font-size: ${props.style.fontSize}; - `} - - ${(props) => - props.style?.fontSize && - css` - font-size: ${props.style.fontSize}; - `} - - ${(props) => - props.color && - css` - font-size: ${props.color}; - `} - - ${(props) => - props.isHaveChildren - ? css` - display: flex; - align-items: center; - gap: 10px; - - text-align: left; - width: 100%; - ` - : css` - border-radius: var(--radius-md); - `} - - &:hover { - background-color: var(--hover-background-color); - } - - & svg { - ${(props) => - props.iconStyle?.size && - css` - width: ${props.iconStyle.size}; - height: ${props.iconStyle.size}; - `} - - ${(props) => - props.iconStyle?.color && - css` - color: ${props.iconStyle.color}; - `} - transition: all 0.3s; - } -`; - -StyledButtonIcon.defaultProps = { - style: { - fontSize: SIZE.DEFAULT, - backgroundColor: COLOR.DEFAULT, - color: COLOR.BLACK, - }, - iconStyle: { - color: COLOR.BLACK, - size: SIZE.DEFAULT, - }, -}; +import { StyledButtonIcon } from './styled'; interface IButtonIcon { icon: ReactNode; diff --git a/hotel-management/src/components/ButtonIcon/styled.ts b/hotel-management/src/components/ButtonIcon/styled.ts index e69de29..26d978d 100644 --- a/hotel-management/src/components/ButtonIcon/styled.ts +++ b/hotel-management/src/components/ButtonIcon/styled.ts @@ -0,0 +1,90 @@ +import styled, { css } from 'styled-components'; +import { COLOR, SIZE } from '@constant/styles'; + +interface IStyledButtonIcon { + isHaveChildren: boolean; + style?: { + fontSize?: string; + backgroundColor?: string; + color?: string; + }; + iconStyle?: { + color?: string; + size?: string; + }; +} + +const StyledButtonIcon = styled.button` + background: none; + + padding: 10px; + transition: all 0.2s; + + border: none; + + ${(props) => + props.style?.fontSize && + css` + font-size: ${props.style.fontSize}; + `} + + ${(props) => + props.style?.fontSize && + css` + font-size: ${props.style.fontSize}; + `} + + ${(props) => + props.color && + css` + font-size: ${props.color}; + `} + + ${(props) => + props.isHaveChildren + ? css` + display: flex; + align-items: center; + gap: 10px; + + text-align: left; + width: 100%; + ` + : css` + border-radius: var(--radius-md); + `} + + &:hover { + background-color: var(--hover-background-color); + } + + & svg { + ${(props) => + props.iconStyle?.size && + css` + width: ${props.iconStyle.size}; + height: ${props.iconStyle.size}; + `} + + ${(props) => + props.iconStyle?.color && + css` + color: ${props.iconStyle.color}; + `} + transition: all 0.3s; + } +`; + +StyledButtonIcon.defaultProps = { + style: { + fontSize: SIZE.DEFAULT, + backgroundColor: COLOR.DEFAULT, + color: COLOR.BLACK, + }, + iconStyle: { + color: COLOR.BLACK, + size: SIZE.DEFAULT, + }, +}; + +export { StyledButtonIcon }; diff --git a/hotel-management/src/components/ConfirmMessage/index.tsx b/hotel-management/src/components/ConfirmMessage/index.tsx index 9659911..ce9b911 100644 --- a/hotel-management/src/components/ConfirmMessage/index.tsx +++ b/hotel-management/src/components/ConfirmMessage/index.tsx @@ -15,7 +15,6 @@ interface IConfirmMessage { const ConfirmMessage = memo( ({ message, disabled, onConfirm, onCloseModal }: IConfirmMessage) => { - return (

{message}

diff --git a/hotel-management/src/components/ConfirmMessage/styled.ts b/hotel-management/src/components/ConfirmMessage/styled.ts index 2336197..47590e1 100644 --- a/hotel-management/src/components/ConfirmMessage/styled.ts +++ b/hotel-management/src/components/ConfirmMessage/styled.ts @@ -1,4 +1,4 @@ -import styled from "styled-components"; +import styled from 'styled-components'; const StyledConfirmDelete = styled.div` width: 450px; diff --git a/hotel-management/src/components/Menus/index.tsx b/hotel-management/src/components/Menus/index.tsx index 58f36b7..5ed7a41 100644 --- a/hotel-management/src/components/Menus/index.tsx +++ b/hotel-management/src/components/Menus/index.tsx @@ -5,6 +5,7 @@ import { HiEllipsisVertical } from 'react-icons/hi2'; // Hooks import { useOutsideClick } from '@hook/useOutsideClick'; +import ButtonIcon from '@component/ButtonIcon'; // Styled import { StyledMenu, StyledList, StyledToggle } from './styled'; @@ -14,7 +15,8 @@ import MenusContext from '@context/MenuContext'; // Types import { Nullable } from '@type/common'; -import ButtonIcon from '@component/ButtonIcon'; + +// Constants import { COLOR } from '@constant/styles'; interface IButton { diff --git a/hotel-management/src/components/Search/index.tsx b/hotel-management/src/components/Search/index.tsx index 887ce30..fcd8bb6 100644 --- a/hotel-management/src/components/Search/index.tsx +++ b/hotel-management/src/components/Search/index.tsx @@ -1,11 +1,13 @@ import { useEffect, useState } from 'react'; +import { useSearchParams } from 'react-router-dom'; // Styled import { StyledSearch } from './styled'; // Hooks import { useDebounce } from '@hook/useDebounce'; -import { useSearchParams } from 'react-router-dom'; + +// Types import { Nullable } from '@type/common'; interface ISearch { diff --git a/hotel-management/src/constants/commons.ts b/hotel-management/src/constants/commons.ts index 5eb0957..9e62af2 100644 --- a/hotel-management/src/constants/commons.ts +++ b/hotel-management/src/constants/commons.ts @@ -43,20 +43,6 @@ const ROOM_PAGE = { ], }; -const INIT_VALUE_USER_FORM = { - name: '', - id: 0, - identifiedCode: '', - phone: '', -}; - -const INIT_VALUE_ROOM_FORM = { - name: '', - id: 0, - price: 0, - discount: 0, -}; - const FORM = { EDIT: 'edit', DELETE: 'delete', @@ -76,6 +62,4 @@ export { FORM, REGEX, ORDERBY_OPTIONS, - INIT_VALUE_USER_FORM, - INIT_VALUE_ROOM_FORM, }; diff --git a/hotel-management/src/constants/path.ts b/hotel-management/src/constants/path.ts index 3070b68..c96883d 100644 --- a/hotel-management/src/constants/path.ts +++ b/hotel-management/src/constants/path.ts @@ -2,5 +2,3 @@ export const DASHBOARD = '/dashboard'; export const USER = '/user'; export const ROOM = '/room'; export const OTHER_PATH = '*'; -export const USER_PATH = 'users'; -export const ROOM_PATH = 'rooms'; diff --git a/hotel-management/src/contexts/UserRoomAvailableContext.ts b/hotel-management/src/contexts/UserRoomAvailableContext.ts index 40d1a9e..17371d3 100644 --- a/hotel-management/src/contexts/UserRoomAvailableContext.ts +++ b/hotel-management/src/contexts/UserRoomAvailableContext.ts @@ -1,6 +1,8 @@ -import { IDataState } from '@type/common'; import { Dispatch, createContext } from 'react'; +// Types +import { IDataState } from '@type/common'; + interface IUserRoomState { usersAvailable: IDataState[]; roomsAvailable: IDataState[]; @@ -36,16 +38,19 @@ const initialState: IUserRoomState = { const reducer = (state: IUserRoomState, action: IAction) => { switch (action.type) { + case 'initRoom': return { ...state, roomsAvailable: action.payload, }; + case 'initUser': return { ...state, usersAvailable: action.payload, }; + case 'addUser': { const tempArr = state.usersAvailable; const itemExist = state.usersAvailable.find( @@ -61,6 +66,7 @@ const reducer = (state: IUserRoomState, action: IAction) => { usersAvailable: tempArr, }; } + case 'updateUserName': { const tempArr = state.usersAvailable; @@ -77,6 +83,7 @@ const reducer = (state: IUserRoomState, action: IAction) => { usersAvailable: tempArr, }; } + case 'removeUser': return { ...state, @@ -84,6 +91,7 @@ const reducer = (state: IUserRoomState, action: IAction) => { (item) => item.id !== action.payload[0].id ), }; + case 'addRoom': { const tempArr = state.roomsAvailable; const itemExist = state.roomsAvailable.find( @@ -99,6 +107,7 @@ const reducer = (state: IUserRoomState, action: IAction) => { roomsAvailable: tempArr, }; } + case 'updateRoomName': { const tempArr = state.roomsAvailable; @@ -115,6 +124,7 @@ const reducer = (state: IUserRoomState, action: IAction) => { roomsAvailable: tempArr, }; } + case 'removeRoom': return { ...state, @@ -122,6 +132,7 @@ const reducer = (state: IUserRoomState, action: IAction) => { (item) => item.id !== action.payload[0].id ), }; + default: throw new Error('Action unknown'); } diff --git a/hotel-management/src/hooks/rooms/useCreateRoom.ts b/hotel-management/src/hooks/rooms/useCreateRoom.ts index 7578bd6..045cd10 100644 --- a/hotel-management/src/hooks/rooms/useCreateRoom.ts +++ b/hotel-management/src/hooks/rooms/useCreateRoom.ts @@ -6,6 +6,8 @@ import { createRoom as createRoomFn } from '@service/roomServices'; // Constants import { ADD_SUCCESS } from '@constant/messages'; + +// Hooks import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; /** diff --git a/hotel-management/src/hooks/rooms/useRooms.ts b/hotel-management/src/hooks/rooms/useRooms.ts index 84518dd..f6ffc75 100644 --- a/hotel-management/src/hooks/rooms/useRooms.ts +++ b/hotel-management/src/hooks/rooms/useRooms.ts @@ -1,9 +1,9 @@ -import toast from "react-hot-toast"; -import { useQuery } from "@tanstack/react-query"; -import { useSearchParams } from "react-router-dom"; +import toast from 'react-hot-toast'; +import { useQuery } from '@tanstack/react-query'; +import { useSearchParams } from 'react-router-dom'; // Services -import { getAllRooms } from "@service/roomServices"; +import { getAllRooms } from '@service/roomServices'; /** * Fetch room from database @@ -13,7 +13,7 @@ const useRooms = () => { const [searchParams] = useSearchParams(); const sortByValue = searchParams.get('sortBy') || 'id'; const orderByValue = searchParams.get('orderBy') || 'asc'; - const phoneSearch = searchParams.get('search') || '' + const phoneSearch = searchParams.get('search') || ''; const { isLoading, diff --git a/hotel-management/src/hooks/rooms/useUpdateRoom.ts b/hotel-management/src/hooks/rooms/useUpdateRoom.ts index 7b1bf15..6b6d6e6 100644 --- a/hotel-management/src/hooks/rooms/useUpdateRoom.ts +++ b/hotel-management/src/hooks/rooms/useUpdateRoom.ts @@ -6,6 +6,8 @@ import { updateRoom as updateRoomFn } from '@service/roomServices'; // Constants import { UPDATE_SUCCESS } from '@constant/messages'; + +// Hooks import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; /** diff --git a/hotel-management/src/hooks/useUserRoomAvailable.ts b/hotel-management/src/hooks/useUserRoomAvailable.ts index 18ae1e3..e362b9d 100644 --- a/hotel-management/src/hooks/useUserRoomAvailable.ts +++ b/hotel-management/src/hooks/useUserRoomAvailable.ts @@ -1,6 +1,8 @@ -import { UserRoomAvailableContext } from '@context/UserRoomAvailableContext'; import { useContext } from 'react'; +// Contexts +import { UserRoomAvailableContext } from '@context/UserRoomAvailableContext'; + const useUserRoomAvailable = () => { const context = useContext(UserRoomAvailableContext); diff --git a/hotel-management/src/hooks/users/useCreateUser.ts b/hotel-management/src/hooks/users/useCreateUser.ts index 7d7c8e3..7f89db0 100644 --- a/hotel-management/src/hooks/users/useCreateUser.ts +++ b/hotel-management/src/hooks/users/useCreateUser.ts @@ -6,6 +6,8 @@ import { createUser as createUserFn } from '@service/userServices'; // Constants import { ADD_SUCCESS } from '@constant/messages'; + +// Hooks import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; /** diff --git a/hotel-management/src/hooks/users/useUpdateUser.ts b/hotel-management/src/hooks/users/useUpdateUser.ts index 6603c8d..3c4a029 100644 --- a/hotel-management/src/hooks/users/useUpdateUser.ts +++ b/hotel-management/src/hooks/users/useUpdateUser.ts @@ -6,6 +6,8 @@ import { updateUser as updateUserFn } from '@service/userServices'; // Messages import { UPDATE_SUCCESS } from '@constant/messages'; + +// Hooks import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; /** diff --git a/hotel-management/src/hooks/users/useUsers.ts b/hotel-management/src/hooks/users/useUsers.ts index 5fc1e4a..876aa99 100644 --- a/hotel-management/src/hooks/users/useUsers.ts +++ b/hotel-management/src/hooks/users/useUsers.ts @@ -1,9 +1,9 @@ -import toast from "react-hot-toast"; -import { useQuery } from "@tanstack/react-query"; -import { useSearchParams } from "react-router-dom"; +import toast from 'react-hot-toast'; +import { useQuery } from '@tanstack/react-query'; +import { useSearchParams } from 'react-router-dom'; // Services -import { getAllUsers } from "@service/userServices"; +import { getAllUsers } from '@service/userServices'; /** * Fetch data of users from database @@ -13,7 +13,7 @@ const useUsers = () => { const [searchParams] = useSearchParams(); const sortByValue = searchParams.get('sortBy') || 'id'; const orderByValue = searchParams.get('orderBy') || 'asc'; - const phoneSearch = searchParams.get('search') || '' + const phoneSearch = searchParams.get('search') || ''; const { isLoading, diff --git a/hotel-management/src/pages/Dashboard.tsx b/hotel-management/src/pages/Dashboard.tsx index 94d877b..592fd32 100644 --- a/hotel-management/src/pages/Dashboard.tsx +++ b/hotel-management/src/pages/Dashboard.tsx @@ -1,6 +1,8 @@ -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; import styled from 'styled-components'; +// Hooks +import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; + const StyledDashboard = styled.main` padding: 20px; `; diff --git a/hotel-management/src/services/roomServices.ts b/hotel-management/src/services/roomServices.ts index fa96d94..ed0a843 100644 --- a/hotel-management/src/services/roomServices.ts +++ b/hotel-management/src/services/roomServices.ts @@ -1,9 +1,9 @@ // Types import { IRoom } from '@type/rooms'; +import { IDataState } from '@type/common'; // Services import supabase from './supabaseService'; -import { IDataState } from '@type/common'; // Constants const ROOMS_TABLE = 'rooms'; @@ -25,7 +25,7 @@ const getAllRooms = async ( .from(ROOMS_TABLE) .select('*') .order(sortBy, { ascending: orderBy === 'asc' }) - .like('name', `%${roomName}%`); + .ilike('name', `%${roomName}%`); if (error) { console.error(error.message); diff --git a/hotel-management/src/services/supabaseService.ts b/hotel-management/src/services/supabaseService.ts index bfdcbea..27b485a 100644 --- a/hotel-management/src/services/supabaseService.ts +++ b/hotel-management/src/services/supabaseService.ts @@ -1,8 +1,10 @@ -import { createClient } from "@supabase/supabase-js"; -import { Database } from "@type/supabase"; +import { createClient } from '@supabase/supabase-js'; + +// Types +import { Database } from '@type/supabase'; // Constants -import { supabaseKey, supabaseUrl } from "@constant/config"; +import { supabaseKey, supabaseUrl } from '@constant/config'; const supabase = createClient(supabaseUrl, supabaseKey!); diff --git a/hotel-management/src/services/userServices.ts b/hotel-management/src/services/userServices.ts index 6578517..62d2fc9 100644 --- a/hotel-management/src/services/userServices.ts +++ b/hotel-management/src/services/userServices.ts @@ -1,9 +1,9 @@ // Types import { IUser } from '@type/users'; +import { IDataState } from '@type/common'; // Services import supabase from './supabaseService'; -import { IDataState } from '@type/common'; const USERS_TABLE = 'users'; const ERROR_FETCHING = "Users can't be loaded!"; @@ -65,7 +65,7 @@ const getAllUsers = async ( .from(USERS_TABLE) .select('*') .order(sortBy, { ascending: orderBy === 'asc' }) - .like('phone', `%${phoneSearch}%`); + .ilike('phone', `%${phoneSearch}%`); if (error) { console.error(error.message);