mirror of
https://github.com/Nezumi-2711/react-training.git
synced 2026-09-22 13:38:51 +00:00
Load data from api to the page
This commit is contained in:
@@ -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;
|
||||
@@ -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/';
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
];
|
||||
@@ -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 };
|
||||
};
|
||||
@@ -11,7 +11,10 @@ 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';
|
||||
|
||||
type TUserModal = { user: TUser };
|
||||
|
||||
@@ -50,10 +53,19 @@ const UserRow = ({ user }: TUserModal) => {
|
||||
};
|
||||
|
||||
const UserTable = () => {
|
||||
return sampleData.length ? (
|
||||
const { data, isPending, errorMsg } = useFetch('users');
|
||||
let users: TUser[] = [];
|
||||
|
||||
if (data) users = data;
|
||||
|
||||
if (isPending) return <Spinner />;
|
||||
|
||||
if (errorMsg) console.error(errorMsg);
|
||||
|
||||
return users.length ? (
|
||||
<Direction>
|
||||
<StyledOperationTable>
|
||||
<p>Sort / Filter / Search table</p>
|
||||
<p>Sort / Search table</p>
|
||||
</StyledOperationTable>
|
||||
|
||||
<Menus>
|
||||
@@ -66,7 +78,7 @@ const UserTable = () => {
|
||||
<div>Room</div>
|
||||
</Table.Header>
|
||||
<Table.Body<TUser>
|
||||
data={sampleData}
|
||||
data={users}
|
||||
render={(user: TUser) => <UserRow user={user} key={user.id} />}
|
||||
/>
|
||||
</Table>
|
||||
|
||||
Reference in New Issue
Block a user