Working on email templating, updating with swagger
This commit is contained in:
@@ -17,11 +17,11 @@ export function CommunicationTable({ communications }: { communications: Communi
|
||||
<Table.Tr>
|
||||
<Table.Th>ID</Table.Th>
|
||||
<Table.Th>Name</Table.Th>
|
||||
<Table.Th>Frequencies (MHz)</Table.Th>
|
||||
<Table.Th>MHz</Table.Th>
|
||||
<Table.Th>Phone</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>{rows}</Table.Tbody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@ export function RunwayTable({ runways }: { runways: Runway[] }) {
|
||||
<Table.Tbody>{rows}</Table.Tbody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,10 +151,10 @@ function AirportInfoRow({ style, children }: { style?: CSSProperties; children:
|
||||
);
|
||||
}
|
||||
|
||||
function AirportInfo({ map, airport }: { map: LeafletMap, airport: Airport }) {
|
||||
function AirportInfo({ map, airport }: { map: LeafletMap; airport: Airport }) {
|
||||
function goToLocation(map: LeafletMap, latitude: number, longitude: number) {
|
||||
if (!map) return
|
||||
map.setView([latitude, longitude], map.getZoom())
|
||||
if (!map) return;
|
||||
map.setView([latitude, longitude], map.getZoom());
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -171,9 +171,11 @@ function AirportInfo({ map, airport }: { map: LeafletMap, airport: Airport }) {
|
||||
</AirportInfoSlot>
|
||||
<AirportInfoSlot title={'Elevation'} style={{ paddingLeft: '1rem' }} children={`${airport.elevation_ft} ft`} />
|
||||
<AirportInfoSlot style={{ marginLeft: 'auto', paddingLeft: '1rem', paddingTop: '0.5rem' }}>
|
||||
<UnstyledButton onClick={() => {
|
||||
goToLocation(map, airport.latitude, airport.longitude)
|
||||
}}>
|
||||
<UnstyledButton
|
||||
onClick={() => {
|
||||
goToLocation(map, airport.latitude, airport.longitude);
|
||||
}}
|
||||
>
|
||||
<IconViewfinder />
|
||||
</UnstyledButton>
|
||||
</AirportInfoSlot>
|
||||
@@ -181,9 +183,7 @@ function AirportInfo({ map, airport }: { map: LeafletMap, airport: Airport }) {
|
||||
<Accordion chevronPosition={'right'} variant={'contained'}>
|
||||
{airport.runways != null && airport.runways.length > 0 && (
|
||||
<Accordion.Item value={'runways'}>
|
||||
<Accordion.Control>
|
||||
Runways
|
||||
</Accordion.Control>
|
||||
<Accordion.Control>Runways</Accordion.Control>
|
||||
<Accordion.Panel>
|
||||
<RunwayTable runways={airport.runways} />
|
||||
</Accordion.Panel>
|
||||
@@ -191,9 +191,7 @@ function AirportInfo({ map, airport }: { map: LeafletMap, airport: Airport }) {
|
||||
)}
|
||||
{airport.communications != null && airport.communications.length > 0 && (
|
||||
<Accordion.Item value={'communication'}>
|
||||
<Accordion.Control>
|
||||
Communication
|
||||
</Accordion.Control>
|
||||
<Accordion.Control>Communication</Accordion.Control>
|
||||
<Accordion.Panel>
|
||||
<CommunicationTable communications={airport.communications} />
|
||||
</Accordion.Panel>
|
||||
|
||||
@@ -20,7 +20,7 @@ export function CustomControl({ position = 'bottomright', onClick, active = fals
|
||||
const ctrl = new L.Control({ position });
|
||||
ctrl.onAdd = () => {
|
||||
return L.DomUtil.create('div', 'leaflet-bar leaflet-control custom-control');
|
||||
}
|
||||
};
|
||||
|
||||
ctrl.addTo(map);
|
||||
controlRef.current = ctrl;
|
||||
@@ -28,6 +28,7 @@ export function CustomControl({ position = 'bottomright', onClick, active = fals
|
||||
// @ts-expect-error ctrl is a L.Control
|
||||
const container = (ctrl as unknown)._container as HTMLElement;
|
||||
rootRef.current = createRoot(container);
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
|
||||
return () => {
|
||||
if (rootRef.current) {
|
||||
@@ -45,7 +46,7 @@ export function CustomControl({ position = 'bottomright', onClick, active = fals
|
||||
href={'#'}
|
||||
title={title}
|
||||
className={active ? 'active' : ''}
|
||||
onClick={e => {
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onClick();
|
||||
@@ -59,7 +60,7 @@ export function CustomControl({ position = 'bottomright', onClick, active = fals
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
);
|
||||
}
|
||||
}, [onClick, active, title, children]);
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ export function GroupControl({ position = 'bottomright', buttons }: GroupControl
|
||||
// @ts-expect-error ctrl is a L.Control
|
||||
const container = (ctrl as unknown)._container as HTMLElement;
|
||||
rootRef.current = createRoot(container);
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
|
||||
return () => {
|
||||
ctrl.remove();
|
||||
@@ -48,10 +49,10 @@ export function GroupControl({ position = 'bottomright', buttons }: GroupControl
|
||||
{buttons.map((b, i) => (
|
||||
<a
|
||||
key={i}
|
||||
href="#"
|
||||
href='#'
|
||||
title={b.title}
|
||||
className={b.active ? 'active' : ''}
|
||||
onClick={e => {
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
b.onClick();
|
||||
|
||||
@@ -7,7 +7,7 @@ export function LocateControl() {
|
||||
|
||||
function handleClick() {
|
||||
if (!navigator.geolocation) {
|
||||
alert('Geolocation is not supported by your browser');
|
||||
console.warn('Geolocation is not supported by your browser');
|
||||
return;
|
||||
}
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
@@ -17,15 +17,14 @@ export function LocateControl() {
|
||||
map.setView([latitude, longitude], map.getZoom());
|
||||
},
|
||||
(err) => {
|
||||
console.error(err);
|
||||
alert('Unable to retrieve your location');
|
||||
console.warn('Unable to retrieve your location', err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<CustomControl onClick={handleClick} title="Go to my location">
|
||||
<CustomControl onClick={handleClick} title='Go to my location'>
|
||||
<IconCurrentLocation />
|
||||
</CustomControl>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,36 @@ import { UserContext } from './UserContext.tsx';
|
||||
import { profile } from '@lib/account.ts';
|
||||
import { User } from '@lib/account.types.ts';
|
||||
import { Center, Loader } from '@mantine/core';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
const sessionExpirationName = 'session_expiration';
|
||||
|
||||
export function UserProvider({ children }: { children: ReactNode }) {
|
||||
const [user, setUser] = useState<User | undefined>(undefined);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
profile().then((refreshUser) => {
|
||||
if (refreshUser) {
|
||||
setUser(refreshUser);
|
||||
const sessionExpiration = Cookies.get(sessionExpirationName);
|
||||
|
||||
if (sessionExpiration != undefined) {
|
||||
const date = new Date(parseInt(sessionExpiration) * 1000);
|
||||
const now = new Date();
|
||||
if (date > now) {
|
||||
profile().then((refreshUser) => {
|
||||
if (refreshUser) {
|
||||
setUser(refreshUser);
|
||||
} else {
|
||||
setUser(undefined);
|
||||
}
|
||||
setLoading(false);
|
||||
});
|
||||
} else {
|
||||
setUser(undefined);
|
||||
Cookies.remove(sessionExpirationName);
|
||||
setLoading(false);
|
||||
}
|
||||
} else {
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user