diff --git a/hotel-management/src/components/Empty.tsx b/hotel-management/src/components/Empty.tsx
new file mode 100644
index 0000000..2c89f4e
--- /dev/null
+++ b/hotel-management/src/components/Empty.tsx
@@ -0,0 +1,13 @@
+import styled from 'styled-components';
+
+const StyledMessage = styled.p`
+ font-size: var(--fs-sm);
+ text-align: center;
+ padding: 20px;
+`;
+
+const Empty = ({ children }: { children: string }) => {
+ return {children};
+};
+
+export default Empty;
diff --git a/hotel-management/src/components/Menus/Menus.tsx b/hotel-management/src/components/Menus/Menus.tsx
new file mode 100644
index 0000000..04d726f
--- /dev/null
+++ b/hotel-management/src/components/Menus/Menus.tsx
@@ -0,0 +1,80 @@
+import { useContext, useState } from 'react';
+
+// Components
+import { HiEllipsisVertical } from 'react-icons/hi2';
+import { useOutsideClick } from '../../hooks/useOutsideClick';
+import { StyledButton, StyledList, StyledMenu, StyledToggle } from './styled';
+
+// Interfaces
+import { IButton } from '../../globals/interfaces';
+
+// Contexts
+import MenusContext from '../../contexts/MenuContext';
+
+const Menus = ({ children }: { children: JSX.Element }) => {
+ const [openId, setOpenId] = useState('');
+
+ const close = () => setOpenId('');
+ const open = setOpenId;
+
+ return (
+
+ {children}
+
+ );
+};
+
+const Toggle = ({ id }: { id: string }): React.JSX.Element => {
+ const { openId, close, open } = useContext(MenusContext);
+
+ const handleClick = (e: React.MouseEvent) => {
+ e.stopPropagation();
+
+ openId === '' || openId !== id ? open!(id) : close!();
+ };
+
+ return (
+ handleClick(e)}>
+
+
+ );
+};
+
+const List = ({
+ id,
+ children,
+}: {
+ id: string;
+ children: JSX.Element[];
+}): React.JSX.Element | null => {
+ const { openId, close } = useContext(MenusContext);
+ const ref = useOutsideClick(close!, false);
+
+ if (openId !== id) return null;
+
+ return {children};
+};
+
+const Button = ({ children, icon, onClick }: IButton): React.JSX.Element => {
+ const { close } = useContext(MenusContext);
+
+ const handleClick = () => {
+ onClick?.();
+ close!();
+ };
+
+ return (
+
+
+ {icon} {children}
+
+
+ );
+};
+
+Menus.Menu = StyledMenu;
+Menus.Toggle = Toggle;
+Menus.List = List;
+Menus.Button = Button;
+
+export default Menus;
diff --git a/hotel-management/src/components/Menus/styled.ts b/hotel-management/src/components/Menus/styled.ts
new file mode 100644
index 0000000..33079a7
--- /dev/null
+++ b/hotel-management/src/components/Menus/styled.ts
@@ -0,0 +1,63 @@
+import styled from 'styled-components';
+
+export const StyledMenu = styled.div`
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+`;
+
+export const StyledButton = styled.button`
+ width: 100%;
+ text-align: left;
+ background: none;
+ border: none;
+ padding: 10px 20px;
+ font-size: var(--fs-sm-x);
+ transition: all 0.2s;
+
+ display: flex;
+ align-items: center;
+ gap: 10px;
+
+ &:hover {
+ background-color: var(--hover-background-color);
+ }
+
+ & svg {
+ width: 18px;
+ height: 18px;
+ color: var(--primary-color);
+ transition: all 0.3s;
+ }
+`;
+
+export const StyledToggle = styled.button`
+ background: none;
+ border: none;
+ padding: 8px;
+ border-radius: var(--radius-sm);
+ transform: translateX(5px);
+ transition: all 0.2s;
+
+ &:hover {
+ background-color: var(--hover-background-color);
+ }
+
+ & svg {
+ width: 18px;
+ height: 18px;
+ }
+`;
+
+export const StyledList = styled.ul`
+ position: absolute;
+ z-index: 1000;
+
+ background-color: white;
+ box-shadow: var(--shadow-sm);
+ border-radius: var(--radius-sm);
+
+ right: -10px;
+ top: 40px;
+`;
diff --git a/hotel-management/src/components/Table/index.tsx b/hotel-management/src/components/Table/index.tsx
new file mode 100644
index 0000000..8f48a46
--- /dev/null
+++ b/hotel-management/src/components/Table/index.tsx
@@ -0,0 +1,41 @@
+import { ReactNode, useContext } from 'react';
+
+// Components
+import { StyledBody, StyledHeader, StyledRow, StyledTable } from './styled';
+
+// Interfaces
+import { ITable, ITableBody } from '../../globals/interfaces';
+
+// Contexts
+import TableContext from '../../contexts/TableContext';
+
+type CallbackMapFunc = (value: T, index: number, array: T[]) => ReactNode;
+
+const Table = ({ columns, children }: ITable) => {
+ return (
+
+ {children}
+
+ );
+};
+
+const Header = ({ children }: ITable) => {
+ const columns = useContext(TableContext);
+ return {children};
+};
+
+const Body = ({ data, render }: ITableBody) => {
+ if (data && data.length > 0)
+ return {data?.map(render as CallbackMapFunc)};
+};
+
+const Row = ({ children }: ITable) => {
+ const columns = useContext(TableContext);
+ return {children};
+};
+
+Table.Header = Header;
+Table.Body = Body;
+Table.Row = Row;
+
+export default Table;
diff --git a/hotel-management/src/components/Table/styled.ts b/hotel-management/src/components/Table/styled.ts
new file mode 100644
index 0000000..4906f3f
--- /dev/null
+++ b/hotel-management/src/components/Table/styled.ts
@@ -0,0 +1,43 @@
+import styled from 'styled-components';
+
+// Interfaces
+import { ITable } from '../../globals/interfaces';
+
+export const StyledTable = styled.div`
+ border: 1px solid var(--border-color);
+
+ font-size: 20px;
+ border-radius: var(--radius-md);
+`;
+
+const CommonRow = styled.div`
+ display: grid;
+ grid-template-columns: ${(props) => props.columns};
+ column-gap: 10px;
+ align-items: center;
+`;
+
+export const StyledBody = styled.div`
+ font-size: var(--fs-sm-x);
+`;
+
+export const StyledRow = styled(CommonRow)`
+ padding: 20px;
+
+ &:not(:last-child) {
+ border-bottom: 1px solid var(--border-color);
+ }
+`;
+
+export const StyledHeader = styled(CommonRow)`
+ padding: 10px 20px;
+
+ border-bottom: 1px solid var(--border-color);
+ background-color: var(--header-table-color);
+ border-top-left-radius: var(--radius-md);
+ border-top-right-radius: var(--radius-md);
+
+ font-size: var(--fs-sm);
+ text-transform: capitalize;
+ font-weight: 600;
+`;
diff --git a/hotel-management/src/contexts/MenuContext.ts b/hotel-management/src/contexts/MenuContext.ts
new file mode 100644
index 0000000..2f051cc
--- /dev/null
+++ b/hotel-management/src/contexts/MenuContext.ts
@@ -0,0 +1,8 @@
+import { createContext } from 'react';
+
+// Interfaces
+import { IMenusContext } from '../globals/interfaces';
+
+const MenusContext = createContext({});
+
+export default MenusContext;
diff --git a/hotel-management/src/contexts/TableContext.ts b/hotel-management/src/contexts/TableContext.ts
new file mode 100644
index 0000000..394f4a7
--- /dev/null
+++ b/hotel-management/src/contexts/TableContext.ts
@@ -0,0 +1,5 @@
+import { createContext } from 'react';
+
+const TableContext = createContext('');
+
+export default TableContext;
diff --git a/hotel-management/src/globals/interfaces.ts b/hotel-management/src/globals/interfaces.ts
new file mode 100644
index 0000000..6dbad0e
--- /dev/null
+++ b/hotel-management/src/globals/interfaces.ts
@@ -0,0 +1,21 @@
+export interface IMenusContext {
+ openId?: string;
+ close?: () => void;
+ open?: React.Dispatch>;
+}
+
+export interface IButton {
+ children?: string;
+ icon?: JSX.Element;
+ onClick?: () => void;
+}
+
+export interface ITable {
+ columns?: string;
+ children: React.ReactNode;
+}
+
+export interface ITableBody {
+ data?: T[];
+ render?: (value: T) => JSX.Element;
+}
diff --git a/hotel-management/src/globals/types.ts b/hotel-management/src/globals/types.ts
new file mode 100644
index 0000000..3f870af
--- /dev/null
+++ b/hotel-management/src/globals/types.ts
@@ -0,0 +1,8 @@
+export type TUser = {
+ id: string;
+ name: string;
+ identifiedCode: string;
+ address: string;
+ phone: string;
+ roomId: string;
+};
diff --git a/hotel-management/src/hooks/useOutsideClick.ts b/hotel-management/src/hooks/useOutsideClick.ts
new file mode 100644
index 0000000..c7278d5
--- /dev/null
+++ b/hotel-management/src/hooks/useOutsideClick.ts
@@ -0,0 +1,23 @@
+import { useEffect, useRef } from 'react';
+
+export const useOutsideClick = (
+ handler: () => void,
+ listeningCapturing = true,
+): React.MutableRefObject => {
+ const ref = useRef(null);
+
+ useEffect(() => {
+ const handleClick = (e: Event) => {
+ if (ref.current && !ref.current.contains(e.target as Node)) {
+ handler();
+ }
+ };
+
+ document.addEventListener('click', handleClick, listeningCapturing);
+
+ return () =>
+ document.removeEventListener('click', handleClick, listeningCapturing);
+ }, [handler, listeningCapturing]);
+
+ return ref;
+};