Merge pull request #13 from Nez27/feat/load-data-from-api

Load data from api to user page
This commit is contained in:
Loi Phan
2023-10-29 09:58:44 +07:00
committed by GitHub
6 changed files with 183 additions and 92 deletions
+76
View File
@@ -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"
}
]
}
@@ -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;
+1
View File
@@ -2,3 +2,4 @@ export const DASHBOARD: string = '/dashboard';
export const USER: string = '/user'; export const USER: string = '/user';
export const ROOM: string = '/room'; export const ROOM: string = '/room';
export const OTHER_PATH: string = '*'; export const OTHER_PATH: string = '*';
export const BASE_URL: string = 'https://hotel-management-api.loiphan.com/';
@@ -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',
},
];
+36
View File
@@ -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<string | null>(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 };
};
+46 -24
View File
@@ -11,7 +11,11 @@ import Message from '../../components/Message';
import { TUser } from '../../globals/types'; import { TUser } from '../../globals/types';
// Constants // 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 }; type TUserModal = { user: TUser };
@@ -50,30 +54,48 @@ const UserRow = ({ user }: TUserModal) => {
}; };
const UserTable = () => { const UserTable = () => {
return sampleData.length ? ( const { data, isPending, errorMsg } = useFetch('users');
<Direction> const [users, setUsers] = useState<TUser[]>([]);
<StyledOperationTable>
<p>Sort / Filter / Search table</p>
</StyledOperationTable>
<Menus> useEffect(() => {
<Table columns="10% 30% 20% 20% 10% 5%"> if (data) {
<Table.Header> setUsers(data);
<div>Id</div> }
<div>Name</div>
<div>Identified Code</div> if (errorMsg) {
<div>Phone</div> console.error(errorMsg);
<div>Room</div> }
</Table.Header> }, [data, errorMsg]);
<Table.Body<TUser>
data={sampleData} return (
render={(user: TUser) => <UserRow user={user} key={user.id} />} <>
/> {isPending && <Spinner />}
</Table> {users.length ? (
</Menus> <Direction>
</Direction> <StyledOperationTable>
) : ( <p>Sort / Search table</p>
<Message>No data to show here!</Message> </StyledOperationTable>
<Menus>
<Table columns="10% 30% 20% 20% 10% 5%">
<Table.Header>
<div>Id</div>
<div>Name</div>
<div>Identified Code</div>
<div>Phone</div>
<div>Room</div>
</Table.Header>
<Table.Body<TUser>
data={users}
render={(user: TUser) => <UserRow user={user} key={user.id} />}
/>
</Table>
</Menus>
</Direction>
) : (
<Message>No data to show here!</Message>
)}
</>
); );
}; };