import React, { useEffect, useRef, useCallback, useState, Suspense, } from 'react'; import PropTypes from 'prop-types'; import { atom, useRecoilState, useRecoilValueLoadable, useRecoilValue, } from 'recoil'; import { useParams } from 'react-router-dom'; import { Container, Header, Input, Segment, Table, Form, } from 'semantic-ui-react'; import { authState } from '../lib/personium_auth_adapter'; import { locationACLStatusState, locationURLFromId, locationODataFromId, useLocationACLSubscribe, } from '../common/location_stat'; const locationId = atom({ key: 'userLocationId', default: null, }); function LocationDataURLViewChild({ __id, locationUrl }) { const { updateLocationACL } = useLocationACLSubscribe(__id, locationUrl); const aclStatus = useRecoilValue(locationACLStatusState(__id)); const isLoading = aclStatus === 'loading'; const refInput = useRef(null); useEffect(() => { updateLocationACL(); }, []); const onClick = useCallback(() => { refInput.current.select(); document.execCommand('copy'); }, []); return ( <Form.Field disabled={isLoading}> <label>This location is set as `{aclStatus}`</label> <Input fluid disabled={aclStatus === 'private'} ref={refInput} value={locationUrl} action={{ color: 'teal', icon: 'copy', labelPosition: 'right', content: 'Copy', onClick: onClick, }} /> </Form.Field> ); } LocationDataURLViewChild.propTypes = { __id: PropTypes.string, locationUrl: PropTypes.string, }; function LocationDataURLView({ __id }) { const locationUrlLoadable = useRecoilValueLoadable(locationURLFromId(__id)); const locationUrl = locationUrlLoadable.state === 'hasValue' ? locationUrlLoadable.contents : null; console.log({ locationUrl }); const isLoading = locationUrlLoadable.state === 'loading'; return ( <Segment> <Header as="h4">Location URL</Header> <Form loading={isLoading}> {locationUrl ? ( <LocationDataURLViewChild __id={__id} locationUrl={locationUrl} /> ) : null} </Form> </Segment> ); } LocationDataURLView.propTypes = { __id: PropTypes.string, }; function LocationRawDataView({ __id }) { return ( <Segment> <Header as="h4">Raw data</Header> <Suspense fallback={<div>Loading...</div>}> <LocationRawDataViewChild __id={__id} /> </Suspense> </Segment> ); } LocationRawDataView.propTypes = { __id: PropTypes.string, }; function LocationRawDataViewChild({ __id }) { const locationUrl = useRecoilValue(locationURLFromId(__id)); const [locationInfo, setLocationInfo] = useState({}); useEffect(() => { let unmounted = false; fetch(locationUrl, { headers: { Authorization: `Bearer ${authState.accessToken.access_token}`, }, }) .then(res => res.json()) .then(jsonDat => { if (!unmounted) setLocationInfo(jsonDat); }); return function cleanup() { unmounted = true; }; }, [locationUrl]); return ( <Table> <Table.Header> <Table.Row> <Table.HeaderCell>Name</Table.HeaderCell> <Table.HeaderCell>Value</Table.HeaderCell> </Table.Row> </Table.Header> <Table.Body> {Object.entries(locationInfo).map(([key, val]) => { const _val = typeof val === 'object' ? JSON.stringify(val) : val; return ( <Table.Row key={key}> <Table.Cell>{key}</Table.Cell> <Table.Cell style={{ overflowWrap: 'anywhere' }}> {_val} </Table.Cell> </Table.Row> ); })} </Table.Body> </Table> ); } LocationRawDataViewChild.propTypes = { __id: PropTypes.string, }; function LocationODataView({ __id }) { const locationInfoLoadable = useRecoilValueLoadable( locationODataFromId(__id) ); const isLoading = locationInfoLoadable.state === 'loading'; const locationInfo = locationInfoLoadable.state === 'hasValue' ? locationInfoLoadable.contents : null; return ( <Segment> <Header as="h4">some information about the location</Header> {isLoading ? ( <div>Loading...</div> ) : locationInfo === null ? null : ( <Table> <Table.Header> <Table.Row> <Table.HeaderCell>Name</Table.HeaderCell> <Table.HeaderCell>Value</Table.HeaderCell> </Table.Row> </Table.Header> <Table.Body> {Object.entries(locationInfo).map(([key, val]) => { if (typeof val === 'object') return null; return ( <Table.Row key={key}> <Table.Cell>{key}</Table.Cell> <Table.Cell style={{ overflowWrap: 'anywhere' }}> {val} </Table.Cell> </Table.Row> ); })} </Table.Body> </Table> )} </Segment> ); } LocationODataView.propTypes = { __id: PropTypes.string, }; export function DetailPage() { const { __id } = useParams(); const [Id, setId] = useRecoilState(locationId); console.log(__id); useEffect(() => { console.log({ __id }); setId(__id); }, [__id]); return ( <Container> <Header as="h3">Detail of #{Id}</Header> <LocationDataURLView __id={__id} /> <LocationODataView __id={__id} /> <LocationRawDataView __id={__id} /> </Container> ); } DetailPage.propTypes = { match: PropTypes.shape({ params: PropTypes.shape({ __id: PropTypes.string, type: PropTypes.string, }), }), };