diff --git a/src/features/schema/FieldDetails.jsx b/src/features/schema/FieldDetails.jsx index e73ff16985..4ff4a89d97 100644 --- a/src/features/schema/FieldDetails.jsx +++ b/src/features/schema/FieldDetails.jsx @@ -5,6 +5,7 @@ import PhotoSelect from './fields/photoselect/PhotoSelect'; import Toggle from './fields/Toggle'; import DateTime from './fields/DateTime'; import Dropdown from './fields/Dropdown'; +import LocationForm from './fields/location/LocationForm'; import TextInput from './fields/TextInput'; import Typeahead from './fields/Typeahead'; import Typography from '@mui/material/Typography'; @@ -17,7 +18,7 @@ export default function FieldDetails({ field }) { case 'dropdown': return case 'location': - return schema.Location() is not yet supported in pixlet, but is supported in the community repo. Be on the lookout for this field to be available in a future release. + return case 'locationbased': return schema.LocationBased() is not yet supported in pixlet, but is supported in the community repo. Be on the lookout for this field to be available in a future release. case 'oauth2': diff --git a/src/features/schema/fields/location/InputSlider.jsx b/src/features/schema/fields/location/InputSlider.jsx new file mode 100644 index 0000000000..884997567e --- /dev/null +++ b/src/features/schema/fields/location/InputSlider.jsx @@ -0,0 +1,79 @@ +// Largely based on https://mui.com/material-ui/react-slider/#InputSlider.js +import React, { useState } from 'react'; + +import { styled } from '@mui/material/styles'; +import Box from '@mui/material/Box'; +import Grid from '@mui/material/Grid'; +import Typography from '@mui/material/Typography'; +import Slider from '@mui/material/Slider'; +import MuiInput from '@mui/material/Input'; + +const Input = styled(MuiInput)` + width: 80px; +`; + +export default function InputSlider({ min, max, step, defaultValue, onChange}) { + const [value, setValue] = useState(defaultValue); + + const handleSliderChange = (event, newValue) => { + setValue(newValue); + onChange(event); + }; + + const handleInputChange = (event) => { + if (event.target.value === '') { + setValue(''); + onChange(event); + return; + } + const value = Number(event.target.value); + if (value < min) { + setValue(min); + } else if (value > max) { + setValue(max); + } else { + setValue(value); + } + onChange(event); + }; + + const handleBlur = () => { + if (value < min) { + setValue(min); + } else if (value > max) { + setValue(max); + } + }; + + return ( + + + + + + + + + + + ); +} \ No newline at end of file diff --git a/src/features/schema/fields/location/LocationForm.jsx b/src/features/schema/fields/location/LocationForm.jsx new file mode 100644 index 0000000000..160436eed3 --- /dev/null +++ b/src/features/schema/fields/location/LocationForm.jsx @@ -0,0 +1,107 @@ +import React, { useState, useEffect } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; + +import InputLabel from '@mui/material/InputLabel'; +import MenuItem from '@mui/material/MenuItem'; +import FormControl from '@mui/material/FormControl'; +import Select from '@mui/material/Select'; +import TextField from '@mui/material/TextField'; +import Typography from '@mui/material/Typography'; + +import InputSlider from './InputSlider'; +import { set } from '../../../config/configSlice'; + +export default function LocationForm({ field }) { + const [value, setValue] = useState({ + // Default to Brooklyn, because that's where tidbyt folks + // are and we can only dispatch a location object which + // has all fields set. + 'lat': 40.6782, + 'lng': -73.9442, + 'locality': 'Brooklyn, New York', + 'timezone': 'America/New_York', + // But overwrite with app-specific defaults set in config. + ...field.default + }); + + const config = useSelector(state => state.config); + + const dispatch = useDispatch(); + + useEffect(() => { + if (field.id in config) { + setValue(JSON.parse(config[field.id].value)); + } else if (field.default) { + dispatch(set({ + id: field.id, + value: field.default, + })); + } + }, []) + + const setPart = (partName, partValue) => { + let newValue = {...value}; + newValue[partName] = partValue; + setValue(newValue); + dispatch(set({ + id: field.id, + value: JSON.stringify(newValue), + })); + } + + const onChangeLatitude = (event) => { + setPart('lat', event.target.value); + } + + const onChangeLongitude = (event) => { + setPart('lng', event.target.value); + } + + const onChangeLocality = (event) => { + setPart('locality', event.target.value); + } + + const onChangeTimezone = (event) => { + setPart('timezone', event.target.value); + } + + return ( + + Latitude + + + Longitude + + + Locality + + Timezone + + + ); +} \ No newline at end of file