diff --git a/hotel-management/jest-setup.ts b/hotel-management/jest-setup.ts new file mode 100644 index 0000000..c44951a --- /dev/null +++ b/hotel-management/jest-setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom' diff --git a/hotel-management/jest.config.ts b/hotel-management/jest.config.ts index 24064df..c621d0e 100644 --- a/hotel-management/jest.config.ts +++ b/hotel-management/jest.config.ts @@ -1,25 +1,18 @@ import type { Config } from 'jest'; const config: Config = { + preset: 'ts-jest', verbose: true, testEnvironment: 'jsdom', transform: { '^.+\\.tsx?$': 'ts-jest', + '.+\\.(svg|css|styl|less|sass|scss|png|jpg|ttf|woff|gif)$': + 'jest-transform-stub', }, moduleNameMapper: { - '\\.(gif|ttf|eot|svg|png)$': '/test/__mocks__/fileMock.ts', - '\\.(css|less|sass|scss)$': 'identity-obj-proxy', - '@service/(.*)': ['/src/services/$1'], - '@constant/(.*)': ['/src/constants/$1'], - '@hook/(.*)': ['/src/hooks/$1'], - '@helper/(.*)': ['/src/helpers/$1'], - '@context/(.*)': ['/src/contexts/$1'], - '@component/(.*)': ['/src/components/$1'], - '@commonStyle/(.*)': ['/src/commons/styles/$1'], - '@type/(.*)': ['/src/types/$1'], - '@page/(.*)': ['/src/pages/$1'], + '@src/(.*)': ['/src/$1'], }, - setupFilesAfterEnv: ['/jest.setup.ts'], + setupFilesAfterEnv: ['/jest-setup.ts'], setupFiles: ['/.jest/setEnvVar.ts'], testEnvironmentOptions: { customExportConditions: [''], diff --git a/hotel-management/jest.setup.ts b/hotel-management/jest.setup.ts deleted file mode 100644 index d0de870..0000000 --- a/hotel-management/jest.setup.ts +++ /dev/null @@ -1 +0,0 @@ -import "@testing-library/jest-dom"; diff --git a/hotel-management/package.json b/hotel-management/package.json index 9c8d398..a8092fb 100644 --- a/hotel-management/package.json +++ b/hotel-management/package.json @@ -28,6 +28,7 @@ "styled-components": "^6.1.0" }, "devDependencies": { + "@babel/preset-typescript": "^7.23.3", "@testing-library/jest-dom": "^6.1.4", "@testing-library/react": "^14.1.0", "@testing-library/user-event": "^14.5.1", @@ -45,6 +46,7 @@ "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", + "jest-transform-stub": "^2.0.0", "ts-jest": "^29.1.1", "ts-node": "^10.9.1", "typescript": "^5.0.2", diff --git a/hotel-management/pnpm-lock.yaml b/hotel-management/pnpm-lock.yaml index 72ff2fd..742fe4c 100644 --- a/hotel-management/pnpm-lock.yaml +++ b/hotel-management/pnpm-lock.yaml @@ -40,6 +40,9 @@ dependencies: version: 6.1.0(react-dom@18.2.0)(react@18.2.0) devDependencies: + '@babel/preset-typescript': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.2) '@testing-library/jest-dom': specifier: ^6.1.4 version: 6.1.4(@types/jest@29.5.8)(jest@29.7.0) @@ -91,6 +94,9 @@ devDependencies: jest-environment-jsdom: specifier: ^29.7.0 version: 29.7.0 + jest-transform-stub: + specifier: ^2.0.0 + version: 2.0.0 ts-jest: specifier: ^29.1.1 version: 29.1.1(@babel/core@7.23.2)(jest@29.7.0)(typescript@5.2.2) @@ -175,6 +181,13 @@ packages: jsesc: 2.5.2 dev: true + /@babel/helper-annotate-as-pure@7.22.5: + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + /@babel/helper-compilation-targets@7.22.15: resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} engines: {node: '>=6.9.0'} @@ -186,6 +199,24 @@ packages: semver: 6.3.1 dev: true + /@babel/helper-create-class-features-plugin@7.23.5(@babel/core@7.23.2): + resolution: {integrity: sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 + dev: true + /@babel/helper-environment-visitor@7.22.20: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} @@ -206,6 +237,13 @@ packages: '@babel/types': 7.23.0 dev: true + /@babel/helper-member-expression-to-functions@7.23.0: + resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} @@ -227,11 +265,44 @@ packages: '@babel/helper-validator-identifier': 7.22.20 dev: true + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.2): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/helper-optimise-call-expression@7.22.5: + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + /@babel/helper-plugin-utils@7.22.5: resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} engines: {node: '>=6.9.0'} dev: true + /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.2): + resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + dev: true + /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} @@ -239,6 +310,13 @@ packages: '@babel/types': 7.23.0 dev: true + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: + resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} @@ -418,6 +496,18 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true + /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.2): + resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + dev: true + /@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==} engines: {node: '>=6.9.0'} @@ -438,6 +528,33 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true + /@babel/plugin-transform-typescript@7.23.5(@babel/core@7.23.2): + resolution: {integrity: sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.2) + dev: true + + /@babel/preset-typescript@7.23.3(@babel/core@7.23.2): + resolution: {integrity: sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.22.15 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.2) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.2) + '@babel/plugin-transform-typescript': 7.23.5(@babel/core@7.23.2) + dev: true + /@babel/runtime@7.23.2: resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} engines: {node: '>=6.9.0'} @@ -3383,6 +3500,10 @@ packages: - supports-color dev: true + /jest-transform-stub@2.0.0: + resolution: {integrity: sha512-lspHaCRx/mBbnm3h4uMMS3R5aZzMwyNpNIJLXj4cEsV0mIUtS4IjYJLSoyjRCtnxb6RIGJ4NL2quZzfIeNhbkg==} + dev: true + /jest-util@29.7.0: resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} diff --git a/hotel-management/src/App.test.tsx b/hotel-management/src/App.test.tsx index 761b4f7..3879495 100644 --- a/hotel-management/src/App.test.tsx +++ b/hotel-management/src/App.test.tsx @@ -1,14 +1,14 @@ import { render, act, RenderResult } from '@testing-library/react'; // Services -import * as userServices from '@service/userServices'; -import * as roomServices from '@service/roomServices'; +import * as userServices from '@src/services/userServices'; +import * as roomServices from '@src/services/roomServices'; // Components import App from './App'; -jest.mock('@service/userServices'); -jest.mock('@service/roomServices'); +jest.mock('@src/services/userServices'); +jest.mock('@src/services/roomServices'); describe('App', () => { let wrapper: RenderResult | null = null; diff --git a/hotel-management/src/App.tsx b/hotel-management/src/App.tsx index 534dbb3..b837bdc 100644 --- a/hotel-management/src/App.tsx +++ b/hotel-management/src/App.tsx @@ -2,106 +2,51 @@ import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'; import isPropValid from '@emotion/is-prop-valid'; import { StyleSheetManager } from 'styled-components'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { useEffect, useMemo, useReducer } from 'react'; // Components import AppLayout from './components/AppLayout'; import Toast from './components/Toast'; -import RouteProtected from '@component/RouteProtected'; -import RootLayout from '@component/RootLayout'; +import RouteProtected from '@src/components/RouteProtected'; +import RootLayout from '@src/components/RootLayout'; // Pages import User from './pages/User'; import Booking from './pages/Booking'; import Room from './pages/Room'; import NotFound from './pages/NotFound'; -import Login from '@page/Login'; -import Account from '@page/Account'; +import Login from '@src/pages/Login'; +import Account from '@src/pages/Account'; // Constants import * as PATH from './constants/path'; -// Hooks -import { - UserRoomAvailableContext, - initialState, - reducer, -} from '@context/UserRoomAvailableContext'; - -// Services -import { getAllUsers } from '@service/userServices'; -import { getAllRooms } from '@service/roomServices'; - const queryClient = new QueryClient(); function App() { - const [{ usersAvailable, roomsAvailable }, dispatch] = useReducer( - reducer, - initialState - ); - - // Init list user and room available - useEffect(() => { - const load = async () => { - const tempUser = await getAllUsers({ - sortBy: 'id', - orderBy: 'asc', - phoneSearch: '', - page: 0, - }); - - if (tempUser) { - dispatch({ type: 'initUser', payload: tempUser.data }); - } - - const tempRoom = await getAllRooms({ - sortBy: 'id', - orderBy: 'asc', - roomSearch: '', - page: 0, - }); - - if (tempRoom) { - dispatch({ type: 'initRoom', payload: tempRoom.data }); - } - }; - - load(); - }, []); - - const store = useMemo(() => { - return { roomsAvailable, usersAvailable, dispatch }; - }, [roomsAvailable, usersAvailable]); - return ( - - - - }> - - - - } - > - } - /> - } /> - } /> - } /> - } /> - - } /> - } /> + + + }> + + + + } + > + } /> + } /> + } /> + } /> + } /> - - - + } /> + } /> + + + diff --git a/hotel-management/src/commons/styles/Direction.ts b/hotel-management/src/commons/styles/Direction.ts index 60a3944..d671927 100644 --- a/hotel-management/src/commons/styles/Direction.ts +++ b/hotel-management/src/commons/styles/Direction.ts @@ -1,7 +1,7 @@ import styled, { css } from 'styled-components'; // Types -import { TDirection } from '@type/common'; +import { TDirection } from '@src/types/common'; interface IDirection { type?: TDirection; diff --git a/hotel-management/src/commons/styles/Spinner.ts b/hotel-management/src/commons/styles/Spinner.ts index 38f3f49..ebe349b 100644 --- a/hotel-management/src/commons/styles/Spinner.ts +++ b/hotel-management/src/commons/styles/Spinner.ts @@ -16,7 +16,6 @@ const Spinner = styled.div` top/10px 10px no-repeat, conic-gradient(#0000 30%, var(--primary-color)); -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 10px), #000 0); - mask: none; animation: ${rotate} 1.5s infinite linear; `; diff --git a/hotel-management/src/components/AppLayout/__snapshots__/AppLayout.test.tsx.snap b/hotel-management/src/components/AppLayout/__snapshots__/AppLayout.test.tsx.snap index 45eb3ab..06f0d09 100644 --- a/hotel-management/src/components/AppLayout/__snapshots__/AppLayout.test.tsx.snap +++ b/hotel-management/src/components/AppLayout/__snapshots__/AppLayout.test.tsx.snap @@ -21,8 +21,9 @@ exports[`AppLayout Should render correctly 1`] = `
  • @@ -172,8 +172,9 @@ exports[`AppLayout Should render correctly 1`] = `
  • diff --git a/hotel-management/src/components/AppLayout/index.tsx b/hotel-management/src/components/AppLayout/index.tsx index e4070a6..74bb6f7 100644 --- a/hotel-management/src/components/AppLayout/index.tsx +++ b/hotel-management/src/components/AppLayout/index.tsx @@ -1,26 +1,71 @@ import { Outlet } from 'react-router-dom'; // Components -import Header from '@component/Header'; -import Sidebar from '@component/Sidebar'; +import Header from '../Header'; +import Sidebar from '../Sidebar'; // Styled import { Main, StyledAppLayout } from './styled'; // Hooks -import { useAccount } from '@hook/authentication/useAccount'; +import { useAccount } from '@src/hooks/authentication/useAccount'; + +// Contexts +import { initialState, reducer, UserRoomAvailableContext } from '@src/contexts/UserRoomAvailableContext.ts'; +import { useEffect, useReducer } from 'react'; + +// Services +import { getAllUsers } from '@src/services/userServices.ts'; +import { getAllRooms } from '@src/services/roomServices.ts'; const AppLayout = () => { const { account } = useAccount(); + const [{ usersAvailable, roomsAvailable }, dispatch] = useReducer( + reducer, + initialState + ); + + // Init list user and room available + // Init list user and room available + useEffect(() => { + const load = async () => { + const tempUser = await getAllUsers({ + sortBy: 'id', + orderBy: 'asc', + phoneSearch: '', + page: 0, + }); + + if (tempUser) { + dispatch({ type: 'initUser', payload: tempUser.data }); + } + + const tempRoom = await getAllRooms({ + sortBy: 'id', + orderBy: 'asc', + roomSearch: '', + page: 0, + }); + + if (tempRoom) { + dispatch({ type: 'initRoom', payload: tempRoom.data }); + } + }; + + load(); + }, []); + return ( - -
    - -
    - -
    - + + +
    + +
    + +
    + + ); }; diff --git a/hotel-management/src/components/ButtonIcon/ButtonIcon.test.tsx b/hotel-management/src/components/ButtonIcon/ButtonIcon.test.tsx index 2ba19a9..b4ca1cf 100644 --- a/hotel-management/src/components/ButtonIcon/ButtonIcon.test.tsx +++ b/hotel-management/src/components/ButtonIcon/ButtonIcon.test.tsx @@ -9,7 +9,6 @@ describe('ButtonIcon', () => { } - iconStyle={{ size: '23px' }} /> ); diff --git a/hotel-management/src/components/ButtonIcon/__snapshots__/ButtonIcon.test.tsx.snap b/hotel-management/src/components/ButtonIcon/__snapshots__/ButtonIcon.test.tsx.snap index 12e3a40..d7202f3 100644 --- a/hotel-management/src/components/ButtonIcon/__snapshots__/ButtonIcon.test.tsx.snap +++ b/hotel-management/src/components/ButtonIcon/__snapshots__/ButtonIcon.test.tsx.snap @@ -6,8 +6,10 @@ exports[`ButtonIcon Should render correctly 1`] = ` "baseElement":
    , "container":
    , "debug": [Function], diff --git a/hotel-management/src/components/ButtonIcon/index.tsx b/hotel-management/src/components/ButtonIcon/index.tsx index 44e47c0..0249f6f 100644 --- a/hotel-management/src/components/ButtonIcon/index.tsx +++ b/hotel-management/src/components/ButtonIcon/index.tsx @@ -1,50 +1,35 @@ -import { ReactNode } from 'react'; +import { ButtonHTMLAttributes, ReactNode } from 'react'; // Styled import { StyledButtonIcon } from './styled'; -interface IButtonIcon { +interface IButtonIcon extends ButtonHTMLAttributes { icon: ReactNode; - children?: ReactNode; - style?: { - fontSize?: string; - backgroundColor?: string; - color?: string; - }; - iconStyle?: { - color?: string; - size?: string; - }; - onClick?: () => void; - disabled?: boolean; - label?: string; + iconSize?: string; + iconColor?: string; + fontSize?: string; + text?: string; + variations?: string; } const ButtonIcon = ({ icon, - children, - style, - iconStyle, - onClick, - disabled, - label, + iconSize, + iconColor, + text, + fontSize, + variations, + ...props }: IButtonIcon) => { - const isHaveChildren = Boolean(children); - return ( - {icon} {children} + {icon} {text && {text}} ); }; diff --git a/hotel-management/src/components/ButtonIcon/styled.ts b/hotel-management/src/components/ButtonIcon/styled.ts index d0cd174..f308b2b 100644 --- a/hotel-management/src/components/ButtonIcon/styled.ts +++ b/hotel-management/src/components/ButtonIcon/styled.ts @@ -1,89 +1,104 @@ -import styled, { css } from 'styled-components'; +import styled, { css, RuleSet } from 'styled-components'; interface IStyledButtonIcon { - isHaveChildren: boolean; - style?: { - fontSize?: string; - backgroundColor?: string; - color?: string; - }; - iconStyle?: { - color?: string; - size?: string; - }; + iconSize?: string; + iconColor?: string; + fontSize?: string; + variations?: string; } +export interface IVariations { + [key: string]: RuleSet; +} + +const variations: IVariations = { + success: css` + background-color: var(--success-btn-color); + color: var(--light-text); + + &:hover { + background-color: var(--success-btn-hover-color); + } + + &:disabled { + background-color: var(--success-btn-hover-color); + } + `, + primary: css` + background-color: var(--primary-color); + color: var(--light-text); + + &:hover { + background-color: var(--primary-hover-color); + } + `, + danger: css` + background-color: var(--danger-btn-color); + color: var(--light-text); + + &:hover { + background-color: var(--danger-btn-hover-color); + } + + &:disabled { + background-color: var(--danger-btn-hover-color); + } + `, + default: css` + &:hover { + background-color: var(--hover-background-color); + } + `, +}; + const StyledButtonIcon = styled.button` background: none; - padding: 10px; + display: flex; + align-items: center; + gap: 8px; + + ${(props) => + props.fontSize && + css` + font-size: ${props.fontSize}; + `} + + padding: 10px 20px; 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); + border-radius: var(--radius-md); + + &:disabled { + cursor: not-allowed; } + ${(props) => variations[props.variations!]} + & svg { ${(props) => - props.iconStyle?.size && + props.iconSize && css` - width: ${props.iconStyle.size}; - height: ${props.iconStyle.size}; + width: ${props.iconSize}; + height: ${props.iconSize}; `} ${(props) => - props.iconStyle?.color && + props.iconColor && css` - color: ${props.iconStyle.color}; + color: ${props.iconColor}; `} + transition: all 0.3s; } `; StyledButtonIcon.defaultProps = { - style: { - fontSize: '14px', - backgroundColor: 'var(--primary-color)', - color: '#000', - }, - iconStyle: { - color: '#000', - size: '14px', - }, + iconSize: '16px', + iconColor: '#000', + fontSize: 'var(--fs-sm-2x)', + variations: 'default', }; export { StyledButtonIcon }; diff --git a/hotel-management/src/components/ConfirmMessage/index.tsx b/hotel-management/src/components/ConfirmMessage/index.tsx index 2ad2f14..5faa825 100644 --- a/hotel-management/src/components/ConfirmMessage/index.tsx +++ b/hotel-management/src/components/ConfirmMessage/index.tsx @@ -4,7 +4,7 @@ import { memo, useCallback } from 'react'; import { StyledConfirmDelete } from './styled'; // Component -import Button from '@commonStyle/Button'; +import Button from '@src/commons/styles/Button'; interface IConfirmMessage { message: string; diff --git a/hotel-management/src/components/Form/Form.test.tsx b/hotel-management/src/components/Form/Form.test.tsx index 783d197..63ff2ff 100644 --- a/hotel-management/src/components/Form/Form.test.tsx +++ b/hotel-management/src/components/Form/Form.test.tsx @@ -4,7 +4,7 @@ import { render } from '@testing-library/react'; import Form from '.'; // Styled -import Input from '@commonStyle/Input'; +import Input from '@src/commons/styles/Input'; describe('Form ', () => { const isDisable = true; diff --git a/hotel-management/src/components/Form/index.tsx b/hotel-management/src/components/Form/index.tsx index ea3c4d5..7c7edce 100644 --- a/hotel-management/src/components/Form/index.tsx +++ b/hotel-management/src/components/Form/index.tsx @@ -11,7 +11,7 @@ import { } from './styled'; // Types -import { TDirection } from '@type/common'; +import { TDirection } from '@src/types/common'; interface IFormProps { children: ReactNode; diff --git a/hotel-management/src/components/Form/styled.ts b/hotel-management/src/components/Form/styled.ts index ac469c2..8bc1420 100644 --- a/hotel-management/src/components/Form/styled.ts +++ b/hotel-management/src/components/Form/styled.ts @@ -1,14 +1,14 @@ import styled, { css } from 'styled-components'; // Types -import { TDirection } from '@type/common'; +import { TDirection } from '@src/types/common'; interface IStyledFormRow { direction?: TDirection; } // Styled -import Button from '@commonStyle/Button'; +import Button from '@src/commons/styles/Button'; const StyledForm = styled.form` display: flex; diff --git a/hotel-management/src/components/Header/__snapshots__/Header.test.tsx.snap b/hotel-management/src/components/Header/__snapshots__/Header.test.tsx.snap index 656178a..662bb23 100644 --- a/hotel-management/src/components/Header/__snapshots__/Header.test.tsx.snap +++ b/hotel-management/src/components/Header/__snapshots__/Header.test.tsx.snap @@ -19,8 +19,9 @@ exports[`Header Should render correctly 1`] = `
  • @@ -87,8 +87,9 @@ exports[`Header Should render correctly 1`] = `
  • diff --git a/hotel-management/src/components/HeaderMenu/__snapshots__/HeaderMenu.test.tsx.snap b/hotel-management/src/components/HeaderMenu/__snapshots__/HeaderMenu.test.tsx.snap index c88ef2e..0d59e80 100644 --- a/hotel-management/src/components/HeaderMenu/__snapshots__/HeaderMenu.test.tsx.snap +++ b/hotel-management/src/components/HeaderMenu/__snapshots__/HeaderMenu.test.tsx.snap @@ -11,8 +11,9 @@ exports[`HeaderMenu Should render correctly 1`] = `
  • @@ -70,8 +70,9 @@ exports[`HeaderMenu Should render correctly 1`] = `
  • diff --git a/hotel-management/src/components/HeaderMenu/index.tsx b/hotel-management/src/components/HeaderMenu/index.tsx index 517a86c..dd4cdff 100644 --- a/hotel-management/src/components/HeaderMenu/index.tsx +++ b/hotel-management/src/components/HeaderMenu/index.tsx @@ -3,13 +3,13 @@ import { useNavigate } from 'react-router-dom'; // Components import { IoPersonCircleOutline } from 'react-icons/io5'; import { HiOutlineLogout } from 'react-icons/hi'; -import ButtonIcon from '@component/ButtonIcon'; +import ButtonIcon from '../ButtonIcon'; // Styled import { StyledHeaderMenu } from './styled'; // Hooks -import { useLogout } from '@hook/authentication/useLogout'; +import { useLogout } from '@src/hooks/authentication/useLogout'; const HeaderMenu = () => { const { logout, isPending } = useLogout(); @@ -19,19 +19,19 @@ const HeaderMenu = () => {
  • } - iconStyle={{ size: '23px' }} + iconSize='23px' onClick={() => navigate('/account')} />
  • logout()} disabled={isPending} - label='Logout' + aria-label='Logout' icon={} - iconStyle={{ size: '23px' }} + iconSize='23px' />
  • diff --git a/hotel-management/src/components/Menus/Menus.test.tsx b/hotel-management/src/components/Menus/Menus.test.tsx index 9fe6ca1..d3b5a36 100644 --- a/hotel-management/src/components/Menus/Menus.test.tsx +++ b/hotel-management/src/components/Menus/Menus.test.tsx @@ -17,12 +17,16 @@ describe('Menus', () => { - }> - Edit - - }> - Delete - + } + label="Edit" + /> + } + label="Delete" + /> diff --git a/hotel-management/src/components/Menus/index.tsx b/hotel-management/src/components/Menus/index.tsx index b6e1909..45cbaab 100644 --- a/hotel-management/src/components/Menus/index.tsx +++ b/hotel-management/src/components/Menus/index.tsx @@ -2,26 +2,22 @@ import { MouseEvent, ReactNode, useContext, useState } from 'react'; // Components import { HiEllipsisVertical } from 'react-icons/hi2'; -import ButtonIcon from '@component/ButtonIcon'; +import ButtonIcon from '../ButtonIcon'; // Hooks -import { useOutsideClick } from '@hook/useOutsideClick'; +import { useOutsideClick } from '@src/hooks/useOutsideClick'; // Styled -import { - StyledMenu, - StyledList, - StyledToggle -} from './styled'; +import { StyledMenu, StyledList, StyledToggle } from './styled'; // Contexts -import MenusContext from '@context/MenuContext'; +import MenusContext from '@src/contexts/MenuContext'; // Types -import { Nullable } from '@type/common'; +import { Nullable } from '@src/types/common'; interface IButton { - children?: string; + label?: string; icon?: ReactNode; onClick?: () => void; disabled?: boolean; @@ -46,17 +42,11 @@ const Menus = ({ children }: { children: ReactNode }) => { }; const Toggle = ({ id }: { id: string }): ReactNode => { - const { - openId, - close, - open - } = useContext(MenusContext); + const { openId, close, open } = useContext(MenusContext); const handleClick = (e: MouseEvent) => { e.stopPropagation(); - openId !== id - ? open!(id) - : close!(); + openId !== id ? open!(id) : close!(); }; return ( @@ -81,7 +71,7 @@ const List = ({ return {children}; }; -const Button = ({ children, icon, onClick, disabled }: IButton): ReactNode => { +const Button = ({ label, icon, onClick, disabled }: IButton): ReactNode => { const { close } = useContext(MenusContext); const handleClick = () => { onClick?.(); @@ -91,14 +81,13 @@ const Button = ({ children, icon, onClick, disabled }: IButton): ReactNode => { return (
  • - {children} - + />
  • ); }; diff --git a/hotel-management/src/components/Modal/Modal.test.tsx b/hotel-management/src/components/Modal/Modal.test.tsx index 5c43801..5a055e9 100644 --- a/hotel-management/src/components/Modal/Modal.test.tsx +++ b/hotel-management/src/components/Modal/Modal.test.tsx @@ -2,7 +2,7 @@ import { render } from '@testing-library/react'; // Components import Modal from '.'; -import Button from '@commonStyle/Button'; +import Button from '@src/commons/styles/Button'; describe('Modal', () => { const wrapper = render( @@ -13,9 +13,11 @@ describe('Modal', () => { )} /> - -

    This is a windows

    -
    +

    This is a windows

    } + /> ); diff --git a/hotel-management/src/components/Modal/index.tsx b/hotel-management/src/components/Modal/index.tsx index add80a6..f4d0d81 100644 --- a/hotel-management/src/components/Modal/index.tsx +++ b/hotel-management/src/components/Modal/index.tsx @@ -1,17 +1,15 @@ import { - ReactElement, ReactNode, - cloneElement, useContext, useState, } from 'react'; import { createPortal } from 'react-dom'; // Hooks -import { useOutsideClick } from '@hook/useOutsideClick'; +import { useOutsideClick } from '@src/hooks/useOutsideClick'; // Contexts -import { ModalContext } from '@context/ModalContext'; +import { ModalContext } from '@src/contexts/ModalContext'; // Styled import { Overlay, StyledModal, StyledModalContent, TitleModal } from './styled'; @@ -25,7 +23,7 @@ const Modal = ({ children }: IModal) => { const close = () => setOpenName(''); const open = setOpenName; - + return ( {children} @@ -34,7 +32,7 @@ const Modal = ({ children }: IModal) => { }; interface IOpen { - renderChildren: (onCloseModal: () => void) => ReactNode; + renderChildren: (onOpenModal: () => void) => ReactNode; modalName: string; } @@ -45,12 +43,12 @@ const Open = ({ renderChildren, modalName }: IOpen) => { }; interface IWindow { - children: ReactElement; + renderChildren: (callBack: () => void) => ReactNode; name: string; title: string; } -const Window = ({ children, name, title }: IWindow) => { +const Window = ({ renderChildren, name, title }: IWindow) => { const { openName, close } = useContext(ModalContext); const ref = useOutsideClick(close!); @@ -61,7 +59,7 @@ const Window = ({ children, name, title }: IWindow) => { {title} - {cloneElement(children, { onCloseModal: close })} + {renderChildren(close!)} , diff --git a/hotel-management/src/components/Nav/Nav.test.tsx b/hotel-management/src/components/Nav/Nav.test.tsx index 7747d44..c6fb013 100644 --- a/hotel-management/src/components/Nav/Nav.test.tsx +++ b/hotel-management/src/components/Nav/Nav.test.tsx @@ -1,4 +1,3 @@ - import { render } from '@testing-library/react'; import { BrowserRouter } from 'react-router-dom'; diff --git a/hotel-management/src/components/Nav/index.tsx b/hotel-management/src/components/Nav/index.tsx index b5bb011..ff938ce 100644 --- a/hotel-management/src/components/Nav/index.tsx +++ b/hotel-management/src/components/Nav/index.tsx @@ -7,7 +7,7 @@ import { BsHouseDoorFill } from 'react-icons/bs'; import { StyledNav, StyledNavLink } from './styled'; // Constants -import { BOOKING, ROOM, USER } from '@constant/path'; +import { BOOKING, ROOM, USER } from '@src/constants/path'; const Nav = () => { return ( diff --git a/hotel-management/src/components/Pagination/__snapshots__/index.test.tsx.snap b/hotel-management/src/components/Pagination/__snapshots__/index.test.tsx.snap index 9b98ef4..c4c9ee2 100644 --- a/hotel-management/src/components/Pagination/__snapshots__/index.test.tsx.snap +++ b/hotel-management/src/components/Pagination/__snapshots__/index.test.tsx.snap @@ -12,10 +12,10 @@ exports[`Pagination Should render correctly 1`] = ` Showing 1 to - 5 + 10 of - 10 + 20 results

    @@ -84,10 +84,10 @@ exports[`Pagination Should render correctly 1`] = ` Showing 1 to - 5 + 10 of - 10 + 20 results

    diff --git a/hotel-management/src/components/Pagination/index.test.tsx b/hotel-management/src/components/Pagination/index.test.tsx index aa428cb..d3fe58f 100644 --- a/hotel-management/src/components/Pagination/index.test.tsx +++ b/hotel-management/src/components/Pagination/index.test.tsx @@ -5,7 +5,7 @@ import { BrowserRouter } from 'react-router-dom'; import Pagination from '.'; describe('Pagination', () => { - const count = 10; + const count = 20; let wrapper: RenderResult | null = null; beforeEach(() => { diff --git a/hotel-management/src/components/Pagination/index.tsx b/hotel-management/src/components/Pagination/index.tsx index 2ed3d40..0eaec52 100644 --- a/hotel-management/src/components/Pagination/index.tsx +++ b/hotel-management/src/components/Pagination/index.tsx @@ -1,7 +1,7 @@ import { useSearchParams } from 'react-router-dom'; // Constants -import { DEFAULT_PAGE_SIZE } from '@constant/config'; +import { DEFAULT_PAGE_SIZE } from '@src/constants/config'; // Styled import { Buttons, PaginationBtn, StyledPagination } from './styled'; diff --git a/hotel-management/src/components/RootLayout/index.tsx b/hotel-management/src/components/RootLayout/index.tsx index 8ca6e58..7bfe8a3 100644 --- a/hotel-management/src/components/RootLayout/index.tsx +++ b/hotel-management/src/components/RootLayout/index.tsx @@ -1,11 +1,11 @@ import { Outlet } from 'react-router-dom'; // Styled -import Spinner from '@commonStyle/Spinner'; +import Spinner from '@src/commons/styles/Spinner'; import { FullPageLayout } from './styled'; // Hooks -import { useAccount } from '@hook/authentication/useAccount'; +import { useAccount } from '@src/hooks/authentication/useAccount'; const RootLayout = () => { const { isPending } = useAccount(); diff --git a/hotel-management/src/components/RouteProtected/index.test.tsx b/hotel-management/src/components/RouteProtected/index.test.tsx index 69da977..cab085e 100644 --- a/hotel-management/src/components/RouteProtected/index.test.tsx +++ b/hotel-management/src/components/RouteProtected/index.test.tsx @@ -1,6 +1,6 @@ import { render } from '@testing-library/react'; import RouteProtected from '.'; -import AppLayout from '@component/AppLayout'; +import AppLayout from '../AppLayout'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { BrowserRouter } from 'react-router-dom'; diff --git a/hotel-management/src/components/RouteProtected/index.tsx b/hotel-management/src/components/RouteProtected/index.tsx index 1726ef0..1b18703 100644 --- a/hotel-management/src/components/RouteProtected/index.tsx +++ b/hotel-management/src/components/RouteProtected/index.tsx @@ -1,4 +1,4 @@ -import { useAccount } from '@hook/authentication/useAccount'; +import { useAccount } from '@src/hooks/authentication/useAccount'; import { ReactNode } from 'react'; import { Navigate } from 'react-router-dom'; diff --git a/hotel-management/src/components/Search/Search.test.tsx b/hotel-management/src/components/Search/Search.test.tsx index 5e6ff00..3949f6b 100644 --- a/hotel-management/src/components/Search/Search.test.tsx +++ b/hotel-management/src/components/Search/Search.test.tsx @@ -9,7 +9,7 @@ jest.mock('react-router-dom', () => ({ useSearchParams: jest.fn(), })); -jest.mock('@hook/useDebounce', () => ({ +jest.mock('@src/hooks/useDebounce', () => ({ useDebounce: jest.fn((value) => value), })); diff --git a/hotel-management/src/components/Search/index.tsx b/hotel-management/src/components/Search/index.tsx index fcd8bb6..da50c11 100644 --- a/hotel-management/src/components/Search/index.tsx +++ b/hotel-management/src/components/Search/index.tsx @@ -5,10 +5,10 @@ import { useSearchParams } from 'react-router-dom'; import { StyledSearch } from './styled'; // Hooks -import { useDebounce } from '@hook/useDebounce'; +import { useDebounce } from '@src/hooks/useDebounce'; // Types -import { Nullable } from '@type/common'; +import { Nullable } from '@src/types/common'; interface ISearch { setPlaceHolder: string; @@ -17,7 +17,12 @@ interface ISearch { const Search = ({ setPlaceHolder }: ISearch) => { const field = 'search'; const [searchParams, setSearchParams] = useSearchParams(); - const [query, setQuery] = useState>(null); + const [query, setQuery] = useState>( + searchParams.get(field) + ? searchParams.get(field) + : '', + ); + const debounceValue = useDebounce>(query, 700); useEffect(() => { @@ -32,6 +37,7 @@ const Search = ({ setPlaceHolder }: ISearch) => { setQuery(e.target.value)} placeholder={setPlaceHolder} + value={query!} /> ); }; diff --git a/hotel-management/src/components/Sidebar/index.tsx b/hotel-management/src/components/Sidebar/index.tsx index 7d97768..89a8159 100644 --- a/hotel-management/src/components/Sidebar/index.tsx +++ b/hotel-management/src/components/Sidebar/index.tsx @@ -1,5 +1,5 @@ // Components -import Nav from '@component/Nav'; +import Nav from '../Nav'; // Styled import { Heading, StyledSidebar } from './styled'; diff --git a/hotel-management/src/components/SortBy/index.tsx b/hotel-management/src/components/SortBy/index.tsx index 546e5ed..ca85296 100644 --- a/hotel-management/src/components/SortBy/index.tsx +++ b/hotel-management/src/components/SortBy/index.tsx @@ -2,7 +2,7 @@ import { useSearchParams } from 'react-router-dom'; import { ChangeEvent, memo } from 'react'; // Components -import Select from '@component/Select'; +import Select from '../Select'; interface ISortByProps { options: { diff --git a/hotel-management/src/components/Table/Table.test.tsx b/hotel-management/src/components/Table/Table.test.tsx deleted file mode 100644 index 9f6100f..0000000 --- a/hotel-management/src/components/Table/Table.test.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { render } from '@testing-library/react'; - -// Components -import Table from '.'; - -// Types -import { IUser } from '@type/user'; - -interface ITableRow { - user: IUser; -} - -describe('Table', () => { - const columnName = ['Column 1', 'Column 2']; - const tempUser: IUser[] = [ - { - id: 1, - name: 'Nezumi', - phone: '123', - isBooked: true, - isDelete: true, - }, - { - id: 2, - name: 'Loi Phan', - phone: '453', - isBooked: false, - isDelete: true, - }, - ]; - const TableRow = ({ user }: ITableRow) => { - const { - id, - name, - phone, - isBooked - } = user; - - return ( - -
    {id}
    -
    {name}
    -
    {phone}
    -
    {isBooked}
    -
    - ); - }; - const renderRow = (user: IUser) => ; - - const wrapper = render( - - - data={tempUser} render={renderRow} /> -
    - ); - - test('Should render correctly', () => { - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/hotel-management/src/components/Table/index.tsx b/hotel-management/src/components/Table/index.tsx index 76024e3..9de0afa 100644 --- a/hotel-management/src/components/Table/index.tsx +++ b/hotel-management/src/components/Table/index.tsx @@ -1,70 +1,151 @@ -import { ReactNode, useContext } from 'react'; +// Types +import {ColumnProps} from '@src/types/common'; // Styled import { StyledBody, + StyledFooter, StyledHeader, StyledRow, StyledTable, - StyledFooter, } from './styled'; -// Contexts -import TableContext from '@context/TableContext'; +// Components +import Pagination from '../Pagination'; +import {TbArrowNarrowRight} from 'react-icons/tb'; +import {StyledTableOption} from '@src/pages/Room/styled.ts'; +import OrderBy from '@src/components/OrderBy'; +import {ORDERBY_OPTIONS} from '@src/constants/commons.ts'; +import SortBy from '@src/components/SortBy'; +import Search from '@src/components/Search'; +import Direction from '@src/commons/styles/Direction.ts'; +import {Dispatch, SetStateAction} from 'react'; -export interface ITable { - columns?: string; - children: ReactNode; -} +const parseWidthString = (columnsWidth: number[]): string => { + let result: string = ''; -export interface IHeader { - headerColumn: string[]; -} + const totalWidth = columnsWidth.reduce(( + partialSum, + a + ) => partialSum + a, 0); + columnsWidth.forEach((width) => { + result += Math.round(( + width / totalWidth + ) * 100) + .toString() + '% '; + }); -interface ITableBody { - data?: T[]; - render?: CallbackMapFunc; -} - -type CallbackMapFunc = (value: T, index: number, array: T[]) => ReactNode; - -const Table = ({ columns, children }: ITable) => { - return ( - - {children} - - ); + return result; }; -const Header = ({ headerColumn }: IHeader) => { - const { columns } = useContext(TableContext); +type Props = { + columns: ColumnProps[]; + rows: T[]; + stateSelected: { + itemSelected: T | undefined; + setItemSelected: Dispatch>; + }; + count?: number | null; + onRowClick?: (rowData: T) => void; + enabledOrder?: boolean; + sortBy?: { + value: string; + label: string; + }[]; + searchPlaceHolder?: string; +}; + +const Table = ({ + rows, + columns, + count, + onRowClick, + stateSelected, + sortBy, + searchPlaceHolder, + enabledOrder = false, +}: Props) => { + const width = parseWidthString(columns.map((item) => item.width)); + const {itemSelected, setItemSelected} = stateSelected; + + const headers = columns.map(( + column, + index + ) => { + return
    {column.title}
    ; + }); + + const renderRows = rows.map(( + row, + rowIndex + ) => { + const handleRowClick = () => { + if (onRowClick) { + onRowClick(row); + setItemSelected(row); + } + }; + + return ( + + {columns.map(( + column, + columnIndex + ) => { + const value = row[column.key as keyof typeof row] as string; + + if (column.isDateValue) { + return ( +
    + {value[0]}   +   {value[1]} +
    + ); + } + + return
    {value}
    ; + })} +
    + ); + }); return ( - - {headerColumn.map((item) => ( -
    {item}
    - ))} -
    + + + {enabledOrder && } + {Boolean(sortBy?.length) && } + {Boolean(searchPlaceHolder) && } + + + {rows && rows.length && + ( + + {headers} + + {renderRows} + + {Boolean(count) && ( + + + + )} + + ) + } + ); -}; - -const Body = ({ data, render }: ITableBody) => { - return ( - data!.length && ( - {data?.map(render as CallbackMapFunc)} - ) - ); -}; - -const Row = ({ children }: ITable) => { - const { columns } = useContext(TableContext); - - return {children}; -}; - -Table.Header = Header; -Table.Body = Body; -Table.Row = Row; -Table.Footer = StyledFooter; +} export default Table; diff --git a/hotel-management/src/components/Table/styled.ts b/hotel-management/src/components/Table/styled.ts index 7c10749..57d76bd 100644 --- a/hotel-management/src/components/Table/styled.ts +++ b/hotel-management/src/components/Table/styled.ts @@ -1,7 +1,8 @@ import styled from 'styled-components'; -// Interfaces -import { ITable } from '.'; +interface ICommonRow { + width: string; +} const StyledTable = styled.div` border: 1px solid var(--border-color); @@ -10,9 +11,9 @@ const StyledTable = styled.div` font-size: 20px; `; -const CommonRow = styled.div` +const CommonRow = styled.div` display: grid; - grid-template-columns: ${(props) => props.columns}; + grid-template-columns: ${(props) => props.width}; column-gap: 10px; align-items: center; justify-items: center; @@ -24,6 +25,16 @@ const StyledBody = styled.div` const StyledRow = styled(CommonRow)` padding: 20px; + + cursor: pointer; + + &:hover { + background-color: var(--item-hover); + } + + &.selected { + background-color: var(--item-selected); + } &:not(:last-child) { border-bottom: 1px solid var(--border-color); diff --git a/hotel-management/src/contexts/ItemSelected.ts b/hotel-management/src/contexts/ItemSelected.ts new file mode 100644 index 0000000..0832895 --- /dev/null +++ b/hotel-management/src/contexts/ItemSelected.ts @@ -0,0 +1,35 @@ +import { Dispatch, createContext } from 'react'; + +export type TItemSelectAction = 'setData' | 'removeData'; + +interface IAction { + type: TItemSelectAction; + payload: T; +} + +interface IItemSelect { + data?: any; + dispatch?: Dispatch>; +} + +const ItemSelectContext = createContext({}); + +const itemSelectReducer = + () => + (state: T, action: IAction) => { + switch (action.type) { + // Init data for the first load + case 'setData': { + const tempData = { ...state }; + + return { + data: tempData, + }; + } + + default: + throw new Error('Action unknown'); + } + }; + +export { itemSelectReducer, ItemSelectContext }; diff --git a/hotel-management/src/contexts/UserRoomAvailableContext.ts b/hotel-management/src/contexts/UserRoomAvailableContext.ts index 66d03f4..9cf76db 100644 --- a/hotel-management/src/contexts/UserRoomAvailableContext.ts +++ b/hotel-management/src/contexts/UserRoomAvailableContext.ts @@ -1,7 +1,7 @@ import { Dispatch, createContext } from 'react'; // Types -import { IDataState } from '@type/common'; +import { IDataState } from '@src/types/common'; interface IUserRoomState { usersAvailable: IDataState[]; diff --git a/hotel-management/src/contexts/__tests__/userRoomAvailableContext.test.tsx b/hotel-management/src/contexts/__tests__/userRoomAvailableContext.test.tsx index 90b2d00..93764f3 100644 --- a/hotel-management/src/contexts/__tests__/userRoomAvailableContext.test.tsx +++ b/hotel-management/src/contexts/__tests__/userRoomAvailableContext.test.tsx @@ -1,8 +1,8 @@ // Contexts -import { reducer } from '@context/UserRoomAvailableContext'; +import { reducer } from '../UserRoomAvailableContext'; // Types -import { IDataState } from '@type/common'; +import { IDataState } from '@src/types/common'; describe('userRoomAvailableContext', () => { let initialState: { diff --git a/hotel-management/src/helpers/__tests__/helpers.test.ts b/hotel-management/src/helpers/__tests__/helpers.test.ts index 4e24245..b112d48 100644 --- a/hotel-management/src/helpers/__tests__/helpers.test.ts +++ b/hotel-management/src/helpers/__tests__/helpers.test.ts @@ -1,5 +1,5 @@ // Helpers -import { formatCurrency, getDayDiff } from '@helper/helper'; +import { formatCurrency, getDayDiff } from '../helper'; describe('formatCurrency', () => { test('Should format correctly', () => { diff --git a/hotel-management/src/helpers/__tests__/validators.test.ts b/hotel-management/src/helpers/__tests__/validators.test.ts index 2d6be25..1abd19f 100644 --- a/hotel-management/src/helpers/__tests__/validators.test.ts +++ b/hotel-management/src/helpers/__tests__/validators.test.ts @@ -1,5 +1,5 @@ // Constants -import { REGEX } from '@constant/commons'; +import { REGEX } from '@src/constants/commons'; // Helpers import { @@ -7,7 +7,7 @@ import { isValidDiscount, isValidRegex, isValidString, -} from '@helper/validators'; +} from '../validators'; describe('isValidPhone', () => { const isValidPhone = (phone: string) => diff --git a/hotel-management/src/helpers/helper.ts b/hotel-management/src/helpers/helper.ts index 7b0c324..56f7f58 100644 --- a/hotel-management/src/helpers/helper.ts +++ b/hotel-management/src/helpers/helper.ts @@ -29,7 +29,12 @@ const getDayDiff = (startDate: Date, endDate: Date): number => { return 0; } +const findItemInListById = (id: number, listItem: T[]): T | undefined => { + return listItem.find((item) => item["id" as keyof typeof item] === id); +} + export { formatCurrency, getDayDiff, + findItemInListById, }; diff --git a/hotel-management/src/hooks/__tests__/useDebounce.test.tsx b/hotel-management/src/hooks/__tests__/useDebounce.test.tsx index 5db8fce..9e917d0 100644 --- a/hotel-management/src/hooks/__tests__/useDebounce.test.tsx +++ b/hotel-management/src/hooks/__tests__/useDebounce.test.tsx @@ -2,7 +2,7 @@ import { act, fireEvent, render } from '@testing-library/react'; import { useState } from 'react'; // Hooks -import { useDebounce } from '@hook/useDebounce'; +import { useDebounce } from '../useDebounce'; jest.useFakeTimers(); diff --git a/hotel-management/src/hooks/__tests__/useOutsideClick.test.tsx b/hotel-management/src/hooks/__tests__/useOutsideClick.test.tsx index 0873162..4331d26 100644 --- a/hotel-management/src/hooks/__tests__/useOutsideClick.test.tsx +++ b/hotel-management/src/hooks/__tests__/useOutsideClick.test.tsx @@ -1,7 +1,7 @@ import { fireEvent, render, renderHook, screen } from '@testing-library/react'; // Hooks -import { useOutsideClick } from '@hook/useOutsideClick'; +import { useOutsideClick } from '../useOutsideClick'; describe('useOutsideClick', () => { test('Call handler when click outside element', () => { diff --git a/hotel-management/src/hooks/authentication/__tests__/useAccount.test.ts b/hotel-management/src/hooks/authentication/__tests__/useAccount.test.ts index 2fe036a..c7d098f 100644 --- a/hotel-management/src/hooks/authentication/__tests__/useAccount.test.ts +++ b/hotel-management/src/hooks/authentication/__tests__/useAccount.test.ts @@ -3,7 +3,7 @@ import { renderHook } from '@testing-library/react'; import { User } from '@supabase/supabase-js'; // Services -import * as authenticationService from '@service/authenticationService'; +import * as authenticationService from '@src/services/authenticationService'; // Hooks import { useAccount } from '../useAccount'; diff --git a/hotel-management/src/hooks/authentication/useAccount.ts b/hotel-management/src/hooks/authentication/useAccount.ts index 869f278..6a60876 100644 --- a/hotel-management/src/hooks/authentication/useAccount.ts +++ b/hotel-management/src/hooks/authentication/useAccount.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; // Services -import { getCurrentAccount } from '@service/authenticationService'; +import { getCurrentAccount } from '@src/services/authenticationService'; /** * Get data of account currently login diff --git a/hotel-management/src/hooks/authentication/useLogin.ts b/hotel-management/src/hooks/authentication/useLogin.ts index 6cf34fe..3cc6be9 100644 --- a/hotel-management/src/hooks/authentication/useLogin.ts +++ b/hotel-management/src/hooks/authentication/useLogin.ts @@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom'; import toast from 'react-hot-toast'; // Services -import { login as loginFn } from '@service/authenticationService'; +import { login as loginFn } from '@src/services/authenticationService'; /** * Login web diff --git a/hotel-management/src/hooks/authentication/useLogout.ts b/hotel-management/src/hooks/authentication/useLogout.ts index fd6cb28..10ec984 100644 --- a/hotel-management/src/hooks/authentication/useLogout.ts +++ b/hotel-management/src/hooks/authentication/useLogout.ts @@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; // Services -import { logout as logoutFn } from '@service/authenticationService'; +import { logout as logoutFn } from '@src/services/authenticationService'; /** * Logout web diff --git a/hotel-management/src/hooks/authentication/useUpdateAccount.ts b/hotel-management/src/hooks/authentication/useUpdateAccount.ts index ebe4d9d..f451a61 100644 --- a/hotel-management/src/hooks/authentication/useUpdateAccount.ts +++ b/hotel-management/src/hooks/authentication/useUpdateAccount.ts @@ -2,10 +2,10 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from 'react-hot-toast'; // Services -import { updateAccount as updateAccountFn } from '@service/authenticationService'; +import { updateAccount as updateAccountFn } from '@src/services/authenticationService'; // Constants -import { UPDATE_ACCOUNT_SUCCESSFUL } from '@constant/messages'; +import { UPDATE_ACCOUNT_SUCCESSFUL } from '@src/constants/messages'; /** * Update account currently login. diff --git a/hotel-management/src/hooks/bookings/__tests__/useBookings.test.tsx b/hotel-management/src/hooks/bookings/__tests__/useBookings.test.tsx index 4f58c8b..134124f 100644 --- a/hotel-management/src/hooks/bookings/__tests__/useBookings.test.tsx +++ b/hotel-management/src/hooks/bookings/__tests__/useBookings.test.tsx @@ -11,7 +11,7 @@ import { URLSearchParams } from 'url'; import { useBookings } from '../useBookings'; // Services -import { getAllBookings } from '@service/bookingServices'; +import { getAllBookings } from '@src/services/bookingServices'; jest.mock('react-router-dom', () => ({ useSearchParams: jest.fn(), @@ -22,7 +22,7 @@ jest.mock('@tanstack/react-query', () => ({ useQuery: jest.fn(), })); -jest.mock('@service/bookingServices', () => ({ +jest.mock('@src/services/bookingServices', () => ({ getAllBookings: jest.fn(), })); @@ -67,7 +67,7 @@ describe('useBookings hook', () => { }); test('Should prefetch the second page when in the first page', async () => { - const sampleDate = { data: [{ id: 1, name: 'Booking 1' }], count: 7 }; + const sampleDate = { data: [{ id: 1, name: 'Booking 1' }], count: 11 }; (queryClient.prefetchQuery as jest.Mock) = jest.fn(); (useSearchParams as jest.Mock).mockReturnValue([ @@ -105,7 +105,7 @@ describe('useBookings hook', () => { }); test('Should prefetch the previous page and next page when in the second page', async () => { - const sampleDate = { data: [{ id: 1, name: 'Booking 1' }], count: 12 }; + const sampleDate = { data: [{ id: 1, name: 'Booking 1' }], count: 22 }; (useSearchParams as jest.Mock).mockReturnValue([ new URLSearchParams('page=2'), diff --git a/hotel-management/src/hooks/bookings/__tests__/useCheckout.test.tsx b/hotel-management/src/hooks/bookings/__tests__/useCheckout.test.tsx index a8b4772..32b0ce5 100644 --- a/hotel-management/src/hooks/bookings/__tests__/useCheckout.test.tsx +++ b/hotel-management/src/hooks/bookings/__tests__/useCheckout.test.tsx @@ -8,13 +8,13 @@ import useCheckOut from '../useCheckout'; import { act, renderHook } from '@testing-library/react'; // Services -import { checkOutBooking } from '@service/bookingServices'; +import { checkOutBooking } from '@src/services/bookingServices'; // Hooks -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; +import { useUserRoomAvailable } from '@src/hooks/useUserRoomAvailable'; // Constants -import { CHECKOUT_SUCCESS } from '@constant/messages'; +import { CHECKOUT_SUCCESS } from '@src/constants/messages'; // Mock services and constants jest.mock('react-hot-toast'); @@ -22,10 +22,10 @@ jest.mock('@tanstack/react-query', () => ({ ...jest.requireActual('@tanstack/react-query'), useQueryClient: jest.fn(), })); -jest.mock('@service/bookingServices', () => ({ +jest.mock('@src/services/bookingServices', () => ({ checkOutBooking: jest.fn(), })); -jest.mock('@hook/useUserRoomAvailable', () => ({ +jest.mock('@src/hooks/useUserRoomAvailable', () => ({ useUserRoomAvailable: jest.fn(), })); diff --git a/hotel-management/src/hooks/bookings/__tests__/useCreateBooking.test.tsx b/hotel-management/src/hooks/bookings/__tests__/useCreateBooking.test.tsx index 4bbda0d..bde07f2 100644 --- a/hotel-management/src/hooks/bookings/__tests__/useCreateBooking.test.tsx +++ b/hotel-management/src/hooks/bookings/__tests__/useCreateBooking.test.tsx @@ -11,20 +11,20 @@ import toast from 'react-hot-toast'; import { useCreateBooking } from '../useCreateBooking'; // Types -import { IBooking } from '@type/booking'; +import { IBooking } from '@src/types/booking'; // Constants -import { ADD_SUCCESS } from '@constant/messages'; +import { ADD_SUCCESS } from '@src/constants/messages'; // Services -import { createBooking } from '@service/bookingServices'; +import { createBooking } from '@src/services/bookingServices'; // Mock the necessary dependencies jest.mock('@tanstack/react-query', () => ({ ...jest.requireActual('@tanstack/react-query'), useQueryClient: jest.fn(), })); -jest.mock('@service/bookingServices', () => ({ +jest.mock('@src/services/bookingServices', () => ({ createBooking: jest.fn(), })); jest.mock('react-hot-toast'); diff --git a/hotel-management/src/hooks/bookings/__tests__/useUpdateBooking.test.tsx b/hotel-management/src/hooks/bookings/__tests__/useUpdateBooking.test.tsx index 1e064fa..9468dc3 100644 --- a/hotel-management/src/hooks/bookings/__tests__/useUpdateBooking.test.tsx +++ b/hotel-management/src/hooks/bookings/__tests__/useUpdateBooking.test.tsx @@ -8,13 +8,13 @@ import { import { ReactNode } from 'react'; // Types -import { IBooking } from '@type/booking'; +import { IBooking } from '@src/types/booking'; // Constants -import { UPDATE_SUCCESS } from '@constant/messages'; +import { UPDATE_SUCCESS } from '@src/constants/messages'; // Services -import { updateBooking } from '@service/bookingServices'; +import { updateBooking } from '@src/services/bookingServices'; // Hooks import { useUpdateBooking } from '../useUpdateBooking'; @@ -24,7 +24,7 @@ jest.mock('@tanstack/react-query', () => ({ ...jest.requireActual('@tanstack/react-query'), useQueryClient: jest.fn(), })); -jest.mock('@service/bookingServices', () => ({ +jest.mock('@src/services/bookingServices', () => ({ updateBooking: jest.fn(), })); jest.mock('react-hot-toast'); diff --git a/hotel-management/src/hooks/bookings/useBookings.ts b/hotel-management/src/hooks/bookings/useBookings.ts index 7b37689..3cbd2d8 100644 --- a/hotel-management/src/hooks/bookings/useBookings.ts +++ b/hotel-management/src/hooks/bookings/useBookings.ts @@ -3,10 +3,10 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useSearchParams } from 'react-router-dom'; // Services -import { getAllBookings } from '@service/bookingServices'; +import { getAllBookings } from '@src/services/bookingServices'; // Constants -import { DEFAULT_PAGE_SIZE } from '@constant/config'; +import { DEFAULT_PAGE_SIZE } from '@src/constants/config'; /** * Fetch booking from database diff --git a/hotel-management/src/hooks/bookings/useCheckout.ts b/hotel-management/src/hooks/bookings/useCheckout.ts index 8ee438b..97b9d16 100644 --- a/hotel-management/src/hooks/bookings/useCheckout.ts +++ b/hotel-management/src/hooks/bookings/useCheckout.ts @@ -2,13 +2,13 @@ import toast from 'react-hot-toast'; import { useMutation, useQueryClient } from '@tanstack/react-query'; // Constants -import { CHECKOUT_SUCCESS } from '@constant/messages'; +import { CHECKOUT_SUCCESS } from '@src/constants/messages'; // Hooks -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; +import { useUserRoomAvailable } from '../useUserRoomAvailable'; // Services -import { checkOutBooking as checkOutBookingFn } from '@service/bookingServices'; +import { checkOutBooking as checkOutBookingFn } from '@src/services/bookingServices'; const useCheckOut = () => { const queryClient = useQueryClient(); diff --git a/hotel-management/src/hooks/bookings/useCreateBooking.ts b/hotel-management/src/hooks/bookings/useCreateBooking.ts index 4b9dc27..a402b47 100644 --- a/hotel-management/src/hooks/bookings/useCreateBooking.ts +++ b/hotel-management/src/hooks/bookings/useCreateBooking.ts @@ -2,10 +2,10 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; // Services -import { createBooking as createBookingFn } from '@service/bookingServices'; +import { createBooking as createBookingFn} from '@src/services/bookingServices'; // Constants -import { ADD_SUCCESS } from '@constant/messages'; +import { ADD_SUCCESS } from '@src/constants/messages'; /** * Create booking on database diff --git a/hotel-management/src/hooks/bookings/useUpdateBooking.ts b/hotel-management/src/hooks/bookings/useUpdateBooking.ts index 1c04d30..0d6624f 100644 --- a/hotel-management/src/hooks/bookings/useUpdateBooking.ts +++ b/hotel-management/src/hooks/bookings/useUpdateBooking.ts @@ -2,10 +2,10 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; // Services -import { updateBooking as updateBookingFn } from '@service/bookingServices'; +import { updateBooking as updateBookingFn } from '@src/services/bookingServices'; // Constants -import { UPDATE_SUCCESS } from '@constant/messages'; +import { UPDATE_SUCCESS } from '@src/constants/messages'; /** * Update booking from database diff --git a/hotel-management/src/hooks/rooms/__tests__/useCreateRoom.test.tsx b/hotel-management/src/hooks/rooms/__tests__/useCreateRoom.test.tsx index 41c21ec..d9ae52e 100644 --- a/hotel-management/src/hooks/rooms/__tests__/useCreateRoom.test.tsx +++ b/hotel-management/src/hooks/rooms/__tests__/useCreateRoom.test.tsx @@ -8,22 +8,22 @@ import { import { ReactNode } from 'react'; // Types -import { IRoom } from '@type/room'; +import { IRoom } from '@src/types/room'; // Hooks import { useCreateRoom } from '../useCreateRoom'; // Constants -import { ADD_SUCCESS } from '@constant/messages'; +import { ADD_SUCCESS } from '@src/constants/messages'; // Services -import { createRoom } from '@service/roomServices'; +import { createRoom } from '@src/services/roomServices'; jest.mock('@tanstack/react-query', () => ({ ...jest.requireActual('@tanstack/react-query'), useQueryClient: jest.fn(), })); -jest.mock('@service/roomServices', () => ({ +jest.mock('@src/services/roomServices', () => ({ createRoom: jest.fn(), })); jest.mock('react-hot-toast'); diff --git a/hotel-management/src/hooks/rooms/__tests__/useRooms.test.tsx b/hotel-management/src/hooks/rooms/__tests__/useRooms.test.tsx index 7f2687c..d186617 100644 --- a/hotel-management/src/hooks/rooms/__tests__/useRooms.test.tsx +++ b/hotel-management/src/hooks/rooms/__tests__/useRooms.test.tsx @@ -8,7 +8,7 @@ import { renderHook } from '@testing-library/react'; import { URLSearchParams } from 'url'; // Services -import { getAllRooms } from '@service/roomServices'; +import { getAllRooms } from '@src/services/roomServices'; // Hooks import { useRooms } from '../useRooms'; @@ -22,7 +22,7 @@ jest.mock('@tanstack/react-query', () => ({ useQuery: jest.fn(), })); -jest.mock('@service/roomServices', () => ({ +jest.mock('@src/services/roomServices', () => ({ getAllRooms: jest.fn(), })); @@ -69,7 +69,7 @@ describe('useRooms hook', () => { }); test('Should prefetch the second page when in the first page', async () => { - const sampleDate = { data: [{ id: 1, name: 'Room 1' }], count: 7 }; + const sampleDate = { data: [{ id: 1, name: 'Room 1' }], count: 11 }; (useSearchParams as jest.Mock).mockReturnValue([ new URLSearchParams('page=1'), @@ -106,7 +106,7 @@ describe('useRooms hook', () => { }); test('Should prefetch the previous page and next page when in the second page', async () => { - const sampleDate = { data: [{ id: 1, name: 'Room 1' }], count: 12 }; + const sampleDate = { data: [{ id: 1, name: 'Room 1' }], count: 22 }; (useSearchParams as jest.Mock).mockReturnValue([ new URLSearchParams('page=2'), diff --git a/hotel-management/src/hooks/rooms/__tests__/useSetIsDeleteRoom.test.tsx b/hotel-management/src/hooks/rooms/__tests__/useSetIsDeleteRoom.test.tsx index 8c38731..3dae2e7 100644 --- a/hotel-management/src/hooks/rooms/__tests__/useSetIsDeleteRoom.test.tsx +++ b/hotel-management/src/hooks/rooms/__tests__/useSetIsDeleteRoom.test.tsx @@ -8,13 +8,13 @@ import { import { ReactNode } from 'react'; // Types -import { IRoom } from '@type/room'; +import { IRoom } from '@src/types/room'; // Constants -import { DELETE_SUCCESS } from '@constant/messages'; +import { DELETE_SUCCESS } from '@src/constants/messages'; // Services -import { setIsDeleteRoom } from '@service/roomServices'; +import { setIsDeleteRoom } from '@src/services/roomServices'; // Hooks import { useSetIsDeleteRoom } from '../useSetIsDeleteRoom'; @@ -24,7 +24,7 @@ jest.mock('@tanstack/react-query', () => ({ ...jest.requireActual('@tanstack/react-query'), useQueryClient: jest.fn(), })); -jest.mock('@service/roomServices', () => ({ +jest.mock('@src/services/roomServices', () => ({ setIsDeleteRoom: jest.fn(), })); jest.mock('react-hot-toast'); diff --git a/hotel-management/src/hooks/rooms/__tests__/useUpdateRoom.test.tsx b/hotel-management/src/hooks/rooms/__tests__/useUpdateRoom.test.tsx index 064c1d8..03d12e4 100644 --- a/hotel-management/src/hooks/rooms/__tests__/useUpdateRoom.test.tsx +++ b/hotel-management/src/hooks/rooms/__tests__/useUpdateRoom.test.tsx @@ -8,13 +8,13 @@ import { import { ReactNode } from 'react'; // Types -import { IRoom } from '@type/room'; +import { IRoom } from '@src/types/room'; // Constants -import { UPDATE_SUCCESS } from '@constant/messages'; +import { UPDATE_SUCCESS } from '@src/constants/messages'; // Services -import { updateRoom } from '@service/roomServices'; +import { updateRoom } from '@src/services/roomServices'; // Hooks import { useUpdateRoom } from '../useUpdateRoom'; @@ -24,7 +24,7 @@ jest.mock('@tanstack/react-query', () => ({ ...jest.requireActual('@tanstack/react-query'), useQueryClient: jest.fn(), })); -jest.mock('@service/roomServices', () => ({ +jest.mock('@src/services/roomServices', () => ({ updateRoom: jest.fn(), })); jest.mock('react-hot-toast'); diff --git a/hotel-management/src/hooks/rooms/useCreateRoom.ts b/hotel-management/src/hooks/rooms/useCreateRoom.ts index ba3f767..fb56ee4 100644 --- a/hotel-management/src/hooks/rooms/useCreateRoom.ts +++ b/hotel-management/src/hooks/rooms/useCreateRoom.ts @@ -2,13 +2,13 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; // Services -import { createRoom as createRoomFn } from '@service/roomServices'; +import { createRoom as createRoomFn} from '@src/services/roomServices'; // Constants -import { ADD_SUCCESS } from '@constant/messages'; +import { ADD_SUCCESS } from '@src/constants/messages'; // Hooks -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; +import { useUserRoomAvailable } from '../useUserRoomAvailable'; /** * Create room on database diff --git a/hotel-management/src/hooks/rooms/useRooms.ts b/hotel-management/src/hooks/rooms/useRooms.ts index 1a1ad03..a6d6601 100644 --- a/hotel-management/src/hooks/rooms/useRooms.ts +++ b/hotel-management/src/hooks/rooms/useRooms.ts @@ -3,10 +3,10 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useSearchParams } from 'react-router-dom'; // Services -import { getAllRooms } from '@service/roomServices'; +import { getAllRooms } from '@src/services/roomServices'; // Constants -import { DEFAULT_PAGE_SIZE } from '@constant/config'; +import { DEFAULT_PAGE_SIZE } from '@src/constants/config'; /** * Fetch room from database diff --git a/hotel-management/src/hooks/rooms/useSetIsDeleteRoom.ts b/hotel-management/src/hooks/rooms/useSetIsDeleteRoom.ts index b68b766..5eda176 100644 --- a/hotel-management/src/hooks/rooms/useSetIsDeleteRoom.ts +++ b/hotel-management/src/hooks/rooms/useSetIsDeleteRoom.ts @@ -2,13 +2,13 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; // Services -import { setIsDeleteRoom as setIsDeleteRoomFn } from '@service/roomServices'; +import { setIsDeleteRoom as setIsDeleteRoomFn } from '@src/services/roomServices'; // Constants -import * as messages from '@constant/messages'; +import { DELETE_SUCCESS } from '@src/constants/messages'; // Hooks -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; +import { useUserRoomAvailable } from '../useUserRoomAvailable'; /** * Delete the room from database @@ -25,7 +25,7 @@ const useSetIsDeleteRoom = () => { } = useMutation({ mutationFn: setIsDeleteRoomFn, onSuccess: (room) => { - toast.success(messages.DELETE_SUCCESS); + toast.success(DELETE_SUCCESS); queryClient.invalidateQueries({ queryKey: ['rooms'], }); diff --git a/hotel-management/src/hooks/rooms/useUpdateRoom.ts b/hotel-management/src/hooks/rooms/useUpdateRoom.ts index 7560074..3ac8b0e 100644 --- a/hotel-management/src/hooks/rooms/useUpdateRoom.ts +++ b/hotel-management/src/hooks/rooms/useUpdateRoom.ts @@ -2,13 +2,13 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; // Services -import { updateRoom as updateRoomFn } from '@service/roomServices'; +import { updateRoom as updateRoomFn } from '@src/services/roomServices'; // Constants -import { UPDATE_SUCCESS } from '@constant/messages'; +import { UPDATE_SUCCESS } from '@src/constants/messages'; // Hooks -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; +import { useUserRoomAvailable } from '../useUserRoomAvailable'; /** * Update room from database diff --git a/hotel-management/src/hooks/useItemSelected.ts b/hotel-management/src/hooks/useItemSelected.ts new file mode 100644 index 0000000..a2fe3e5 --- /dev/null +++ b/hotel-management/src/hooks/useItemSelected.ts @@ -0,0 +1,22 @@ +import { useContext } from 'react'; + +// Contexts +import { ItemSelectContext } from '@src/contexts/ItemSelected'; + +/** + * The hooks check the place call is in UserRoomAvailableProvider or not + * @returns The context of UserRoomAvailableContext + */ +const useItemSelect = () => { + const context = useContext(ItemSelectContext); + + if (context === undefined) { + throw new Error( + 'ItemSelectContext was used outside of ItemSelectContextProvider' + ); + } + + return context; +}; + +export { useItemSelect }; diff --git a/hotel-management/src/hooks/useOutsideClick.ts b/hotel-management/src/hooks/useOutsideClick.ts index 84a2248..24182a0 100644 --- a/hotel-management/src/hooks/useOutsideClick.ts +++ b/hotel-management/src/hooks/useOutsideClick.ts @@ -1,7 +1,7 @@ import { MutableRefObject, useEffect, useRef } from 'react'; // Types -import { Nullable } from '@type/common'; +import { Nullable } from '@src/types/common'; /** * Custom hook to call handler when click outside element diff --git a/hotel-management/src/hooks/useUserRoomAvailable.ts b/hotel-management/src/hooks/useUserRoomAvailable.ts index ffc1fbd..e34043a 100644 --- a/hotel-management/src/hooks/useUserRoomAvailable.ts +++ b/hotel-management/src/hooks/useUserRoomAvailable.ts @@ -1,7 +1,7 @@ import { useContext } from 'react'; // Contexts -import { UserRoomAvailableContext } from '@context/UserRoomAvailableContext'; +import { UserRoomAvailableContext } from '@src/contexts/UserRoomAvailableContext'; /** * The hooks check the place call is in UserRoomAvailableProvider or not diff --git a/hotel-management/src/hooks/users/__tests__/useCreateUser.test.tsx b/hotel-management/src/hooks/users/__tests__/useCreateUser.test.tsx index 3b8aee8..d7fba49 100644 --- a/hotel-management/src/hooks/users/__tests__/useCreateUser.test.tsx +++ b/hotel-management/src/hooks/users/__tests__/useCreateUser.test.tsx @@ -11,20 +11,20 @@ import { ReactNode } from 'react'; import { useCreateUser } from '../useCreateUser'; // Types -import { IUser } from '@type/user'; +import { IUser } from '@src/types/user'; // Constants -import { ADD_SUCCESS } from '@constant/messages'; +import { ADD_SUCCESS } from '@src/constants/messages'; // Services -import { createUser } from '@service/userServices'; +import { createUser } from '@src/services/userServices'; // Mock the necessary dependencies jest.mock('@tanstack/react-query', () => ({ ...jest.requireActual('@tanstack/react-query'), useQueryClient: jest.fn(), })); -jest.mock('@service/userServices', () => ({ +jest.mock('@src/services/userServices', () => ({ createUser: jest.fn(), })); jest.mock('react-hot-toast'); diff --git a/hotel-management/src/hooks/users/__tests__/useSetIsDeleteUser.test.tsx b/hotel-management/src/hooks/users/__tests__/useSetIsDeleteUser.test.tsx index 544abea..78b2729 100644 --- a/hotel-management/src/hooks/users/__tests__/useSetIsDeleteUser.test.tsx +++ b/hotel-management/src/hooks/users/__tests__/useSetIsDeleteUser.test.tsx @@ -8,13 +8,13 @@ import { import { ReactNode } from 'react'; // Types -import { IUser } from '@type/user'; +import { IUser } from '@src/types/user'; // Constants -import { DELETE_SUCCESS } from '@constant/messages'; +import { DELETE_SUCCESS } from '@src/constants/messages'; // Services -import { setIsDeleteUser } from '@service/userServices'; +import { setIsDeleteUser } from '@src/services/userServices'; // Hooks import { useIsDeleteUser } from '../useSetIsDeleteUser'; @@ -24,7 +24,7 @@ jest.mock('@tanstack/react-query', () => ({ ...jest.requireActual('@tanstack/react-query'), useQueryClient: jest.fn(), })); -jest.mock('@service/userServices', () => ({ +jest.mock('@src/services/userServices', () => ({ setIsDeleteUser: jest.fn(), })); jest.mock('react-hot-toast'); diff --git a/hotel-management/src/hooks/users/__tests__/useUpdateUser.test.tsx b/hotel-management/src/hooks/users/__tests__/useUpdateUser.test.tsx index c2bd258..bd507a1 100644 --- a/hotel-management/src/hooks/users/__tests__/useUpdateUser.test.tsx +++ b/hotel-management/src/hooks/users/__tests__/useUpdateUser.test.tsx @@ -8,13 +8,13 @@ import { import { ReactNode } from 'react'; // Types -import { IUser } from '@type/user'; +import { IUser } from '@src/types/user'; // Constants -import { UPDATE_SUCCESS } from '@constant/messages'; +import { UPDATE_SUCCESS } from '@src/constants/messages'; // Services -import { updateUser } from '@service/userServices'; +import { updateUser } from '@src/services/userServices'; // Hooks import { useUpdateUser } from '../useUpdateUser'; @@ -24,7 +24,7 @@ jest.mock('@tanstack/react-query', () => ({ ...jest.requireActual('@tanstack/react-query'), useQueryClient: jest.fn(), })); -jest.mock('@service/userServices', () => ({ +jest.mock('@src/services/userServices', () => ({ updateUser: jest.fn(), })); jest.mock('react-hot-toast'); diff --git a/hotel-management/src/hooks/users/__tests__/useUsers.test.tsx b/hotel-management/src/hooks/users/__tests__/useUsers.test.tsx index 8c2dcbf..46b319a 100644 --- a/hotel-management/src/hooks/users/__tests__/useUsers.test.tsx +++ b/hotel-management/src/hooks/users/__tests__/useUsers.test.tsx @@ -8,7 +8,7 @@ import { renderHook } from '@testing-library/react'; import { URLSearchParams } from 'url'; // Services -import { getAllUsers } from '@service/userServices'; +import { getAllUsers } from '@src/services/userServices'; // Hooks import { useUsers } from '../useUsers'; @@ -22,7 +22,7 @@ jest.mock('@tanstack/react-query', () => ({ useQuery: jest.fn(), })); -jest.mock('@service/userServices', () => ({ +jest.mock('@src/services/userServices', () => ({ getAllUsers: jest.fn(), })); @@ -69,7 +69,7 @@ describe('useUsers hook', () => { }); test('Should prefetch the second page when in the first page', async () => { - const sampleDate = { data: [{ id: 1, name: 'User 1' }], count: 7 }; + const sampleDate = { data: [{ id: 1, name: 'User 1' }], count: 11 }; (useSearchParams as jest.Mock).mockReturnValue([ new URLSearchParams('page=1'), @@ -106,7 +106,7 @@ describe('useUsers hook', () => { }); test('Should prefetch the previous page and next page when in the second page', async () => { - const sampleDate = { data: [{ id: 1, name: 'User 1' }], count: 12 }; + const sampleDate = { data: [{ id: 1, name: 'User 1' }], count: 22 }; (useSearchParams as jest.Mock).mockReturnValue([ new URLSearchParams('page=2'), diff --git a/hotel-management/src/hooks/users/useCreateUser.ts b/hotel-management/src/hooks/users/useCreateUser.ts index dcd7830..15146c3 100644 --- a/hotel-management/src/hooks/users/useCreateUser.ts +++ b/hotel-management/src/hooks/users/useCreateUser.ts @@ -2,13 +2,13 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; // Services -import { createUser as createUserFn } from '@service/userServices'; +import { createUser as createUserFn } from '@src/services/userServices'; // Constants -import { ADD_SUCCESS } from '@constant/messages'; +import { ADD_SUCCESS } from '@src/constants/messages'; // Hooks -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; +import { useUserRoomAvailable } from '../useUserRoomAvailable'; /** * Create user in database diff --git a/hotel-management/src/hooks/users/useSetIsDeleteUser.ts b/hotel-management/src/hooks/users/useSetIsDeleteUser.ts index 4a2cad6..7b97cca 100644 --- a/hotel-management/src/hooks/users/useSetIsDeleteUser.ts +++ b/hotel-management/src/hooks/users/useSetIsDeleteUser.ts @@ -2,11 +2,13 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; // Services -import { setIsDeleteUser as setIsDeleteUserFn } from '@service/userServices'; +import { setIsDeleteUser as setIsDeleteUserFn } from '@src/services/userServices'; // Constants -import * as messages from '@constant/messages'; -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; +import { DELETE_SUCCESS } from '@src/constants/messages'; + +// Hooks +import { useUserRoomAvailable } from '../useUserRoomAvailable'; /** * Delete the user from database @@ -23,7 +25,7 @@ const useIsDeleteUser = () => { } = useMutation({ mutationFn: setIsDeleteUserFn, onSuccess: (user) => { - toast.success(messages.DELETE_SUCCESS); + toast.success(DELETE_SUCCESS); queryClient.invalidateQueries({ queryKey: ['users'], }); diff --git a/hotel-management/src/hooks/users/useUpdateUser.ts b/hotel-management/src/hooks/users/useUpdateUser.ts index db023b2..7773ac6 100644 --- a/hotel-management/src/hooks/users/useUpdateUser.ts +++ b/hotel-management/src/hooks/users/useUpdateUser.ts @@ -2,13 +2,13 @@ import toast from 'react-hot-toast'; import { useMutation, useQueryClient } from '@tanstack/react-query'; // Services -import { updateUser as updateUserFn } from '@service/userServices'; +import { updateUser as updateUserFn } from '@src/services/userServices'; // Constants -import { UPDATE_SUCCESS } from '@constant/messages'; +import { UPDATE_SUCCESS } from '@src/constants/messages'; // Hooks -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; +import { useUserRoomAvailable } from '../useUserRoomAvailable'; /** * Update user from database diff --git a/hotel-management/src/hooks/users/useUsers.ts b/hotel-management/src/hooks/users/useUsers.ts index fd0582f..4da439d 100644 --- a/hotel-management/src/hooks/users/useUsers.ts +++ b/hotel-management/src/hooks/users/useUsers.ts @@ -3,10 +3,10 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useSearchParams } from 'react-router-dom'; // Services -import { getAllUsers } from '@service/userServices'; +import { getAllUsers } from '@src/services/userServices'; // Constants -import { DEFAULT_PAGE_SIZE } from '@constant/config'; +import { DEFAULT_PAGE_SIZE } from '@src/constants/config'; /** * Fetch data of users from database diff --git a/hotel-management/src/pages/Account/AccountInforForm.tsx b/hotel-management/src/pages/Account/AccountInforForm.tsx index 1494b7f..28d0fe7 100644 --- a/hotel-management/src/pages/Account/AccountInforForm.tsx +++ b/hotel-management/src/pages/Account/AccountInforForm.tsx @@ -1,17 +1,17 @@ import { useForm } from 'react-hook-form'; // Styled -import Input from '@commonStyle/Input'; +import Input from '@src/commons/styles/Input'; // Components -import Form from '@component/Form'; +import Form from '@src/components/Form'; // Constants -import { REQUIRED_FIELD_ERROR } from '@constant/formValidateMessage'; +import { REQUIRED_FIELD_ERROR } from '@src/constants/formValidateMessage'; // Hooks -import { useUpdateAccount } from '@hook/authentication/useUpdateAccount'; -import { useAccount } from '@hook/authentication/useAccount'; +import { useUpdateAccount } from '@src/hooks/authentication/useUpdateAccount'; +import { useAccount } from '@src/hooks/authentication/useAccount'; interface IAccountForm { fullName: string; diff --git a/hotel-management/src/pages/Account/AccountPasswordForm.tsx b/hotel-management/src/pages/Account/AccountPasswordForm.tsx index 8f97e99..5b8f7c4 100644 --- a/hotel-management/src/pages/Account/AccountPasswordForm.tsx +++ b/hotel-management/src/pages/Account/AccountPasswordForm.tsx @@ -3,24 +3,24 @@ import { useForm } from 'react-hook-form'; import toast from 'react-hot-toast'; // Styled -import Input from '@commonStyle/Input'; +import Input from '@src/commons/styles/Input'; // Components -import Form from '@component/Form'; +import Form from '@src/components/Form'; // Constants -import { REGEX } from '@constant/commons'; +import { REGEX } from '@src/constants/commons'; import { PASSWORD_CONDITION, PASSWORD_NOT_MATCH, PASSWORD_NOT_MATCH_REQUIREMENT, -} from '@constant/formValidateMessage'; +} from '@src/constants/formValidateMessage'; // Helpers -import { isValidRegex } from '@helper/validators'; +import { isValidRegex } from '@src/helpers/validators'; // Hooks -import { useUpdateAccount } from '@hook/authentication/useUpdateAccount'; +import { useUpdateAccount } from '@src/hooks/authentication/useUpdateAccount'; interface IAccountPasswordForm { password: string; diff --git a/hotel-management/src/pages/Account/__tests__/AccountInforForm.test.tsx b/hotel-management/src/pages/Account/__tests__/AccountInforForm.test.tsx index 28fa3e2..b720cef 100644 --- a/hotel-management/src/pages/Account/__tests__/AccountInforForm.test.tsx +++ b/hotel-management/src/pages/Account/__tests__/AccountInforForm.test.tsx @@ -2,14 +2,14 @@ import { act, fireEvent, render, RenderResult, waitFor } from '@testing-library/ import '@testing-library/jest-dom'; // Components -import AccountInforForm from '@page/Account/AccountInforForm'; +import AccountInforForm from '@src/pages/Account/AccountInforForm'; // Hooks -import { useAccount } from '@hook/authentication/useAccount'; -import { useUpdateAccount } from '@hook/authentication/useUpdateAccount'; +import { useAccount } from '@src/hooks/authentication/useAccount'; +import { useUpdateAccount } from '@src/hooks/authentication/useUpdateAccount'; -jest.mock('@hook/authentication/useUpdateAccount'); -jest.mock('@hook/authentication/useAccount'); +jest.mock('@src/hooks/authentication/useUpdateAccount'); +jest.mock('@src/hooks/authentication/useAccount'); const mockAccount = { email: 'admin@nezumi.site', diff --git a/hotel-management/src/pages/Account/__tests__/AccountPasswordForm.test.tsx b/hotel-management/src/pages/Account/__tests__/AccountPasswordForm.test.tsx index 46dd14b..aacf471 100644 --- a/hotel-management/src/pages/Account/__tests__/AccountPasswordForm.test.tsx +++ b/hotel-management/src/pages/Account/__tests__/AccountPasswordForm.test.tsx @@ -10,9 +10,9 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import AccountPasswordForm from '../AccountPasswordForm'; // Hooks -import { useUpdateAccount } from '@hook/authentication/useUpdateAccount'; +import { useUpdateAccount } from '@src/hooks/authentication/useUpdateAccount'; -jest.mock('@hook/authentication/useUpdateAccount'); +jest.mock('@src/hooks/authentication/useUpdateAccount'); describe('AccountPasswordForm', () => { let wrapper: RenderResult | null = null; diff --git a/hotel-management/src/pages/Booking/BookingForm.tsx b/hotel-management/src/pages/Booking/BookingForm.tsx index 8b27fad..fe948d0 100644 --- a/hotel-management/src/pages/Booking/BookingForm.tsx +++ b/hotel-management/src/pages/Booking/BookingForm.tsx @@ -2,29 +2,29 @@ import { useCallback, useMemo, useState } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; // Styled -import Input from '@commonStyle/Input.ts'; +import Input from '@src/commons/styles/Input'; // Constants -import { REQUIRED_FIELD_ERROR } from '@constant/formValidateMessage.ts'; +import { REQUIRED_FIELD_ERROR } from '@src/constants/formValidateMessage'; // Components -import Form from '@component/Form/index.tsx'; -import Select, { ISelectOptions } from '@component/Select/index.tsx'; +import Form from '@src/components/Form'; +import Select, { ISelectOptions } from '@src/components/Select/index.tsx'; // Hooks -import { useCreateBooking } from '@hook/bookings/useCreateBooking.ts'; -import { useUpdateBooking } from '@hook/bookings/useUpdateBooking.ts'; -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable.ts'; +import { useCreateBooking } from '@src/hooks/bookings/useCreateBooking'; +import { useUpdateBooking } from '@src/hooks/bookings/useUpdateBooking'; +import { useUserRoomAvailable } from '@src/hooks/useUserRoomAvailable'; // Helpers -import { formatCurrency, getDayDiff } from '@helper/helper.ts'; +import { formatCurrency, getDayDiff } from '@src/helpers/helper'; // Services -import { getRoomById, updateRoomStatus } from '@service/roomServices.ts'; -import { updateUserBookedStatus } from '@service/userServices.ts'; +import { getRoomById, updateRoomStatus } from '@src/services/roomServices'; +import { updateUserBookedStatus } from '@src/services/userServices'; // Types -import { IBooking, TBookingResponse } from '@type/booking.ts'; +import { IBooking, TBookingResponse } from '@src/types/booking'; interface IBookingFormProp { onCloseModal?: () => void; @@ -37,6 +37,7 @@ const BookingForm = ({ onCloseModal, booking }: IBookingFormProp) => { usersAvailable, dispatch } = useUserRoomAvailable(); + const { isCreating, createBooking } = useCreateBooking(); const { isUpdating, updateBooking } = useUpdateBooking(); const isLoading = isCreating || isUpdating; @@ -83,7 +84,7 @@ const BookingForm = ({ onCloseModal, booking }: IBookingFormProp) => { type: 'updateStatusRoom', payload: [{ id: newBooking.roomId, status: true }], }); - + // Update room, user available in server await updateRoomStatus(newBooking.roomId, true); await updateUserBookedStatus(newBooking.userId, true); diff --git a/hotel-management/src/pages/Booking/BookingRow.tsx b/hotel-management/src/pages/Booking/BookingRow.tsx deleted file mode 100644 index ab7f9bd..0000000 --- a/hotel-management/src/pages/Booking/BookingRow.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import toast from 'react-hot-toast'; -import { useCallback, useMemo } from 'react'; - -// Helpers -import { formatCurrency } from '@helper/helper'; - -// Types -import { TBookingResponse } from '@type/booking'; - -// Components -import Modal from '@component/Modal'; -import Table from '@component/Table'; -import Menus from '@component/Menus'; -import { RiEditBoxFill } from 'react-icons/ri'; -import { TbArrowNarrowRight } from 'react-icons/tb'; -import { ImExit } from 'react-icons/im'; -import BookingForm from './BookingForm'; -import ConfirmMessage from '@component/ConfirmMessage'; - -// Hooks -import useCheckOut from '@hook/bookings/useCheckout'; - -// Constants -import { FORM } from '@constant/commons'; - -interface IBookingRow { - booking: TBookingResponse; -} - -const BookingRow = ({ booking }: IBookingRow) => { - const { checkOutBooking } = useCheckOut(); - const { - id, - users, - startDate, - endDate, - rooms, - amount, - status - } = booking; - const formattedPrice = useMemo(() => formatCurrency(amount), [amount]); - const renderEditBtn = useCallback( - (onCloseModal: () => void) => ( - } - disabled={!status} - > - Edit - - ), - [status] - ); - - const renderCheckOutBtn = useCallback( - (onCloseModal: () => void) => ( - } - disabled={!status} - > - Checkout - - ), - [status] - ); - - const handleClickCheckOutBtn = useCallback(() => { - if (booking.status) { - checkOutBooking({ - idBooking: booking.id, - roomId: booking!.rooms!.id, - userId: booking!.users!.id, - }); - } else { - toast.error('User already checkout!'); - } - }, [booking, checkOutBooking]); - - return ( - -
    {users?.name}
    -
    - {startDate}   -   {endDate} -
    -
    {rooms?.name}
    -
    {formattedPrice}
    -
    { - status - ? 'Check in' - : 'Check out' - }
    - -
    - - - - - - - - - - - - - - - - - - - -
    -
    - ); -}; - -export default BookingRow; diff --git a/hotel-management/src/pages/Booking/BookingTable.tsx b/hotel-management/src/pages/Booking/BookingTable.tsx deleted file mode 100644 index dd5faea..0000000 --- a/hotel-management/src/pages/Booking/BookingTable.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { useCallback } from 'react'; - -// Components -import Menus from '@component/Menus'; -import Table from '@component/Table'; -import Message from '@component/Message'; -import Search from '@component/Search'; -import Pagination from '@component/Pagination'; -import BookingRow from './BookingRow'; - -// Styled -import { StyledOperationTable } from './styled'; -import Direction from '@commonStyle/Direction'; -import Spinner from '@commonStyle/Spinner'; - -// Hooks -import { useBookings } from '@hook/bookings/useBookings'; - -// Types -import { TBookingResponse } from '@type/booking'; - -const BookingTable = () => { - const columnName = [ - 'User', - 'Date', - 'Room', - 'Amount', - 'Status' - ]; - const { - isLoading, - bookings, - count - } = useBookings(); - - const renderBookingRow = useCallback( - (booking: TBookingResponse) => ( - - ), - [] - ); - - return ( - <> - - - - - - {isLoading && } - - {bookings && bookings.length ? ( - - - - - data={bookings} - render={renderBookingRow} - /> - - - -
    -
    - ) : ( - !isLoading && No data to show here! - )} -
    - - ); -}; - -export default BookingTable; diff --git a/hotel-management/src/pages/Booking/__tests__/BookingForm.test.tsx b/hotel-management/src/pages/Booking/__tests__/BookingForm.test.tsx index 61ff7f5..f29bfa8 100644 --- a/hotel-management/src/pages/Booking/__tests__/BookingForm.test.tsx +++ b/hotel-management/src/pages/Booking/__tests__/BookingForm.test.tsx @@ -8,25 +8,25 @@ import { } from '@testing-library/react'; // Types -import { TBookingResponse } from '@type/booking'; +import { TBookingResponse } from '@src/types/booking'; // Components import BookingForm from '../BookingForm'; // Hooks -import { useUserRoomAvailable } from '@hook/useUserRoomAvailable'; +import { useUserRoomAvailable } from '@src/hooks/useUserRoomAvailable'; const mockUpdateBooking = jest.fn(); -jest.mock('@hook/bookings/useUpdateBooking', () => ({ - ...jest.requireActual('@hook/bookings/useUpdateBooking'), +jest.mock('@src/hooks/bookings/useUpdateBooking', () => ({ + ...jest.requireActual('@src/hooks/bookings/useUpdateBooking'), useUpdateBooking: jest.fn(() => ({ isUpdating: false, updateBooking: mockUpdateBooking, })), })); -jest.mock('@hook/useUserRoomAvailable.ts'); +jest.mock('@src/hooks/useUserRoomAvailable.ts'); const mockUseUserRoomAvailable = useUserRoomAvailable as jest.MockedFunction< typeof useUserRoomAvailable diff --git a/hotel-management/src/pages/Booking/__tests__/BookingRow.test.tsx b/hotel-management/src/pages/Booking/__tests__/BookingRow.test.tsx deleted file mode 100644 index 570ab85..0000000 --- a/hotel-management/src/pages/Booking/__tests__/BookingRow.test.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { render } from '@testing-library/react'; - -// Types -import { TBookingResponse } from '@type/booking'; - -// Components -import BookingRow from '../BookingRow'; - -describe('BookingRow', () => { - const tempBooking: TBookingResponse = { - id: 1, - startDate: '2024-11-21', - endDate: '2024-11-22', - amount: 1200, - status: true, - rooms: { - id: 1, - name: 'Room 1', - }, - users: { - id: 2, - name: 'Room 2', - }, - }; - - const queryClient = new QueryClient(); - const wrapper = render( - - - - ); - - test('Should render correctly', () => { - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/hotel-management/src/pages/Booking/__tests__/BookingTable.test.tsx b/hotel-management/src/pages/Booking/__tests__/BookingTable.test.tsx deleted file mode 100644 index 15470f4..0000000 --- a/hotel-management/src/pages/Booking/__tests__/BookingTable.test.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { BrowserRouter } from 'react-router-dom'; -import { render } from '@testing-library/react'; - -// Components -import BookingTable from '@page/Booking/BookingTable'; - -describe('UserTable', () => { - const queryClient = new QueryClient(); - - const wrapper = render( - - - - - - ); - - test('Should render correctly', () => { - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/hotel-management/src/pages/Booking/__tests__/__snapshots__/BookingForm.test.tsx.snap b/hotel-management/src/pages/Booking/__tests__/__snapshots__/BookingForm.test.tsx.snap index 54009f0..0683a96 100644 --- a/hotel-management/src/pages/Booking/__tests__/__snapshots__/BookingForm.test.tsx.snap +++ b/hotel-management/src/pages/Booking/__tests__/__snapshots__/BookingForm.test.tsx.snap @@ -79,7 +79,7 @@ exports[`BookingForm Should render correctly 1`] = ` @@ -223,7 +223,7 @@ exports[`BookingForm Should render correctly 1`] = ` diff --git a/hotel-management/src/pages/Booking/index.tsx b/hotel-management/src/pages/Booking/index.tsx index 0edb7b4..6a9a122 100644 --- a/hotel-management/src/pages/Booking/index.tsx +++ b/hotel-management/src/pages/Booking/index.tsx @@ -1,36 +1,209 @@ -// Styled -import Direction from '@commonStyle/Direction'; -import { StyledBooking, Title } from './styled'; -import Button from '@commonStyle/Button'; - // Components -import Modal from '@component/Modal'; -import BookingTable from './BookingTable'; import BookingForm from './BookingForm'; +import Modal from '@src/components/Modal'; +import ButtonIcon from '@src/components/ButtonIcon'; +import Direction from '@src/commons/styles/Direction'; +import {FiEdit} from 'react-icons/fi'; +import {MdOutlineAddCircleOutline} from 'react-icons/md'; +import Table from '@src/components/Table'; -// Constants -import { FORM } from '@constant/commons'; +// Styled +import {ActionTable, StyledBooking, Title} from './styled'; +import Spinner from '@src/commons/styles/Spinner.ts'; + +// Types +import {ColumnProps} from '@src/types/common.ts'; +import {TBookingResponse} from '@src/types/booking.ts'; + +// Hooks +import {useBookings} from '@src/hooks/bookings/useBookings.ts'; +import {useEffect, useState} from 'react'; +import {FORM} from '@src/constants/commons.ts'; +import {findItemInListById, formatCurrency} from '@src/helpers/helper.ts'; +import ConfirmMessage from '@src/components/ConfirmMessage'; +import useCheckOut from '@src/hooks/bookings/useCheckout.ts'; +import toast from 'react-hot-toast'; +import {ImExit} from "react-icons/im"; +import Message from "@src/components/Message"; + +interface IBookingTable extends Omit { + amount: string; + status: string; +} const Booking = () => { + const {checkOutBooking} = useCheckOut(); + const [itemSelected, setItemSelected] = useState(); + let bookingSelected: TBookingResponse | undefined; + + const columns: ColumnProps[] = [ + { + key: 'user', + title: 'User', + width: 10 + }, + { + key: 'date', + title: 'Date', + width: 25, + isDateValue: true + }, + { + key: 'room', + title: 'Room', + width: 20 + }, + { + key: 'amount', + title: 'Amount', + width: 15 + }, + { + key: 'status', + title: 'Status', + width: 20 + } + ]; + const {isLoading, bookings, count} = useBookings(); + + // Reset value when bookings changed. + useEffect(() => { + setItemSelected(undefined); + }, [bookings]); + + const tempBookings = bookings?.map((booking) => ( + { + ...booking, + date: [booking.startDate, booking.endDate], + amount: formatCurrency(booking.amount), + room: booking.rooms!.name, + user: booking.users!.name, + status: booking.status + ? 'Check in' + : 'Check out', + } + )); + + if (itemSelected && bookings) { + bookingSelected = findItemInListById(itemSelected.id, bookings); + } + + const handleClickCheckOutBtn = () => { + if (itemSelected && itemSelected.status) { + checkOutBooking({ + idBooking: itemSelected.id, + roomId: itemSelected!.rooms!.id, + userId: itemSelected!.users!.id + }); + } else { + toast.error('User already checkout!'); + } + }; + return ( List Booking - ( - - )} - /> - - - + + ( + } + text={'Add Booking'} + iconSize={'18px'} + fontSize={'var(--fs-sm)'} + variations={'primary'} + iconColor={'white'} + onClick={onCloseModal} + /> + )} + /> + + ( + } + text={'Edit'} + iconSize={'18px'} + fontSize={'var(--fs-sm)'} + variations={'success'} + iconColor={'white'} + disabled={!itemSelected || itemSelected?.status === 'Check out'} + onClick={onCloseModal} + /> + )} + /> + + ( + } + text={'Check out'} + iconSize={'18px'} + fontSize={'var(--fs-sm)'} + variations={'danger'} + iconColor={'white'} + disabled={!itemSelected || itemSelected?.status === 'Check out'} + onClick={onCloseModal} + /> + )} + /> + + ( + + )} + /> + + + + }/> + + + + }/> + + - + {isLoading && } + + { + tempBookings && + Boolean(tempBookings.length) && + + columns={columns} + rows={tempBookings} + count={count} + searchPlaceHolder={'Search by name...'} + stateSelected={{ + itemSelected, + setItemSelected + }} + onRowClick={(data) => { + setItemSelected(data); + }}/> + } + + {tempBookings && Boolean(!tempBookings.length) && No data to show here!} ); }; diff --git a/hotel-management/src/pages/Booking/styled.ts b/hotel-management/src/pages/Booking/styled.ts index 7ea7730..7595e3a 100644 --- a/hotel-management/src/pages/Booking/styled.ts +++ b/hotel-management/src/pages/Booking/styled.ts @@ -14,14 +14,20 @@ const Title = styled.h2` text-transform: capitalize; `; -const StyledOperationTable = styled.div` +const StyledTableOption = styled.div` display: flex; gap: 30px; justify-content: flex-end; `; +const ActionTable = styled.div` + display: flex; + gap: 30px; +` + export { StyledBooking, Title, - StyledOperationTable + StyledTableOption, + ActionTable }; diff --git a/hotel-management/src/pages/Login/LoginForm.tsx b/hotel-management/src/pages/Login/LoginForm.tsx index af7d617..cca73dd 100644 --- a/hotel-management/src/pages/Login/LoginForm.tsx +++ b/hotel-management/src/pages/Login/LoginForm.tsx @@ -1,29 +1,29 @@ import { useForm } from 'react-hook-form'; // Components -import Form from '@component/Form'; +import Form from '@src/components/Form'; // Styled import { FieldInput, StyledLoginForm } from './styled'; -import Button from '@commonStyle/Button'; +import Button from '@src/commons/styles/Button'; // Constants import { INVALID_EMAIL, REQUIRED_FIELD_ERROR, -} from '@constant/formValidateMessage'; +} from '@src/constants/formValidateMessage'; // Types -import { ILogin } from '@type/common'; +import { ILogin } from '@src/types/common'; // Hooks -import { useLogin } from '@hook/authentication/useLogin'; +import { useLogin } from '@src/hooks/authentication/useLogin'; // Helpers -import { isValidRegex } from '@helper/validators'; +import { isValidRegex } from '@src/helpers/validators'; // Constants -import { REGEX } from '@constant/commons'; +import { REGEX } from '@src/constants/commons'; const LoginForm = () => { const { diff --git a/hotel-management/src/pages/Login/__tests__/LoginForm.test.tsx b/hotel-management/src/pages/Login/__tests__/LoginForm.test.tsx index 46e477a..05cbcc4 100644 --- a/hotel-management/src/pages/Login/__tests__/LoginForm.test.tsx +++ b/hotel-management/src/pages/Login/__tests__/LoginForm.test.tsx @@ -1,10 +1,10 @@ -import { useLogin } from "@hook/authentication/useLogin"; -import LoginForm from "@page/Login/LoginForm"; +import { useLogin } from "@src/hooks/authentication/useLogin"; +import LoginForm from "@src/pages/Login/LoginForm"; import { fireEvent, render, waitFor } from "@testing-library/react"; // Mock the useLogin hook -jest.mock('@hook/authentication/useLogin', () => ({ +jest.mock('@src/hooks/authentication/useLogin', () => ({ useLogin: jest.fn(), })); diff --git a/hotel-management/src/pages/Login/index.tsx b/hotel-management/src/pages/Login/index.tsx index e809c1c..84edaae 100644 --- a/hotel-management/src/pages/Login/index.tsx +++ b/hotel-management/src/pages/Login/index.tsx @@ -7,7 +7,7 @@ import { LoginLayout, StyledLogo, TitleStyled } from './styled'; import LoginForm from './LoginForm'; // Hooks -import { useAccount } from '@hook/authentication/useAccount'; +import { useAccount } from '@src/hooks/authentication/useAccount'; const Login = () => { const { account } = useAccount(); diff --git a/hotel-management/src/pages/Login/styled.ts b/hotel-management/src/pages/Login/styled.ts index 0dbc971..a5bfa43 100644 --- a/hotel-management/src/pages/Login/styled.ts +++ b/hotel-management/src/pages/Login/styled.ts @@ -1,7 +1,7 @@ import styled from 'styled-components'; // Styled -import CommonInput from '@commonStyle/CommonInput'; +import CommonInput from '@src/commons/styles/CommonInput'; const LoginLayout = styled.main` height: 100vh; diff --git a/hotel-management/src/pages/NotFound/__tests__/index.test.tsx b/hotel-management/src/pages/NotFound/__tests__/index.test.tsx index c09765d..1fadf02 100644 --- a/hotel-management/src/pages/NotFound/__tests__/index.test.tsx +++ b/hotel-management/src/pages/NotFound/__tests__/index.test.tsx @@ -1,4 +1,4 @@ -import { fireEvent, render, screen } from "@testing-library/react"; +import { fireEvent, render } from "@testing-library/react"; import NotFound from ".."; import { useNavigate } from "react-router-dom"; @@ -9,18 +9,18 @@ jest.mock('react-router-dom', () => ({ describe('NotFound', () => { test('Should render correctly', () => { - render(); + const wrapper = render(); - expect(screen.getByText('The page not found!')).toBeInTheDocument(); - expect(screen.getByText('Go back!')).toBeInTheDocument(); + expect(wrapper.getByText('The page not found!')).toBeInTheDocument(); + expect(wrapper.getByText('Go back!')).toBeInTheDocument(); }); test('Should call navigate correctly when click button', () => { const mockNavigate = jest.fn(); (useNavigate as jest.Mock).mockReturnValue(mockNavigate); - render(); + const wrapper = render(); - fireEvent.click(screen.getByText('Go back!')); + fireEvent.click(wrapper.getByText('Go back!')); expect(mockNavigate).toHaveBeenCalledTimes(1); expect(mockNavigate).toHaveBeenCalledWith(-1); diff --git a/hotel-management/src/pages/Room/RoomForm.tsx b/hotel-management/src/pages/Room/RoomForm.tsx index 2b1fdde..078e6cb 100644 --- a/hotel-management/src/pages/Room/RoomForm.tsx +++ b/hotel-management/src/pages/Room/RoomForm.tsx @@ -1,27 +1,27 @@ import { useForm } from 'react-hook-form'; // Styled -import Input from '@commonStyle/Input.ts'; +import Input from '@src/commons/styles/Input.ts'; // Types -import { IRoom } from '@type/room.ts'; +import { IRoom } from '@src/types/room.ts'; // Constants import { INVALID_FIELD, REQUIRED_FIELD_ERROR, -} from '@constant/formValidateMessage.ts'; +} from '@src/constants/formValidateMessage.ts'; import { REGEX } from '../../constants/commons.ts'; // Helpers -import { isValidRegex, isValidString } from '@helper/validators.ts'; +import { isValidRegex, isValidString } from '@src/helpers/validators.ts'; // Components -import Form from '@component/Form/index.tsx'; +import Form from '@src/components/Form/index.tsx'; // Hooks -import { useCreateRoom } from '@hook/rooms/useCreateRoom.ts'; -import { useUpdateRoom } from '@hook/rooms/useUpdateRoom.ts'; +import { useCreateRoom } from '@src/hooks/rooms/useCreateRoom.ts'; +import { useUpdateRoom } from '@src/hooks/rooms/useUpdateRoom.ts'; interface IRoomFormProp { onCloseModal?: () => void; diff --git a/hotel-management/src/pages/Room/RoomRow.tsx b/hotel-management/src/pages/Room/RoomRow.tsx deleted file mode 100644 index df5d73e..0000000 --- a/hotel-management/src/pages/Room/RoomRow.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { useCallback, useMemo } from 'react'; - -// Helpers -import { formatCurrency } from '@helper/helper'; - -// Types -import { IRoom } from '@type/room'; - -// Components -import RoomForm from './RoomForm'; -import Modal from '@component/Modal'; -import Table from '@component/Table'; -import Menus from '@component/Menus'; -import { RiEditBoxFill } from 'react-icons/ri'; -import { HiTrash } from 'react-icons/hi'; -import ConfirmMessage from '@component/ConfirmMessage'; - -// Hooks -import { useSetIsDeleteRoom } from '@hook/rooms/useSetIsDeleteRoom'; - -// Constants -import { FORM } from '@constant/commons'; - -interface IRoomRow { - room: IRoom; -} - -const RoomRow = ({ room }: IRoomRow) => { - const { - id, - name, - price, - status - } = room; - const { setIsDeleteRoom } = useSetIsDeleteRoom(); - const formattedPrice = useMemo(() => formatCurrency(price), [price]); - const renderEditBtn = useCallback( - (onCloseModal: () => void) => ( - }> - Edit - - ), - [] - ); - const renderDeleteBtn = useCallback( - (onCloseModal: () => void) => ( - } onClick={onCloseModal} disabled={status}> - Delete - - ), - [status] - ); - - return ( - -
    {id}
    -
    {name}
    -
    {formattedPrice}
    -
    { - status - ? 'Unavailable' - : 'Available' - }
    - -
    - - - - - - - - - - - - - - - setIsDeleteRoom(id)} - /> - - - -
    -
    - ); -}; - -export default RoomRow; diff --git a/hotel-management/src/pages/Room/RoomTable.tsx b/hotel-management/src/pages/Room/RoomTable.tsx deleted file mode 100644 index e0d8ce6..0000000 --- a/hotel-management/src/pages/Room/RoomTable.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { useCallback } from 'react'; - -// Components -import Menus from '@component/Menus'; -import Table from '@component/Table'; -import Message from '@component/Message'; -import Search from '@component/Search'; -import SortBy from '@component/SortBy'; -import OrderBy from '@component/OrderBy'; -import RoomRow from './RoomRow'; - -// Types -import { IRoom } from '@type/room'; - -// Constants -import { ORDERBY_OPTIONS, ROOM_PAGE } from '@constant/commons'; - -// Styled -import { StyledOperationTable } from './styled'; -import Direction from '@commonStyle/Direction'; -import Spinner from '@commonStyle/Spinner'; - -// Hooks -import { useRooms } from '@hook/rooms/useRooms'; -import Pagination from '@component/Pagination'; - -const RoomTable = () => { - const columnName = ['Id', 'Name', 'Price', 'Status']; - const { - isLoading, - rooms, - count - } = useRooms(); - - const renderRoomRow = useCallback( - (room: IRoom) => , - [] - ); - - return ( - <> - - - - - - - - - {isLoading && } - - {rooms && rooms.length ? ( - - - - data={rooms} render={renderRoomRow} /> - - - -
    -
    - ) : ( - !isLoading && No data to show here! - )} -
    - - ); -}; - -export default RoomTable; diff --git a/hotel-management/src/pages/Room/__tests__/RoomForm.test.tsx b/hotel-management/src/pages/Room/__tests__/RoomForm.test.tsx index 535f39b..6d06e9f 100644 --- a/hotel-management/src/pages/Room/__tests__/RoomForm.test.tsx +++ b/hotel-management/src/pages/Room/__tests__/RoomForm.test.tsx @@ -8,7 +8,7 @@ import { } from '@testing-library/react'; // Types -import { IRoom } from '@type/room'; +import { IRoom } from '@src/types/room'; // Components import RoomForm from '../RoomForm'; @@ -16,16 +16,16 @@ import RoomForm from '../RoomForm'; const mockCreateRoom = jest.fn(); const mockUpdateRoom = jest.fn(); -jest.mock('@hook/rooms/useCreateRoom.ts', () => ({ - ...jest.requireActual('@hook/rooms/useCreateRoom.ts'), +jest.mock('@src/hooks/rooms/useCreateRoom.ts', () => ({ + ...jest.requireActual('@src/hooks/rooms/useCreateRoom.ts'), useCreateRoom: jest.fn(() => ({ isCreating: false, createRoom: mockCreateRoom, })), })); -jest.mock('@hook/rooms/useUpdateRoom', () => ({ - ...jest.requireActual('@hook/rooms/useUpdateRoom'), +jest.mock('@src/hooks/rooms/useUpdateRoom', () => ({ + ...jest.requireActual('@src/hooks/rooms/useUpdateRoom'), useUpdateRoom: jest.fn(() => ({ isUpdating: false, updateRoom: mockUpdateRoom, diff --git a/hotel-management/src/pages/Room/__tests__/RoomRow.test.tsx b/hotel-management/src/pages/Room/__tests__/RoomRow.test.tsx deleted file mode 100644 index 838f984..0000000 --- a/hotel-management/src/pages/Room/__tests__/RoomRow.test.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { render } from '@testing-library/react'; - -// Types -import { IRoom } from '@type/room'; - -// Components -import RoomRow from '../RoomRow'; - -describe('RoomRow', () => { - const tempRoom: IRoom = { - id: 1, - name: 'Temp Room', - price: 2399, - status: false, - isDelete: true, - }; - - const queryClient = new QueryClient(); - const wrapper = render( - - - - ); - - test('Should render correctly', () => { - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/hotel-management/src/pages/Room/__tests__/RoomTable.test.tsx b/hotel-management/src/pages/Room/__tests__/RoomTable.test.tsx deleted file mode 100644 index d069141..0000000 --- a/hotel-management/src/pages/Room/__tests__/RoomTable.test.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { BrowserRouter } from 'react-router-dom'; -import { render } from '@testing-library/react'; - -// Components -import RoomTable from '@page/Room/RoomTable'; - -describe('UserTable', () => { - const queryClient = new QueryClient(); - - const wrapper = render( - - - - - - ); - - test('Should render correctly', () => { - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/hotel-management/src/pages/Room/index.tsx b/hotel-management/src/pages/Room/index.tsx index ddde771..a97a32c 100644 --- a/hotel-management/src/pages/Room/index.tsx +++ b/hotel-management/src/pages/Room/index.tsx @@ -1,33 +1,185 @@ // Components -import RoomTable from './RoomTable'; import RoomForm from './RoomForm'; -import Modal from '@component/Modal'; +import Modal from '@src/components/Modal'; +import ButtonIcon from '@src/components/ButtonIcon'; +import Direction from '@src/commons/styles/Direction'; +import { FiEdit } from 'react-icons/fi'; +import { FaRegTrashAlt } from 'react-icons/fa'; +import { MdOutlineAddCircleOutline } from 'react-icons/md'; +import Table from '@src/components/Table'; // Styled -import { StyledRoom, Title } from './styled'; -import Direction from '@commonStyle/Direction.ts'; -import Button from '@commonStyle/Button'; +import { ActionTable, StyledRoom, Title } from './styled'; +import Spinner from '@src/commons/styles/Spinner.ts'; + +// Types +import { ColumnProps } from '@src/types/common.ts'; +import { IRoom } from '@src/types/room.ts'; + +// Hooks +import { useRooms } from '@src/hooks/rooms/useRooms.ts'; +import { useEffect, useState } from 'react'; +import {FORM, ROOM_PAGE} from '@src/constants/commons.ts'; +import { findItemInListById } from '@src/helpers/helper.ts'; +import ConfirmMessage from '@src/components/ConfirmMessage'; +import { useSetIsDeleteRoom } from '@src/hooks/rooms/useSetIsDeleteRoom.ts'; +import Message from "@src/components/Message"; + +interface IRoomTable extends Omit { + status: string; +} const Room = () => { + const { setIsDeleteRoom } = useSetIsDeleteRoom(); + const [itemSelected, setItemSelected] = useState(); + let roomSelected: IRoom | undefined; + + const columns: ColumnProps[] = [ + { + key: 'id', + title: 'Id', + width: 10 + }, + { + key: 'name', + title: 'Name', + width: 40 + }, + { + key: 'price', + title: 'Price', + width: 20 + }, + { + key: 'status', + title: 'Status', + width: 20 + } + ]; + const { isLoading, rooms, count } = useRooms(); + + // Reset value when rooms changed. + useEffect(() => { + setItemSelected(undefined); + }, [rooms]); + + const tempRooms = rooms?.map((room) => ({ + ...room, + status: room.status + ? 'Unavailable' + : 'Available' + })); + + if (itemSelected && rooms) { + roomSelected = findItemInListById(itemSelected.id, rooms); + } + return ( List Room - ( - - )} - /> - - - + + ( + } + text={'Add Room'} + iconSize={'18px'} + fontSize={'var(--fs-sm)'} + variations={'primary'} + iconColor={'white'} + onClick={onCloseModal} + /> + )} + /> + + ( + } + text={'Edit'} + iconSize={'18px'} + fontSize={'var(--fs-sm)'} + variations={'success'} + iconColor={'white'} + disabled={!itemSelected} + onClick={onCloseModal} + /> + )} + /> + + ( + } + text={'Delete'} + iconSize={'18px'} + fontSize={'var(--fs-sm)'} + variations={'danger'} + iconColor={'white'} + disabled={!itemSelected || itemSelected?.status === 'Available'} + onClick={onCloseModal} + /> + )} + /> + + ( + + )} + /> + + + + } /> + + + setIsDeleteRoom(roomSelected!.id)} + onCloseModal={onCloseModal} + /> + } /> + + - + {isLoading && } + + { + tempRooms && + Boolean(tempRooms.length) && + + columns={columns} + rows={tempRooms} + count={count} + sortBy={ROOM_PAGE.SORTBY_OPTIONS} + enabledOrder={true} + searchPlaceHolder={'Search by name...'} + stateSelected={{ + itemSelected, + setItemSelected + }} + onRowClick={(data) => { + setItemSelected(data); + }} /> + } + + {tempRooms && Boolean(!tempRooms.length) && No data to show here!} ); }; diff --git a/hotel-management/src/pages/Room/styled.ts b/hotel-management/src/pages/Room/styled.ts index d6ded8e..239f9e9 100644 --- a/hotel-management/src/pages/Room/styled.ts +++ b/hotel-management/src/pages/Room/styled.ts @@ -14,14 +14,20 @@ const Title = styled.h2` text-transform: capitalize; `; -const StyledOperationTable = styled.div` +const StyledTableOption = styled.div` display: flex; gap: 30px; justify-content: flex-end; `; +const ActionTable = styled.div` + display: flex; + gap: 30px; +` + export { StyledRoom, Title, - StyledOperationTable + StyledTableOption, + ActionTable }; diff --git a/hotel-management/src/pages/User/UserForm.tsx b/hotel-management/src/pages/User/UserForm.tsx index ed9457f..d4fe3c1 100644 --- a/hotel-management/src/pages/User/UserForm.tsx +++ b/hotel-management/src/pages/User/UserForm.tsx @@ -1,28 +1,28 @@ import { FormProvider, useForm } from 'react-hook-form'; // Hooks -import { useCreateUser } from '@hook/users/useCreateUser.ts'; -import { useUpdateUser } from '@hook/users/useUpdateUser.ts'; +import { useCreateUser } from '@src/hooks/users/useCreateUser'; +import { useUpdateUser } from '@src/hooks/users/useUpdateUser'; // Styled -import Input from '@commonStyle/Input.ts'; +import Input from '@src/commons/styles/Input'; // Components -import Form from '@component/Form/index.tsx'; +import Form from '@src/components/Form'; // Helpers -import { isValidRegex } from '@helper/validators.ts'; +import { isValidRegex } from '@src/helpers/validators'; // Constants import { INVALID_FIELD, INVALID_PHONE, REQUIRED_FIELD_ERROR, -} from '@constant/formValidateMessage.ts'; -import { REGEX } from '@constant/commons.ts'; +} from '@src/constants/formValidateMessage'; +import { REGEX } from '@src/constants/commons'; // Types -import { IUser } from '@type/user'; +import { IUser } from '@src/types/user'; interface IUserFormProp { onCloseModal?: () => void; diff --git a/hotel-management/src/pages/User/UserRow.tsx b/hotel-management/src/pages/User/UserRow.tsx deleted file mode 100644 index 027449a..0000000 --- a/hotel-management/src/pages/User/UserRow.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { useCallback } from 'react'; - -// Components -import { RiEditBoxFill } from 'react-icons/ri'; -import Modal from '@component/Modal'; -import Table from '@component/Table'; -import Menus from '@component/Menus'; -import UserForm from './UserForm'; -import ConfirmMessage from '@component/ConfirmMessage'; -import { HiTrash } from 'react-icons/hi'; - -// Types -import { IUser } from '@type/user'; - -// Constants -import { FORM } from '@constant/commons'; - -// Hooks -import { useIsDeleteUser } from '@hook/users/useSetIsDeleteUser'; - -interface IUserRow { - user: IUser; -} - -const UserRow = ({ user }: IUserRow) => { - const { - id, - name, - phone, - isBooked - } = user; - const { setIsDeleteUser } = useIsDeleteUser(); - - const renderEditBtn = useCallback( - (onCloseModal: () => void) => ( - }> - Edit - - ), - [] - ); - - const renderDeleteBtn = useCallback( - (onCloseModal: () => void) => ( - } onClick={onCloseModal} disabled={isBooked}> - Delete - - ), - [isBooked] - ); - return ( - -
    {id}
    -
    {name}
    -
    {phone}
    -
    { - isBooked - ? 'Yes' - : 'No' - }
    -
    - - - - - - - - - - - - - - - - setIsDeleteUser(id)} - /> - - - -
    -
    - ); -}; - -export default UserRow; diff --git a/hotel-management/src/pages/User/UserTable.tsx b/hotel-management/src/pages/User/UserTable.tsx deleted file mode 100644 index 2e453ef..0000000 --- a/hotel-management/src/pages/User/UserTable.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { useCallback } from 'react'; - -// Components -import Menus from '@component/Menus'; -import Table from '@component/Table'; -import Message from '@component/Message'; -import Search from '@component/Search'; -import SortBy from '@component/SortBy'; -import OrderBy from '@component/OrderBy'; -import UserRow from './UserRow'; -import Pagination from '@component/Pagination'; - -// Types -import { IUser } from '@type/user'; - -// Constants -import { ORDERBY_OPTIONS, USER_PAGE } from '@constant/commons'; - -// Styled -import Direction from '@commonStyle/Direction'; -import { StyledOperationTable } from './styled'; -import Spinner from '@commonStyle/Spinner'; - -// Hooks -import { useUsers } from '@hook/users/useUsers'; - -const UserTable = () => { - const columnName = [ - 'Id', - 'Name', - 'Phone', - 'Is Booked' - ]; - const { - isLoading, - users, - count - } = useUsers(); - - const renderUserRow = useCallback( - (user: IUser) => ( - - ), - [] - ); - - return ( - <> - - - - - - - - - {isLoading && } - - {users && users.length ? ( - - - - data={users} render={renderUserRow} /> - - - -
    -
    - ) : ( - !isLoading && No data to show here! - )} -
    - - ); -}; - -export default UserTable; diff --git a/hotel-management/src/pages/User/__tests__/UserForm.test.tsx b/hotel-management/src/pages/User/__tests__/UserForm.test.tsx index 4df7455..bb387a1 100644 --- a/hotel-management/src/pages/User/__tests__/UserForm.test.tsx +++ b/hotel-management/src/pages/User/__tests__/UserForm.test.tsx @@ -11,21 +11,21 @@ import { import UserForm from '../UserForm'; // Types -import { IUser } from '@type/user'; +import { IUser } from '@src/types/user'; const mockCreateUser = jest.fn(); const mockUpdateUser = jest.fn(); -jest.mock('@hook/users/useCreateUser.ts', () => ({ - ...jest.requireActual('@hook/users/useCreateUser.ts'), +jest.mock('@src/hooks/users/useCreateUser.ts', () => ({ + ...jest.requireActual('@src/hooks/users/useCreateUser.ts'), useCreateUser: jest.fn(() => ({ isCreating: false, createUser: mockCreateUser, })), })); -jest.mock('@hook/users/useUpdateUser', () => ({ - ...jest.requireActual('@hook/users/useUpdateUser'), +jest.mock('@src/hooks/users/useUpdateUser', () => ({ + ...jest.requireActual('@src/hooks/users/useUpdateUser'), useUpdateUser: jest.fn(() => ({ isUpdating: false, updateUser: mockUpdateUser, diff --git a/hotel-management/src/pages/User/__tests__/UserRow.test.tsx b/hotel-management/src/pages/User/__tests__/UserRow.test.tsx deleted file mode 100644 index bc484a5..0000000 --- a/hotel-management/src/pages/User/__tests__/UserRow.test.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { render } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; - -// Types -import { IUser } from '@type/user'; - -// Components -import UserRow from '../UserRow'; - -describe('UserRow', () => { - const tempUser: IUser = { - id: 1, - name: 'Temp Room', - phone: '0324421232', - isBooked: false, - isDelete: true, - }; - const queryClient = new QueryClient(); - const wrapper = render( - - - - ); - - test('Should render correctly', () => { - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/hotel-management/src/pages/User/__tests__/UserTable.test.tsx b/hotel-management/src/pages/User/__tests__/UserTable.test.tsx deleted file mode 100644 index 9f69a75..0000000 --- a/hotel-management/src/pages/User/__tests__/UserTable.test.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { render } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { BrowserRouter } from 'react-router-dom'; - -// Components -import RoomTable from '@page/Room/RoomTable'; - -describe('UserTable', () => { - const queryClient = new QueryClient(); - - const wrapper = render( - - - - - - ); - - test('Should render correctly', () => { - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/hotel-management/src/pages/User/index.tsx b/hotel-management/src/pages/User/index.tsx index 3a29e9f..d52fe54 100644 --- a/hotel-management/src/pages/User/index.tsx +++ b/hotel-management/src/pages/User/index.tsx @@ -1,41 +1,188 @@ // Components -import UserTable from './UserTable'; -import Modal from '@component/Modal'; import UserForm from './UserForm'; +import Modal from '@src/components/Modal'; +import ButtonIcon from '@src/components/ButtonIcon'; +import Direction from '@src/commons/styles/Direction'; +import {FiEdit} from 'react-icons/fi'; +import {FaRegTrashAlt} from 'react-icons/fa'; +import {MdOutlineAddCircleOutline} from 'react-icons/md'; +import Table from '@src/components/Table'; // Styled -import Button from '@commonStyle/Button'; -import Direction from '@commonStyle/Direction.ts'; -import { StyledUser, Title } from './styled'; +import {ActionTable, StyledUser, Title} from './styled'; +import Spinner from '@src/commons/styles/Spinner.ts'; -// Constants -import { FORM } from '@constant/commons'; +// Types +import {ColumnProps} from '@src/types/common.ts'; +import {IUser} from '@src/types/user.ts'; + +// Hooks +import {useUsers} from '@src/hooks/users/useUsers.ts'; +import {useEffect, useState} from 'react'; +import {FORM, USER_PAGE} from '@src/constants/commons.ts'; +import {findItemInListById} from '@src/helpers/helper.ts'; +import ConfirmMessage from '@src/components/ConfirmMessage'; +import {useIsDeleteUser} from '@src/hooks/users/useSetIsDeleteUser.ts'; +import Message from "@src/components/Message"; + +interface IUserTable extends Omit { + isBooked: string; +} const User = () => { - const TITLE = 'Add user'; + const {setIsDeleteUser} = useIsDeleteUser(); + const [itemSelected, setItemSelected] = useState(); + let userSelected: IUser | undefined; + + const columns: ColumnProps[] = [ + { + key: 'id', + title: 'Id', + width: 10 + }, + { + key: 'name', + title: 'Name', + width: 40 + }, + { + key: 'phone', + title: 'Phone', + width: 20 + }, + { + key: 'isBooked', + title: 'Is Booked', + width: 20 + } + ]; + const {isLoading, users, count} = useUsers(); + + // Reset value when users changed. + useEffect(() => { + setItemSelected(undefined); + }, [users]); + + const tempUsers = users?.map((user) => ( + { + ...user, + isBooked: user.isBooked + ? 'Yes' + : 'No' + } + )); + + if (itemSelected && users) { + userSelected = findItemInListById(itemSelected.id, users); + } return ( - <> - - - List User + + + List User - + + ( - + } + text={'Add User'} + iconSize={'18px'} + fontSize={'var(--fs-sm)'} + variations={'primary'} + iconColor={'white'} + onClick={onCloseModal} + /> )} /> - - - - - - - - + ( + } + text={'Edit'} + iconSize={'18px'} + fontSize={'var(--fs-sm)'} + variations={'success'} + iconColor={'white'} + disabled={!itemSelected} + onClick={onCloseModal} + /> + )} + /> + + ( + } + text={'Delete'} + iconSize={'18px'} + fontSize={'var(--fs-sm)'} + variations={'danger'} + iconColor={'white'} + disabled={!itemSelected || itemSelected?.isBooked === 'Yes'} + onClick={onCloseModal} + /> + )} + /> + + ( + + )} + /> + + + + }/> + + + setIsDeleteUser(userSelected!.id)} + onCloseModal={onCloseModal} + /> + }/> + + + + + + {isLoading && } + + { + tempUsers && + Boolean(tempUsers.length) && + + columns={columns} + rows={tempUsers} + count={count} + sortBy={USER_PAGE.SORTBY_OPTIONS} + enabledOrder={true} + searchPlaceHolder={'Search by phone...'} + stateSelected={{ + itemSelected, + setItemSelected + }} + onRowClick={(data) => { + setItemSelected(data); + }}/> + } + + {tempUsers && Boolean(!tempUsers.length) && No data to show here!} + ); }; diff --git a/hotel-management/src/pages/User/styled.ts b/hotel-management/src/pages/User/styled.ts index 3b1775b..f163b2e 100644 --- a/hotel-management/src/pages/User/styled.ts +++ b/hotel-management/src/pages/User/styled.ts @@ -14,14 +14,20 @@ const Title = styled.h2` text-transform: capitalize; `; -const StyledOperationTable = styled.div` +const StyledTableOption = styled.div` display: flex; gap: 30px; justify-content: flex-end; `; +const ActionTable = styled.div` + display: flex; + gap: 30px; +` + export { StyledUser, Title, - StyledOperationTable + StyledTableOption, + ActionTable }; diff --git a/hotel-management/src/services/__tests__/authenticationService.test.ts b/hotel-management/src/services/__tests__/authenticationService.test.ts index d9bddcf..a1cfc7c 100644 --- a/hotel-management/src/services/__tests__/authenticationService.test.ts +++ b/hotel-management/src/services/__tests__/authenticationService.test.ts @@ -3,12 +3,12 @@ import { login, logout, updateAccount, -} from '@service/authenticationService'; -import supabase from '@service/supabaseService'; +} from '@src/services/authenticationService'; +import supabase from '@src/services/supabaseService'; import { Session, UserAttributes } from '@supabase/supabase-js'; // Mock Supabase module -jest.mock('@service/supabaseService', () => ({ +jest.mock('@src/services/supabaseService', () => ({ auth: { signInWithPassword: jest.fn(), getSession: jest.fn(), diff --git a/hotel-management/src/services/__tests__/bookingService.test.ts b/hotel-management/src/services/__tests__/bookingService.test.ts index 3b726c0..ebf25e5 100644 --- a/hotel-management/src/services/__tests__/bookingService.test.ts +++ b/hotel-management/src/services/__tests__/bookingService.test.ts @@ -3,17 +3,17 @@ import { ERROR_CREATE_BOOKING, ERROR_FETCHING_BOOKING, ERROR_UPDATE_BOOKING, -} from '@constant/messages'; +} from '@src/constants/messages'; import { checkOutBooking, createBooking, getAllBookings, updateBooking, -} from '@service/bookingServices'; -import supabase from '@service/supabaseService'; -import { IBooking } from '@type/booking'; +} from '@src/services/bookingServices'; +import supabase from '@src/services/supabaseService'; +import { IBooking } from '@src/types/booking'; -jest.mock('@service/supabaseService', () => ({ +jest.mock('@src/services/supabaseService', () => ({ __esModule: true, default: { from: jest.fn(() => ({ diff --git a/hotel-management/src/services/__tests__/roomService.test.ts b/hotel-management/src/services/__tests__/roomService.test.ts index 12b8b95..abfe624 100644 --- a/hotel-management/src/services/__tests__/roomService.test.ts +++ b/hotel-management/src/services/__tests__/roomService.test.ts @@ -1,8 +1,8 @@ -import { ERROR_CREATE_ROOM, ERROR_DELETE_ROOM, ERROR_FETCHING_ROOM, ERROR_UPDATE_ROOM } from '@constant/messages'; -import { createRoom, getAllRooms, getRoomById, setIsDeleteRoom, updateRoom, updateRoomStatus } from '@service/roomServices'; -import supabase from '@service/supabaseService'; +import { ERROR_CREATE_ROOM, ERROR_DELETE_ROOM, ERROR_FETCHING_ROOM, ERROR_UPDATE_ROOM } from '@src/constants/messages'; +import { createRoom, getAllRooms, getRoomById, setIsDeleteRoom, updateRoom, updateRoomStatus } from '@src/services/roomServices'; +import supabase from '@src/services/supabaseService'; -jest.mock('@service/supabaseService', () => ({ +jest.mock('@src/services/supabaseService', () => ({ __esModule: true, default: { from: jest.fn(() => ({ diff --git a/hotel-management/src/services/__tests__/userService.test.ts b/hotel-management/src/services/__tests__/userService.test.ts index fc17dcd..a9f4e2f 100644 --- a/hotel-management/src/services/__tests__/userService.test.ts +++ b/hotel-management/src/services/__tests__/userService.test.ts @@ -1,12 +1,12 @@ // Services -import { createUser, getAllUsers, setIsDeleteUser, updateUser, updateUserBookedStatus } from '@service/userServices'; +import { createUser, getAllUsers, setIsDeleteUser, updateUser, updateUserBookedStatus } from '@src/services/userServices'; // Types -import { IUser } from '@type/user'; -import supabase from '@service/supabaseService'; -import { ERROR_CREATE_USER, ERROR_DELETE_USER, ERROR_FETCHING_USER, ERROR_UPDATE_USER } from '@constant/messages'; +import { IUser } from '@src/types/user'; +import supabase from '@src/services/supabaseService'; +import { ERROR_CREATE_USER, ERROR_DELETE_USER, ERROR_FETCHING_USER, ERROR_UPDATE_USER } from '@src/constants/messages'; -jest.mock('@service/supabaseService', () => ({ +jest.mock('@src/services/supabaseService', () => ({ __esModule: true, default: { from: jest.fn(() => ({ diff --git a/hotel-management/src/services/authenticationService.ts b/hotel-management/src/services/authenticationService.ts index a064ce3..ef43fd0 100644 --- a/hotel-management/src/services/authenticationService.ts +++ b/hotel-management/src/services/authenticationService.ts @@ -1,11 +1,11 @@ -import { ILogin } from '@type/common'; +import { ILogin } from '@src/types/common'; import { UserAttributes } from '@supabase/supabase-js'; // Services import supabase from './supabaseService'; // Types -import { IAccount } from '@type/account'; +import { IAccount } from '@src/types/account'; /** * Login services diff --git a/hotel-management/src/services/bookingServices.ts b/hotel-management/src/services/bookingServices.ts index bd24708..aef0b11 100644 --- a/hotel-management/src/services/bookingServices.ts +++ b/hotel-management/src/services/bookingServices.ts @@ -1,18 +1,18 @@ // Types -import { IBooking, TBookingResponse } from '@type/booking'; +import { IBooking, TBookingResponse } from '@src/types/booking'; // Services import supabase from './supabaseService'; // Constants -import { DEFAULT_PAGE_SIZE } from '@constant/config'; +import { DEFAULT_PAGE_SIZE } from '@src/constants/config'; import { BOOKINGS_TABLE, ERROR_CHECKOUT, ERROR_CREATE_BOOKING, ERROR_FETCHING_BOOKING, ERROR_UPDATE_BOOKING, -} from '@constant/messages'; +} from '@src/constants/messages'; import { updateRoomStatus } from './roomServices'; import { updateUserBookedStatus } from './userServices'; diff --git a/hotel-management/src/services/roomServices.ts b/hotel-management/src/services/roomServices.ts index ed78b85..f59d4a1 100644 --- a/hotel-management/src/services/roomServices.ts +++ b/hotel-management/src/services/roomServices.ts @@ -1,18 +1,18 @@ // Types -import { IRoom } from '@type/room'; +import { IRoom } from '@src/types/room'; // Services import supabase from './supabaseService'; // Constants -import { DEFAULT_PAGE_SIZE } from '@constant/config'; +import { DEFAULT_PAGE_SIZE } from '@src/constants/config'; import { ERROR_CREATE_ROOM, ERROR_DELETE_ROOM, ERROR_FETCHING_ROOM, ERROR_UPDATE_ROOM, - ROOMS_TABLE, -} from '@constant/messages'; + ROOMS_TABLE +} from '@src/constants/messages'; interface IGetAllRooms { sortBy: string; @@ -26,11 +26,11 @@ interface IGetAllRooms { * @returns Return all rooms in database */ const getAllRooms = async ({ - sortBy, - orderBy, - roomSearch, - page, -}: IGetAllRooms): Promise<{ data: IRoom[]; count: number | null }> => { + sortBy, + orderBy, + roomSearch, + page + }: IGetAllRooms): Promise<{ data: IRoom[]; count: number | null }> => { const from = (page - 1) * DEFAULT_PAGE_SIZE; const to = from + DEFAULT_PAGE_SIZE - 1; @@ -157,5 +157,5 @@ export { createRoom, setIsDeleteRoom, getRoomById, - updateRoomStatus, + updateRoomStatus }; diff --git a/hotel-management/src/services/supabaseService.ts b/hotel-management/src/services/supabaseService.ts index 27b485a..bd17283 100644 --- a/hotel-management/src/services/supabaseService.ts +++ b/hotel-management/src/services/supabaseService.ts @@ -1,10 +1,10 @@ import { createClient } from '@supabase/supabase-js'; // Types -import { Database } from '@type/supabase'; +import { Database } from '@src/types/supabase'; // Constants -import { supabaseKey, supabaseUrl } from '@constant/config'; +import { supabaseKey, supabaseUrl } from '@src/constants/config'; const supabase = createClient(supabaseUrl, supabaseKey!); diff --git a/hotel-management/src/services/userServices.ts b/hotel-management/src/services/userServices.ts index 2652372..cf2dc7b 100644 --- a/hotel-management/src/services/userServices.ts +++ b/hotel-management/src/services/userServices.ts @@ -1,18 +1,18 @@ // Types -import { IUser } from '@type/user'; +import { IUser } from '@src/types/user'; // Services import supabase from './supabaseService'; // Constants -import { DEFAULT_PAGE_SIZE } from '@constant/config'; +import { DEFAULT_PAGE_SIZE } from '@src/constants/config'; import { ERROR_CREATE_USER, ERROR_DELETE_USER, ERROR_FETCHING_USER, ERROR_UPDATE_USER, USERS_TABLE, -} from '@constant/messages'; +} from '@src/constants/messages'; /** * Create user to the database diff --git a/hotel-management/src/styles/abstracts/variables.css b/hotel-management/src/styles/abstracts/variables.css index 8ced783..2777805 100644 --- a/hotel-management/src/styles/abstracts/variables.css +++ b/hotel-management/src/styles/abstracts/variables.css @@ -1,13 +1,21 @@ :root { --primary-color: #0010ba; + --primary-hover-color: #0010ba8c; --header-table-color: #ebebeb; + --item-hover: #f1f1f1; + --item-selected: #ececec; --border-color: #8c8c8c; --footer-table-color: #ebebeb; --secondary-btn-color: #d1d1d1; --disabled-btn-color: #7f82a6; + --danger-btn-color: #ff4f4f; + --danger-btn-hover-color: #ff4f4f8c; + + --success-btn-color: #228b22; + --success-btn-hover-color: #228b2299; --hover-background-color: #f3f4f6; --hover-dark-background-color: #d0d0d0; diff --git a/hotel-management/src/types/common.ts b/hotel-management/src/types/common.ts index 08e954e..440884b 100644 --- a/hotel-management/src/types/common.ts +++ b/hotel-management/src/types/common.ts @@ -12,6 +12,19 @@ interface ILogin { password: string; } +interface ColumnProps { + key: string; + title: string; + width: number; + isDateValue?: boolean; +} + type TDirection = 'vertical' | 'horizontal'; -export type { Nullable, IDataState, TDirection, ILogin }; +export type { + Nullable, + IDataState, + TDirection, + ILogin, + ColumnProps +}; diff --git a/hotel-management/test/__mocks__/fileMock.ts b/hotel-management/test/__mocks__/fileMock.ts deleted file mode 100644 index 86059f3..0000000 --- a/hotel-management/test/__mocks__/fileMock.ts +++ /dev/null @@ -1 +0,0 @@ -module.exports = 'test-file-stub'; diff --git a/hotel-management/tsconfig.json b/hotel-management/tsconfig.json index 75af449..fd9b15a 100644 --- a/hotel-management/tsconfig.json +++ b/hotel-management/tsconfig.json @@ -24,15 +24,7 @@ /* Alias */ "paths": { - "@service/*": ["./src/services/*"], - "@constant/*": ["./src/constants/*"], - "@hook/*": ["./src/hooks/*"], - "@helper/*": ["./src/helpers/*"], - "@context/*": ["./src/contexts/*"], - "@component/*": ["./src/components/*"], - "@commonStyle/*": ["./src/commons/styles/*"], - "@type/*": ["./src/types/*"], - "@page/*": ["./src/pages/*"], + "@src/*": ["./src/*"], } }, "include": ["src", "test"],