import { Box, Button, Card, Dialog, DialogActions, DialogContent, DialogTitle, Grid2 as Grid, InputAdornment, MenuItem, Slider, TextField, Typography } from "@mui/material"; import { useMobile } from "hooks"; import { cloneDeep } from "lodash"; import { DevicePreset } from "models/DevicePreset"; import { ObjectTypeString } from "objects/ObjectDescriber"; import { pond } from "protobuf-ts/pond"; import { useGlobalState, useSnackbar } from "providers"; import { useDevicePresetAPI } from "providers/pond/devicePresetAPI"; import React, { useEffect, useState } from "react"; interface Props { preset: DevicePreset; existing?: boolean; objectKey?: string; objectType?: pond.ObjectType; addCallback?: (preset: DevicePreset, tempKey: string) => void; removeCallback?: (preset: DevicePreset) => void; updateCallback?: (oldPreset: DevicePreset, newPreset: DevicePreset) => void; } export default function DevicePresetCard(props: Props) { const { preset, existing, objectKey, objectType, addCallback, removeCallback, updateCallback } = props; const devicePresetAPI = useDevicePresetAPI(); const [presetName, setPresetName] = useState(""); const [presetType, setPresetType] = useState(1); const [controllerType, setControllerType] = useState(1); const [openDeleteConfirmation, setOpenDeleteConfirmation] = useState(false); const { openSnack } = useSnackbar(); const [tempString, setTempString] = useState("0"); const [tempC, setTempC] = useState(0); const [humString, setHumString] = useState("0"); const [hum, setHum] = useState(0); const isMobile = useMobile(); const [{user}] = useGlobalState(); useEffect(() => { setPresetName(preset.name); setPresetType(preset.settings.type); setControllerType(preset.settings.controller); setTempC(preset.settings.temperature); setHum(preset.settings.humidity); setHumString(preset.settings.humidity.toString()); let displayTemp = preset.settings.temperature.toString(); if (user.tempUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT) { displayTemp = ((preset.settings.temperature * 9) / 5 + 32).toFixed(); } setTempString(displayTemp); }, [preset, user]); const saveNewPreset = () => { let typestring; if (objectType) { typestring = ObjectTypeString(objectType); } let p = preset; p.name = presetName; p.settings.type = presetType; p.settings.controller = controllerType; p.settings.temperature = tempC; p.settings.humidity = hum; devicePresetAPI .addDevicePreset(p.name, p.settings, objectKey, typestring) .then(resp => { //get the temp key from the preset let temp = p.key; //update the key in the preset with the key that came back from the add p.key = resp.data.key; //use the callback function passing in the preset and the temp key if (addCallback) { addCallback(p, temp); } openSnack("New preset saved"); }) .catch(err => { openSnack("Failed to save new preset"); }); }; const updatePreset = () => { let newPreset = cloneDeep(preset); let oldPreset = cloneDeep(preset); newPreset.name = presetName; newPreset.settings.type = presetType; newPreset.settings.controller = controllerType; newPreset.settings.temperature = tempC; newPreset.settings.humidity = hum; devicePresetAPI .updateDevicePreset(newPreset.key, newPreset.name, newPreset.settings) .then(resp => { if (updateCallback) { updateCallback(oldPreset, newPreset); } openSnack("Preset Updated"); }) .catch(err => { openSnack("There was a problem updating the preset"); }); }; const removePreset = () => { devicePresetAPI .removeDevicePreset(preset.key) .then(resp => { openSnack("Preset has been deleted"); setOpenDeleteConfirmation(false); if (removeCallback) { removeCallback(preset); } }) .catch(err => { openSnack("There was a problem deleting this preset"); }); }; const deleteConfirmation = () => { return ( { setOpenDeleteConfirmation(false); }}> Delete Preset This action will delete the selected preset ); }; const presetComparitors = () => { if (controllerType === pond.ControllerType.CONTROLLER_TYPE_HEATER) { switch (presetType) { case pond.PresetType.PRESET_TYPE_DRYING: return { temp: "below", hum: "above" }; case pond.PresetType.PRESET_TYPE_COOLING: return { temp: "below", hum: "above" }; } } else { //the controller type is a fan switch (presetType) { case pond.PresetType.PRESET_TYPE_DRYING: return { temp: "above", hum: "below" }; case pond.PresetType.PRESET_TYPE_COOLING: return { temp: "below", hum: "below" }; case pond.PresetType.PRESET_TYPE_HYDRATING: return { temp: "below", hum: "above" }; } } //replace having a default case with final return return { temp: "", hum: "" }; }; return ( {deleteConfirmation()} { setPresetName(e.target.value); }} /> {presetType !== pond.PresetType.PRESET_TYPE_UNKNOWN && controllerType !== pond.ControllerType.CONTROLLER_TYPE_UNKNOWN && ( Toggle{" "} {controllerType === pond.ControllerType.CONTROLLER_TYPE_HEATER ? "heater" : "fan"}{" "} on when temperature {presetComparitors().temp} and humidity{" "} {presetComparitors().hum} set points )} {/* type */} { setPresetType(+e.target.value as pond.PresetType); }}> Mode For Preset Drying Cooling Hydrating {/* controller type */} { setControllerType(+e.target.value as pond.ControllerType); }}> Controller For Preset Heater Fan {/* temp slider */} {isMobile ? ( Temperature {user.tempUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT ? "°F" : "°C"} ) }} error={isNaN(+tempString)} value={tempString} onChange={e => { if (!isNaN(+e.target.value)) { let temp = +e.target.value; if (user.tempUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT) { temp = Math.round((((temp - 32) * 5) / 9) * 10) / 10; } setTempC(temp); } setTempString(e.target.value); }} /> { if (user.tempUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT) { return ((value * 9) / 5 + 32).toFixed() + "°F"; } return value.toFixed() + "°C"; }} onChange={(_, value) => { setTempC(value as number); setTempString(value.toString()); }} /> ) : ( Temperature { if (user.tempUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT) { return ((value * 9) / 5 + 32).toFixed() + "°F"; } return value.toFixed() + "°C"; }} onChange={(_, value) => { setTempC(value as number); setTempString(value.toString()); }} /> {user.tempUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT ? "°F" : "°C"} ) }} error={isNaN(+tempString)} value={tempString} onChange={e => { if (!isNaN(+e.target.value)) { let temp = +e.target.value; if (user.tempUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT) { temp = Math.round((((temp - 32) * 5) / 9) * 10) / 10; } setTempC(temp); } setTempString(e.target.value); }} /> )} {/* humidity slider */} {isMobile ? ( Humidity % }} error={isNaN(+humString)} value={humString} onChange={e => { if (!isNaN(+humString)) { setHum(+e.target.value); } setHumString(e.target.value); }} /> value.toFixed() + "%"} onChange={(_, value) => { setHum(value as number); setHumString(value.toString()); }} /> ) : ( Humidity value.toFixed() + "%"} onChange={(_, value) => { setHum(value as number); setHumString(value.toString()); }} /> % }} error={isNaN(+humString)} value={humString} onChange={e => { if (!isNaN(+humString)) { setHum(+e.target.value); } setHumString(e.target.value); }} /> )} {existing && ( )} {existing ? ( ) : ( )} ); }