searchbar fixed, working on modal

This commit is contained in:
2023-09-29 09:37:14 -04:00
parent 240aae606b
commit 2ba9d93bfd
4 changed files with 52 additions and 76 deletions

View File

@@ -14,6 +14,7 @@ export default function MapTiles() {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [airports, setAirports] = useState<Airport[]>([]); const [airports, setAirports] = useState<Airport[]>([]);
const [selectedAirport, setSelectedAirport] = useState<Airport | undefined>(); const [selectedAirport, setSelectedAirport] = useState<Airport | undefined>();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [zoomLevel, setZoomLevel] = useState(8); const [zoomLevel, setZoomLevel] = useState(8);
// const [dragging, setDragging] = useState(false); // const [dragging, setDragging] = useState(false);
const map = useMap(); const map = useMap();
@@ -59,70 +60,29 @@ export default function MapTiles() {
setAirports(_airports); setAirports(_airports);
} }
function iconSize() {
if (zoomLevel <= 5) {
return 'xs';
} else {
return 'sm';
}
}
function metarIcon(airport: Airport) { function metarIcon(airport: Airport) {
function innerIcon({ tag, color, size = 'sm' }: { tag: string; color: string; size?: string }) {
return new DivIcon({
html: ReactDOMServer.renderToString(
<MantineProvider>
<Avatar variant='filled' color={color} radius='xl' size={size}>
{tag}
</Avatar>
</MantineProvider>
),
className: 'metar-marker-icon'
});
}
if (airport.metar?.flight_category == 'VFR') { if (airport.metar?.flight_category == 'VFR') {
return new DivIcon({ return innerIcon({ tag: 'V', color: 'green' });
html: ReactDOMServer.renderToString(
<MantineProvider>
<Avatar variant='filled' color='green' radius='xl' size={iconSize()}>
V
</Avatar>
</MantineProvider>
),
className: 'metar-marker-icon'
});
} else if (airport.metar?.flight_category == 'MVFR') { } else if (airport.metar?.flight_category == 'MVFR') {
return new DivIcon({ return innerIcon({ tag: 'M', color: 'blue' });
html: ReactDOMServer.renderToString(
<MantineProvider>
<Avatar variant='filled' color='blue' radius='xl' size={iconSize()}>
M
</Avatar>
</MantineProvider>
),
className: 'metar-marker-icon'
});
} else if (airport.metar?.flight_category == 'IFR') { } else if (airport.metar?.flight_category == 'IFR') {
return new DivIcon({ return innerIcon({ tag: 'I', color: 'red' });
html: ReactDOMServer.renderToString(
<MantineProvider>
<Avatar variant='filled' color='red' radius='xl' size={iconSize()}>
I
</Avatar>
</MantineProvider>
),
className: 'metar-marker-icon'
});
} else if (airport.metar?.flight_category == 'LIFR') { } else if (airport.metar?.flight_category == 'LIFR') {
return new DivIcon({ return innerIcon({ tag: 'L', color: 'purple' });
html: ReactDOMServer.renderToString(
<MantineProvider>
<Avatar variant='filled' color='purple' radius='xl' size={iconSize()}>
L
</Avatar>
</MantineProvider>
),
className: 'metar-marker-icon'
});
} else { } else {
return new DivIcon({ return innerIcon({ tag: 'U', color: 'black', size: 'xs' });
html: ReactDOMServer.renderToString(
<MantineProvider>
<Avatar variant='filled' color='black' radius='xl' size={iconSize()}>
U
</Avatar>
</MantineProvider>
),
className: 'metar-marker-icon'
});
} }
} }

View File

@@ -85,15 +85,15 @@ export default function MetarModal({ airport, isOpen, onClose }: MetarModalProps
function MetarInfo({ metar }: { metar: Metar }) { function MetarInfo({ metar }: { metar: Metar }) {
function metarBGColor(metar: Metar | undefined) { function metarBGColor(metar: Metar | undefined) {
if (metar?.flight_category == 'VFR') { if (metar?.flight_category == 'VFR') {
return 'bg-emerald-600'; return 'green';
} else if (metar?.flight_category == 'MVFR') { } else if (metar?.flight_category == 'MVFR') {
return 'bg-blue-600'; return 'blue';
} else if (metar?.flight_category == 'IFR') { } else if (metar?.flight_category == 'IFR') {
return 'bg-red-600'; return 'red';
} else if (metar?.flight_category == 'LIFR') { } else if (metar?.flight_category == 'LIFR') {
return 'bg-purple-600'; return 'purple';
} else { } else {
return 'bg-black'; return 'black';
} }
} }
@@ -121,16 +121,23 @@ function MetarInfo({ metar }: { metar: Metar }) {
return ( return (
<div> <div>
<p className='text-xs font-small text-gray-500'>{metar.raw_text}</p> <p style={{ fontWeight: '200', fontSize: '0.8em', color: 'gray' }}>{metar.raw_text}</p>
<Grid gutter={18}> <Grid gutter={18}>
<Grid.Col className='gutter-row' span={6}> <Grid.Col className='gutter-row' span={6} style={{ marginTop: '0.5em' }}>
<span <span
className={`text-sm text-white py-2 px-4 rounded-full style={{
${metarBGColor(metar)} color: 'white',
`} backgroundColor: metarBGColor(metar),
borderRadius: '25px',
padding: '0.4em 0.8em 0.4em 0.8em'
}}
> >
{metar.flight_category ? metar.flight_category : 'UNKN'} {metar.flight_category ? metar.flight_category : 'UNKN'}
</span> </span>
<span style={{ marginLeft: '0.5em' }}>
{metar.wind_speed_kt != undefined && metar.wind_speed_kt > 0 ? `${metar.wind_speed_kt} KT` : 'CALM'}
</span>
{/* {metar.sky_condition != undefined && metar.sky_condition.map((skyCondition) => <>test</>)} */}
</Grid.Col> </Grid.Col>
<Grid.Col className='gutter-row' span={12}> <Grid.Col className='gutter-row' span={12}>
{metar.wx_string && metar.wx_string.split(' ').map((wx) => <MetarIcon wx={wx} />)} {metar.wx_string && metar.wx_string.split(' ').map((wx) => <MetarIcon wx={wx} />)}

View File

@@ -4,14 +4,14 @@ import Link from 'next/link';
import { AiOutlineUser } from 'react-icons/ai'; import { AiOutlineUser } from 'react-icons/ai';
import { useState } from 'react'; import { useState } from 'react';
import { getAirports } from '@/api/airport'; import { getAirports } from '@/api/airport';
// import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { Autocomplete, Avatar } from '@mantine/core'; import { Autocomplete, Avatar } from '@mantine/core';
import './topbar.css'; import './topbar.css';
export default function Topbar() { export default function Topbar() {
const [searchValue, setSearchValue] = useState(''); const [searchValue, setSearchValue] = useState('');
const [airports, setAirports] = useState<{ key: string; value: string; label: string }[]>([]); const [airports, setAirports] = useState<{ key: string; value: string; label: string }[]>([]);
// const router = useRouter(); const router = useRouter();
async function onChange(value: string) { async function onChange(value: string) {
setSearchValue(value); setSearchValue(value);
@@ -25,9 +25,10 @@ export default function Topbar() {
); );
} }
// function onClick(value: string) { function onClick(value: string) {
// router.push(`/airport/${value}`); router.push(`/airport/${value}`);
// } setSearchValue('');
}
return ( return (
<nav className='navbar'> <nav className='navbar'>
@@ -37,19 +38,19 @@ export default function Topbar() {
</Link> </Link>
<div className='search'> <div className='search'>
<Autocomplete <Autocomplete
autoFocus
radius='xl' radius='xl'
placeholder='Search Airports...' placeholder='Search Airports...'
limit={10}
data={airports} data={airports}
limit={10}
value={searchValue} value={searchValue}
onChange={onChange} onChange={onChange}
onOptionSubmit={onClick}
onBlur={() => setSearchValue('')} onBlur={() => setSearchValue('')}
/> />
</div> </div>
</div> </div>
<Link className='avatar' href={'/profile'}> <Link className='avatar' href={'/profile'}>
<Avatar> <Avatar variant='filled'>
<AiOutlineUser /> <AiOutlineUser />
</Avatar> </Avatar>
</Link> </Link>

View File

@@ -2,6 +2,8 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
height: 46px; height: 46px;
background-color: #0057a3;
color: white;
} }
.navbar .left { .navbar .left {
@@ -16,4 +18,10 @@
.navbar .left .search { .navbar .left .search {
margin: auto; margin: auto;
}
.navbar .avatar {
padding-right: 2em;
margin-top: auto;
margin-bottom: auto;
} }