151 lines
4.1 KiB
JavaScript
151 lines
4.1 KiB
JavaScript
import React, { useState, useEffect, useContext } from "react";
|
|
import Paper from '@mui/material/Paper';
|
|
import {
|
|
useParams,
|
|
useNavigate
|
|
} from "react-router-dom";
|
|
|
|
import './Location.css';
|
|
import { GlobalContext } from "./GlobalContext.js";
|
|
import { base } from "./Common.js";
|
|
|
|
function Location(props) {
|
|
const propLocation = props.location;
|
|
const { csrfToken } = useContext(GlobalContext);
|
|
const [googleApiKey, setGoogleApiKey] = useState(undefined);
|
|
const [ location, setLocation ] = useState(
|
|
typeof propLocation === 'object' ? propLocation : undefined);
|
|
const [ error, setError ] = useState(null);
|
|
const locationId =
|
|
typeof propLocation === 'number' ? propLocation : undefined;
|
|
|
|
useEffect(() => {
|
|
if (!csrfToken || googleApiKey) {
|
|
return;
|
|
}
|
|
const effect = async () => {
|
|
const res = await window.fetch(
|
|
`${base}/api/v1/locations/google-api-key`, {
|
|
method: 'GET',
|
|
cache: 'no-cache',
|
|
credentials: 'same-origin',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'CSRF-Token': csrfToken
|
|
}
|
|
});
|
|
const data = await res.json();
|
|
if (res.status >= 400) {
|
|
setError(data.message ? data.message : res.statusText);
|
|
return;
|
|
}
|
|
if (!data) {
|
|
return;
|
|
}
|
|
setGoogleApiKey(data.key);
|
|
}
|
|
effect();
|
|
}, [csrfToken, googleApiKey, setGoogleApiKey]);
|
|
|
|
useEffect(() => {
|
|
if (!csrfToken || location || !locationId) {
|
|
return;
|
|
}
|
|
|
|
const effect = async () => {
|
|
const res = await window.fetch(
|
|
`${base}/api/v1/locations/${locationId}`, {
|
|
method: 'GET',
|
|
cache: 'no-cache',
|
|
credentials: 'same-origin',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'CSRF-Token': csrfToken
|
|
}
|
|
});
|
|
const data = await res.json();
|
|
if (res.status >= 400) {
|
|
setError(data.message ? data.message : res.statusText);
|
|
return;
|
|
}
|
|
if (!data) {
|
|
return;
|
|
}
|
|
setLocation(data);
|
|
}
|
|
effect();
|
|
}, [locationId, csrfToken, location]);
|
|
|
|
const createLocation = (location) => {
|
|
const fields = Object.getOwnPropertyNames(location)
|
|
.filter(field => location[field])
|
|
.map(field => {
|
|
return <div key={field}
|
|
style={{
|
|
display: 'flex',
|
|
flexDirection: 'row',
|
|
alignItems: 'flex-start',
|
|
width: '100%'
|
|
}}>
|
|
<div style={{
|
|
display: 'flex',
|
|
alignSelf: 'flex-start',
|
|
fontWeight: 'bold',
|
|
minWidth: '8rem'
|
|
}}>{field}</div>
|
|
<div style={{
|
|
display: 'flex',
|
|
alignSelf: 'flex-start',
|
|
textAlign: 'left'
|
|
}}>
|
|
{ typeof location[field] === 'string'
|
|
&& location[field].match(/^http.*/)
|
|
&& <a href={location[field]}>{field.toUpperCase()}</a> }
|
|
{ typeof location[field] === 'string'
|
|
&& !location[field].match(/^http.*/)
|
|
&& location[field] }
|
|
{ typeof location[field] === 'number' && location[field]}
|
|
</div>
|
|
</div>
|
|
} );
|
|
return <div key={location.id} style={{
|
|
display: 'flex',
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
}}>
|
|
<div style={{
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'center'
|
|
}}>{fields}</div>
|
|
{ googleApiKey && <iframe
|
|
title={location.id}
|
|
width="256"
|
|
height="128"
|
|
style={{ border: "0" }}
|
|
loading="lazy"
|
|
referrerPolicy="no-referrer-when-downgrade"
|
|
src={`https://www.google.com/maps/embed/v1/place?key=${googleApiKey}&q=${encodeURIComponent(location.name.replace(/ +/g, '+'))},Hillsboro+OR`}
|
|
/> }
|
|
</div>;
|
|
};
|
|
|
|
return (
|
|
<Paper className="Location" style={{
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
padding: '0.5rem',
|
|
marginTop: '0.25rem',
|
|
marginBottom: '0.25rem'
|
|
}}>
|
|
{ error && <div>{error}</div>}
|
|
{ !error && <>
|
|
{ createLocation(location) }
|
|
</> }
|
|
</Paper>
|
|
);
|
|
}
|
|
|
|
export { Location };
|