searchbar fixed, working on modal
This commit is contained in:
@@ -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'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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} />)}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user