diff --git a/hotel-management/db.json b/hotel-management/db.json new file mode 100644 index 0000000..07a3a79 --- /dev/null +++ b/hotel-management/db.json @@ -0,0 +1,76 @@ +{ + "users": [ + { + "id": "123", + "name": "Nezumi", + "identifiedCode": "123", + "phone": "0937425123", + "roomId": 246, + "address": "Da Nang" + }, + { + "id": "231", + "name": "Phan Huu Loi", + "identifiedCode": "123", + "phone": "0937425123", + "roomId": 246, + "address": "Ho Chi Minh" + }, + { + "id": "312", + "name": "Nezumi", + "identifiedCode": "123", + "phone": "0937425123", + "roomId": 246, + "address": "Da Nang" + }, + { + "id": "523", + "name": "Nezumi", + "identifiedCode": "123", + "phone": "0937425123", + "roomId": 246, + "address": "Da Nang" + }, + { + "id": "534", + "name": "Nezumi", + "identifiedCode": "123", + "phone": "0937425123", + "roomId": 246, + "address": "Da Nang" + }, + { + "id": "756", + "name": "Nezumi", + "identifiedCode": "123", + "phone": "0937425123", + "roomId": 246, + "address": "Da Nang" + }, + { + "id": "23", + "name": "Nezumi", + "identifiedCode": "123", + "phone": "0937425123", + "roomId": 246, + "address": "Da Nang" + }, + { + "id": "756", + "name": "Nezumi", + "identifiedCode": "123", + "phone": "0937425123", + "roomId": 246, + "address": "Da Nang" + }, + { + "id": "756", + "name": "Nezumi", + "identifiedCode": "123", + "phone": "0937425123", + "roomId": 246, + "address": "Da Nang" + } + ] +} diff --git a/hotel-management/src/commons/styles/Spinner.ts b/hotel-management/src/commons/styles/Spinner.ts new file mode 100644 index 0000000..0dcb41d --- /dev/null +++ b/hotel-management/src/commons/styles/Spinner.ts @@ -0,0 +1,24 @@ +import styled, { keyframes } from 'styled-components'; + +const rotate = keyframes` + to { + transform: rotate(1turn) + } +`; + +const Spinner = styled.div` + margin: 100px auto; + + width: 80px; + aspect-ratio: 1; + border-radius: 50%; + background: + radial-gradient(farthest-side, var(--primary-color) 94%, #0000) 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; +`; + +export default Spinner; diff --git a/hotel-management/src/constants/path.ts b/hotel-management/src/constants/path.ts index 98c28d3..e4900ab 100644 --- a/hotel-management/src/constants/path.ts +++ b/hotel-management/src/constants/path.ts @@ -2,3 +2,4 @@ export const DASHBOARD: string = '/dashboard'; export const USER: string = '/user'; export const ROOM: string = '/room'; export const OTHER_PATH: string = '*'; +export const BASE_URL: string = 'https://hotel-management-api.loiphan.com/'; diff --git a/hotel-management/src/constants/sampleData.ts b/hotel-management/src/constants/sampleData.ts deleted file mode 100644 index c851dec..0000000 --- a/hotel-management/src/constants/sampleData.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { TUser } from '../globals/types'; - -export const sampleData: TUser[] = [ - { - id: '123', - name: 'Nezumi', - identifiedCode: '123', - phone: '0937425123', - roomId: '246', - address: 'Da Nang', - }, - { - id: '456', - name: 'Nezumi', - identifiedCode: '123', - phone: '123', - roomId: '246', - address: 'Da Nang', - }, - { - id: '231', - name: 'Nezumi', - identifiedCode: '123', - phone: '123', - roomId: '246', - address: 'Da Nang', - }, - { - id: '241', - name: 'Nezumi', - identifiedCode: '123', - phone: '123', - roomId: '246', - address: 'Da Nang', - }, - { - id: '512', - name: 'Nezumi', - identifiedCode: '123', - phone: '123', - roomId: '246', - address: 'Da Nang', - }, - { - id: '524', - name: 'Nezumi', - identifiedCode: '123', - phone: '123', - roomId: '246', - address: 'Da Nang', - }, - { - id: '125', - name: 'Nezumi', - identifiedCode: '123', - phone: '123', - roomId: '246', - address: 'Da Nang', - }, - { - id: '111', - name: 'Nezumi', - identifiedCode: '123', - phone: '123', - roomId: '246', - address: 'Da Nang', - }, -]; diff --git a/hotel-management/src/hooks/useFetch.ts b/hotel-management/src/hooks/useFetch.ts new file mode 100644 index 0000000..cb21b4f --- /dev/null +++ b/hotel-management/src/hooks/useFetch.ts @@ -0,0 +1,36 @@ +import { useEffect, useState } from 'react'; + +// Constants +import { BASE_URL } from '../constants/path'; + +export const useFetch = (path: string) => { + const [data, setData] = useState(null); + const [isPending, setIsPending] = useState(false); + const [errorMsg, setErrorMsg] = useState(null); + + useEffect(() => { + const fetchData = async () => { + setIsPending(true); + + try { + const response = await fetch(BASE_URL + path); + const json = await response.json(); + + if (!response.ok) + throw new Error( + `Error code: ${response.status} \n Messages: ${response.statusText}`, + ); + + setIsPending(false); + setData(json); + setErrorMsg(null); + } catch (error) { + setErrorMsg(`Could not fetch data.\n ${error}`); + setIsPending(false); + } + }; + + fetchData(); + }, [path]); + return { data, isPending, errorMsg }; +}; diff --git a/hotel-management/src/pages/User/Table.tsx b/hotel-management/src/pages/User/Table.tsx index 279c7f8..1d1ddb5 100644 --- a/hotel-management/src/pages/User/Table.tsx +++ b/hotel-management/src/pages/User/Table.tsx @@ -11,7 +11,11 @@ import Message from '../../components/Message'; import { TUser } from '../../globals/types'; // Constants -import { sampleData } from '../../constants/sampleData'; +import { useFetch } from '../../hooks/useFetch'; + +// Styled +import Spinner from '../../commons/styles/Spinner'; +import { useEffect, useState } from 'react'; type TUserModal = { user: TUser }; @@ -50,30 +54,48 @@ const UserRow = ({ user }: TUserModal) => { }; const UserTable = () => { - return sampleData.length ? ( - - -

Sort / Filter / Search table

-
+ const { data, isPending, errorMsg } = useFetch('users'); + const [users, setUsers] = useState([]); - - - -
Id
-
Name
-
Identified Code
-
Phone
-
Room
-
- - data={sampleData} - render={(user: TUser) => } - /> -
-
-
- ) : ( - No data to show here! + useEffect(() => { + if (data) { + setUsers(data); + } + + if (errorMsg) { + console.error(errorMsg); + } + }, [data, errorMsg]); + + return ( + <> + {isPending && } + {users.length ? ( + + +

Sort / Search table

+
+ + + + +
Id
+
Name
+
Identified Code
+
Phone
+
Room
+
+ + data={users} + render={(user: TUser) => } + /> +
+
+
+ ) : ( + No data to show here! + )} + ); };