Testing: fetch servers by region

This commit is contained in:
cracklesparkle
2024-07-09 16:44:41 +09:00
parent 6f4aa1903d
commit a65a431b09
11 changed files with 227 additions and 23 deletions

View File

@ -11,6 +11,7 @@
"-": "^0.0.1",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@fontsource/inter": "^5.0.19",
"@fontsource/open-sans": "^5.0.28",
"@js-preview/docx": "^1.6.2",
"@js-preview/excel": "^1.7.8",
@ -2495,6 +2496,11 @@
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz",
"integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw=="
},
"node_modules/@fontsource/inter": {
"version": "5.0.19",
"resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.0.19.tgz",
"integrity": "sha512-tVU77yjKnsoUotrXGYbbYxmL9nbm/MSo3deZietmf8V2FEDlbi9fvkJHMrYbo7ZsOqR1AYBBqRYmemz4pSE5Mg=="
},
"node_modules/@fontsource/open-sans": {
"version": "5.0.28",
"resolved": "https://registry.npmjs.org/@fontsource/open-sans/-/open-sans-5.0.28.tgz",

View File

@ -13,6 +13,7 @@
"-": "^0.0.1",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@fontsource/inter": "^5.0.19",
"@fontsource/open-sans": "^5.0.28",
"@js-preview/docx": "^1.6.2",
"@js-preview/excel": "^1.7.8",

View File

@ -10,8 +10,42 @@ import Tooltip from '@mui/material/Tooltip';
import Settings from '@mui/icons-material/Settings';
import Logout from '@mui/icons-material/Logout';
import { useNavigate } from 'react-router-dom';
import { logout } from '../store/auth';
import { ListItem } from '@mui/material';
import { logout, useAuthStore } from '../store/auth';
import { ListItem, Switch, styled } from '@mui/material';
import { setDarkMode, usePrefStore } from '../store/preferences';
const Android12Switch = styled(Switch)(({ theme }) => ({
padding: 8,
'& .MuiSwitch-track': {
borderRadius: 22 / 2,
'&::before, &::after': {
content: '""',
position: 'absolute',
top: '50%',
transform: 'translateY(-50%)',
width: 16,
height: 16,
},
'&::before': {
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 24 24"><path fill="${encodeURIComponent(
theme.palette.getContrastText(theme.palette.primary.main),
)}" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"/></svg>')`,
left: 12,
},
'&::after': {
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 24 24"><path fill="${encodeURIComponent(
theme.palette.getContrastText(theme.palette.primary.main),
)}" d="M19,13H5V11H19V13Z" /></svg>')`,
right: 12,
},
},
'& .MuiSwitch-thumb': {
boxShadow: 'none',
width: 16,
height: 16,
margin: 2,
},
}));
export default function AccountMenu() {
const navigate = useNavigate()
@ -26,6 +60,9 @@ export default function AccountMenu() {
const handleClose = () => {
setAnchorEl(null);
};
const prefStore = usePrefStore()
return (
<React.Fragment>
<Box sx={{ display: 'flex', alignItems: 'center', textAlign: 'center' }}>
@ -47,7 +84,6 @@ export default function AccountMenu() {
id="account-menu"
open={open}
onClose={handleClose}
onClick={handleClose}
PaperProps={{
elevation: 0,
sx: {
@ -77,12 +113,25 @@ export default function AccountMenu() {
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
>
<MenuItem onClick={() => {
console.log()
}}>
<Android12Switch
defaultChecked={prefStore.darkMode}
onChange={(e) => {
setDarkMode(e.target.checked)
}} />
Тема
</MenuItem>
<MenuItem onClick={handleClose}>
<ListItemIcon>
<Settings fontSize="small" />
</ListItemIcon>
Настройки
</MenuItem>
<MenuItem
onClick={() => {
logout()

View File

@ -116,12 +116,12 @@ export function useReport(city_id?: number) {
}
// API general
// API general (fuel)
export function useAddress(limit?: number, page?: number) {
const { data, error, isLoading } = useSWR(
`/general/address?limit=${limit || 10}&page=${page || 1}`,
(url) => fetcher(url, import.meta.env.VITE_API_FUEL_URL),
(url) => fetcher(url, BASE_URL.fuel),
{
revalidateOnFocus: false
}
@ -134,9 +134,41 @@ export function useAddress(limit?: number, page?: number) {
}
}
export function useRegions(limit?: number, page?: number, search?: string) {
const { data, error, isLoading } = useSWR(
`/general/regions?limit=${limit || 10}&page=${page || 1}${search ? `&search=${search}` : ''}`,
(url) => fetcher(url, BASE_URL.fuel),
{
revalidateOnFocus: false
}
)
return {
regions: data,
isLoading,
isError: error
}
}
export function useCities(limit?: number, page?: number, search?: string) {
const { data, error, isLoading } = useSWR(
`/general/cities?limit=${limit || 10}&page=${page || 1}${search ? `&search=${search}` : ''}`,
(url) => fetcher(url, BASE_URL.fuel),
{
revalidateOnFocus: false
}
)
return {
cities: data,
isLoading,
isError: error
}
}
export function useBoilers(limit?: number, page?: number, search?: string) {
const { data, error, isLoading } = useSWR(
`/general/boilers?limit=${limit || 10}&page=${page || 1}&search=${search || ""}`,
`/general/boilers?limit=${limit || 10}&page=${page || 1}${search ? `&search=${search}` : ''}`,
(url) => fetcher(url, BASE_URL.fuel),
{
revalidateOnFocus: false

View File

@ -0,0 +1,4 @@
export interface IRegion {
id: number;
name: string;
}

View File

@ -0,0 +1,3 @@
export interface PreferencesState {
darkMode: boolean;
}

View File

@ -1,4 +1,4 @@
import "@fontsource/open-sans";
import "@fontsource/inter";
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
@ -7,12 +7,13 @@ import { registerSW } from 'virtual:pwa-register'
import { ThemeProvider } from '@emotion/react'
import { createTheme } from '@mui/material'
import { ruRU } from '@mui/material/locale'
import { usePrefStore } from "./store/preferences.ts";
const theme = createTheme(
{
typography: {
fontFamily: [
'Open Sans'
'Inter'
].join(',')
},
components: {

View File

@ -1,21 +1,103 @@
import { useEffect, useState } from "react"
import { Button, Typography } from "@mui/material"
import { useServers } from "../hooks/swrHooks"
import { Autocomplete, Box, Button, CircularProgress, Paper, TextField, Typography } from "@mui/material"
import { useBoilers, useCities, useRegions, useServers } from "../hooks/swrHooks"
import { Fragment, useEffect, useState } from "react"
import { IRegion } from "../interfaces/fuel"
import { DataGrid, GridColDef } from "@mui/x-data-grid"
export default function ApiTest() {
const [state, setState] = useState<any>(null)
const [open, setOpen] = useState(false)
const [options, setOptions] = useState<any>([])
const [search, setSearch] = useState<any>(null)
const [debouncedSearch, setDebouncedSearch] = useState("")
const [selectedOption, setSelectedOption] = useState<IRegion | null>(null)
const { regions, isLoading } = useRegions(10, 1, debouncedSearch)
const { servers } = useServers(32, 0, 10)
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedSearch(search)
}, 500)
return () => {
clearTimeout(handler)
}
}, [search])
useEffect(() => {
if (regions) {
setOptions([...regions])
}
}, [regions])
const handleInputChange = (event: any, value: any) => {
setSearch(value)
}
const handleOptionChange = (event: any, value: any) => {
setSelectedOption(value)
}
//const { boilers } = useBoilers(10, 1)
//const { cities } = useCities(10, 1)
const { servers, isLoading: serversLoading } = useServers(selectedOption?.id, 0, 10)
const serversColumns: GridColDef[] = [
{ field: 'id', headerName: 'ID', type: "number" },
{ field: 'name', headerName: 'Название', type: "string" },
]
return (
<>
<Typography>
<Button onClick={() => {
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px', height: '100%' }}>
<Paper elevation={1}>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px', height: '100%', p: '16px'}}>
<Typography variant='h6' fontWeight='600'>
Get servers
</Typography>
}}>
{servers && JSON.stringify(servers)}
</Button>
</Typography>
</>
<Autocomplete
open={open}
onOpen={() => {
setOpen(true)
}}
onClose={() => {
setOpen(false)
}}
onInputChange={handleInputChange}
onChange={handleOptionChange}
filterOptions={(x) => x}
isOptionEqualToValue={(option: any, value: any) => option.name === value.name}
getOptionLabel={(option: any) => option.name ? option.name : ""}
options={options}
loading={isLoading}
value={selectedOption}
renderInput={(params) => (
<TextField
{...params}
label="Район"
InputProps={{
...params.InputProps,
endAdornment: (
<Fragment>
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
{params.InputProps.endAdornment}
</Fragment>
)
}}
/>
)}
/>
{serversLoading ?
<CircularProgress />
:
servers &&
<DataGrid
rowSelection={false}
rows={servers}
columns={serversColumns}
/>
}
</Box>
</Paper>
</Box>
)
}

View File

@ -79,5 +79,5 @@ export {
refreshToken,
initAuth,
login,
logout
logout,
}

View File

@ -0,0 +1,21 @@
import { create } from 'zustand';
import { PreferencesState } from '../interfaces/preferences';
export const usePrefStore = create<PreferencesState>((set, get) => ({
darkMode: false
}));
const getDarkMode = () => {
const darkMode = localStorage.getItem('darkMode')
return darkMode
}
const setDarkMode = (darkMode: boolean) => {
localStorage.setItem('darkMode', JSON.stringify(darkMode))
usePrefStore.setState(() => ({ darkMode: darkMode }))
}
export {
getDarkMode,
setDarkMode
}

View File

@ -1148,6 +1148,11 @@
resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz"
integrity sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==
"@fontsource/inter@^5.0.19":
version "5.0.19"
resolved "https://registry.npmjs.org/@fontsource/inter/-/inter-5.0.19.tgz"
integrity sha512-tVU77yjKnsoUotrXGYbbYxmL9nbm/MSo3deZietmf8V2FEDlbi9fvkJHMrYbo7ZsOqR1AYBBqRYmemz4pSE5Mg==
"@fontsource/open-sans@^5.0.28":
version "5.0.28"
resolved "https://registry.npmjs.org/@fontsource/open-sans/-/open-sans-5.0.28.tgz"