hunt-blacklist-frontend/app/routes/home.tsx

121 lines
4.6 KiB
TypeScript

import {useEffect, useState} from "react";
import '../assets/styles/home.css';
import {
Box,
Divider, Fab,
TextField,
ThemeProvider, Typography,
useTheme
} from "@mui/material";
import {getAll} from '~/api';
import customTheme from "~/assets/mui/themes/home";
import {BlacklistItem} from "~/classes/blacklistItem";
import {ResponseError} from "~/classes/responseError";
import ItemList from "~/components/itemList";
import ItemDialog from "~/components/itemDialog";
import OutlinedFlagIcon from '@mui/icons-material/OutlinedFlag';
import ReportDialog from "~/components/reportDialog";
export default function Home() {
const outerTheme = useTheme();
const [searchText, setSearchText] = useState('');
const [isFetchingList, setIsFetchingList] = useState(false);
const [blacklistItems, setBlacklistItems] = useState<BlacklistItem[]>([]);
const [showDialog, setShowDialog] = useState(false);
const [currentDialogBlacklistItem, setCurrentDialogBlacklistItem] = useState<BlacklistItem|null>(null);
const [fabIsHovered, setFabIsHovered] = useState(false);
const [showReportDialog, setReportShowDialog] = useState(false);
useEffect(() => {
let isIgnore = false;
setIsFetchingList(true);
getAll(searchText).then((res: BlacklistItem[] | ResponseError | undefined)=> {
if (!isIgnore) {
if (res instanceof Array){
setBlacklistItems(res);
} else if (res instanceof ResponseError) {
// TODO error handler
console.log(res);
}
setIsFetchingList(false);
}
});
return () => {
isIgnore = true; // При следующем изменении someValue старый запрос будет проигнорирован
};
}, [searchText, showReportDialog]);
function handleSearch(text: string) {
setSearchText(text);
}
function handleItemClick(item: BlacklistItem){
setCurrentDialogBlacklistItem(item);
setShowDialog(true);
}
const handleDialogClose = () => {
setShowDialog(false);
};
const handleReportDialogOpen = () => {
setReportShowDialog(true);
};
const handleReportDialogClose = () => {
setReportShowDialog(false);
};
return (
<ThemeProvider theme={customTheme(outerTheme)}>
<div className="bg-dark">
<div className="search-container">
<TextField
id="search-field"
label="Search"
variant="outlined"
value={searchText}
onChange={(e) => handleSearch(e.target.value)}
fullWidth
/>
</div>
<div style={{justifyItems: 'center'}}>
<Divider sx={{marginTop: '10px', marginBottom: '10px'}}/>
</div>
<ItemList isFetching={isFetchingList} blacklistItems={blacklistItems} showDialog={handleItemClick}></ItemList>
<ItemDialog blacklistItem={currentDialogBlacklistItem} open={showDialog} handleClose={handleDialogClose}></ItemDialog>
<ReportDialog open={showReportDialog} handleClose={handleReportDialogClose}/>
<Fab
onClick={() => handleReportDialogOpen()}
onMouseEnter={() => setFabIsHovered(true)}
onMouseLeave={() => setFabIsHovered(false)}
variant={fabIsHovered ? 'extended' : 'circular'}
sx={{
position: 'fixed',
bottom: 16,
right: 16,
z-index: 1000,
width: fabIsHovered ? '160px' : '56px', // Переход между кругом и овалом
transition: 'width 0.3s ease-in-out',
overflow: 'hidden',
}}
>
<OutlinedFlagIcon />
<Box
sx={{
opacity: fabIsHovered ? 1 : 0,
ml: fabIsHovered ? 1 : 0,
width: fabIsHovered ? 'auto' : 0,
transition: 'all 0.1s ease-in-out',
whiteSpace: 'nowrap',
}}
>
<Typography variant="button">{fabIsHovered ? 'Send report' : ''}</Typography>
</Box>
</Fab>
</div>
</ThemeProvider>
);
}