{"version":3,"sources":["reducers/user.reducer.js","assets/images/LogoTopLeft.png","reducers/auth.reducer.js","reducers/general.reducer.js","assets/mock_images/cam32_concat.jpg","reducers/reports.reducer.js","assets/images/computer_screen_frame.png","assets/images/metervibe_app_desktop_1.png","assets/images/metervibe_app_desktop_2.png","assets/images/metervibe_app_desktop_3.png","assets/images/metervibe_device_transparent.png","assets/images/MeterVibe_logo_1444x596.png","assets/images/waterfall.jpeg","assets/images/meter_1.png","assets/images/meter_2.png","assets/images/meter_3.png","assets/images/meter_4.png","store/index.js","../node_modules/@aws-amplify/ui-components/dist/esm-es5 lazy /^/.*/.entry/.js$/ include: /.entry/.js$/ exclude: /.system/.entry/.js$/ groupOptions: {} namespace object","config.js","components/shared/buttons/MeterVibeButton.js","components/shared/modal/ModalComponents.js","components/modals/camera_modals/LeakageDetailsModal.js","components/modals/camera_modals/ImageDetailsModal.js","components/modals/camera_modals/MeterReadingsModal.js","components/shared/buttons/MeterVibeButtonSecondary.js","components/shared/buttons/MeterVibeButtonPrimary.js","components/modals/camera_modals/EditCameraModal.js","utils/toTitleCase.js","services/images.services.js","services/reports.services.js","services/cameras.services.js","components/CameraCard.js","components/NoCameras.js","containers/Dashboard.js","components/ActivateResponse.js","containers/Activate.js","containers/Admin.js","components/ImagesDropdown.js","services/snap.services.js","services/turk.services.js","components/Snap.js","containers/Device.js","components/NotFound.js","containers/LoginScreen.js","components/shared/typography/PublicLandingText.js","components/PublicLandingHeader.js","components/PublicLandingPaymentSuccess.js","components/PublicLandingPaymentFailure.js","components/shared/fun_backgrounds/WavyBackground.js","components/PublicLandingFooter.js","components/stripe/prebuilt/GlobalStyles.jsx","components/stripe/Layout.jsx","components/stripe/prebuilt/Row.jsx","components/QuantityRadio.js","components/stripe/CheckoutForm.jsx","components/OrderCard.js","components/Stripe.js","components/PublicLandingComputerScreen.js","components/shared/image_components/Slideshow.js","components/PublicLanding.js","components/Header.js","components/CameraDropdown.js","utils/protectedRoute.js","layouts/MeterVibeAppLayout.js","markdown/TermsOfServiceMarkdown.js","components/TermsOfService.js","markdown/PrivacyPolicyMarkdown.js","components/PrivacyPolicy.js","components/reports_components/ReportsNavbar.js","utils/Reports.utils.js","components/reports_components/ReportsFilters.js","components/reports_components/ReportsChart.js","components/reports_components/ReportsReadingsTable.js","containers/Reports.js","components/alerts_components/AlertsNavbar.js","components/shared/containers/PageSection.js","components/alerts_components/StatusAndAlerts/IssueFoundSection.js","components/alerts_components/StatusAndAlerts/AlertsSection.js","components/alerts_components/StatusAndAlerts/AlertDetailsModal.js","components/alerts_components/StatusAndAlerts/StatusAndAlerts.js","components/alerts_components/AlertsSettings/CheckboxesSection.js","components/alerts_components/AlertsSettings/HoursSection.js","components/alerts_components/AlertsSettings/AlertsSettings.js","mocks/alerts.mock.js","containers/Alerts.js","containers/UserSettings.js","Routes.js","components/shared/helper_components/ScrollToTopOnMount.jsx","App.js","registerServiceWorker.js","index.js","reducers/root.reducer.js","store/store.prod.js","reducers/cameras.reducer.js"],"names":["USER_ACTIONS","SET_USER_EMAIL","SET_USER","SET_ADMIN","initialState","user","userEmail","admin","userReducer","state","action","type","payload","module","exports","AUTH_ACTIONS","SET_AUTH_STATE","authReducer","API_ACTIONS","SET_AWAITING_API","awaitingAPI","generalReducer","REPORTS_ACTIONS","ROW_SELECTED","CLEAR_ALL_SELECTED_ROWS","SET_PAGE_STATE","TOGGLE_SELECT_MODE_ENABLED","SET_BAR_CHART_DATA","SET_IS_LOADING","SET_READINGS_DATA","DELETE_SELECTED_ROWS","SELECT_ALL_ROWS","SET_CHART_DATA","SET_CAMERA_DATA","SET_IMAGES_LIST","SET_REPORT_INFO","SET_START_DATE","SET_END_DATE","SET_PERIOD_TYPE","RESET_TIME","isLoading","imagesList","barChartData","readingsData","chartData","cameraData","cameraId","cameraName","cameraLocation","pageState","showFilter","showChart","showDetailCards","usageOverviewSelectedTab","readingsTabSelected","perAppliancesTabSelected","customReportsTabSelected","activeTab","isSelectModeEnabled","selectedRows","reportInfo","reportCount","reportLabel","reportMult","startDate","endDate","moment","format","currentPeriodType","reportsReducer","newSelectedRowsState","includes","original","timestampSaved","filter","newSelectModeEnabledState","Set","map","require","webpackAsyncContext","req","__webpack_require__","o","Promise","resolve","then","e","Error","code","ids","id","keys","Object","REGION","BUCKET","URL","URL_ML","USER_POOL_ID","APP_CLIENT_ID","IDENTITY_POOL_ID","useStyles","makeStyles","root","outline","MeterVibeButton","Icon","text","onClick","className","backgroundColor","textTransform","fontWeight","color","border","background","rest","classes","Button","variant","style","DialogTitle","withStyles","theme","margin","padding","spacing","title","fontFamily","join","textAlign","closeButton","position","right","top","palette","grey","props","children","onClose","other","disableTypography","Typography","IconButton","aria-label","DialogContent","MuiDialogContent","DialogActions","MuiDialogActions","PaperComponent","DraggableModal","React","memo","open","isLeaking","dividers","display","flexDirection","width","overflowWrap","imageData","mostRecentReading","label","reading","component","gutterBottom","Tooltip","arrow","placement","cursor","src","lastSnapShot","alt","subheading","fontSize","imageSectionRoot","overflow","breakdownSectionRoot","altText","snapshotImg","digitsText","marginTop","breakdownTableHead","breakdownTableRow","buttonsContainer","justifyContent","deviceDetails","previousImageData","meterReadingsMultiplied","unitCostUSD","currentDigits","current","previousDigits","previous","differenceDigits","difference","mostRecentTime","prevTime","hoursDiff","diff","toFixed","digitsDiff","number","rateNumber","Number","toLocaleString","rateText","minWidth","formatted","category","digits","imageSource","timeStampSaved","ImageSection","Grid","item","container","xs","BreakdownSection","Table","TableHead","TableRow","cellText","key","TableCell","TableBody","MeterVibeButtonSecondary","MeterVibeButtonPrimary","EditCameraModal","onSave","costPerUnit","unitsLabel","useState","formData","setFormData","costPerUnitUSD","useMemo","labelSingular","pluralize","TextField","name","onChange","target","value","prevState","toLowerCase","getAllImagesListAPI","a","API","get","imagesData","getAllImagesListProc","getMostRecentImgAPI","mostRecentData","getOneImageByTimestamp","oneImage","putDigits","timestamp","path","init","body","console","log","put","response","getReportOnlyParams","reportOnlyParams","apiCameras","camerasData","getCameraVersion","cameraVersion","reassignCamera","cameraToReassign","post","reassignResult","activateCamera","aCode","getCameraParams","cameraParams","updateCameraCostPerUnit","userInput","eventData","updatedCostPerUnit","deleteTimestamp","del","updateCameraFlash","undefined","flash1","flash2","flash3","marginBottom","media","height","paddingTop","expand","transform","marginLeft","transition","transitions","create","duration","shortest","expandOpen","avatar","red","cardHeaderRoot","alignItems","cardHeaderLeft","cardHeaderTitle","lineHeight","cardHeaderSubHeader","cardFooter","borderTop","actionsButton","cardMiddleContainer","imageListContainer","maxWidth","separator","deviceInfo","borderLeft","statusHeaderRoot","borderBottom","breakpoints","down","paddingBottom","deviceStatusHeader","boldBlueText","lastSavedDate","iconCategoryText","iconStatusText","iconGroup","iconCircle","borderRadius","marginRight","iconTextContainer","IconCircle","icon","IconGroup","categoryText","statusText","Box","checkIsAfterMidnight","date","time","midnight","isSameOrAfter","calculateMeterReadingMultiplied","result","Math","max","log10","getPreviousImageData","currentReading","data","currentReadingTimestamp","el","isAfterMidnight","CameraCard","camera","onViewDetails","onViewReports","location","setCameraData","setImageData","setPreviousImageData","setReportInfo","unitsData","setUnitsData","setMeterReadingsMultiplied","isLeakageModalOpen","setIsLeakageModalOpen","isImageModalOpen","setIsImageModalOpen","isReadingsModalOpen","setIsReadingsModalOpen","isEditModalOpen","setIsEditModalOpen","isCameraDataLoaded","setCameraIsDataLoaded","isDataLoaded","setIsDataLoaded","useTheme","matchesSm","useMediaQuery","useEffect","getImageData","responseData","previousReading","SignedUrl","getReportInfo","params","units","mult","multiplier","string","split","word","charAt","toUpperCase","substring","getCameraData","active","cameraNotes","rotation","rot4","lastSavedTimestamp","NaN","currentDigitsMultiplied","previousDigitsMultiplied","digitsDifference","showLeakageModal","useCallback","closeLeakageModal","showImageModal","closeImageModal","showReadingsModal","closeReadingsModal","showEditModal","closeEditModal","Card","direction","wrap","md","CardContent","CardHeader","subheader","cardHeaderRight","WaterIcon","ThumbsUpIcon","EyeIcon","LinearProgress","epoch13digit","d","Date","parseInt","toLocaleTimeString","toLocaleDateString","epochToLocalTimeDateString","CardActions","NoCameras","href","typography","imageDiv","camerasList","maxHeight","overflowY","listStyle","SET_USER_SELECTED_CAMERA","CAMERA_ACTIONS","ListCameraCards","history","useHistory","dispatch","useDispatch","cameras","useSelector","camerasReducer","setUserSelectedCamera","CARDS","i","toString","push","Dashboard","length","buttonDiv","button","ActivateResponse","setShowResult","Toolbar","textField","Activate","activationCode","setActivationCode","activateResponse","setActivateResponse","setCameraToReassign","showResult","handleReassignCamera","handleFormSubmit","event","preventDefault","onSubmit","autoFocus","placeholder","size","fullWidth","Admin","cognitoIdentityId","Auth","currentCredentials","apiButton","identityId","headerText","slot","usernameAlias","hideSignIn","formFields","required","formControl","ImagesDropdown","allImagesList","FormControl","Select","native","setUserSelectedTimestamp","image","dayjs","postSnap","newSnap","beginCalibration","imageURL","noSignatureUrl","substr","indexOf","image_url","Snap","setSnapped","userSelectedCamera","setFlash1","setFlash2","setFlash3","handleChangeFlash1","handleChangeFlash2","handleChangeFlash3","saveFlash","snapImage","framesize","vflip","vFlip","hflip","hFlip","getTime","winX","subXOrig","winY","subYOrig","winWidth","subWidth","winHeight","subHeight","fetchFlashState","FormLabel","FormGroup","FormControlLabel","control","Slider","defaultValue","valueLabelDisplay","isNaN","rot","Device","displayImg","setDisplayImg","setAllImagesList","userSelectedTimestamp","snapped","getMostRecentImg","getImgList","getImg","setTimeout","imgList","userSelectedImg","parseMostRecentImg","imgSignedURL","search","splitResult","mostRecentImg","consoleLogCameraVersion","NotFound","LoginScreen","allowSignUp","hideSignUp","PublicLandingText","appBar","zIndex","drawer","logo","flexGrow","signInButton","buyNowButton","navButton","offset","mixins","toolbar","closeIcon","infoIcon","HideOnScroll","window","trigger","useScrollTrigger","Slide","appear","in","SignInModal","handleClose","Dialog","PublicLandingHeader","pathname","useLocation","isSignInOpen","setIsSignInOpen","storedState","localStorage","getItem","showAlert","setShowAlert","matchesXs","currentUserInfo","attributes","email","AppBar","Logo","Hidden","activeClass","to","spy","smooth","CartIcon","smDown","currentAuthenticatedUser","lg","xsDown","sm","setItem","PublicLandingPaymentSuccess","align","PublicLandingPaymentFailure","WavyBackground","xmlns","viewBox","fill","fillOpacity","PublicLandingFooter","pageSection","innerColumn","GlobalStyles","styles","css","stripePromise","loadStripe","Layout","charSet","content","stripe","Row","styled","div","responsive","QuantityRadio","quantity","RadioGroup","row","Radio","StripePayment","handleClick","error","OrderCard","numDevices","setNumDevices","CheckoutForm","paragraph","Stripe","verticalAlign","computerScreen","left","PublicLandingComputerScreen","slideImages","MeterVibeAppImg1","MeterVibeAppImg2","MeterVibeAppImg3","easing","arrows","imgSrc","ComputerScreenFrame","Slideshow","images","slideProps","containerWidth","imgWidth","imgHeight","justify","backgroundImage","backgroundSize","backgroundRepeat","mediumBluePaper","whitePaper","sweetAiranPaper","pageContent","customBorderRadius","scrollMarginTop","welcome","minHeight","pageBreak","listMain","listAlt","installationInfoList","deviceImage","sectionImage","PublicLanding","matchesMd","matchesXS","Paper","my","MeterVibeLogoImg","objectFit","MeterVibeDeviceImg","canSwipe","MeterImg1","MeterImg2","MeterImg3","MeterImg4","WaterfallImg","signOutButton","Header","selectEmpty","CameraDropDown","showMore","userSelectedCameraId","InputLabel","labelId","selectedCameraId","selectedCameraObject","getCameraObject","displayEmpty","inputProps","MenuItem","protectedRoute","Component","route","checkAuthState","paddingRight","toolbarIcon","iconButton","sharp","leavingScreen","appBarShift","enteringScreen","menuButton","menuButtonHidden","drawerPaper","whiteSpace","drawerPaperClose","overflowX","up","appBarSpacer","paper","fixedHeight","boldText","navLinks","DashboardIcon","AddBoxIcon","isAdminLink","LinkedCameraIcon","VpnKeyIcon","ReportsIcon","AlertsIcon","PersonIcon","customLayoutPaths","setOpen","renderPaperWrapper","test","Drawer","clsx","Divider","List","boxShadow","CameraDropdown","DrawerListLink","ListItem","Link","activeStyle","PaperWrapper","Container","COLORS","toolbarDistance","markdown","letterSpacing","TermsOfService","goBack","tab","ReportsNavbar","changeToTab","Tabs","indicatorColor","textColor","orientation","Tab","periodDates","startPeriodDate","periodType","startDateResult","startOf","endDateResult","endOf","addRealMonth","futureMonth","add","futureMonthEnd","isSame","nextPeriodDates","currentStartPeriodDate","currentEndPeriodDate","nextStartPeriodDate","nextEndPeriodDate","computeDeltas","tSeries","idx","removeOutliers","sublistArray","len","lowerQuartileIdx","upperQuartileIdx","sort","b","lowerBound","upperBound","index","arr","createDeltaProperties","deltaDigits","deltaTimeMS","buttonGroup","borderRight","sectionTitle","userSelect","updateInfoButton","titleHidden","visibility","ReportsFilters","selectButtonsDisabled","setSelectButtonsDisabled","toggleSelectMode","onDeleteClick","status","selectAllItems","unSelectAllItems","render","DateFilters","minimumDate","min","SelectModeButtons","allItemsSelected","setAllItemsSelected","disabled","PeriodTypeButtons","ToggleButtonGroup","_e","newValue","exclusive","ToggleButton","ReportsChart","chartType","legendToggle","loader","options","colors","hAxis","vAxis","chart","tableContainer","tableFooterRow","paginationSpacer","flex","paginationActions","flexShrink","Linebreak","EditDigitsCell","initialValue","column","handleCellInputChange","setValue","onBlur","ReportsReadingsTable","newReadingsData","filteredReadingsData","dateToCheck","isBetween","handleSelectRow","rowInfo","columns","accessor","Cell","cell","cellValue","gallons","values","delta","mins","useTable","autoResetPage","pageIndex","pageSize","usePagination","gotoPage","setPageSize","pageOptions","getTableProps","getTableBodyProps","headerGroups","rows","page","prepareRow","TableContainer","stickyHeader","table","headerGroup","getHeaderGroupProps","headers","getHeaderProps","tableHeader","isSelected","getRowProps","handleOriginal","hover","cells","getCellProps","TableFooter","TablePagination","rowsPerPageOptions","colSpan","pagination","count","rowsPerPage","onPageChange","labelDisplayedRows","spacer","onRowsPerPageChange","ActionsComponent","TableActions","canGoNext","canGoBack","selectTable","PageSection","gridItemStyles","Reports","reportsState","setIsLoading","noData","setNoData","handlePeriodicFilter","currentTimestamp","isAfter","endPeriodDate","prevResultDigits","cleanData","noZerosList","reverse","elt","lIdx","cleanedData","rIdx","concat","slice","handleDeviceSelected","digitsMultiplier","hasDigitsList","Boolean","chartD","flowD","unshift","err","onDateFilterChange","onDeviceSelected","CircularProgress","paddingLeft","AlertsNavbar","issueTypeText","issueHeaderText","issueMessageText","textBold","issueFound","closeIssueFound","openDetailsModal","message","AlertRow","alert","severity","alertSeverity","alertRowItemsContainer","alertRowSeverityCircle","alertRowMessage","viewDetailsButton","alertRowTimestamp","ALERT_SEVERITIES","info","success","warning","danger","buttonStyles","alertsSectionHeader","verticalSpacer","alertsSectionFooter","alertsClearAllButton","alerts","handleClearAlerts","closeBtn","resolveBtn","SEVERITY_TITLES","SEVERITY_RATINGS","formattedTime","_emptyCell","resolveIssue","modalTitle","signedUrl","StatusAndAlerts","clearOneAlert","isDetailsModalOpen","setIsDetailsModalOpen","modalData","setModalData","closeDetailsModal","onIssueResolved","recentSnapshot","firstSnapshot","CheckboxesSection","potentialLeakageAlerts","dailyWaterUsageAlerts","dailyWaterUsageReport","monthlyWaterUsageReport","enabledCheckboxes","setEnabledCheckboxes","initialCheckboxesState","onEmail","onMobilePhone","inWebApplication","sendPotentialLeakageAlerts","setSendPotentialLeakageAlerts","sendAlertDaily","setSendAlertDaily","sendDailyWaterUsageReport","setSendDailyWaterUsageReport","sendMonthlyWaterUsageReport","setSendMonthlyWaterUsageReport","toggleEnabledCheckboxes","handleSubmit","reqBody","send","dailyAlerts","average","_testSubmit","setState","stateName","checkboxAliases","CheckboxGroup","labelText","Checkbox","checked","CheckboxRow","DailyWaterAlertsRow","defaultParagraph","HoursSection","now","hours","setHours","handleChange","link","AlertsSettings","IntroSection","SectionComponent","Fragment","SectionSeparator","mockSnapshotRecent","mockSnapshotSRC","mockSnapshotPrior","ONE_HOUR_IN_MS","mockAlerts","isCleared","ONE_DAY_IN_MS","Alerts","setActiveTab","setIssueFound","allVisibleAlerts","setAllVisibleAlerts","unclearedAlerts","newTab","updatedAlert","toggleAlertCleared","mappedAlert","newIssueFound","find","checkNewIssueFound","UserSettings","PersonalDetails","phoneNumber","personalDetails","setPersonalDetails","onSavePersonalDetails","JSON","stringify","sectionItems","FormHelperText","saveButton","ChangePassword","oldPassword","newPassword","passwordData","setPasswordData","onSaveNewPassword","DefaultPreferences","showDataType","gallonPrice","defaultPreferences","setDefaultPreferences","onSaveDefaultPreferences","htmlFor","inputLabel","exact","PrivacyPolicy","ScrollToTopOnMount","scrollTo","SET_CAMERAS","App","getCameras","apiCamerasResponse","sortedCameras","localeCompare","authListener","Hub","listen","remove","onAuthUIStateChange","nextAuthState","authData","CssBaseline","Routes","isLocalhost","hostname","match","registerValidSW","swUrl","navigator","serviceWorker","register","registration","onupdatefound","installingWorker","installing","onstatechange","controller","catch","reduxStore","configureStore","Amplify","configure","mandatorySignIn","region","config","userPoolId","identityPoolId","userPoolWebClientId","Storage","bucket","endpoints","endpoint","ReactDOM","store","document","getElementById","process","origin","addEventListener","fetch","ready","unregister","reload","checkValidServiceWorker","registerServiceWorker","combineReducers","createStore","rootReducer"],"mappings":"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","file":"static/js/main.680d1d7f.chunk.js","sourcesContent":["export const USER_ACTIONS = {\r\n SET_USER_EMAIL: 'SET_USER_EMAIL',\r\n SET_USER: 'SET_USER',\r\n SET_ADMIN: 'SET_ADMIN',\r\n};\r\n\r\nconst { SET_USER, SET_ADMIN, SET_USER_EMAIL } = USER_ACTIONS;\r\n\r\nconst initialState = {\r\n user: null,\r\n userEmail: '',\r\n admin: false,\r\n};\r\n\r\nexport default function userReducer(state = initialState, action) {\r\n const { type, payload } = action;\r\n\r\n switch (type) {\r\n case SET_USER_EMAIL: {\r\n return {\r\n ...state,\r\n userEmail: payload,\r\n };\r\n }\r\n\r\n case SET_USER: {\r\n return {\r\n ...state,\r\n user: payload,\r\n };\r\n }\r\n\r\n case SET_ADMIN: {\r\n return {\r\n ...state,\r\n admin: payload,\r\n };\r\n }\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n","module.exports = __webpack_public_path__ + \"static/media/LogoTopLeft.b2b739b6.png\";","export const AUTH_ACTIONS = {\r\n SET_AUTH_STATE: 'SET_AUTH_STATE',\r\n};\r\n\r\nconst { SET_AUTH_STATE } = AUTH_ACTIONS;\r\n\r\nconst initialState = null;\r\n\r\nexport default function authReducer(state = initialState, action) {\r\n const { type, payload } = action;\r\n\r\n switch (type) {\r\n case SET_AUTH_STATE: {\r\n return payload;\r\n }\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n","export const API_ACTIONS = {\r\n SET_AWAITING_API: 'SET_AWAITING_API',\r\n};\r\n\r\nconst { SET_AWAITING_API } = API_ACTIONS;\r\n\r\nconst initialState = {\r\n awaitingAPI: true,\r\n};\r\n\r\n/*\r\n This reducer is for general state,\r\n ex: loading state, misc booleans, preferences, etc.\r\n*/\r\n\r\nexport default function generalReducer(state = initialState, action) {\r\n const { type, payload } = action;\r\n\r\n switch (type) {\r\n case SET_AWAITING_API: {\r\n return {\r\n ...state,\r\n awaitingAPI: payload,\r\n };\r\n }\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n","module.exports = __webpack_public_path__ + \"static/media/cam32_concat.18ba079f.jpg\";","import moment from 'moment';\r\n\r\nexport const REPORTS_ACTIONS = {\r\n ROW_SELECTED: 'ROW_SELECTED',\r\n CLEAR_ALL_SELECTED_ROWS: 'CLEAR_ALL_SELECTED_ROWS',\r\n SET_PAGE_STATE: 'SET_PAGE_STATE',\r\n TOGGLE_SELECT_MODE_ENABLED: 'TOGGLE_SELECT_MODE_ENABLED',\r\n SET_BAR_CHART_DATA: 'SET_BAR_CHART_DATA',\r\n SET_IS_LOADING: 'SET_IS_LOADING',\r\n SET_READINGS_DATA: 'SET_READINGS_DATA',\r\n DELETE_SELECTED_ROWS: 'DELETE_SELECTED_ROWS',\r\n SELECT_ALL_ROWS: 'SELECT_ALL_ROWS',\r\n SET_CHART_DATA: 'SET_CHART_DATA',\r\n SET_CAMERA_DATA: 'SET_CAMERA_DATA',\r\n SET_IMAGES_LIST: 'SET_IMAGES_LIST',\r\n SET_REPORT_INFO: 'SET_REPORT_INFO',\r\n SET_START_DATE: 'SET_START_DATE',\r\n SET_END_DATE: 'SET_END_DATE',\r\n SET_PERIOD_TYPE: 'SET_PERIOD_TYPE',\r\n RESET_TIME: 'RESET_TIME',\r\n};\r\n\r\nconst {\r\n ROW_SELECTED,\r\n SET_PAGE_STATE,\r\n CLEAR_ALL_SELECTED_ROWS,\r\n TOGGLE_SELECT_MODE_ENABLED,\r\n SET_BAR_CHART_DATA,\r\n SET_IS_LOADING,\r\n DELETE_SELECTED_ROWS,\r\n SELECT_ALL_ROWS,\r\n SET_READINGS_DATA, // readings table data\r\n SET_CHART_DATA,\r\n SET_CAMERA_DATA,\r\n SET_IMAGES_LIST,\r\n SET_REPORT_INFO,\r\n SET_START_DATE,\r\n SET_END_DATE,\r\n SET_PERIOD_TYPE,\r\n RESET_TIME,\r\n} = REPORTS_ACTIONS;\r\n\r\nconst initialState = {\r\n isLoading: true,\r\n imagesList: [],\r\n\r\n barChartData: [],\r\n readingsData: [],\r\n chartData: [],\r\n\r\n cameraData: {\r\n cameraId: '',\r\n cameraName: '',\r\n cameraLocation: '',\r\n },\r\n\r\n pageState: {\r\n // Usage Overview tab\r\n showFilter: true,\r\n showChart: true,\r\n showDetailCards: true,\r\n\r\n // Selected tab\r\n usageOverviewSelectedTab: true,\r\n readingsTabSelected: false,\r\n perAppliancesTabSelected: false,\r\n customReportsTabSelected: false,\r\n },\r\n activeTab: 0, // the number for the Mui component to know which tab to give the selected style (readings tab, usage overview tab).\r\n\r\n // selecting rows at readings table,\r\n isSelectModeEnabled: false, // the state boolean for being able to select a table row\r\n selectedRows: [], // the selected table rows in the readings page.\r\n\r\n reportInfo: {\r\n reportCount: 0,\r\n reportLabel: 'unitsLabel',\r\n reportMult: 1,\r\n },\r\n\r\n startDate: null,\r\n endDate: moment().format('YYYY-MM-DD'),\r\n\r\n currentPeriodType: 'month', // month,week, all buttons\r\n};\r\n\r\nexport default function reportsReducer(state = initialState, action) {\r\n const { type, payload } = action;\r\n\r\n switch (type) {\r\n case SET_IS_LOADING: {\r\n return {\r\n ...state,\r\n isLoading: payload,\r\n };\r\n }\r\n\r\n case CLEAR_ALL_SELECTED_ROWS: {\r\n return {\r\n ...state,\r\n selectedRows: [],\r\n };\r\n }\r\n\r\n case ROW_SELECTED: {\r\n let newSelectedRowsState;\r\n\r\n // useTable gives us the index of the table row.\r\n\r\n if (state.selectedRows.includes(payload.original.timestampSaved)) {\r\n // if the row is already selected and user clicks on it, that means user wants to remove/unselect the row\r\n newSelectedRowsState = [...state.selectedRows].filter(\r\n (timestampSaved) => timestampSaved !== payload.original.timestampSaved\r\n );\r\n } else {\r\n // push newly selected row\r\n newSelectedRowsState = [\r\n ...state.selectedRows,\r\n payload.original.timestampSaved,\r\n ];\r\n }\r\n\r\n return {\r\n ...state,\r\n selectedRows: newSelectedRowsState,\r\n };\r\n }\r\n\r\n // for displaying certain components.\r\n case SET_PAGE_STATE: {\r\n switch (payload) {\r\n case 'UsageOverview':\r\n return {\r\n ...state,\r\n activeTab: 0,\r\n pageState: {\r\n // set content\r\n showFilter: true,\r\n showChart: true,\r\n showDetailCards: true,\r\n // set tab appearance\r\n usageOverviewSelectedTab: true,\r\n readingsTabSelected: false,\r\n },\r\n };\r\n\r\n case 'Readings':\r\n const newSelectModeEnabledState =\r\n state.isSelectModeEnabled && payload !== 'Readings'\r\n ? false\r\n : state.isSelectModeEnabled; // disable select mode when moving to other page\r\n\r\n return {\r\n ...state,\r\n isSelectModeEnabled: newSelectModeEnabledState,\r\n activeTab: 1, // the number for the Mui component to know which tab to give the selected style.\r\n pageState: {\r\n showFilter: true,\r\n showChart: false,\r\n showDetailCards: false,\r\n // set tab appearance\r\n usageOverviewSelectedTab: false,\r\n readingsTabSelected: true,\r\n },\r\n };\r\n\r\n default:\r\n return state;\r\n }\r\n }\r\n\r\n case TOGGLE_SELECT_MODE_ENABLED: {\r\n return {\r\n ...state,\r\n isSelectModeEnabled: !state.isSelectModeEnabled,\r\n };\r\n }\r\n\r\n case SET_BAR_CHART_DATA: {\r\n return {\r\n ...state,\r\n barChartData: payload,\r\n };\r\n }\r\n\r\n case SET_READINGS_DATA: {\r\n return {\r\n ...state,\r\n readingsData: payload,\r\n };\r\n }\r\n\r\n case SET_CHART_DATA: {\r\n return {\r\n ...state,\r\n chartData: payload,\r\n };\r\n }\r\n\r\n case SET_CAMERA_DATA: {\r\n const { cameraId, cameraName, cameraLocation } = payload;\r\n\r\n return {\r\n ...state,\r\n cameraData: {\r\n cameraId,\r\n cameraName,\r\n cameraLocation,\r\n },\r\n };\r\n }\r\n case SELECT_ALL_ROWS: {\r\n // delete readings data of selected rows.\r\n return {\r\n ...state,\r\n selectedRows: [\r\n ...new Set(\r\n state.readingsData.map(({ timestampSaved }) => timestampSaved)\r\n ),\r\n ],\r\n };\r\n }\r\n\r\n case DELETE_SELECTED_ROWS: {\r\n // delete readings data of selected rows.\r\n return {\r\n ...state,\r\n readingsData: state.readingsData.filter(\r\n ({ timestampSaved }) => !state.selectedRows.includes(timestampSaved)\r\n ),\r\n\r\n selectedRows: [],\r\n };\r\n }\r\n\r\n case SET_IMAGES_LIST: {\r\n // remove all the elements from the list that don't have digits.\r\n // const hasDigitsList = payload.filter(({ digits }) => Boolean(digits));\r\n\r\n return {\r\n ...state,\r\n imagesList: payload,\r\n };\r\n }\r\n\r\n case SET_REPORT_INFO: {\r\n return {\r\n ...state,\r\n reportInfo: payload,\r\n };\r\n }\r\n\r\n case SET_START_DATE: {\r\n return {\r\n ...state,\r\n startDate: payload,\r\n };\r\n }\r\n\r\n case SET_END_DATE: {\r\n return {\r\n ...state,\r\n endDate: payload,\r\n };\r\n }\r\n\r\n case SET_PERIOD_TYPE: {\r\n return {\r\n ...state,\r\n currentPeriodType: payload,\r\n };\r\n }\r\n\r\n case RESET_TIME: {\r\n // reset the time filters to initial state when page loaded\r\n return {\r\n ...state,\r\n startDate: moment(state.chartData[1][0]).format('YYYY-MM-DD'),\r\n endDate: moment().format('YYYY-MM-DD'),\r\n currentPeriodType: 'month',\r\n };\r\n }\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n","module.exports = __webpack_public_path__ + \"static/media/computer_screen_frame.77baa30b.png\";","module.exports = __webpack_public_path__ + \"static/media/metervibe_app_desktop_1.764586aa.png\";","module.exports = __webpack_public_path__ + \"static/media/metervibe_app_desktop_2.95ee9b2a.png\";","module.exports = __webpack_public_path__ + \"static/media/metervibe_app_desktop_3.2edbd913.png\";","module.exports = __webpack_public_path__ + \"static/media/metervibe_device_transparent.03edf4bc.png\";","module.exports = __webpack_public_path__ + \"static/media/MeterVibe_logo_1444x596.0364e28b.png\";","module.exports = __webpack_public_path__ + \"static/media/waterfall.f847ba2e.jpeg\";","module.exports = __webpack_public_path__ + \"static/media/meter_1.8f112ebd.png\";","module.exports = __webpack_public_path__ + \"static/media/meter_2.e563fd76.png\";","module.exports = __webpack_public_path__ + \"static/media/meter_3.33ba45e1.png\";","module.exports = __webpack_public_path__ + \"static/media/meter_4.48857c6d.png\";","/* eslint-disable */\r\nif (process.env.NODE_ENV === 'production') {\r\n module.exports = require('./store.prod'); // store for prod, same as dev but without devtools and window.store\r\n} else {\r\n module.exports = require('./store.dev'); // same as prod but WITH devtools and window.store\r\n}\r\n","var map = {\n\t\"./amplify-amazon-button_5.entry.js\": [\n\t\t732,\n\t\t16\n\t],\n\t\"./amplify-auth-fields_9.entry.js\": [\n\t\t733,\n\t\t17\n\t],\n\t\"./amplify-authenticator.entry.js\": [\n\t\t734,\n\t\t5\n\t],\n\t\"./amplify-button_3.entry.js\": [\n\t\t735,\n\t\t18\n\t],\n\t\"./amplify-chatbot.entry.js\": [\n\t\t736,\n\t\t4\n\t],\n\t\"./amplify-checkbox.entry.js\": [\n\t\t737,\n\t\t19\n\t],\n\t\"./amplify-confirm-sign-in_7.entry.js\": [\n\t\t738,\n\t\t6\n\t],\n\t\"./amplify-container.entry.js\": [\n\t\t739,\n\t\t20\n\t],\n\t\"./amplify-federated-buttons_2.entry.js\": [\n\t\t740,\n\t\t21\n\t],\n\t\"./amplify-federated-sign-in.entry.js\": [\n\t\t741,\n\t\t22\n\t],\n\t\"./amplify-form-field_4.entry.js\": [\n\t\t742,\n\t\t23\n\t],\n\t\"./amplify-greetings.entry.js\": [\n\t\t743,\n\t\t24\n\t],\n\t\"./amplify-icon-button.entry.js\": [\n\t\t744,\n\t\t25\n\t],\n\t\"./amplify-icon.entry.js\": [\n\t\t745,\n\t\t7\n\t],\n\t\"./amplify-link.entry.js\": [\n\t\t746,\n\t\t26\n\t],\n\t\"./amplify-nav_2.entry.js\": [\n\t\t747,\n\t\t27\n\t],\n\t\"./amplify-photo-picker.entry.js\": [\n\t\t748,\n\t\t28\n\t],\n\t\"./amplify-picker.entry.js\": [\n\t\t749,\n\t\t29\n\t],\n\t\"./amplify-radio-button_2.entry.js\": [\n\t\t750,\n\t\t8\n\t],\n\t\"./amplify-s3-album.entry.js\": [\n\t\t751,\n\t\t9\n\t],\n\t\"./amplify-s3-image-picker.entry.js\": [\n\t\t752,\n\t\t10\n\t],\n\t\"./amplify-s3-image.entry.js\": [\n\t\t753,\n\t\t11\n\t],\n\t\"./amplify-s3-text-picker.entry.js\": [\n\t\t754,\n\t\t12\n\t],\n\t\"./amplify-s3-text.entry.js\": [\n\t\t755,\n\t\t13\n\t],\n\t\"./amplify-select-mfa-type.entry.js\": [\n\t\t756,\n\t\t30\n\t],\n\t\"./amplify-sign-in-button.entry.js\": [\n\t\t757,\n\t\t14\n\t],\n\t\"./amplify-toast.entry.js\": [\n\t\t758,\n\t\t31\n\t],\n\t\"./amplify-tooltip.entry.js\": [\n\t\t759,\n\t\t32\n\t]\n};\nfunction webpackAsyncContext(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\treturn Promise.resolve().then(function() {\n\t\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\t\te.code = 'MODULE_NOT_FOUND';\n\t\t\tthrow e;\n\t\t});\n\t}\n\n\tvar ids = map[req], id = ids[0];\n\treturn __webpack_require__.e(ids[1]).then(function() {\n\t\treturn __webpack_require__(id);\n\t});\n}\nwebpackAsyncContext.keys = function webpackAsyncContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackAsyncContext.id = 671;\nmodule.exports = webpackAsyncContext;","export default {\r\n s3: {\r\n REGION: \"us-east-1\",\r\n BUCKET: \"iotvid-images-dev\"\r\n },\r\n //adding a second api gateway with lambda's from iotvid-improc service\r\n // in apigateway -> APIs -> API:dev-iotvid-app -> Settings -> Derault Endpoint, \r\n // copy that default execute-api endpoint name and append /dev.\r\n apiGateway: {\r\n REGION: \"us-east-1\",\r\n URL: \"https://t2ydu8fzid.execute-api.us-east-1.amazonaws.com/dev\",\r\n // URL_IMPROC: \"https://r94pkske1e.execute-api.us-east-1.amazonaws.com/dev\"\r\n URL_ML: \"https://kwxghgs1yc.execute-api.us-east-1.amazonaws.com/dev\",\r\n },\r\n cognito: {\r\n REGION: \"us-east-1\",\r\n USER_POOL_ID: \"us-east-1_LlwfyXdYh\",\r\n APP_CLIENT_ID: \"1jlth39gv9h205vs3coluid435\",\r\n IDENTITY_POOL_ID: \"us-east-1:50d17485-815f-40ba-866c-c95fc994cdef\"\r\n }\r\n};\r\n","import React from 'react';\r\nimport Button from '@material-ui/core/Button';\r\nimport makeStyles from '@material-ui/core/styles/makeStyles';\r\n\r\nconst useStyles = makeStyles({\r\n root: {\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n },\r\n});\r\n\r\nconst MeterVibeButton = ({\r\n Icon,\r\n text,\r\n onClick,\r\n className,\r\n backgroundColor,\r\n textTransform,\r\n fontWeight,\r\n color,\r\n border,\r\n background,\r\n ...rest\r\n}) => {\r\n const classes = useStyles();\r\n\r\n return (\r\n \r\n {text}\r\n {Icon && (\r\n <>\r\n  \r\n \r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default MeterVibeButton;\r\n","import React from 'react';\r\nimport MuiDialogTitle from '@material-ui/core/DialogTitle';\r\nimport MuiDialogContent from '@material-ui/core/DialogContent';\r\nimport MuiDialogActions from '@material-ui/core/DialogActions';\r\nimport MuiDialog from '@material-ui/core/Dialog';\r\nimport MuiPaper from '@material-ui/core/Paper';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport Draggable from 'react-draggable';\r\nimport { withStyles } from '@material-ui/core/styles';\r\nimport CloseIcon from '@material-ui/icons/Close';\r\n\r\nexport const styles = (theme) => ({\r\n root: {\r\n margin: 0,\r\n padding: theme.spacing(2),\r\n backgroundColor: '#FAFAFA',\r\n },\r\n\r\n title: {\r\n fontWeight: 700,\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n textAlign: 'center',\r\n },\r\n\r\n closeButton: {\r\n position: 'absolute',\r\n right: theme.spacing(1),\r\n top: theme.spacing(1),\r\n color: theme.palette.grey[500],\r\n },\r\n});\r\n\r\nexport const DialogTitle = withStyles(styles)((props) => {\r\n const { children, classes, onClose, ...other } = props;\r\n return (\r\n \r\n \r\n {children}\r\n \r\n {onClose ? (\r\n \r\n \r\n \r\n ) : null}\r\n \r\n );\r\n});\r\n\r\nexport const DialogContent = withStyles((theme) => ({\r\n root: {\r\n padding: theme.spacing(2),\r\n },\r\n}))(MuiDialogContent);\r\n\r\nexport const DialogActions = withStyles((theme) => ({\r\n root: {\r\n margin: 0,\r\n padding: theme.spacing(1),\r\n },\r\n}))(MuiDialogActions);\r\n\r\nconst PaperComponent = (props) => {\r\n return (\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport const DraggableModal = ({ children, ...rest }) => {\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\n","import React from 'react';\r\nimport MeterVibeButton from '../../shared/buttons/MeterVibeButton';\r\nimport {\r\n DialogTitle,\r\n DialogContent,\r\n DialogActions,\r\n DraggableModal,\r\n} from '../../shared/modal/ModalComponents';\r\n\r\nfunction LeakageDetailsModal({ open, onClose, isLeaking }) {\r\n return (\r\n \r\n Leakage Details\r\n\r\n \r\n {isLeaking ? <>leakage Details : <>No flow detected}\r\n \r\n\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default React.memo(LeakageDetailsModal); // only re-render when props change\r\n","import React from 'react';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport Tooltip from '@material-ui/core/Tooltip';\r\nimport MeterVibeButton from '../../shared/buttons/MeterVibeButton';\r\nimport {\r\n DialogTitle,\r\n DialogContent,\r\n DialogActions,\r\n DraggableModal,\r\n} from '../../shared/modal/ModalComponents';\r\n\r\nfunction ImageDetailsModal({\r\n open,\r\n onClose,\r\n imageData,\r\n mostRecentReading,\r\n label,\r\n reading,\r\n title,\r\n}) {\r\n return (\r\n \r\n {title ?? 'Last Snapshot'}\r\n\r\n \r\n {mostRecentReading && mostRecentReading !== 'NaN' && (\r\n <>\r\n {/* don't show gallons if NaN */}\r\n \r\n Most Recent Reading: {mostRecentReading} {label}\r\n \r\n
\r\n \r\n )}\r\n\r\n {reading && reading !== 'NaN' && (\r\n \r\n Reading: {reading} {label}\r\n \r\n )}\r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n
\r\n );\r\n}\r\n\r\nexport default React.memo(ImageDetailsModal);\r\n","import React from 'react';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport MeterVibeButton from '../../shared/buttons/MeterVibeButton';\r\nimport {\r\n DialogTitle,\r\n DialogContent,\r\n DialogActions,\r\n DraggableModal,\r\n} from '../../shared/modal/ModalComponents';\r\nimport moment from 'moment';\r\nimport 'moment-timezone';\r\nimport {\r\n makeStyles,\r\n Table,\r\n TableCell,\r\n TableHead,\r\n TableRow,\r\n TableBody,\r\n} from '@material-ui/core';\r\n\r\nconst useStyles = makeStyles({\r\n subheading: {\r\n fontSize: '14px',\r\n fontWeight: 700,\r\n color: '#7A7A7A',\r\n },\r\n\r\n imageSectionRoot: {\r\n overflow: 'visible',\r\n padding: '20px',\r\n },\r\n\r\n breakdownSectionRoot: {\r\n overflow: 'visible',\r\n padding: '20px',\r\n },\r\n\r\n altText: {\r\n color: '#363636',\r\n fontSize: '14px',\r\n fontWeight: 400,\r\n fontFamily: ['Public Sans', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n\r\n snapshotImg: {\r\n width: '100%',\r\n },\r\n\r\n digitsText: {\r\n fontSize: '16px',\r\n color: '#363636',\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n fontWeight: 700,\r\n marginTop: '10px',\r\n },\r\n\r\n breakdownTableHead: {\r\n '& > th': {\r\n fontWeight: 700,\r\n color: '#242424',\r\n padding: '5px 10px',\r\n },\r\n },\r\n\r\n breakdownTableRow: {\r\n ' & > td': {\r\n color: '#363636',\r\n padding: '15px 10px',\r\n },\r\n },\r\n\r\n buttonsContainer: {\r\n padding: '20px',\r\n display: 'flex',\r\n justifyContent: 'flex-start',\r\n },\r\n});\r\n\r\nfunction MeterReadingsModal({\r\n open,\r\n onClose,\r\n deviceDetails,\r\n imageData,\r\n previousImageData,\r\n meterReadingsMultiplied,\r\n label,\r\n unitCostUSD,\r\n}) {\r\n const {\r\n current: currentDigits,\r\n previous: previousDigits,\r\n difference: differenceDigits,\r\n } = meterReadingsMultiplied;\r\n //console.log(\"meterReadingsMultiplied\", meterReadingsMultiplied);\r\n\r\n const classes = useStyles();\r\n\r\n const mostRecentTime = moment(imageData?.timestampSaved);\r\n const prevTime = moment(previousImageData?.timestampSaved);\r\n\r\n /* By default, moment#diff will truncate the result to zero decimal places, returning an integer.\r\n If you want a floating point number, pass true as the third argument */\r\n // 2 decimal places with toFixed(2)\r\n const hoursDiff = mostRecentTime.diff(prevTime, 'hours', true).toFixed(2);\r\n\r\n // rate = GallonsDiff / hoursDiff = (Gallons / hour)\r\n const digitsDiff = differenceDigits.number;\r\n const rateNumber = Number(digitsDiff / hoursDiff).toLocaleString();\r\n const rateText = `${rateNumber} ${label} / hour`;\r\n\r\n const { cameraLocation, cameraId } = deviceDetails;\r\n\r\n return (\r\n \r\n \r\n Meter Readings (More Detail)\r\n
\r\n \r\n Device code: {cameraId}, {cameraLocation}\r\n \r\n
\r\n\r\n \r\n {previousDigits?.formatted !== 'NaN' && (\r\n \r\n )}\r\n\r\n {currentDigits?.formatted !== 'NaN' && (\r\n \r\n )}\r\n\r\n {differenceDigits?.formatted !== 'NaN' && (\r\n \r\n )}\r\n\r\n {previousDigits?.formatted === 'NaN' &&\r\n currentDigits?.formatted === 'NaN' && (\r\n No Readings\r\n )}\r\n \r\n\r\n \r\n \r\n \r\n
\r\n );\r\n}\r\n\r\nexport default React.memo(MeterReadingsModal);\r\n\r\n// a section with the image, timestamp and the digits\r\nconst ImageSection = ({ imageSource, timeStampSaved, digits, category }) => {\r\n const classes = useStyles();\r\n\r\n return (\r\n \r\n {/* recent snapshot: 10-20-2021 */}\r\n \r\n \r\n {category} snapshot:{' '}\r\n {moment(timeStampSaved).format('hh:mmA MM/DD/yyyy')}\r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n {digits}\r\n \r\n \r\n \r\n );\r\n};\r\n\r\n// the section at the bottom with the gallons and hours difference, and rate\r\nconst BreakdownSection = ({\r\n label,\r\n hoursDiff,\r\n rateText,\r\n digits,\r\n unitCostUSD,\r\n}) => {\r\n const classes = useStyles();\r\n\r\n /* That is on Modal : Prior Reading : 12:05 am 10/7/2021 286,065.45 \r\n Gallons Recent Readings: 10:31 am 10/7/2021 286,165.45 Gallons\r\n Used: Gallons: 100 Time:10.43 minutes Rate: 9.6 Gallons / minute\r\n */\r\n\r\n /* \r\n Used: {label}: {digits}, Time: {hoursDiff} hours, Rate: {rateText}\r\n */\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {['Used', 'Time', 'Rate'].map((cellText, key) => (\r\n {cellText}\r\n ))}\r\n \r\n \r\n\r\n \r\n \r\n {[\r\n `${digits} ${label} (${unitCostUSD})`,\r\n `${hoursDiff} hours`,\r\n rateText,\r\n ].map((cellText, key) => (\r\n {cellText}\r\n ))}\r\n \r\n \r\n
\r\n \r\n );\r\n};\r\n","import React from 'react';\r\nimport MeterVibeButton from './MeterVibeButton';\r\n\r\nexport default function MeterVibeButtonSecondary({\r\n onClick,\r\n text,\r\n textTransform = 'none',\r\n fontWeight = 700,\r\n ...rest\r\n}) {\r\n return (\r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport MeterVibeButton from './MeterVibeButton';\r\n\r\nexport default function MeterVibeButtonPrimary({\r\n text,\r\n textTransform = 'none',\r\n onClick,\r\n fontWeight = 700,\r\n ...rest\r\n}) {\r\n return (\r\n \r\n );\r\n}\r\n","import React, { useState, useMemo } from 'react';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport {\r\n DialogTitle,\r\n DialogContent,\r\n DialogActions,\r\n DraggableModal,\r\n} from '../../shared/modal/ModalComponents';\r\n\r\nimport pluralize from 'pluralize'; // for units label: convert 'gallons' to 'gallon'\r\nimport MeterVibeButtonSecondary from '../../shared/buttons/MeterVibeButtonSecondary';\r\nimport MeterVibeButtonPrimary from '../../shared/buttons/MeterVibeButtonPrimary';\r\n\r\n// right now only contains the input to change costPerUnit\r\nexport default function EditCameraModal({ open, onClose, cameraData, onSave }) {\r\n const { costPerUnit, reportLabel: unitsLabel } = cameraData;\r\n\r\n const [formData, setFormData] = useState({\r\n costPerUnit,\r\n });\r\n\r\n const costPerUnitUSD = useMemo(() => {\r\n return `$${Number(formData.costPerUnit).toFixed(3)}`;\r\n }, [formData.costPerUnit]);\r\n\r\n const handleChange = (e) => {\r\n const { name, value } = e.target;\r\n setFormData((prevState) => ({\r\n ...prevState,\r\n [name]: Number(value),\r\n }));\r\n };\r\n\r\n const labelSingular = pluralize(unitsLabel, 1); // singularize with pluralize(text, 1)\r\n\r\n return (\r\n \r\n {'Edit Camera'}\r\n\r\n \r\n <>\r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n onSave(formData.costPerUnit)}\r\n text=\"Save\"\r\n />\r\n \r\n \r\n );\r\n}\r\n","/* this is for when we get units label from api\r\n they come as \"CUBIC FEET\", should be \"Cubic Feet\"\r\n and \"gallons\" should be \"Gallons\" */\r\n\r\n/**\r\n * @method toTitleCase\r\n * @param {string} string\r\n * @returns {String} title-cased string\r\n */\r\nexport const toTitleCase = (string) =>\r\n string\r\n .toLowerCase()\r\n .split(' ')\r\n .map((word) => word.charAt(0).toUpperCase() + word.substring(1))\r\n .join(' ');\r\n","import { API } from 'aws-amplify';\r\n\r\n/**\r\n * @method getAllImagesListAPI\r\n * list all images of camera by providing a cameraId (cameraId needed)\r\n * @param {String} cameraId the cameraId to be passed\r\n * @returns {Promise} the images list array after resolved.\r\n */\r\nexport const getAllImagesListAPI = async (cameraId) => {\r\n try {\r\n const imagesData = await API.get(\r\n 'dev-iotvid-app',\r\n `/images/${cameraId}/list-all`\r\n );\r\n return imagesData;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method getAllImagesListProc\r\n * get all processed images for one camera (cameraId needed)\r\n * @param {String} cameraId the cameraId to be passed\r\n * @returns {Promise} the processed images array after resolved. List of all\r\n * parameters for each dynamoDb entry for each snap augmented with signedURL for processed images. \r\n * returns a list of image attributes, cameraId, digits, s3Path (original, unrotated), timestampsaved,\r\n * and SignedUrl of rotated concatenated image in /proc/{cameraId}/elts/{timestamp}.jpg\r\n * Currently returning the most recent 900 entries\r\n */\r\nexport const getAllImagesListProc = async (cameraId) => {\r\n try {\r\n let imagesData = await API.get(\r\n 'dev-iotvid-app',\r\n `/images/${cameraId}/list-all-proc`\r\n );\r\n //console.log(\"getAllImagesListProc returns:\", imagesData)\r\n return imagesData;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method getMostRecentImgAPI\r\n * API call for most recent images\r\n * @param {String} cameraId the cameraId to be passed\r\n * @returns {Promise} the most recent images array after resolved.\r\n */\r\nexport const getMostRecentImgAPI = async (cameraId) => {\r\n try {\r\n const mostRecentData = await API.get(\r\n 'dev-iotvid-app',\r\n `/images/${cameraId}/most-recent`\r\n );\r\n return mostRecentData;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method getOneImageByTimestamp\r\n * API call for getting a specific image at userSelectedTimestamp\r\n * @param {String} cameraId the cameraId to be passed\r\n * @param {Date} timestampSaved the timeStampsaved to help find the specific image. (in unix)\r\n * @returns {Promise} the one image source string after promise has resolved.\r\n */\r\nexport const getOneImageByTimestamp = async (cameraId, timestampSaved) => {\r\n try {\r\n const oneImage = await API.get(\r\n 'dev-iotvid-app',\r\n `/images/${cameraId}/${timestampSaved}`\r\n );\r\n return oneImage;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method getOneImageByTimestamp\r\n * save the user entered digits off in DynamoDb\r\n * @param {Number} digits the digits value to be passed\r\n * @param {String} cameraId the cameraId to be passed\r\n * @param {Date} timestamp the timestamp in unix (to send to the right path)\r\n * @returns {Promise<{status: boolean}>} the status if went successfully (true or false)\r\n */\r\nexport const putDigits = async (digits, cameraId, timestamp) => {\r\n try {\r\n let apiName = 'dev-iotvid-app';\r\n let path = `/images/digits/${cameraId}/${timestamp}`; //call update-digits in iotvid-app\r\n\r\n let init = {\r\n body: { digits: digits },\r\n };\r\n console.log('init', init);\r\n\r\n const response = await API.put(apiName, path, init);\r\n return response;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n","import { API } from 'aws-amplify';\r\n\r\n/**\r\n * @method getReportOnlyParams\r\n * get report params for one camera (cameraId needed)\r\n * @param {String} cameraId the cameraId to be passed\r\n * @returns {Promise<{multiplier: number, units: string, costPerUnit: number}>} \r\n * { multiplier: 0.001, units: 'CUBIC FEET', costPerUnit: 0.00748 }\r\n * the reportParams object after promised resolved.\r\n */\r\n export const getReportOnlyParams = async (cameraId) => {\r\n try {\r\n let reportOnlyParams = await API.get(\r\n 'dev-iotvid-app',\r\n `/report-only-params/${cameraId}`\r\n );\r\n //console.log(\"getReportOnlyParams:\", reportOnlyParams);\r\n return reportOnlyParams;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n\r\n\r\n/**\r\n * @method getReportParams\r\n * deprecated : get all params for one camera (cameraId needed)\r\n * @param {String} cameraId the cameraId to be passed\r\n * @returns {Promise<{{eltList: [ [Array], [Array], [Array] ], cameraNotes: 'M5 ...', cameraSetup: \r\n * {...,flash2: true,...},cameraLocation: 'Fr...',multiplier: 0.001,...}>} \r\n * the full tree of parameters object after promised resolved.\r\n */\r\n/* export const getReportParams = async (cameraId) => {\r\n try {\r\n let reportsParams = await API.get(\r\n 'dev-iotvid-app',\r\n `/reports/${cameraId}/params`\r\n );\r\n return reportsParams;\r\n } catch (error) {\r\n throw error;\r\n }\r\n}; */\r\n","import { API } from 'aws-amplify';\r\n\r\n/**\r\n * @method apiCameras\r\n * Calls list-owned-cameras-v2 AP\r\n * @returns {Promise} array of cameras to be returned after promise resolved.\r\n */\r\nexport const apiCameras = async () => {\r\n try {\r\n const camerasData = await API.get(\r\n 'dev-iotvid-app',\r\n '/cameras/list/owner-v2'\r\n );\r\n return camerasData;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method getCameraVersion\r\n * get camera version for one camera by id\r\n * @param {String} cameraId the cameraId to be passed\r\n * @returns {Promise} the ocrVersion number to be returned after promise resolved.\r\n */\r\nexport const getCameraVersion = async (cameraId) => {\r\n try {\r\n const cameraVersion = await API.get(\r\n 'dev-iotvid-app',\r\n `/camera/version/${cameraId}/`\r\n );\r\n\r\n return cameraVersion;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method reassignCamera\r\n * function reassigns a camera to a different user (as opposed to registering a user for the first time)\r\n * @param {String} cameraToReassign the camera to be reassign (technically is cameraId)\r\n * @returns {Promise} the success message, for example: `${cameraToReassign} reassigned successfully!`\r\n */\r\nexport const reassignCamera = async (cameraToReassign) => {\r\n try {\r\n const reassignResult = await API.post(\r\n 'dev-iotvid-app',\r\n `/post/reassign/${cameraToReassign}`\r\n );\r\n\r\n return reassignResult;\r\n } catch (error) {\r\n console.log('Error reassigning camera:', error);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method activateCamera\r\n * this calls handlers/update-camera-activate.main\r\n * @param {String} aCode the user entered activation code.\r\n * @returns {Promise} can be a status message like: `${userSubmittedActivationCode} could not be found.` or an object like: { camera: cameraToActivate, body: \"reassign\"}\r\n */\r\nexport const activateCamera = async (aCode) => {\r\n try {\r\n const response = await API.post(\r\n 'dev-iotvid-app',\r\n `/post/activate/${aCode}`\r\n ); //, params);\r\n\r\n return response;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method getCameraParms\r\n * @param {String} cameraId the cameraId to be passed\r\n * @returns {Promise}\r\n */\r\nexport const getCameraParams = async (cameraId) => {\r\n try {\r\n let cameraParams = await API.get(\r\n 'dev-iotvid-app',\r\n `/camera/params/${cameraId}`\r\n );\r\n return cameraParams;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method updateCameraCostPerUnit\r\n * update the costPerUnit of a device\r\n * @param {String} cameraId the cameraId to be passed (required)\r\n * @param {Number} userInput the new costPerUnit to be sent to the back-end.\r\n * @returns {Promise} the updated cost per unit.\r\n */\r\nexport const updateCameraCostPerUnit = async (cameraId, userInput) => {\r\n try {\r\n const appName = 'dev-iotvid-app';\r\n const path = `/camera/costPerUnit/${cameraId}`;\r\n const eventData = {\r\n body: { costPerUnit: userInput },\r\n };\r\n\r\n const response = await API.put(appName, path, eventData);\r\n\r\n const updatedCostPerUnit = response.costPerUnit;\r\n\r\n return updatedCostPerUnit;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method deleteTimestamp\r\n * update the costPerUnit of a device\r\n * @param {String} cameraId the cameraId to be passed (required)\r\n * @param {Date} timestampSaved the date of timestampSaved (unix format)\r\n * @returns {Promise{status: boolean}}\r\n */\r\nexport const deleteTimestamp = (cameraId, timestampSaved) => {\r\n let apiName = 'dev-iotvid-app';\r\n let path = `/images/${cameraId}/${timestampSaved}`; //call delete in iotvid-app\r\n console.log('deleteTimestamp: apiName, path', apiName, path);\r\n return API.del(apiName, path);\r\n};\r\n\r\n/**\r\n * @method updateCameraFlash\r\n * update the costPerUnit of a device\r\n * @param {String} cameraId the cameraId to be passed (required)\r\n * @param {<{flash1: integer, flash2: integer, flash3: integer}>} body the integers for flash1(L),flash2(R),flash3 (M) to put in dynamoDb, 0(off)..100(full bright)\r\n * @returns {Promise{status: boolean}}\r\n */\r\nexport const updateCameraFlash = async (cameraId, body) => {\r\n try {\r\n if (body.flash1 === undefined || body.flash2 === undefined || body.flash3 === undefined) {\r\n throw new Error(\r\n 'flash1, flash2, or flash3 not provided in updateCameraFlash (cameras.services.js)'\r\n );\r\n }\r\n\r\n let apiName = 'dev-iotvid-app';\r\n let path = `/put/flash/${cameraId}`; \r\n\r\n const eventData = {\r\n body: { flash1: body.flash1, flash2: body.flash2, flash3: body.flash3 },\r\n };\r\n\r\n return API.put(apiName, path, eventData);\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n","// this holds information about each camera from list-owned-cameras-v2\r\n// the date of the lastSaved image is not showing properly here.\r\n// I think that's because the lastSaved timestamp in the list-owned-cameras-v2 object\r\n// and the timestamps in the list-all API do not match. The ImagesDropdown component renders\r\n// the proper dates. Seems like the lastSaved property is not being updated in the db on each snap.\r\n// I will leave that line of code in so you can see it on the page. - JZ\r\n\r\n// React doesn't like something to do with the new camera card map (check console)\r\n\r\nimport React, { useState, useEffect, useCallback } from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport { red } from '@material-ui/core/colors';\r\nimport MeterVibeButton from './shared/buttons/MeterVibeButton';\r\nimport Moment from 'react-moment';\r\nimport {\r\n Box,\r\n useTheme,\r\n useMediaQuery,\r\n Card,\r\n CardHeader,\r\n CardContent,\r\n CardActions,\r\n Grid,\r\n Typography,\r\n Tooltip,\r\n LinearProgress,\r\n IconButton,\r\n} from '@material-ui/core';\r\n\r\nimport LeakageDetailsModal from './modals/camera_modals/LeakageDetailsModal';\r\nimport ImageDetailsModal from './modals/camera_modals/ImageDetailsModal';\r\nimport MeterReadingsModal from './modals/camera_modals/MeterReadingsModal';\r\nimport EditCameraModal from './modals/camera_modals/EditCameraModal';\r\n\r\n// utils\r\nimport moment from 'moment';\r\nimport 'moment-timezone';\r\nimport { toTitleCase } from '../utils/toTitleCase';\r\n\r\n// icons\r\nimport WaterDropIcon from '@material-ui/icons/InvertColors';\r\nimport WaterIcon from '@material-ui/icons/Opacity';\r\nimport EyeIcon from '@material-ui/icons/VisibilityRounded';\r\nimport ThumbsUpIcon from '@material-ui/icons/ThumbUpRounded';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\n\r\n// services\r\nimport { getAllImagesListProc } from './../services/images.services';\r\nimport { getReportOnlyParams } from '../services/reports.services';\r\nimport { updateCameraCostPerUnit, getCameraParams } from '../services/cameras.services';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n marginBottom: 6,\r\n },\r\n media: {\r\n height: 0,\r\n paddingTop: '56.25%', // 16:9\r\n },\r\n expand: {\r\n transform: 'rotate(0deg)',\r\n marginLeft: 'auto',\r\n transition: theme.transitions.create('transform', {\r\n duration: theme.transitions.duration.shortest,\r\n }),\r\n },\r\n expandOpen: {\r\n transform: 'rotate(180deg)',\r\n },\r\n avatar: {\r\n backgroundColor: red[500],\r\n },\r\n cardHeaderRoot: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'flex-start',\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n cardHeaderLeft: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n flexDirection: 'row',\r\n justifyContent: 'space-between',\r\n },\r\n cardHeaderTitle: {\r\n fontWeight: 700,\r\n color: '#01070F',\r\n textAlign: 'left',\r\n fontSize: '18px',\r\n lineHeight: '30px',\r\n },\r\n cardHeaderSubHeader: {\r\n fontWeight: 700,\r\n color: '#7A7A7A',\r\n fontSize: '14px',\r\n textAlign: 'left',\r\n },\r\n cardFooter: {\r\n borderTop: '1px solid #DBDBDB',\r\n backgroundColor: '#FAFAFA',\r\n padding: '20px',\r\n },\r\n actionsButton: {\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n },\r\n cardMiddleContainer: {\r\n padding: '20px',\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n },\r\n imageListContainer: {\r\n maxWidth: '200px',\r\n },\r\n separator: {\r\n width: 25,\r\n padding: '10px',\r\n height: '100px',\r\n background: '#999',\r\n },\r\n deviceInfo: {\r\n borderLeft: '1px solid #DBDBDB',\r\n },\r\n statusHeaderRoot: {\r\n width: '100%',\r\n borderBottom: '1px solid #DBDBDB',\r\n textAlign: 'left',\r\n padding: '0 0 0 16px',\r\n\r\n [theme.breakpoints.down('sm')]: {\r\n borderTop: '1px solid #DBDBDB',\r\n paddingTop: '10px',\r\n paddingBottom: '10px',\r\n },\r\n },\r\n deviceStatusHeader: {\r\n fontWeight: 700,\r\n color: '#01070F',\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n fontSize: '12px',\r\n },\r\n boldBlueText: {\r\n color: '#0272BC',\r\n fontSize: '12px',\r\n fontWeight: 700,\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n lastSavedDate: {\r\n background: '#E8F5E9',\r\n color: '#2E7D32',\r\n padding: '5px',\r\n border: '1px solid #A5D6A7',\r\n fontWeight: 700,\r\n fontSize: '12px',\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n iconCategoryText: {\r\n color: '#7A7A7A',\r\n fontSize: '12px',\r\n fontWeight: 700,\r\n textAlign: 'left',\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n iconStatusText: {\r\n color: '#363636',\r\n fontSize: '14px',\r\n fontWeight: 700,\r\n textAlign: 'left',\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n iconGroup: {\r\n display: 'flex',\r\n flexDirection: 'row',\r\n alignItems: 'center',\r\n },\r\n iconCircle: {\r\n background: '#F5F5F5',\r\n borderRadius: '50%',\r\n border: '1px solid #F5F5F5',\r\n width: '50px',\r\n height: '50px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n marginRight: '5px',\r\n },\r\n iconTextContainer: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'flex-start',\r\n },\r\n}));\r\n\r\nconst IconCircle = ({ icon: Icon }) => {\r\n const classes = useStyles();\r\n\r\n return (\r\n
\r\n \r\n
\r\n );\r\n};\r\n\r\nconst IconGroup = ({ icon, categoryText, statusText }) => {\r\n const classes = useStyles();\r\n\r\n return (\r\n
\r\n \r\n\r\n {categoryText && statusText && (\r\n
\r\n \r\n \r\n {categoryText}\r\n \r\n \r\n {statusText}\r\n \r\n \r\n
\r\n )}\r\n
\r\n );\r\n};\r\n\r\n//also include if at midnight\r\nconst checkIsAfterMidnight = (date) => {\r\n const time = moment(date, 'h:mm A');\r\n const midnight = moment('12:00am', 'h:mm A');\r\n\r\n const isAfterMidnight = time.isSameOrAfter(midnight);\r\n\r\n //console.log(\"is after midnight?\", date, isAfterMidnight);\r\n return true; //isAfterMidnight; // returns true or false\r\n};\r\n\r\n// function to convert 13 digit epoch into local time string of:\r\n// hh:mm:ss am/pm mm/dd/yyyy ex: 8:00:05 AM 10/12/2022\r\nconst epochToLocalTimeDateString = (epoch13digit) => {\r\n const d= new Date(parseInt(epoch13digit)); //data from dynamoDb is string\r\n //console.log(\"input typeof, and new Date:\", (typeof epoch13digit), d);\r\n const formattedEpoch = d.toLocaleTimeString() + \" \" + d.toLocaleDateString();\r\n //console.log(\"epochToLocalTimeDateString>> epoch13digit:, formattedEpoch:\", epoch13digit, formattedEpoch);\r\n return formattedEpoch;\r\n};\r\n\r\nconst calculateMeterReadingMultiplied = (digits, reportMult) => {\r\n // take digits and calculate to meter reading\r\n // from how it's calculated in readings table\r\n\r\n const result = (Number(digits) * Number(reportMult)).toFixed(\r\n Math.max(0, -Math.log10(reportMult))\r\n ); //set number of decimal places\r\n\r\n return Number(result);\r\n};\r\n\r\nconst getPreviousImageData = (currentReading, data) => {\r\n const currentReadingTimestamp = moment(currentReading?.timestampSaved);\r\n\r\n const previousReadings = data.filter((el) => {\r\n const isAfterMidnight = checkIsAfterMidnight(el?.timestampSaved);\r\n // check if difference in hours is greater than 1 hour ago from the current reading,\r\n // check if the time is after midnight\r\n return (\r\n currentReadingTimestamp.diff(el?.timestampSaved, 'hours') > 1 &&\r\n isAfterMidnight\r\n );\r\n });\r\n\r\n const previousReading = previousReadings[0]; // array already sorted by time, so 0 index is the most recent previous\r\n\r\n // console.log(\r\n // 'curr:',\r\n // currentReading.timestampSaved,\r\n // currentReading.cameraId,\r\n // 'prev:',\r\n // previousReading.timestampSaved,\r\n // previousReading.cameraId\r\n // );\r\n\r\n return previousReading;\r\n};\r\n\r\nconst CameraCard = ({ camera, onViewDetails, onViewReports }) => {\r\n const id = camera.cameraId;\r\n const location = camera.cameraLocation;\r\n\r\n const classes = useStyles();\r\n const [cameraData, setCameraData] = useState({}); //also retreive the properties of this camera\r\n const [imageData, setImageData] = useState({}); // one concatenated image\r\n const [previousImageData, setPreviousImageData] = useState({}); //\r\n const [reportInfo, setReportInfo] = useState({\r\n reportLabel: 'Gallons',\r\n reportMult: 0.01,\r\n }); // reportMult goes here\r\n\r\n const [unitsData, setUnitsData] = useState({\r\n costPerUnit: 0.01,\r\n unitCostUSD: '$0.01',\r\n });\r\n\r\n const [meterReadingsMultiplied, setMeterReadingsMultiplied] = useState({\r\n current: 0,\r\n previous: 0,\r\n difference: 0,\r\n });\r\n\r\n const isLeaking = false; // update to useState once we have something on back-end to tell us\r\n // const [isLeaking, setIsLeaking] = useState(false); // will return true if leakage, else not, need data from back-end.\r\n const [isLeakageModalOpen, setIsLeakageModalOpen] = useState(false);\r\n const [isImageModalOpen, setIsImageModalOpen] = useState(false);\r\n const [isReadingsModalOpen, setIsReadingsModalOpen] = useState(false);\r\n const [isEditModalOpen, setIsEditModalOpen] = useState(false);\r\n\r\n const [isCameraDataLoaded, setCameraIsDataLoaded] = useState(false);\r\n const [isDataLoaded, setIsDataLoaded] = useState(false);\r\n const theme = useTheme();\r\n const matchesSm = useMediaQuery(theme.breakpoints.down('sm'));\r\n\r\n useEffect(() => {\r\n const getImageData = async () => {\r\n const responseData = await getAllImagesListProc(id);\r\n\r\n let currentReading = responseData.filter((el) => {\r\n return checkIsAfterMidnight(el?.timestampSaved);\r\n })[0];\r\n\r\n const previousReading = getPreviousImageData(\r\n currentReading,\r\n responseData\r\n );\r\n\r\n setImageData({\r\n cameraId: currentReading?.cameraId,\r\n timestampSaved: currentReading?.timestampSaved,\r\n lastSnapShot: currentReading?.SignedUrl,\r\n digits: currentReading?.digits,\r\n }); // get only first 5 images of deice\r\n\r\n setPreviousImageData({\r\n cameraId: previousReading?.cameraId,\r\n timestampSaved: previousReading?.timestampSaved,\r\n lastSnapShot: previousReading?.SignedUrl,\r\n digits: previousReading?.digits,\r\n });\r\n\r\n setIsDataLoaded(true);\r\n };\r\n\r\n const getReportInfo = async () => {\r\n const params = await getReportOnlyParams(id);\r\n\r\n const label = params?.units ?? 'Gallons(default)'; // doesn't exist in A101.\r\n const mult = params?.multiplier ?? 0.01; // doesn't exist in A101.\r\n\r\n setReportInfo({\r\n reportLabel: toTitleCase(label),\r\n reportMult: mult,\r\n });\r\n\r\n const { costPerUnit = 1 } = params;\r\n\r\n setUnitsData({\r\n costPerUnit,\r\n unitCostUSD: `$${costPerUnit.toFixed(3)}`,\r\n });\r\n };\r\n\r\n const getCameraData = async () => {\r\n const cameraData = await getCameraParams(id);\r\n\r\n setCameraData({ //get the properties for this camera from dynamoDB\r\n cameraId: cameraData?.cameraId,\r\n active: cameraData?.active,\r\n cameraLocation: cameraData?.cameraLocation,\r\n cameraName: cameraData?.cameraName,\r\n cameraNotes: cameraData?.cameraNotes,\r\n multiplier: cameraData?.multiplier,\r\n rotation: cameraData?.rot4,\r\n lastSavedTimestamp: cameraData?.lastSavedTimestamp,\r\n units: cameraData?.units,\r\n }); \r\n setCameraIsDataLoaded(true);\r\n }\r\n\r\n getImageData();\r\n getReportInfo();\r\n getCameraData();\r\n console.log()\r\n }, [id]); //react update when id (camera) changes\r\n\r\n useEffect(() => {\r\n let currentDigits = Number(imageData?.digits) ?? NaN;\r\n let previousDigits = Number(previousImageData?.digits) ?? NaN;\r\n // let initialDigitsDifference = currentDigits - previousDigits;\r\n\r\n const currentDigitsMultiplied = calculateMeterReadingMultiplied(\r\n currentDigits,\r\n reportInfo.reportMult\r\n );\r\n\r\n const previousDigitsMultiplied = calculateMeterReadingMultiplied(\r\n previousDigits,\r\n reportInfo.reportMult\r\n );\r\n\r\n // const differenceDigitsMultiplied = calculateMeterReadingMultiplied(\r\n // initialDigitsDifference,\r\n // reportInfo.reportMult\r\n // );\r\n\r\n const digitsDifference = Number(\r\n currentDigitsMultiplied - previousDigitsMultiplied\r\n );\r\n\r\n setMeterReadingsMultiplied({\r\n current: {\r\n number: currentDigitsMultiplied, // number without commas\r\n formatted: currentDigitsMultiplied.toLocaleString(), // number with commas\r\n },\r\n previous: {\r\n number: previousDigitsMultiplied,\r\n formatted: previousDigitsMultiplied.toLocaleString(),\r\n },\r\n difference: {\r\n number: digitsDifference,\r\n formatted: digitsDifference.toLocaleString(),\r\n },\r\n });\r\n // set meterReading when reportInfo.reportMult and imageData.digits changes (should be after api call)\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [reportInfo.reportMult, imageData?.digits, previousImageData?.digits]);\r\n\r\n // id = props.id\r\n\r\n const showLeakageModal = useCallback(\r\n () => setIsLeakageModalOpen(id),\r\n [setIsLeakageModalOpen, id]\r\n );\r\n const closeLeakageModal = useCallback(\r\n () => setIsLeakageModalOpen(false),\r\n [setIsLeakageModalOpen]\r\n );\r\n\r\n const showImageModal = useCallback(\r\n () => setIsImageModalOpen(id),\r\n [setIsImageModalOpen, id]\r\n );\r\n const closeImageModal = useCallback(\r\n () => setIsImageModalOpen(false),\r\n [setIsImageModalOpen]\r\n );\r\n\r\n const showReadingsModal = useCallback(\r\n () => setIsReadingsModalOpen(id),\r\n [id, setIsReadingsModalOpen]\r\n );\r\n const closeReadingsModal = useCallback(\r\n () => setIsReadingsModalOpen(false),\r\n [setIsReadingsModalOpen]\r\n );\r\n\r\n const showEditModal = useCallback(\r\n () => setIsEditModalOpen(id),\r\n [id, setIsEditModalOpen]\r\n );\r\n const closeEditModal = useCallback(\r\n () => setIsEditModalOpen(false),\r\n [setIsEditModalOpen]\r\n );\r\n\r\n const onSave = useCallback(\r\n async (userInput) => {\r\n const updatedCostPerUnit = await updateCameraCostPerUnit(id, userInput);\r\n\r\n setUnitsData((prevState) => ({\r\n ...prevState,\r\n costPerUnit: updatedCostPerUnit,\r\n unitCostUSD: `$${updatedCostPerUnit.toFixed(3)}`,\r\n }));\r\n\r\n setIsEditModalOpen(false);\r\n },\r\n [id]\r\n );\r\n\r\n //if last timestamp valid : subheader={dayjs(lastSaved).format(\"dddd, MMM DD, YYYY, hh:mm:ss A\")}\r\n return (\r\n <>\r\n \r\n \r\n {/* CARD LEFT */}\r\n \r\n \r\n
\r\n \r\n\r\n
\r\n {isDataLoaded && isCameraDataLoaded && (\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n
\r\n
\r\n\r\n {(isDataLoaded && isCameraDataLoaded) ? (\r\n \r\n \r\n \r\n \r\n \r\n \r\n {/*\r\n */}\r\n\r\n \r\n \r\n \r\n \r\n \r\n\r\n {/* eye icon with images list */}\r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n ) : (\r\n <>\r\n \r\n \r\n )}\r\n \r\n \r\n\r\n {/* CARD RIGHT */}\r\n \r\n \r\n\r\n \r\n \r\n \r\n  Latest picture at:\r\n \r\n\r\n \r\n \r\n {epochToLocalTimeDateString (cameraData?.lastSavedTimestamp)}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n
\r\n\r\n {isDataLoaded && isCameraDataLoaded && (\r\n <>\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default CameraCard;\r\n","// Renders on Dashboard when user has no cameras registered\r\n\r\nimport React from \"react\";\r\nimport Card from \"@material-ui/core/Card\";\r\nimport Typography from \"@material-ui/core/Typography\";\r\nimport Link from \"@material-ui/core/Button\";\r\n\r\nconst NoCameras = () => {\r\n return (\r\n \r\n \r\n You have no cameras! Visit the setup page to get started.\r\n \r\n \r\n Setup Page\r\n \r\n \r\n );\r\n};\r\n\r\nexport default NoCameras;\r\n","// Dashboard.js shows cards for all active cameras associated with the user\r\n\r\nimport React from 'react';\r\nimport { makeStyles } from '@material-ui/core';\r\nimport CameraCard from '../components/CameraCard';\r\nimport NoCameras from '../components/NoCameras';\r\nimport { useHistory } from 'react-router-dom';\r\n\r\n// redux\r\nimport { useSelector } from 'react-redux';\r\nimport { CAMERA_ACTIONS } from './../reducers/cameras.reducer';\r\nimport { useDispatch } from 'react-redux';\r\n\r\nconst useStyles = makeStyles({\r\n root: {\r\n textAlign: 'center',\r\n },\r\n typography: {\r\n padding: '10px',\r\n background: '#f5f5f5',\r\n },\r\n imageDiv: {\r\n background: 'black',\r\n overflow: 'hidden',\r\n margin: 'auto',\r\n },\r\n camerasList: {\r\n maxHeight: 600,\r\n overflowY: 'auto', // scrollable list\r\n\r\n // reset ul styling\r\n listStyle: 'none',\r\n padding: 0,\r\n margin: 0,\r\n '& > li:not(:last-child)': {\r\n // distance between cards\r\n marginBottom: '3px',\r\n },\r\n },\r\n});\r\n\r\nconst { SET_USER_SELECTED_CAMERA } = CAMERA_ACTIONS;\r\n\r\n//create a list of camera cards with a key on each one\r\nconst ListCameraCards = () => {\r\n const history = useHistory();\r\n const classes = useStyles();\r\n const dispatch = useDispatch();\r\n\r\n const cameras = useSelector(({ camerasReducer }) => camerasReducer.cameras);\r\n\r\n const setUserSelectedCamera = (camera) =>\r\n dispatch({ type: SET_USER_SELECTED_CAMERA, payload: camera });\r\n\r\n const CARDS = cameras.map((camera, i) => (\r\n
  • \r\n {\r\n // view details link, select the camera and push to '/device',\r\n setUserSelectedCamera(camera);\r\n history.push('/device');\r\n }}\r\n onViewReports={() => {\r\n // view reports link, change camera and push to reports\r\n setUserSelectedCamera(camera);\r\n history.push('/reports');\r\n }}\r\n />\r\n
  • \r\n ));\r\n return
      {CARDS}
    ;\r\n};\r\n\r\n// readability: when using multiple components in the same file, use export default function to indiciate that this is the main component\r\nexport default function Dashboard() {\r\n const [cameras, { awaitingAPI }] = useSelector(\r\n ({ camerasReducer, generalReducer }) => [\r\n camerasReducer.cameras,\r\n generalReducer,\r\n ]\r\n );\r\n\r\n const classes = useStyles();\r\n\r\n // only renders before API return\r\n // Can replace this with a component eventually\r\n if (awaitingAPI) {\r\n return (\r\n <>\r\n

    Getting device info...

    \r\n \r\n );\r\n }\r\n\r\n // JZ - all this EB code was attached to a button that brings back the CognitoId\r\n // const cognitoIdentityId = async () => {\r\n // return await Auth.currentCredentials();\r\n // };\r\n\r\n // ========================================================================\r\n\r\n /* const apiButton = async () => {\r\n const id = (await cognitoIdentityId()).identityId;\r\n console.log('CognitoIdentityId: ', id);\r\n };*/\r\n\r\n /* this code was in the return below to add a button to display the logged in user's id\r\n apiButton()}\r\n >\r\n Console.log Cognito Id\r\n \r\n */\r\n // Dashboard.js returns a map of the cameras associated with the logged in user\r\n\r\n return (\r\n
    \r\n {cameras.length > 0 ? (\r\n \r\n ) : (\r\n // only if no cameras return\r\n )}\r\n
    \r\n );\r\n}\r\n","// ActivateResponse.js renders after a user types in their activation code on Activate.js\r\n// Depending on EB plan for activation this may not get used.\r\n\r\nimport React from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport { Toolbar, Typography, Button } from '@material-ui/core';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n marginTop: '16px',\r\n },\r\n buttonDiv: {\r\n padding: '15px',\r\n flexDirection: 'row',\r\n marginTop: '15px',\r\n },\r\n button: {\r\n padding: '10px',\r\n marginRight: '10px',\r\n },\r\n}));\r\n\r\n//component renders on receipt of API return from update-camera-activate\r\nconst ActivateResponse = ({\r\n response,\r\n camera,\r\n reassignCamera,\r\n setShowResult,\r\n}) => {\r\n const classes = useStyles();\r\n // if the camera is already registered, ask user if they'd like to reassign camera\r\n if (camera) {\r\n return (\r\n <>\r\n {/* */}\r\n {/* */}\r\n
    \r\n \r\n Camera {camera} is currently assigned to another user. Would you\r\n like to reassign it to your account?\r\n \r\n
    \r\n \r\n Yes, Reassign\r\n \r\n {\r\n setShowResult(false);\r\n }}>\r\n No, Do Not Reassign\r\n \r\n
    \r\n
    \r\n {/*
    */}\r\n \r\n );\r\n }\r\n\r\n // otherwise, return the string from the back end\r\n return (\r\n <>\r\n \r\n {response}\r\n \r\n );\r\n};\r\n\r\nexport default ActivateResponse;\r\n","// Currently receiving two different data types from the API.\r\n// EB needs to make final decision on how activation works.ß\r\n\r\nimport React, { useState } from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport { TextField, Typography, Button } from '@material-ui/core';\r\nimport ActivateResponse from '../components/ActivateResponse';\r\n\r\n// services\r\nimport { activateCamera, reassignCamera } from './../services/cameras.services';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n },\r\n typography: {\r\n padding: '10px',\r\n background: '#f5f5f5',\r\n },\r\n textField: {\r\n padding: '10px',\r\n },\r\n button: {\r\n padding: '10px',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n },\r\n}));\r\n\r\nconst Activate = () => {\r\n const classes = useStyles();\r\n const [activationCode, setActivationCode] = useState(''); // the user input for activationCode.\r\n const [activateResponse, setActivateResponse] = useState('');\r\n const [cameraToReassign, setCameraToReassign] = useState('');\r\n const [showResult, setShowResult] = useState(false);\r\n\r\n // reassigns camera to currently authenticated user. called from component\r\n const handleReassignCamera = async () => {\r\n console.log({ cameraToReassign });\r\n\r\n const reassignResult = await reassignCamera(cameraToReassign);\r\n console.log('response from post/reassign:', reassignResult);\r\n setActivateResponse(reassignResult);\r\n setCameraToReassign('');\r\n };\r\n\r\n const handleFormSubmit = async (event) => {\r\n event.preventDefault(); // prevents form submission from going to another virtual HTML document\r\n console.log('aCode:', activationCode);\r\n\r\n try {\r\n const result = await activateCamera(activationCode);\r\n console.log('response from post/activate:', result);\r\n setShowResult(true); // on response, show the component\r\n // if API returns an object, it's because the camera was already assigned\r\n\r\n // This will need replacing once the API only one data type (needs to be an object)\r\n\r\n if (typeof result === 'object') {\r\n setCameraToReassign(result.camera);\r\n setActivateResponse(result.body);\r\n }\r\n // if API returns a string, display it\r\n else {\r\n setActivateResponse(result);\r\n setCameraToReassign(''); // resets that variable to make display properly\r\n }\r\n } catch (e) {\r\n console.log('error setting serial number in Activate.js:', e);\r\n }\r\n };\r\n\r\n return (\r\n <>\r\n {/* */}\r\n
    \r\n \r\n Enter Activation Code:\r\n \r\n
    \r\n setActivationCode(e.target.value)}\r\n />\r\n
    \r\n
    \r\n \r\n Submit\r\n \r\n \r\n
    \r\n {/*
    */}\r\n {showResult && (\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default Activate;\r\n","// Admin.js will contain config options for users with admin privileges\r\n// currently serving only as a placeholder\r\n\r\n//1/25/21 testing here to see about amazonTurk doing hits screens to annotate images\r\n//login to eric@uspestprotect.com (username: ericProtect)\r\n// goto : requester.mturk.com or https://requester.mturk.com/create/projects/1726062\r\n// saved the current code in /test crowd/rotationLine.html\r\n\r\nimport React from 'react';\r\nimport { makeStyles, Typography, Button } from '@material-ui/core';\r\nimport { Auth } from 'aws-amplify';\r\nimport { useSelector } from 'react-redux'; //want to bring in admin variable to on allow admin's access\r\n\r\nimport { AmplifySignUp } from '@aws-amplify/ui-react';\r\n\r\nconst useStyles = makeStyles({\r\n root: {\r\n textAlign: 'center',\r\n padding: '2px',\r\n },\r\n typography: {\r\n padding: '10px',\r\n background: '#f5f5f5',\r\n },\r\n});\r\n\r\n/*\r\n\r\nconst Admin = () => {\r\n const classes = useStyles();\r\n return (\r\n <>\r\n
    \r\n\r\n Admin Page\r\n
    \r\n \r\n Here we will have config options for admins.\r\n \r\n\r\n
    \r\n \r\n );\r\n};\r\n\r\n*/\r\n\r\nconst Admin = () => {\r\n \r\n const { admin } = useSelector(({ userReducer }) => \r\n userReducer);\r\n\r\n //console.log(\"admin:\", admin);\r\n \r\n const cognitoIdentityId = async () => {\r\n return await Auth.currentCredentials();\r\n };\r\n const apiButton = async () => {\r\n const id = (await cognitoIdentityId()).identityId;\r\n console.log('CognitoIdentityId: ', id);\r\n };\r\n\r\n\r\n const classes = useStyles();\r\n return admin ? ( //only allow admin==true to use this component\r\n <>\r\n
    \r\n\r\n Admin Page\r\n
    \r\n \r\n Here we will have config options for admins.\r\n \r\n \r\n \r\n {/*do not want \"sign-in\" here, from: https://github.com/aws-amplify/amplify-js/issues/6089 */}\r\n
    \r\n \r\n\r\n apiButton()}>\r\n Console.log Cognito Id\r\n \r\n\r\n
    \r\n \r\n ) : ( \"This user is not ADMIN!\" //got here because admin==false\r\n );\r\n};\r\n\r\nexport default Admin;\r\n","// this dropdown contains the result from list-all-images so a user can select\r\n// an older image from the selected camera. \r\n\r\nimport React from \"react\";\r\nimport { makeStyles } from \"@material-ui/core/styles\";\r\nimport FormControl from \"@material-ui/core/FormControl\";\r\nimport Select from \"@material-ui/core/Select\";\r\nimport dayjs from \"dayjs\";\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n formControl: {\r\n margin: theme.spacing(1),\r\n minWidth: 120,\r\n },\r\n}));\r\n\r\nconst ImagesDropdown = (props) => {\r\n const allImagesList = props.allImagesList; // comes from App.js state\r\n const classes = useStyles();\r\n\r\n // sets userSelectedTimestamp in App.js so the API call to get-image can be made using that timestamp\r\n const handleChange = (event) => {\r\n const timestamp = event.target.value;\r\n props.setUserSelectedTimestamp(timestamp);\r\n };\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport default ImagesDropdown;\r\n","import { API } from 'aws-amplify';\r\n\r\n/**\r\n * @method snap\r\n * post snap\r\n * @param {String} cameraId\r\n * @param {Object} params // the request params to be passed.\r\n *\r\n * @returns {Promise<{cameraId: String, s3Path: String, timestampSaved: Date }>} // the new snap path, with the cameraId and timestamp\r\n */\r\nexport const postSnap = async (cameraId, params) => {\r\n try {\r\n const newSnap = API.post('dev-iotvid-app', `/snap/${cameraId}`, params); //adding in params\r\n return newSnap;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * @method postSnap2\r\n * post snap\r\n * @param {String} cameraId\r\n * @param {<{body: {\r\n * cameraId: string, flash1: number, flash2: number, flash3: number,\r\n * frameSize: number, vflip: boolean, hflip: boolean,\r\n * timestamp: Date, winX: number, winY: number, winWidth: number, winHeight: number\r\n * }}>} params // the request params to be passed.\r\n *\r\n * @returns {Promise<{cameraId: String, s3Path: String, timestampSaved: Date }>} // the new snap path, with the cameraId and timestamp\r\n */\r\nexport const postSnap2 = async (cameraId, params) => {\r\n try {\r\n const newSnap2 = await API.post(\r\n 'dev-iotvid-app',\r\n `/snap2/${cameraId}`,\r\n params\r\n ); //adding in params\r\n return newSnap2;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n","import { API } from 'aws-amplify';\r\n\r\n/**\r\n * @method beginCalibration\r\n * the starts off the calibration of a device\r\n * First try at this is to add into the device params a turk created rotation\r\n * This code breaks if a device has not already been selected\r\n * @param {String} imageURL // the image url to be passed to the params body.\r\n * @param {String} cameraId //the cameraId to be passed to the params body\r\n * @returns {Promise} // a success message, for eexample: 'Created a rotation HIT ID:{hitId}, for device:{cameraId}'\r\n */\r\nexport const beginCalibration = async (imageURL, cameraId) => {\r\n try {\r\n //console.log (\"Begin Calibration, cameraProps.cameraId: \", cameraProps.cameraId, \"userSelectedTimestamp\", userSelectedTimestamp, \" imageURL\", imageURL);\r\n const noSignatureUrl = imageURL.substr(0, imageURL.indexOf('?'));\r\n //console.log('noSignatureUrl:',noSignatureUrl)\r\n let params = {\r\n body: {\r\n //imageURL : \"https://erm2.s3.amazonaws.com/test/1579277254797.jpg\"\r\n image_url: noSignatureUrl,\r\n cameraId,\r\n },\r\n };\r\n //console.log(\"parameters:\", params)\r\n const response = await API.post(\r\n 'dev-iotvid-ml',\r\n `/createhit/rotation`,\r\n params\r\n );\r\n\r\n return response;\r\n } catch (error) {\r\n throw error;\r\n }\r\n};\r\n","import React from 'react';\r\nimport { useState, useEffect } from 'react';\r\nimport { makeStyles } from '@material-ui/core';\r\nimport { Button } from '@material-ui/core';\r\nimport { FormControl } from '@material-ui/core';\r\nimport { FormLabel } from '@material-ui/core';\r\nimport { FormGroup } from '@material-ui/core';\r\nimport { FormControlLabel } from '@material-ui/core';\r\n//import { Checkbox } from '@material-ui/core';\r\nimport { useSelector } from 'react-redux';\r\nimport { Slider } from '@material-ui/core';\r\n\r\n// services\r\n//import { postSnap, postSnap2 } from './../services/snap.services';\r\nimport { postSnap } from './../services/snap.services';\r\nimport { beginCalibration } from '../services/turk.services';\r\nimport {\r\n getCameraParams,\r\n updateCameraFlash,\r\n} from './../services/cameras.services';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n display: 'flex',\r\n justifyContent: 'center',\r\n },\r\n formControl: {\r\n margin: theme.spacing(3),\r\n },\r\n}));\r\n\r\nconst Snap = ({\r\n imageURL,\r\n setSnapped,\r\n // userSelectedTimestamp, // unused prop\r\n}) => {\r\n // const userSelectedTimestamp = props.userSelectedTimestamp; //passing this in for Begin Calibration handle on good image to use for calibration\r\n const classes = useStyles();\r\n\r\n const userSelectedCamera = useSelector(\r\n ({ camerasReducer }) => camerasReducer.userSelectedCamera\r\n );\r\n\r\n // flash values, range: 0..100, used for construction of params object to send to snap-image lambda\r\n\r\n const [flash1, setFlash1] = useState(50);\r\n const [flash2, setFlash2] = useState(40);\r\n const [flash3, setFlash3] = useState(10);\r\n \r\n\r\n // handleFlash function for toggling flash booleans on checkbox selection\r\n const handleChangeFlash1 = async (e, value) => {\r\n //console.log(\"in handleChangeFlash, flash1, value:\", value)\r\n setFlash1(value);\r\n };\r\n\r\n const handleChangeFlash2 = async (e, value) => {\r\n setFlash2(value);\r\n };\r\n\r\n const handleChangeFlash3 = async (e, value) => {\r\n setFlash3(value);\r\n };\r\n \r\n // save off flash1, flash2, flash3 to dynamoDb for this camera, intensity level from 0..100\r\n const saveFlash = async () => {\r\n \r\n // posting flash1 and flash2 and saving in dynamo db everytime checkbox has been checked.\r\n // first convert the boolean (for checkbox) values to 0(false, off), or 1 (true, on/flash)\r\n //const flash1Number = Number(flash1) //0 or 1\r\n //const flash2Number = Number(flash2)\r\n console.log(\"saving flash settings to dynamodb, flash1, flash2, flash3:\", flash1, flash2, flash3);\r\n \r\n await updateCameraFlash(userSelectedCamera?.cameraId, \r\n { \"flash1\":flash1, \"flash2\":flash2, \"flash3\":flash3 });\r\n\r\n }\r\n\r\n // constructs params object based on flash selections and posts to API\r\n const snapImage = async () => {\r\n let params = {\r\n body: {\r\n cameraId: userSelectedCamera.cameraId,\r\n // flash values range 0..100, 0 off, 100 full brighness\r\n flash1: userSelectedCamera.flash1 || 0,\r\n flash2: userSelectedCamera.flash2 || 0,\r\n flash3: userSelectedCamera.flash3 || 0,\r\n framesize: userSelectedCamera.framesize || 8, //8 is VGA 640 x 480 (sensor.h framesize_t)\r\n vflip: userSelectedCamera.vFlip,\r\n hflip: userSelectedCamera.hFlip,\r\n timestamp: new Date().getTime(),\r\n winX: userSelectedCamera.subXOrig,\r\n winY: userSelectedCamera.subYOrig,\r\n winWidth: userSelectedCamera.subWidth,\r\n winHeight: userSelectedCamera.subHeight,\r\n }, \r\n };\r\n\r\n params.body.flash1 = flash1;\r\n params.body.flash2 = flash2;\r\n params.body.flash3 = flash3;\r\n console.log(\"calling postSnap with params after setting the flash's:\", userSelectedCamera.cameraId, params);\r\n await postSnap(userSelectedCamera.cameraId, params);\r\n\r\n setSnapped(true); // sets snapped boolean in parent to trigger useEffect\r\n };\r\n\r\n useEffect(() => {\r\n const fetchFlashState = async () => {\r\n if (!userSelectedCamera?.cameraId) return;\r\n\r\n // getting flash1 and flash2 from api, value integer 0..100\r\n let { flash1 = 0, flash2 = 0, flash3 =0 } = await getCameraParams(\r\n userSelectedCamera?.cameraId\r\n );\r\n //the value should be stored as a number, 0 for no flash, > 0 (usually 1 or 500) for flash\r\n //if the value is a string, it will be treated as true, even if the string is 'false'\r\n //but the interface wants a boolean, so for now just convert it to boolean, and when \r\n //saving it off, save it off as a 1(true or on), or 0(false or off)\r\n //flash1 = Boolean(flash1)\r\n //flash2 = Boolean(flash2)\r\n\r\n // setting it in the state\r\n setFlash1(flash1); //value pulled in from dynamodb \"flash1\"\r\n setFlash2(flash2);\r\n setFlash3(flash3);\r\n };\r\n fetchFlashState();\r\n\r\n // fetch on mount and when cameraId changes\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [userSelectedCamera?.cameraId]);\r\n\r\n return (\r\n <>\r\n
    \r\n \r\n \r\n Choose Flash Intensities, each LED Range: 0..100 \r\n \r\n \r\n \r\n }\r\n label=\"Flash 1 (left)\"\r\n />\r\n \r\n }\r\n label=\"Flash 2 (right)\"\r\n />\r\n \r\n }\r\n label=\"Flash 3 (middle)\"\r\n />\r\n \r\n \r\n \r\n \r\n
    \r\n \r\n beginCalibration(imageURL, userSelectedCamera.cameraId)}>\r\n Begin Calibration\r\n \r\n {/* */}\r\n \r\n );\r\n};\r\n\r\nexport default Snap;\r\n","// Device.js shows the most recent snap and lets user take a fresh snap\r\n\r\nimport React, { useMemo } from 'react';\r\nimport { useState, useEffect } from 'react';\r\nimport { useSelector } from 'react-redux';\r\nimport { Typography, Button } from '@material-ui/core';\r\nimport { makeStyles } from '@material-ui/core';\r\nimport ImagesDropdown from '../components/ImagesDropdown';\r\nimport Snap from '../components/Snap';\r\n\r\n// services\r\nimport {\r\n getMostRecentImgAPI,\r\n getAllImagesListAPI,\r\n getOneImageByTimestamp,\r\n} from '../services/images.services';\r\n\r\nimport { getCameraVersion } from '../services/cameras.services';\r\n\r\n//\r\n//\r\n//\r\nconst useStyles = makeStyles({\r\n root: {\r\n textAlign: 'center',\r\n },\r\n typography: {\r\n padding: '10px',\r\n background: '#f5f5f5',\r\n },\r\n imageDiv: {\r\n background: 'black',\r\n overflow: 'hidden',\r\n margin: 'auto',\r\n\r\n // fix console error by checking if height and width are numbers.\r\n height: ({ subHeight }) => (!isNaN(subHeight / 2) ? subHeight / 2 : 'auto'),\r\n width: ({ subWidth }) => (!isNaN(subWidth / 2) ? subWidth / 2 : '100%'),\r\n },\r\n\r\n image: {\r\n // 100% of parent (imageDiv)\r\n height: '100%',\r\n width: '100%',\r\n\r\n // rot passed in props to useStyles\r\n transform: ({ rot }) => `rotate(${rot}deg)`,\r\n },\r\n});\r\n\r\nconst Device = () => {\r\n const userSelectedCamera = useSelector(\r\n ({ camerasReducer }) => camerasReducer.userSelectedCamera\r\n );\r\n\r\n const cameraId = userSelectedCamera?.cameraId;\r\n\r\n const user = useSelector(({ userReducer }) => userReducer.user);\r\n\r\n const subHeight = useMemo(\r\n () =>\r\n userSelectedCamera === undefined\r\n ? 600 * 1.4\r\n : userSelectedCamera?.subHeight * 1.4,\r\n [userSelectedCamera]\r\n ); // check only for this var to change instead of rerendering every time\r\n\r\n const subWidth = useMemo(\r\n () =>\r\n userSelectedCamera === undefined\r\n ? 800 * 1.4\r\n : userSelectedCamera?.subWidth * 1.4,\r\n [userSelectedCamera]\r\n );\r\n\r\n const rot = useMemo(\r\n () => (userSelectedCamera === undefined ? 0 : userSelectedCamera?.rot4),\r\n [userSelectedCamera]\r\n );\r\n\r\n const name = useMemo(\r\n () =>\r\n userSelectedCamera === undefined ? ' ' : userSelectedCamera?.cameraName,\r\n [userSelectedCamera]\r\n );\r\n\r\n const location = useMemo(\r\n () =>\r\n userSelectedCamera === undefined\r\n ? ' '\r\n : userSelectedCamera?.cameraLocation,\r\n [userSelectedCamera]\r\n );\r\n\r\n const classes = useStyles({ rot, subHeight, subWidth }); // pass props to useStyles\r\n\r\n const [displayImg, setDisplayImg] = useState();\r\n const [allImagesList, setAllImagesList] = useState();\r\n const [userSelectedTimestamp, setUserSelectedTimestamp] = useState();\r\n const [snapped, setSnapped] = useState(false);\r\n\r\n // on mount and on change of selected camera, get most recent image and list of previous images\r\n useEffect(() => {\r\n getMostRecentImg(cameraId); //this should also set the userSelectedTimestamp to match this image\r\n getImgList(cameraId);\r\n //setDisplayImg(null);\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [cameraId, user]);\r\n\r\n // when user selects a different timestamp, get that image from images/{cameraId}/{timestampSaved}\r\n // && is an if statement for executing a single line of code\r\n useEffect(() => {\r\n userSelectedTimestamp && getImg(cameraId, userSelectedTimestamp);\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [userSelectedTimestamp, cameraId]);\r\n\r\n // this is runs when snapped is set to true by the Snap button.\r\n // data is refreshed in 10 seconds. snapped is immediately reset to false\r\n // using if here instead of && because two functions are called, not one\r\n useEffect(() => {\r\n if (snapped) {\r\n setTimeout(() => getMostRecentImg(cameraId), 10000);\r\n setTimeout(() => getImgList(cameraId), 10000);\r\n }\r\n setSnapped(false);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [snapped, cameraId]);\r\n\r\n // API call to get list of older images from userSelectedCamera\r\n const getImgList = async (cameraId) => {\r\n const imgList = await getAllImagesListAPI(cameraId);\r\n setAllImagesList(imgList);\r\n };\r\n\r\n // API call to grab an image based on a specific timestamp\r\n const getImg = async (cameraId, timestampSaved) => {\r\n const userSelectedImg = await getOneImageByTimestamp(\r\n cameraId,\r\n timestampSaved\r\n );\r\n setDisplayImg(userSelectedImg);\r\n };\r\n\r\n //parse the timestamp, (and could also parse path if needed) from mostRecentImg signedURL\r\n const parseMostRecentImg = (imgSignedURL) => {\r\n const imageURL = imgSignedURL.substring(0, imgSignedURL.search('.jpg'));\r\n console.log('most recent image URL', imageURL);\r\n const splitResult = imageURL.split('/');\r\n console.log('splitting:', splitResult);\r\n const timestamp = splitResult[splitResult.length - 1]; //was going to pass timestamp to calibration, instead pass unsigned URL\r\n return timestamp;\r\n };\r\n\r\n // API call to get most recent image from userSelectedCamera (state variable from App.js)\r\n const getMostRecentImg = async (cameraId) => {\r\n console.log('cameraId from getMostRecentImg:', cameraId);\r\n const mostRecentImg = await getMostRecentImgAPI(cameraId);\r\n console.log('mostRecentImg', mostRecentImg);\r\n const timestamp = parseMostRecentImg(mostRecentImg); //need the timestamp of the mostRecentImage\r\n setUserSelectedTimestamp(timestamp); //keep the timestamp in sync with the image displayed\r\n setDisplayImg(mostRecentImg);\r\n };\r\n\r\n const consoleLogCameraVersion = async (cameraId) => {\r\n try {\r\n let cameraVersion = await getCameraVersion(cameraId);\r\n\r\n console.log(`camera version for ${cameraId} is: ${cameraVersion}`);\r\n\r\n return;\r\n } catch (error) {\r\n console.log(`could not get camera version for: ${cameraId}`);\r\n }\r\n };\r\n\r\n return (\r\n <>\r\n
    \r\n \r\n {cameraId || 'None'} :: {name}\r\n \r\n \r\n {location}\r\n \r\n\r\n {/* when image comes back from the API call, display it*/}\r\n\r\n {displayImg && (\r\n // div wraps photo in a rectangular div so rotated images appear more cleanly\r\n // inherits dimensions from props and divides them in half\r\n
    \r\n {/* photo props inherited from props, size divided in half */}\r\n \r\n
    \r\n )}\r\n\r\n {/* when the list of older images comes back from the API call, render a dropdown with those timestamps*/}\r\n {allImagesList && (\r\n <>\r\n Timestamp:\r\n {/* render the dropdown in separate component, passing down props of the image list and function\r\n to select that timestamp in order to make another API call */}\r\n \r\n \r\n )}\r\n \r\n \r\n
    \r\n \r\n );\r\n};\r\n\r\nexport default Device;\r\n","// NotFound.js renders at any unnamed path \r\n\r\nimport React from \"react\";\r\nimport { Typography } from \"@material-ui/core\";\r\nimport { makeStyles } from \"@material-ui/core\";\r\n\r\nconst useStyles = makeStyles({\r\n root: {\r\n textAlign: \"center\",\r\n },\r\n typography: {\r\n padding: \"10px\"\r\n }\r\n});\r\n\r\nconst NotFound = () => {\r\n const classes = useStyles();\r\n return (\r\n <>\r\n
    \r\n \r\n Sorry, page not found!\r\n
    \r\n \r\n Please choose an action from the menu to the left.\r\n \r\n \r\n
    \r\n \r\n );\r\n};\r\n\r\nexport default NotFound;\r\n","// this is the amplify supplied auth system screens for logging in to (currently cognito)\r\n// and for resetting password, creating new user account\r\n//this file modifies the text of the amplify supplied screens, and places the modal menus in the center of the grid\r\n\r\nimport React, {useState} from 'react';\r\nimport { Grid } from '@material-ui/core';\r\nimport {\r\n AmplifyAuthenticator,\r\n AmplifySignIn,\r\n AmplifySignUp,\r\n} from '@aws-amplify/ui-react';\r\n\r\n/**\r\n * @method LoginScreen\r\n * present a login screen to the user, allow password reset, and optionally account creation\r\n * @param {boolean} props.allowSignUp if true, then user can create a new user account\r\n * @returns JSX Grid component\r\n */\r\nexport default function LoginScreen (props) {\r\n /* the allowSignUp prop is always flase for Alpha release, as we do customer signup as Admin, might allow users to do this later */\r\n const [allowSignUp] = useState(props.allowSignUp); //[allowSignUp, setSignUp]\r\n // need to customize the AWS container so minHeight isn't 100vh (makes modal stretch really tall...)\r\n return (\r\n \r\n \r\n {!allowSignUp && //not allowing user to create a new MeterVibe account\r\n \r\n }\r\n {allowSignUp && //enter these items if allowing new account creation\r\n <>\r\n \r\n \r\n \r\n \r\n \r\n }\r\n \r\n \r\n );\r\n};\r\n\r\n//export default LoginScreen;\r\n","import React from 'react';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport { makeStyles } from '@material-ui/core';\r\n\r\nconst useStyles = makeStyles({\r\n root: {\r\n // color passed as props, if there is a color prop show the color, else default is blue.\r\n color: ({ color }) => color ?? '#2969B1',\r\n fontSize: ({ fontSize }) => fontSize && fontSize,\r\n fontWeight: ({ fontWeight }) => fontWeight && fontWeight,\r\n cursor: ({ cursor }) => cursor && cursor,\r\n },\r\n});\r\n\r\nexport const PublicLandingText = ({\r\n color,\r\n fontSize,\r\n fontWeight,\r\n cursor,\r\n children,\r\n ...rest\r\n}) => {\r\n const classes = useStyles({ color, fontSize, fontWeight, cursor });\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\n","// Header component sits at the top of App.js ast all times, holding the logo, user email, and AmplifySignOut button\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport { Auth } from 'aws-amplify';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport {\r\n AppBar,\r\n Toolbar,\r\n Typography,\r\n Hidden,\r\n IconButton,\r\n Box,\r\n Grid,\r\n useTheme,\r\n useMediaQuery,\r\n} from '@material-ui/core';\r\nimport Dialog from '@material-ui/core/Dialog';\r\nimport Logo from '../assets/images/LogoTopLeft.png';\r\nimport LoginScreen from '../containers/LoginScreen';\r\nimport MeterVibeButton from './shared/buttons/MeterVibeButton';\r\nimport CartIcon from '@material-ui/icons/ShoppingCart';\r\nimport { Link } from 'react-scroll';\r\nimport useScrollTrigger from '@material-ui/core/useScrollTrigger';\r\nimport Slide from '@material-ui/core/Slide';\r\nimport { PublicLandingText as Text } from './shared/typography/PublicLandingText';\r\nimport CloseIcon from '@material-ui/icons/Close';\r\nimport InfoIcon from '@material-ui/icons/Info';\r\nimport { useHistory } from 'react-router-dom';\r\nimport { useLocation } from 'react-router-dom';\r\n\r\nimport { useDispatch, useSelector } from 'react-redux';\r\nimport { USER_ACTIONS } from './../reducers/user.reducer';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n appBar: {\r\n background: '#0272BC',\r\n zIndex: theme.zIndex.drawer + 1, // sets the zIndex of the AppBar as +1 to the drawer so the AppBar will always sit on top of the drawer\r\n },\r\n logo: {\r\n flexGrow: 5, // similar to the grid system, these properties make the logo take up as much space as possible relative to the email and signout button\r\n cursor: 'pointer',\r\n },\r\n userEmail: {\r\n flexGrow: 1,\r\n },\r\n signInButton: {\r\n flexGrow: 1,\r\n },\r\n buyNowButton: {\r\n flexGrow: 3,\r\n [theme.breakpoints.down('xs')]: {\r\n marginRight: '5px',\r\n },\r\n },\r\n navButton: {\r\n [theme.breakpoints.down('xs')]: {\r\n fontSize: 'clamp(12px,3vw,16px)',\r\n },\r\n },\r\n offset: theme.mixins.toolbar,\r\n closeIcon: {\r\n color: '#0272BC',\r\n\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n },\r\n infoIcon: {\r\n color: '#0272BC',\r\n },\r\n}));\r\n\r\n// hides navbar when user scrolls down or clicks buy now (to avoid navbar hiding stuff).\r\nconst HideOnScroll = ({ children, window }) => {\r\n const trigger = useScrollTrigger({\r\n target: window ? window() : undefined,\r\n });\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\n\r\nconst SignInModal = ({ open, handleClose }) => (\r\n <>\r\n \r\n \r\n \r\n \r\n);\r\n\r\nconst { SET_USER_EMAIL } = USER_ACTIONS;\r\n\r\nexport default function PublicLandingHeader() {\r\n const classes = useStyles();\r\n const { pathname } = useLocation();\r\n const [isSignInOpen, setIsSignInOpen] = useState(false);\r\n const dispatch = useDispatch();\r\n\r\n const userEmail = useSelector(({ userReducer }) => userReducer.userEmail);\r\n\r\n const [showAlert, setShowAlert] = useState(() => {\r\n const storedState = localStorage.getItem('showAlert');\r\n\r\n if (storedState) {\r\n return storedState === 'true' ? true : false;\r\n }\r\n return true;\r\n });\r\n\r\n const theme = useTheme();\r\n const history = useHistory();\r\n\r\n const matchesSm = useMediaQuery(theme.breakpoints.down('sm'));\r\n const matchesXs = useMediaQuery(theme.breakpoints.down('xs'));\r\n\r\n const handleCloseAlert = () => {\r\n localStorage.setItem('showAlert', 'false');\r\n setShowAlert(false);\r\n };\r\n\r\n useEffect(() => {\r\n Auth.currentUserInfo().then((data) => {\r\n if (data) {\r\n // change email when pathname changes (for this navbar only to fix email still showing when signing out)\r\n dispatch({ type: SET_USER_EMAIL, payload: data.attributes.email });\r\n } else {\r\n dispatch({\r\n type: SET_USER_EMAIL,\r\n payload: '',\r\n });\r\n }\r\n });\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [pathname]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n
    history.push('/')}>\r\n \"MeterVibe\"\r\n
    \r\n {/* MUI component hides its contents on xs screens and below*/}\r\n\r\n \r\n
    \r\n {/* react-scroll link, smooth scrolls to location in page */}\r\n \r\n \r\n \r\n
    \r\n
    \r\n \r\n \r\n {/* if is signed in, show email, else show not signed in */}\r\n {Auth.currentAuthenticatedUser() ? userEmail : 'Not signed in'}\r\n \r\n \r\n\r\n
    \r\n {\r\n // if is signed in, go to the app.\r\n Auth.currentUserInfo().then((data) => {\r\n if (data) {\r\n return history.push('/dashboard');\r\n }\r\n // else open the sign in modal\r\n setIsSignInOpen(true);\r\n });\r\n }}\r\n />\r\n
    \r\n
    \r\n\r\n {showAlert && (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n Selling \"Alpha\" devices now! Be an early customer and help\r\n us perfect the product!\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n
    \r\n )}\r\n \r\n \r\n\r\n {/* adding offset to remove the problem of hidden elements with position: fixed;\r\n https://material-ui.com/components/app-bar/#fixed-placement */}\r\n {/* offset here */}\r\n
    \r\n\r\n setIsSignInOpen(false)}\r\n />\r\n \r\n );\r\n}\r\n","// this will be the landing page for unauthenticated users\r\n\r\nimport React from 'react';\r\nimport { PublicLandingText as Text } from './shared/typography/PublicLandingText';\r\nimport { Grid } from '@material-ui/core';\r\nconst PublicLandingPaymentSuccess = () => {\r\n return (\r\n <>\r\n Thanks for your order!\r\n \r\n \r\n Thanks for your order!\r\n \r\n \r\n \r\n \r\n We appreciate your business! If you have any questions, please email\r\n   orders@MeterVibe.com.\r\n We will send you a confirming email to the email you entered with your purchase.\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport default PublicLandingPaymentSuccess;\r\n","// this will be the landing page for unauthenticated users\r\n\r\nimport React from 'react';\r\nimport { PublicLandingText as Text } from './shared/typography/PublicLandingText';\r\n\r\nconst PublicLandingPaymentFailure = () => (\r\n <>\r\n Something went wrong\r\n \r\n Something went wrong\r\n \r\n

    \r\n Something went wrong with your credit card charge, try again or email\r\n   support@MeterVibe.com.\r\n for further assistance\r\n

    \r\n \r\n);\r\n\r\nexport default PublicLandingPaymentFailure;\r\n","import React from 'react';\r\n\r\nconst WavyBackground = ({ height }) => (\r\n \r\n \r\n \r\n);\r\n\r\nexport default WavyBackground;\r\n","import React from 'react';\r\nimport { Grid, Box } from '@material-ui/core/';\r\nimport { PublicLandingText as Text } from './shared/typography/PublicLandingText';\r\nimport { Link } from 'react-router-dom';\r\nimport WavyBackground from './shared/fun_backgrounds/WavyBackground';\r\n\r\nconst PRIMARY_COLOR = '#2969B1';\r\n\r\nexport default function PublicLandingFooter({ classes }) {\r\n return (\r\n <>\r\n \r\n \r\n \r\n {/* footer left */}\r\n \r\n \r\n \r\n © 2021 MeterVibe™\r\n \r\n \r\n \r\n\r\n \r\n\r\n {/* footer right */}\r\n \r\n \r\n \r\n support@metervibe.com\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n {/* will link to privacy policy page */}\r\n \r\n Privacy Policy\r\n \r\n \r\n \r\n \r\n {/* will link to terms of service page */}\r\n \r\n \r\n Terms of Service\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n","import { Global, css } from \"@emotion/core\";\r\nimport React from \"react\";\r\n\r\n\r\nconst GlobalStyles = () => (\r\n <>\r\n \r\n \r\n \r\n \r\n);\r\n\r\nexport default GlobalStyles;\r\n\r\n//background-color purple : #6772e5\r\n","// this is the amplify supplied auth system screens for logging in to (currently cognito)\r\n// and for resetting password, creating new user account\r\n//this file modifies the text of the amplify supplied screens, and places the modal menus in the center of the grid\r\n\r\nimport React from \"react\";\r\nimport { Grid } from \"@material-ui/core\"\r\nimport { Elements } from '@stripe/react-stripe-js'\r\nimport { loadStripe } from '@stripe/stripe-js'\r\nimport GlobalStyles from \"./prebuilt/GlobalStyles\"\r\nimport Head from \"next/head\";\r\n\r\n\r\n//const PUBLISHABLE_KEY = 'pk_test_51Ivpq9FWfFgbm17XwWSsGASWYvgoobbQ4pDvAe98VbbhIK96PTpP0zMOyYLJvZOIBIzUmHVNZHmpFnJd04u5vUlk00680ppoSs';\r\nconst PUBLISHABLE_KEY ='pk_live_51Ivpq9FWfFgbm17X4uip1W2cH3jZYdpPSzGHma3yzVK34aVNEHEzJx0Lit5rPg0ZMOYJ5wTuHPTn6hmx93rbAUbC00Ww33rfRz';\r\n\r\nconst stripePromise = loadStripe(PUBLISHABLE_KEY);\r\n\r\nconst Layout = ({ children, title }) => {\r\n return (\r\n <>\r\n \r\n \r\n\r\n \r\n \r\n {title}\r\n \r\n \r\n \r\n {children}\r\n \r\n \r\n \r\n \r\n \r\n )\r\n}\r\n\r\nexport default Layout;","import styled from '@emotion/styled';\r\n\r\nconst Row = styled.div`\r\n width: 475px;\r\n margin: 30px auto;\r\n box-shadow: 0 6px 9px rgba(50, 50, 93, 0.06), 0 2px 5px rgba(0, 0, 0, 0.08),\r\n inset 0 1px 0 #829fff;\r\n border-radius: 4px;\r\n background-color: #7795f8;\r\n position: relative;\r\n\r\n /* I need to do this so the purchase card doesn't break the site on low media queries. */\r\n @media screen and (max-width: 768px) {\r\n width: ${({ responsive }) => responsive && '345px'};\r\n }\r\n`;\r\n\r\nexport default Row;\r\n","import React from 'react';\r\nimport Radio from '@material-ui/core/Radio';\r\nimport RadioGroup from '@material-ui/core/RadioGroup';\r\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\r\nimport FormControl from '@material-ui/core/FormControl';\r\nimport FormLabel from '@material-ui/core/FormLabel';\r\n\r\n//for now only allow one sold at a time, quantity limited to \"1\"\r\nconst QuantityRadio = ({ quantity, onChange }) => {\r\n return (\r\n \r\n Quantity\r\n \r\n } label=\"1\" />\r\n {/* } label=\"2\" /> */}\r\n \r\n \r\n );\r\n};\r\n\r\nexport default QuantityRadio;\r\n","import React from 'react';\r\n//import { Button} from '@material-ui/core/Button';\r\nimport { Box, Button } from '@material-ui/core';\r\n//import { useNavigate } from \"react-router-dom\"; need v6\r\n\r\n// services\r\n//import { postStripe } from './../../services/stripe.services';\r\n\r\n//const PRIMARY_COLOR = '#2969B1';\r\n\r\n/*\r\nconst CardElementContainer = styled.div`\r\n height: 40px;\r\n display: flex;\r\n align-items: center;\r\n\r\n & .StripeElement {\r\n width: 100%;\r\n padding: 15px;\r\n }\r\n`;\r\n\r\nconst CheckoutForm = ({ onSuccessfulCheckout }) => {\r\n const [isProcessing, setProcessingTo] = useState(false);\r\n const [checkoutError, setCheckoutError] = useState();\r\n\r\n const stripe = useStripe();\r\n const elements = useElements();\r\n\r\n // TIP\r\n // use the cardElements onChange prop to add a handler\r\n // for setting any errors:\r\n\r\n const handleCardDetailsChange = ev => {\r\n ev.error ? setCheckoutError(ev.error.message) : setCheckoutError();\r\n };\r\n\r\n const handleFormSubmit = async ev => {\r\n ev.preventDefault();\r\n\r\n const billingDetails = {\r\n name: ev.target.name.value,\r\n email: ev.target.email.value,\r\n address: {\r\n city: ev.target.city.value,\r\n line1: ev.target.address.value,\r\n state: ev.target.state.value,\r\n postal_code: ev.target.zip.value\r\n }\r\n };\r\n\r\n setProcessingTo(true);\r\n\r\n const cardElement = elements.getElement(\"card\");\r\n const amount = 5000;\r\n\r\n try {\r\n const apiName = \"dev-iotvid-app\"; // in development (dev), backend: -iotvid-app\r\n const path = `/post/stripe/${amount}` //serverless.yml http path, method: post\r\n const myInit = {\r\n body: billingDetails, //user entered data sent to stripe backend processing\r\n headers: {}, //optional, not used\r\n }\r\n const { data: clientSecret } = await API.post(apiName, path, billingDetails);\r\n\r\n const paymentMethodReq = await stripe.createPaymentMethod({\r\n type: \"card\",\r\n card: cardElement,\r\n billing_details: billingDetails\r\n });\r\n\r\n if (paymentMethodReq.error) {\r\n setCheckoutError(paymentMethodReq.error.message);\r\n setProcessingTo(false);\r\n return;\r\n }\r\n\r\n const { error } = await stripe.confirmCardPayment(clientSecret, {\r\n payment_method: paymentMethodReq.paymentMethod.id\r\n });\r\n\r\n if (error) {\r\n setCheckoutError(error.message);\r\n setProcessingTo(false);\r\n return;\r\n }\r\n\r\n onSuccessfulCheckout();\r\n } catch (err) {\r\n setCheckoutError(err.message);\r\n }\r\n };\r\n\r\n // Learning\r\n // A common ask/bug that users run into is:\r\n // How do you change the color of the card element input text?\r\n // How do you change the font-size of the card element input text?\r\n // How do you change the placeholder color?\r\n // The answer to all of the above is to use the `style` option.\r\n // It's common to hear users confused why the card element appears impervious\r\n // to all their styles. No matter what classes they add to the parent element\r\n // nothing within the card element seems to change. The reason for this is that\r\n // the card element is housed within an iframe and:\r\n // > styles do not cascade from a parent window down into its iframes\r\n\r\n const iframeStyles = {\r\n base: {\r\n color: \"#fff\",\r\n fontSize: \"16px\",\r\n iconColor: \"#fff\",\r\n \"::placeholder\": {\r\n color: \"#87bbfd\"\r\n }\r\n },\r\n invalid: {\r\n iconColor: \"#FFC7EE\",\r\n color: \"#FFC7EE\"\r\n },\r\n complete: {\r\n iconColor: \"#cbf4c9\"\r\n }\r\n };\r\n\r\n const cardElementOpts = {\r\n iconStyle: \"solid\",\r\n style: iframeStyles,\r\n hidePostalCode: true\r\n };\r\n\r\n return (\r\n
    \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {checkoutError && {checkoutError}}\r\n \r\n {/ * TIP always disable your submit button while processing payments * /}\r\n \r\n {isProcessing ? \"Processing...\" : \"Pay $50\"}\r\n \r\n \r\n
    \r\n );\r\n};\r\n\r\n//export default CheckoutForm;\r\n\r\n*/\r\n\r\n//*********************** THIS IS THE NEW CODE FROM THE EXAMPLE STIPE PAYMENTS USING EXTERNAL STRIPE PAYMENT SERVICE */\r\n//** 1/28/22 This worked in test mode, but could not get it to work in production, so now replacing this with payment url below */\r\n\r\n//External payment via stripe, then go to success or failure page via backend\r\n//https://stripe.com/docs/payments/accept-a-payment\r\n\r\n/*\r\nexport default function StripePayment({ quantity }) {\r\n const handleClick = async () => {\r\n // Get Stripe.js instance\r\n //console.log(\"in StripePayment quantity\", quantity)\r\n const result = await postStripe(quantity); //for now quantity is always 1 in the OrderCard.js as provided by stripe.js\r\n\r\n if (result.error) {\r\n // If `redirectToCheckout` fails due to a browser or network\r\n // error, display the localized error message to your customer\r\n // using `result.error.message`.\r\n }\r\n };\r\n\r\n return (\r\n \r\n );\r\n}\r\n\r\n*/\r\n\r\n//********************************************************************************************************************* */\r\n\r\n//************************* NOW TRYING THIS WITH A PAYMENT URL DEFINED IN STRIPE *************************************/\r\n\r\n//This calls the url of the payment defined at stripe>payments>payment links, using a product at stripe>product\r\nfunction StripePayment({ quantity }) {\r\n\r\n const handleClick = async () => {\r\n\r\n //const result = window.location.replace('https://buy.stripe.com/test_7sI02Tg4Y5Akb0keUU');\r\n //const result = window.location.assign('https://buy.stripe.com/test_7sI02Tg4Y5Akb0keUU', '_blank');\r\n const result = window.open('https://buy.stripe.com/dR69DA7NZf6f7Mk001', '_blank'); //try opening in a new tab, also could \r\n // or GeeksforGeeks or target=\"_top\"\r\n console.log (\"window.location.assign:\", result);\r\n if (result.error) {\r\n // If `redirectToCheckout` fails due to a browser or network\r\n // error, display the localized error message to your customer\r\n // using `result.error.message`.\r\n }\r\n };\r\n\r\n //goto external stripe defined url to purchase MeterVibe with subscription\r\n //ERROR caused by CLOUDFRONT: checkout-app-init-4f64b720f0ebbe99e72b2bb408efbd61.js:1 Stripe Checkout is not able to run in an iFrame. Please redirect to Checkout at the top level.\r\n return (\r\n\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default StripePayment;","//from DonutShop.jsx in stripe/prebuilt revising to make this MaterialUI like\r\n\r\n//import React, { useState } from 'react';\r\nimport React from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\n//import clsx from 'clsx';\r\nimport QuantityRadio from './QuantityRadio';\r\nimport CheckoutForm from './stripe/CheckoutForm';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Card from '@material-ui/core/Card';\r\n//import CardActions from '@material-ui/core/CardActions';\r\nimport CardContent from '@material-ui/core/CardContent';\r\n//import Collapse from '@material-ui/core/Collapse';\r\n//import IconButton from '@material-ui/core/IconButton';\r\n//import ExpandMoreIcon from '@material-ui/icons/ExpandMore';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n [theme.breakpoints.down('xs')]: {\r\n maxWidth: 345,\r\n },\r\n padding: '10px',\r\n },\r\n media: {\r\n height: 0,\r\n paddingTop: '56.25%', // 16:9\r\n },\r\n expand: {\r\n transform: 'rotate(0deg)',\r\n marginLeft: 'auto',\r\n transition: theme.transitions.create('transform', {\r\n duration: theme.transitions.duration.shortest,\r\n }),\r\n\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n },\r\n expandOpen: {\r\n transform: 'rotate(180deg)',\r\n },\r\n}));\r\n\r\nexport default function OrderCard({ numDevices, setNumDevices }) {\r\n const classes = useStyles();\r\n //const [expanded, setExpanded] = useState(false);\r\n\r\n //const handleExpandClick = () => {\r\n // setExpanded(!expanded);\r\n //};\r\n\r\n return (\r\n \r\n {/*\"MeterVibe\"*/}\r\n \r\n ALPHA Devices Available\r\n \r\n \r\n with 12 month Alpha subscription\r\n \r\n \r\n ---\r\n \r\n \r\n $198.00 \r\n \r\n MeterVibe device plus one year data subscription\r\n \r\n \r\n ---\r\n \r\n \r\n setNumDevices(Number(e.target.value))}\r\n />\r\n \r\n \r\n On purchase: \r\n
    1. Your MeterVibe login ID will be the email you enter at time of purchase.\r\n
    2. Click \"PURCHASE\" to go to secure external site to complete your purchase.\r\n
    \r\n
    \r\n
    \r\n\r\n{/* */}\r\n \r\n{/*\r\n \r\n \r\n \r\n */}\r\n {/* */}\r\n\r\n {/* */}\r\n \r\n FAQ:\r\n \r\n This purchase is for our introductory MeterVibe Alpha model. Each order contains one device, a USB power block, a USB connector cable, and a 12 month\r\n subscription. When placing your order, we ask for your email address which will become your login user name, \r\n a phone number, for text alerts if this feature is activated, and contact info to troubleshoot issues, and a ship to address for delivery.\r\n \r\n \r\n The MeterVibe alpha is designed to work inside a building, attached to your meter, and is powered with a standard 110V outlet. \r\n The MeterVibe alpha connects to the cloud with available 2.4 Ghz wifi (802.11 b/g/n). \r\n \r\n \r\n This is a new product line and service, so we welcome feedback as we improve our product, and add new features.\r\n \r\n \r\n MeterVibe creates a cloud based \"Snap\" (picture) of your meter.\r\n These pictures are, with a delay, turned into meter readings. \r\n We will track your reading history, and provide you feedback with alerts.\r\n The visual snapshot of your most\r\n recent meter reading will be available after a sucessful\r\n snapshot is taken.\r\n \r\n \r\n Order now, and enjoy your MeterVibe Alpha edition. \r\n \r\n \r\n {/**/}\r\n \r\n
    \r\n );\r\n}\r\n","import { useState } from 'react';\r\nimport React from 'react';\r\nimport Layout from './stripe/Layout';\r\nimport Row from './stripe/prebuilt/Row';\r\nimport OrderCard from './OrderCard';\r\n\r\nexport default function Stripe() {\r\n const [numDevices, setNumDevices] = useState(1);\r\n\r\n // not needed, we have 2 radio buttons each with a value, we just set numDonuts to the value.\r\n // const addDonut = () => setNumDonuts((num) => Math.min(2, num + 1)); //max order 2 for beta\r\n // const remDonut = () => setNumDonuts((num) => Math.max(1, num - 1));\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n {/*\r\n Router.push(\"/success\")}\r\n /> */}\r\n \r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport { Grid, makeStyles } from '@material-ui/core';\r\nimport { Slide } from 'react-slideshow-image';\r\nimport 'react-slideshow-image/dist/styles.css';\r\nimport ComputerScreenFrame from '../assets/images/computer_screen_frame.png';\r\nimport MeterVibeAppImg1 from '../assets/images/metervibe_app_desktop_1.png';\r\nimport MeterVibeAppImg2 from '../assets/images/metervibe_app_desktop_2.png';\r\nimport MeterVibeAppImg3 from '../assets/images/metervibe_app_desktop_3.png';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n overflow: 'hidden',\r\n position: 'relative',\r\n width: '314px',\r\n },\r\n image: {\r\n maxWidth: '100%',\r\n width: 'auto',\r\n height: '166px',\r\n verticalAlign: 'middle',\r\n border: '0',\r\n },\r\n computerScreen: {\r\n position: 'absolute',\r\n height: '100%',\r\n width: '85%',\r\n left: '25px',\r\n top: '13px',\r\n overflow: 'hidden',\r\n },\r\n}));\r\nexport default function PublicLandingComputerScreen() {\r\n const slideImages = [MeterVibeAppImg1, MeterVibeAppImg2, MeterVibeAppImg3];\r\n const classes = useStyles();\r\n\r\n return (\r\n \r\n \r\n \r\n {slideImages.map((imgSrc, key) => (\r\n \r\n ))}\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport { Slide } from 'react-slideshow-image';\r\nimport 'react-slideshow-image/dist/styles.css';\r\n\r\nexport default function Slideshow({\r\n images,\r\n slideProps,\r\n containerWidth,\r\n imgWidth,\r\n imgHeight,\r\n ...rest\r\n}) {\r\n // accepts an array of images, no objects, just strings with values of path.\r\n return (\r\n \r\n \r\n {images.map((imgSrc, key) => (\r\n
    \r\n \r\n
    \r\n ))}\r\n
    \r\n
    \r\n );\r\n}\r\n","// this will be the landing page for unauthenticated users\r\n// test VISA card is 4242 4242 4242 4242\r\n\r\n// hooks\r\nimport React, { useEffect } from 'react';\r\nimport { useLocation, useHistory } from 'react-router-dom';\r\nimport { useMediaQuery, useTheme } from '@material-ui/core';\r\n\r\n// components\r\nimport { Grid, Paper, Box } from '@material-ui/core';\r\nimport LoginScreen from '../containers/LoginScreen';\r\nimport PublicLandingHeader from '../components/PublicLandingHeader';\r\nimport PublicLandingPaymentSuccess from '../components/PublicLandingPaymentSuccess';\r\nimport PublicLandingPaymentFailure from '../components/PublicLandingPaymentFailure';\r\nimport PublicLandingFooter from './PublicLandingFooter';\r\nimport { PublicLandingText as Text } from './shared/typography/PublicLandingText';\r\nimport Stripe from './Stripe';\r\nimport PublicLandingComputerScreen from './PublicLandingComputerScreen';\r\nimport Slideshow from './shared/image_components/Slideshow';\r\nimport WavyBackground from './shared/fun_backgrounds/WavyBackground';\r\n\r\n// images\r\nimport MeterVibeDeviceImg from '../assets/images/metervibe_device_transparent.png';\r\nimport MeterVibeLogoImg from '../assets/images/MeterVibe_logo_1444x596.png'; \r\nimport WaterfallImg from '../assets/images/waterfall.jpeg';\r\nimport MeterImg1 from '../assets/images/meter_1.png';\r\nimport MeterImg2 from '../assets/images/meter_2.png';\r\nimport MeterImg3 from '../assets/images/meter_3.png';\r\nimport MeterImg4 from '../assets/images/meter_4.png';\r\n\r\n// utils\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport MeterVibeButton from './shared/buttons/MeterVibeButton';\r\nimport 'react-slideshow-image/dist/styles.css';\r\n\r\n/* colors from app.css\r\n:root {\r\n --amplify-primary-color:#015388; //dark blue\r\n --amplify-primary-tint:#0272bc; //medium blue\r\n --amplify-primary-shade: #3d93cc; //light blue\r\n}\r\n*/\r\n\r\nconst PRIMARY_TEXT_COLOR = '#2969B1';\r\n\r\n// font-size that scale according to screen size\r\nconst LOUD_VOICE_FONT_SIZE = 'clamp(24px,4vw, 40px)';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n '& > *': {\r\n margin: theme.spacing(1),\r\n width: theme.spacing(32),\r\n height: theme.spacing(16),\r\n },\r\n },\r\n mediumBluePaper: {\r\n backgroundColor: '#0272bc',\r\n },\r\n whitePaper: {\r\n backgroundColor: '#FFFFFF',\r\n },\r\n sweetAiranPaper: {\r\n backgroundColor: '#ffffff',\r\n backgroundImage: 'linear-gradient(315deg, #ffffff 0%, #d7e1ec 74%)',\r\n flexGrow: 1,\r\n },\r\n\r\n pageContent: {\r\n flexGrow: 1,\r\n },\r\n\r\n customBorderRadius: {\r\n borderRadius: 25,\r\n },\r\n\r\n innerColumn: {\r\n width: '98%',\r\n maxWidth: '1100px',\r\n marginRight: 'auto',\r\n marginLeft: 'auto',\r\n padding: '10px',\r\n },\r\n\r\n pageSection: {\r\n scrollMarginTop: '2em',\r\n },\r\n\r\n welcome: {\r\n scrollMarginTop: '2em',\r\n minHeight: '75vh',\r\n width: '98%',\r\n maxWidth: '1100px',\r\n marginRight: 'auto',\r\n marginLeft: 'auto',\r\n padding: '10px',\r\n\r\n [theme.breakpoints.down('md')]: {\r\n // show more of first section in medium screens\r\n minHeight: '80vh',\r\n },\r\n\r\n [theme.breakpoints.down('sm')]: {\r\n // show more of first section in phone queries\r\n minHeight: '85vh',\r\n },\r\n\r\n [theme.breakpoints.down('xs')]: {\r\n // show more of first section in phone queries\r\n minHeight: '89vh',\r\n },\r\n },\r\n\r\n pageBreak: {\r\n flexGrow: 1,\r\n padding: '20px',\r\n },\r\n\r\n listMain: {\r\n color: PRIMARY_TEXT_COLOR,\r\n fontSize: '18px',\r\n lineHeight: '25px',\r\n padding: '5px 20px',\r\n [theme.breakpoints.down('xs')]: {\r\n lineHeight: '30px',\r\n },\r\n\r\n [theme.breakpoints.down('sm')]: {\r\n fontSize: '16px',\r\n },\r\n },\r\n listAlt: {\r\n color: '#fff',\r\n fontSize: '1.2rem',\r\n lineHeight: '50px',\r\n },\r\n installationInfoList: {\r\n color: PRIMARY_TEXT_COLOR,\r\n fontSize: '18px',\r\n lineHeight: '40px',\r\n margin: '0 5px',\r\n padding: '0 20px',\r\n\r\n [theme.breakpoints.down('sm')]: {\r\n fontSize: '16px',\r\n },\r\n },\r\n deviceImage: {\r\n width: '100%',\r\n margin: '10px auto',\r\n padding: '10px',\r\n\r\n [theme.breakpoints.down('sm')]: {\r\n width: '60%',\r\n },\r\n\r\n [theme.breakpoints.down('xs')]: {\r\n width: '80%',\r\n },\r\n },\r\n sectionImage: {\r\n [theme.breakpoints.down('sm')]: {\r\n marginTop: '10px',\r\n },\r\n },\r\n}));\r\n\r\nexport default function PublicLanding() {\r\n const classes = useStyles();\r\n const theme = useTheme();\r\n const { pathname } = useLocation();\r\n const history = useHistory();\r\n\r\n const matchesMd = useMediaQuery(theme.breakpoints.down('md'));\r\n const matchesSm = useMediaQuery(theme.breakpoints.down('sm'));\r\n const matchesXS = useMediaQuery(theme.breakpoints.down('xs'));\r\n\r\n useEffect(() => {\r\n console.log(\"pathname:\", pathname);\r\n //for now, if user cancels during payment (back) :{currentURL: \"/payment_cancel\"} we don't have a seperate page, just go back to /, PublicLanding\r\n if (pathname === '/payment_cancel') history.push('/');\r\n // check for this everytime pathname changes.\r\n }, [pathname, history]);\r\n\r\n // switching to if because we might have an else-if for /payment_failure.\r\n if (pathname === '/payment_success') {\r\n return (\r\n <>\r\n \r\n \r\n
    \r\n \r\n \r\n
    \r\n \r\n
    \r\n \r\n \r\n history.push('/')}\r\n text=\"Go Back\"\r\n />\r\n \r\n \r\n
    \r\n\r\n \r\n \r\n \r\n \r\n
    \r\n
    \r\n \r\n );\r\n } else if (pathname === '/payment_failure') {\r\n return (\r\n <>\r\n \r\n \r\n
    \r\n \r\n \r\n
    \r\n \r\n
    \r\n
    \r\n \r\n \r\n \r\n history.push('/')}\r\n text=\"Go Back\"\r\n />\r\n \r\n \r\n
    \r\n
    \r\n \r\n \r\n );\r\n }\r\n\r\n return (\r\n <>\r\n \r\n \r\n
    \r\n {/* welcome section */}\r\n \r\n \r\n \r\n MeterVibe Water Monitor - Alpha Edition\r\n
    \r\n \r\n\r\n \r\n \r\n Whole house water monitoring and leak detection.\r\n \r\n\r\n \r\n \"We watch your meter so you don't have to.\"\r\n
    \r\n
    \r\n \r\n
    \r\n \r\n Wifi connected whole house water monitoring\r\n \r\n
      \r\n
    • easy to install, attaches to your existing water meter
    • \r\n
    • \r\n alerts to your phone, find leaky toilets, spot excessive water usage\r\n
    • \r\n
    • \r\n plan and budget your water use, no more billing surprises\r\n
    • \r\n
    \r\n
    \r\n\r\n \r\n \r\n
    \r\n \r\n
    \r\n
    \r\n \r\n
    \r\n \r\n The MeterVibe Alpha\r\n \r\n
    \r\n \r\n\r\n \r\n\r\n {/* app section */}\r\n \r\n \r\n \r\n
      \r\n
    • Keeps a history of your water use
    • \r\n
    • Easy to navigate, water use at your fingertips
    • \r\n
    • Easy to compare water use over time
    • \r\n
    • Upgrades will include user customized usage alerts
    • \r\n
    \r\n
    \r\n\r\n \r\n \r\n \r\n \r\n
    \r\n \r\n\r\n
    \r\n \r\n
    \r\n\r\n {/* meters section (used to be customer reviews in UI design) */}\r\n
    \r\n \r\n \r\n \r\n Selling \"Alpha\" devices now!\r\n \r\n\r\n \r\n Be an early customer and help us perfect the product!\r\n \r\n
    \r\n \r\n MeterVibe Alpha is easy to install at your house/condo/office\r\n \r\n\r\n
      \r\n
    • \r\n Attaches to the Water Meter located inside your building.\r\n
    • \r\n
    • Uses wifi to communicate with the Cloud.
    • \r\n
    • Powers from a standard 110V outlet.
    • \r\n
    \r\n
    \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n
    \r\n\r\n
    \r\n\r\n \r\n \r\n \r\n \r\n \r\n Using technology to make a better world\r\n \r\n\r\n \r\n water meters are everywhere, but remote monitoring is not. We\r\n have created an easy to use, non intrusive way, to stop\r\n wasting water. We are only getting started! join us by being\r\n an early customer and help us do our part in making the world\r\n a better place!\r\n \r\n \r\n\r\n \r\n \"waterfall\"\r\n \r\n \r\n
    \r\n \r\n\r\n
    \r\n \r\n
    \r\n\r\n \r\n
    \r\n \r\n Get MeterVibe Today!\r\n \r\n \r\n
    \r\n \r\n\r\n
    \r\n
    \r\n\r\n
    \r\n \r\n
    \r\n\r\n \r\n
    \r\n \r\n );\r\n}\r\n\r\n/*\r\n\r\n */\r\n","// Header component sits at the top of App.js ast all times, holding the logo, user email, and AmplifySignOut button\r\n\r\nimport React from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport { AppBar, Toolbar, Typography, Hidden } from '@material-ui/core';\r\nimport Logo from '../assets/images/LogoTopLeft.png';\r\nimport { AmplifySignOut } from '@aws-amplify/ui-react';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n appBar: {\r\n background: '#0272BC',\r\n zIndex: theme.zIndex.drawer + 1, // sets the zIndex of the AppBar as +1 to the drawer so the AppBar will always sit on top of the drawer\r\n },\r\n logo: {\r\n flexGrow: 10, // similar to the grid system, these properties make the logo take up as much space as possible relative to the email and signout button\r\n },\r\n userEmail: {\r\n flexGrow: 1,\r\n },\r\n signOutButton: {\r\n flexGrow: 1,\r\n },\r\n}));\r\n\r\n// this header is inside MeterVibeAppLayout.js'\r\nconst Header = ({ userEmail }) => {\r\n const classes = useStyles();\r\n return (\r\n <>\r\n \r\n \r\n
    \r\n \"MeterVibe\"\r\n
    \r\n {/* MUI component hides its contents on xs screens and below*/}\r\n \r\n {userEmail}\r\n \r\n {/* TODO: we need to make the signout button also push to / (right now pathname is the same when you leave it) */}\r\n
    \r\n \r\n
    \r\n
    \r\n
    \r\n \r\n );\r\n};\r\n\r\nexport default Header;\r\n","// CameraDropdown.js holds the list of cameras so the user can select one and set it to state\r\n// JZ - there is a bug that after list of cameras comes back, the first camera (A101) will show in the dropdown\r\n// though that camera is not actually selected. It should stay with the disabled menu option, but it doesn't.\r\n\r\nimport React from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport InputLabel from '@material-ui/core/InputLabel';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport FormControl from '@material-ui/core/FormControl';\r\nimport Select from '@material-ui/core/Select';\r\nimport { useHistory } from 'react-router-dom';\r\nimport { useLocation } from 'react-router-dom';\r\nimport { useDispatch, useSelector } from 'react-redux';\r\nimport { CAMERA_ACTIONS } from './../reducers/cameras.reducer';\r\nimport { getCameraObject } from './../reducers/cameras.reducer';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n formControl: {\r\n margin: theme.spacing(1),\r\n minWidth: 120,\r\n },\r\n selectEmpty: {\r\n marginTop: theme.spacing(2),\r\n },\r\n}));\r\n\r\nconst { SET_USER_SELECTED_CAMERA } = CAMERA_ACTIONS;\r\n\r\nconst CameraDropDown = ({ showMore }) => {\r\n let history = useHistory();\r\n let { pathname } = useLocation();\r\n const dispatch = useDispatch();\r\n\r\n const { cameras, userSelectedCamera } = useSelector(\r\n ({ camerasReducer }) => camerasReducer\r\n );\r\n\r\n const userSelectedCameraId = userSelectedCamera?.cameraId;\r\n\r\n const classes = useStyles();\r\n\r\n const handleChange = (event) => {\r\n const selectedCameraId = event.target.value;\r\n\r\n const selectedCameraObject = getCameraObject(cameras, selectedCameraId);\r\n\r\n dispatch({ type: SET_USER_SELECTED_CAMERA, payload: selectedCameraObject });\r\n // don't push to /device if user is in /reports\r\n if (pathname === '/reports') return;\r\n history.push('/device');\r\n };\r\n\r\n /*\r\n \r\n Selected Device\r\n \r\n \r\n */\r\n\r\n return (\r\n \r\n Device\r\n \r\n {/* dropdown items mapped from cameras array, then selected camera is stored in state */}\r\n {cameras.map((camera, i) => (\r\n \r\n {!showMore ? (\r\n camera.cameraId\r\n ) : (\r\n <>\r\n {' (' +\r\n camera.cameraId +\r\n ') ' +\r\n \"'\" +\r\n camera.cameraName +\r\n \"'\" +\r\n ' located at ' +\r\n \"'\" +\r\n camera.cameraLocation +\r\n \"'\"}\r\n \r\n )}\r\n \r\n ))}\r\n \r\n \r\n );\r\n};\r\n\r\nexport default CameraDropDown;\r\n","import React, { useEffect } from 'react';\r\nimport { Auth } from 'aws-amplify';\r\nimport { useHistory } from 'react-router-dom';\r\n\r\n/**\r\n * @param {React.FunctionComponent} Component // the component wrapped in the function when exported\r\n * @param {String} route // the route pushing to on-error (when un-authenticated), defaults to '/' when not provided.\r\n * @returns {React.FunctionComponent} // the component to render when authenticated\r\n */\r\nconst protectedRoute =\r\n (Component, route = '/') =>\r\n (props) => {\r\n const history = useHistory();\r\n async function checkAuthState() {\r\n try {\r\n // check if user is authenticated\r\n await Auth.currentAuthenticatedUser();\r\n } catch (err) {\r\n // if not authenticated, push to the route (defaults to '/')\r\n history.push(route);\r\n }\r\n }\r\n useEffect(() => {\r\n checkAuthState();\r\n // no dependency array, runs first on mount and then every re-render (acts as both componentDidMount and componentDidUpdate)\r\n });\r\n // if is authenticated, return the component as usual.\r\n return ;\r\n };\r\n\r\nexport default protectedRoute;\r\n","import React, { useState, useMemo } from 'react';\r\nimport { useSelector } from 'react-redux';\r\nimport { Grid, Toolbar, Typography } from '@material-ui/core';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport { NavLink } from 'react-router-dom';\r\nimport { ListItem } from '@material-ui/core';\r\nimport clsx from 'clsx';\r\nimport Drawer from '@material-ui/core/Drawer';\r\nimport List from '@material-ui/core/List';\r\nimport Divider from '@material-ui/core/Divider';\r\nimport Container from '@material-ui/core/Container';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Header from '../components/Header';\r\nimport CameraDropdown from '../components/CameraDropdown';\r\nimport { Link, useLocation } from 'react-router-dom';\r\nimport protectedRoute from '../utils/protectedRoute';\r\n\r\n// icons\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport DashboardIcon from '@material-ui/icons/Dashboard';\r\nimport ChevronLeftIcon from '@material-ui/icons/ChevronLeft';\r\nimport LinkedCameraIcon from '@material-ui/icons/LinkedCamera';\r\nimport ChevronRightIcon from '@material-ui/icons/ChevronRight';\r\nimport AddBoxIcon from '@material-ui/icons/AddBox';\r\nimport VpnKeyIcon from '@material-ui/icons/VpnKey';\r\nimport ReportsIcon from '@material-ui/icons/Assessment';\r\nimport AlertsIcon from '@material-ui/icons/ErrorOutline';\r\nimport PersonIcon from '@material-ui/icons/Person';\r\n\r\nconst drawerWidth = 240;\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n display: 'flex',\r\n },\r\n toolbar: {\r\n paddingRight: 24, // keep right padding when drawer closed\r\n },\r\n toolbarIcon: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'flex-end',\r\n padding: '0 8px',\r\n ...theme.mixins.toolbar,\r\n },\r\n iconButton: {\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n },\r\n appBar: {\r\n zIndex: theme.zIndex.drawer + 1,\r\n transition: theme.transitions.create(['width', 'margin'], {\r\n easing: theme.transitions.easing.sharp,\r\n duration: theme.transitions.duration.leavingScreen,\r\n }),\r\n },\r\n appBarShift: {\r\n marginLeft: drawerWidth,\r\n width: `calc(100% - ${drawerWidth}px)`,\r\n transition: theme.transitions.create(['width', 'margin'], {\r\n easing: theme.transitions.easing.sharp,\r\n duration: theme.transitions.duration.enteringScreen,\r\n }),\r\n },\r\n menuButton: {\r\n marginRight: 36,\r\n },\r\n menuButtonHidden: {\r\n display: 'none',\r\n },\r\n title: {\r\n flexGrow: 1,\r\n },\r\n drawerPaper: {\r\n position: 'relative',\r\n whiteSpace: 'nowrap',\r\n width: drawerWidth,\r\n background: '#015388',\r\n transition: theme.transitions.create('width', {\r\n easing: theme.transitions.easing.sharp,\r\n duration: theme.transitions.duration.enteringScreen,\r\n }),\r\n },\r\n drawerPaperClose: {\r\n overflowX: 'hidden',\r\n transition: theme.transitions.create('width', {\r\n easing: theme.transitions.easing.sharp,\r\n duration: theme.transitions.duration.leavingScreen,\r\n }),\r\n width: theme.spacing(7),\r\n [theme.breakpoints.up('sm')]: {\r\n width: theme.spacing(9),\r\n },\r\n },\r\n appBarSpacer: theme.mixins.toolbar,\r\n content: {\r\n // color currently defaults to white - commenting this back in makes it dark\r\n // backgroundColor:\r\n // theme.palette.mode === \"light\"\r\n // ? theme.palette.grey[100]\r\n // : theme.palette.grey[900],\r\n flexGrow: 1,\r\n // height: '100vmax', // this is what makes the page scroll way more down than the content that it has\r\n overflow: 'auto',\r\n },\r\n container: {\r\n paddingTop: theme.spacing(4),\r\n paddingBottom: theme.spacing(4),\r\n },\r\n paper: {\r\n padding: theme.spacing(2),\r\n display: 'flex',\r\n overflow: 'auto',\r\n flexDirection: 'column',\r\n // make it eggshell white in the dashboard page\r\n background: ({ pathname }) => pathname.includes('/dashboard') && '#fafafa',\r\n },\r\n fixedHeight: {\r\n height: 240,\r\n },\r\n boldText: {\r\n fontSize: '14px',\r\n fontWeight: 700,\r\n color: '#01070F',\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n}));\r\n\r\nconst navLinks = [\r\n {\r\n title: 'Dashboard',\r\n Icon: DashboardIcon,\r\n path: '/dashboard',\r\n },\r\n {\r\n title: 'Activate',\r\n Icon: AddBoxIcon,\r\n path: '/activate',\r\n isAdminLink: true,\r\n },\r\n {\r\n title: 'Device',\r\n Icon: LinkedCameraIcon,\r\n path: '/device',\r\n },\r\n {\r\n title: 'Admin',\r\n Icon: VpnKeyIcon,\r\n path: '/admin',\r\n isAdminLink: true,\r\n },\r\n {\r\n title: 'Reports',\r\n Icon: ReportsIcon,\r\n path: '/reports',\r\n },\r\n {\r\n title: 'Alerts',\r\n Icon: AlertsIcon,\r\n path: '/alerts',\r\n isAdminLink: true,\r\n },\r\n {\r\n title: 'User Settings',\r\n Icon: PersonIcon,\r\n path: '/user-settings',\r\n isAdminLink: true, // if is admin link, only admin can see this link\r\n },\r\n];\r\n\r\nconst customLayoutPaths = [/^\\/reports$/, /^\\/alerts$/, /^\\/user-settings$/];\r\n\r\nfunction MeterVibeAppLayout({ children }) {\r\n const [open, setOpen] = useState(true);\r\n const { pathname } = useLocation();\r\n const classes = useStyles({ pathname });\r\n\r\n const toggleDrawer = () => {\r\n setOpen(!open);\r\n };\r\n\r\n // you can destructure multiple state from store like this\r\n const { admin, userEmail, cameras, userSelectedCamera } = useSelector(\r\n ({ userReducer, camerasReducer }) => ({\r\n admin: userReducer.admin,\r\n userEmail: userReducer.userEmail,\r\n cameras: camerasReducer.cameras,\r\n userSelectedCamera: camerasReducer.userSelectedCamera,\r\n })\r\n );\r\n\r\n // can also do this\r\n // const [admin, userEmail] = useSelector(({ userReducer }) => [\r\n // userReducer.admin,\r\n // userReducer.userEmail,\r\n // ]);\r\n\r\n const renderPaperWrapper = useMemo(() => {\r\n for (let url of customLayoutPaths) {\r\n // this is to avoid the paper wrapper for components that have extra navbar\r\n if (url.test(pathname)) return false;\r\n }\r\n return true; // render the container and paper wrapper if its not in these paths array\r\n }, [pathname]);\r\n\r\n return (\r\n <>\r\n
    \r\n\r\n \r\n
    \r\n \r\n {open ? (\r\n \r\n ) : (\r\n \r\n )}\r\n \r\n
    \r\n \r\n \r\n {navLinks.map(({ path, Icon, title, isAdminLink }, key) =>\r\n // if the link is an admin link, only render if user is admin\r\n isAdminLink ? (\r\n admin && (\r\n \r\n )\r\n ) : (\r\n // else if the link isn't an admin link, just render as it is\r\n \r\n )\r\n )}\r\n \r\n \r\n
    \r\n \r\n {/* show something else in dashboard page */}\r\n {!pathname.includes('/dashboard') ? (\r\n \r\n ) : (\r\n \r\n \r\n Device List ({cameras.length || 0})\r\n \r\n \r\n )}\r\n \r\n\r\n {/* doing this because of the Container component making reports navbar not stick to top */}\r\n {renderPaperWrapper ? (\r\n {children}\r\n ) : (\r\n children\r\n )}\r\n
    \r\n \r\n );\r\n}\r\n\r\n// wrap the parent layout with protectedRoute to check if user is authenticated, no need to wrap the children.\r\nexport default protectedRoute(MeterVibeAppLayout);\r\n\r\nconst DrawerListLink = ({ path, title, Icon }) => (\r\n \r\n \r\n \r\n \r\n \r\n {title}\r\n \r\n \r\n);\r\n\r\nconst PaperWrapper = ({ children, classes }) => (\r\n \r\n \r\n \r\n {/*
    */}\r\n {/* page content goes here */}\r\n {children}\r\n \r\n \r\n \r\n);\r\n","/* eslint-disable */\r\n\r\n// MeterVibe Terms of Service\r\n\r\n// To edit the Terms of Service please use markdown syntax. For more details visit https://www.markdownguide.org/cheat-sheet/\r\n\r\n// to convert doc or docx to markdown, you can use: https://word2md.com/\r\n\r\nconst LAST_MODIFIED_DATE = 'September 29, 2021';\r\n\r\nexport default `\r\n*Last modified: ${LAST_MODIFIED_DATE}*\r\n\r\n**TERMS OF USE**\r\n\r\nThese Terms of Service ("Terms") establish a binding contractual agreement between you (the visitor or user; hereinafter referred to as "you" or "your") and XRobotix LLC. "XRobotix LLC", "our", "us" or "we") according to which you may visit the XRobotix LLC website at [http://metervibe.com](http://metervibe.com/) ("Website", "Site" or "Service") as well as your view and use of any and all hosted software and applications including but not limited to the interactive drawing application, plug-ins, modules and hosting services (the "Hosted Services"; the Website together with the Hosted Services may hereinafter be collectively referred to the "Services"). The Website is owned and operated by XRobotix LLC and all Services are the intellectual property of XRobotix LLC.\r\n\r\n**Description of Service**\r\n\r\nXRobotix LLC located at Suite 100, 189 US 9, Englishtown NJ creates a platform through the Website for selling IOT devices and subscription service for that device, MeterVibe.\r\n\r\nThe Website is offered subject to your acceptance without modification of all of these Terms and all other operating rules, policies (including, without limitation, XRobotix LLC Privacy Policy) and procedures that may be published from time to time on this Website or on or through the Hosted Services by us.\r\n\r\nPlease read these Terms carefully before accessing or using the Services. By accessing or using any of the Services, you expressly agree to become bound by the Terms of Use of these Terms. If you do not agree to all the Terms of Use, then you may not access the Website or use any Hosted Services. If these Terms of Use are considered an offer by XRobotix LLC, acceptance is expressly limited to these Terms.\r\n\r\n**1. Your XRobotix LLC Account.**\r\n\r\nIf you create an account on the Website or as required to access and use the Hosted Services, you are responsible for maintaining the security of your account and its content, and you are fully responsible for all activities that occur under the account and any other actions taken in connection with the Services. You must not describe or assign content to your account in a misleading or unlawful manner, including in a manner intended to trade on the name or reputation of others, and XRobotix LLC may change or remove any content or images that it considers inappropriate or unlawful, or otherwise likely to cause XRobotix LLC liability. You must immediately notify XRobotix LLC of any unauthorized uses of your account any other breaches of security. XRobotix LLC will not be liable for any acts or omissions by you, including any damages of any kind incurred as a result of such acts or omissions.\r\n\r\n**2. Content**\r\n\r\nWithout limiting any of those representations or warranties, XRobotix LLC has the right (though not the obligation) to, in XRobotix LLC sole discretion (i) refuse or remove any content that, in XRobotix LLC reasonable opinion, violates any XRobotix LLC's policy or is in any way harmful or objectionable, or (ii) terminate or deny access to and use of the Services to any individual or entity for any reason, in XRobotix LLC sole discretion.\r\n\r\n**3. Intellectual Property**\r\n\r\nUnless otherwise indicated, the Service is our proprietary property and all source code, databases, functionality, software, website designs, audio, video, text, photographs, and graphics on the Site (collectively, the "Content") and the trademarks, service marks, and logos contained therein (the "Marks") are owned or controlled by us or licensed to us, and are protected by copyright and trademark laws and various other intellectual property rights and unfair competition laws of the United States of America, foreign jurisdictions, and international conventions. The Content and the Marks are provided on the Site "AS IS" for your information and personal use only. Except as expressly provided in these Terms of Use, no part of the Site and no Content or Marks may be copied, reproduced, aggregated, republished, uploaded, posted, publicly displayed, encoded, translated, transmitted, distributed, licensed, or otherwise exploited for any commercial purpose whatsoever, without our express prior written permission.\r\n\r\nProvided that you are eligible to use the Site, you are granted a limited license to access and use the Site and to download or print a copy of any portion of the Content to which you have properly gained access solely for your personal, non-commercial use. We reserve all rights not expressly granted to you in and to the Site, the Content, and the Marks.\r\n\r\n**4. Limitation of Liability**\r\n\r\nTo the extent permitted under applicable law, under no circumstances shall we, our officers, directors, employees, parents, affiliates, successors, assigns, or licensors be liable to you or any other third party for any indirect, special, incidental, or consequential, exemplary or punitive damages of any type including, without limitation, damages for loss of goodwill, service interruption, computer failure or malfunction, loss of business profits, loss of data or business information, loss of additional software or computer configurations or costs of procurement of substitute goods or services, damages arising in connection with any use of the website or any and all other commercial damages or losses, arising out of or in connection with these terms. Notwithstanding anything to the contrary contained herein, in no event shall our total liability (including our officers, directors, employees, parents, and affiliates) for any claim arising out of or related to these terms, to the fullest extent possible under applicable law, exceed the amount paid if any, by you for the use of the services\r\n\r\n**5. Notice**\r\n\r\nWe may provide notice to you by means of e-mail, a general notice on the site, or by other reliable method to the address you have provided to us.\r\n\r\n**6. Indemnification**\r\n\r\nYou agree to indemnify, defend, and hold harmless us, our officers, directors, employees, agents, licensors and suppliers (collectively the "Service Providers") from and against all losses, expenses, damages and costs, including reasonable attorneys' fees, resulting from any violation of these Terms of Use or any activity related to your account (including negligent or wrongful conduct) by you or any other person accessing the site using your Internet account.\r\n\r\n**7. Third-Party Links**\r\n\r\nIn an attempt to provide increased value to our visitors, we may link to sites operated by third parties. However, even if the third party is affiliated with us, we have no control over these linked sites, all of which have separate privacy and data collection practices, independent of us. These\r\n\r\n**8. Responsibility of Website Visitors.**\r\n\r\nXRobotix LLC has not reviewed, and cannot review, all of the material, including computer software, posted to the site, and cannot therefore be responsible for that material's content, use or effects. By operating the site, XRobotix LLC does not represent or imply that it endorses the material there posted, or that it believes such material to be accurate, useful or non- harmful. You are responsible for taking precautions as necessary to protect yourself and your computer systems from viruses, worms, Trojan horses, and other harmful or destructive content. The Website may contain content that is offensive, indecent, or otherwise objectionable, as well as content containing technical inaccuracies, typographical mistakes, and other errors. The site may also contain material that violates the privacy or publicity rights, or infringes the intellectual property and other proprietary rights, of third parties, or the downloading, copying or use of which is subject to additional Terms of Use, stated or unstated. We disclaim any and all responsibility for any harm resulting from the use by visitors of the site, or from any downloading by those visitors of content posted thereon.\r\n\r\n**9. Content Posted on Other Sites.**\r\n\r\nWe have not reviewed, and cannot review, all of the material, including computer software, made available through the sites and webpages to which we link, and that link to us. XRobotix LLC does not have any control over those non XRobotix LLC sites and webpages, and is not responsible for their contents or their use. By linking to a non-XRobotix LLC site or webpage, XRobotix LLC does not represent or imply that it endorses such website or webpage. You are responsible for taking precautions as necessary to protect yourself and your computer systems from viruses, worms, Trojan horses, and other harmful or destructive content. XRobotix LLC disclaims any and all responsibility for any harm resulting from your use of non- XRobotix LLC sites and webpages.\r\n\r\n**10. Changes.**\r\n\r\nXRobotix LLC reserves the right, at its sole discretion, to modify or replace any part of these Terms. It is your responsibility to check these Terms periodically for changes. Your continued use of or access to the Website or Hosted Services following the posting of any changes to these Terms constitutes express acceptance of those changes. XRobotix LLC may also, in the future, offer new services and/or features through the site (including, the release of new tools and resources). Such new features and/or services shall be subject to these Terms.\r\n\r\n**11. Termination.**\r\n\r\nWe may terminate your access to all or any part of the site or your access to any of the Hosted Services at any time, with or without cause, effective immediately. If you wish to terminate your agreement with us or your XRobotix LLC account (if you have one), you may simply discontinue using the Services. Notwithstanding the foregoing, if you have a paid Services account, such account can only be terminated by us if you materially breach these Terms and fail to cure such breach within thirty (30) days from XRobotix LLC notice to you thereof; provided that, we can terminate the Services immediately as part of a general shut down of our service. All provisions of these Terms which by their nature should survive termination shall survive termination, including, without limitation, ownership provisions, warranty disclaimers, indemnity and limitations of liability.\r\n\r\n**12. Disclaimer of Warranties.**\r\n\r\nThe Services are provided "as is". XRobotix LLC and its suppliers and licensors hereby disclaim all warranties of any kind, express or implied, including, without limitation, the warranties of merchantability, fitness for a particular purpose and non-infringement. Neither we nor its suppliers and licensors, makes any warranty that the Services will be error free or that access thereto will be continuous or uninterrupted. You understand that you download from, or otherwise obtain content or services through, the Website at your own discretion and risk.\r\n\r\n**13. General Representation and Warranty.**\r\n\r\nYou represent and warrant that (i) your use of the Services will be in strict accordance with the Privacy Policy, with these Terms and with all applicable laws and regulations (including without limitation any local laws or regulations in your country, state, city, or other governmental area, regarding online conduct and acceptable content, and including all applicable laws regarding the transmission of technical data exported from the United States of America or the country in which you reside) and (ii) your use of the Website or Hosted Services will not infringe or misappropriate the intellectual property rights of any third party.\r\n\r\n**14. Miscellaneous.**\r\n\r\nThese Terms constitute the entire agreement between XRobotix LLC and you concerning the subject matter hereof, and they may only be modified by a written amendment signed by an authorized executive of XRobotix LLC, or by the posting by XRobotix LLC of a revised version of these Terms. Except to the extent applicable law, if any, provides otherwise, these Terms, any access to or use of the Services will be governed by the laws of the United States of America, excluding its conflict of law provisions, and the proper venue for any disputes arising out of or relating to any of the same will be the judicial courts of the United States of America.\r\n `;\r\n","import React from 'react';\r\nimport { useHistory } from 'react-router-dom';\r\nimport { useMediaQuery, Grid, Box } from '@material-ui/core';\r\nimport { makeStyles, useTheme } from '@material-ui/core/styles';\r\nimport PublicLandingHeader from './PublicLandingHeader';\r\nimport PublicLandingFooter from './PublicLandingFooter';\r\nimport { PublicLandingText as PageTitle } from './shared/typography/PublicLandingText';\r\nimport MeterVibeButton from './shared/buttons/MeterVibeButton';\r\n\r\n// markdown\r\nimport markdown from '../markdown/TermsOfServiceMarkdown';\r\nimport ReactMarkdown from 'react-markdown';\r\n\r\nconst COLORS = {\r\n DK_TEXT: '#015388',\r\n DEFAULT_TEXT: '#0272bc',\r\n LIGHT_TEXT: '#3d93cc',\r\n};\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n pageContent: {\r\n flexGrow: 1,\r\n },\r\n\r\n toolbarDistance: theme.mixins.toolbar, // create distance from toolbar.\r\n\r\n innerColumn: {\r\n width: '98%',\r\n maxWidth: '1100px',\r\n marginRight: 'auto',\r\n marginLeft: 'auto',\r\n padding: '10px',\r\n },\r\n\r\n markdown: {\r\n flexGrow: 1,\r\n // minHeight: '100vh',\r\n maxWidth: '100%',\r\n color: COLORS.DK_TEXT,\r\n '& h1': {\r\n fontSize: '48px',\r\n fontWeight: 700,\r\n },\r\n '& h2': {\r\n fontSize: '32px',\r\n fontWeight: 700,\r\n },\r\n '& h3': {\r\n fontSize: '20px',\r\n fontWeight: 700,\r\n lineHeight: '25px',\r\n },\r\n '& h4': {\r\n fontSize: '20px',\r\n fontWeight: 700,\r\n letterSpacing: '1.6pt',\r\n },\r\n '& a, a:active, a:visited': {\r\n color: COLORS.LIGHT_TEXT,\r\n },\r\n },\r\n}));\r\n\r\nexport default function TermsOfService() {\r\n const classes = useStyles();\r\n const history = useHistory();\r\n const theme = useTheme();\r\n const matchesSm = useMediaQuery(theme.breakpoints.down('sm'));\r\n\r\n return (\r\n <>\r\n \r\n \r\n
    \r\n
    \r\n
    \r\n \r\n MeterVibe Terms of Service\r\n \r\n \r\n
    \r\n\r\n \r\n \r\n history.goBack()}\r\n />\r\n \r\n \r\n
    \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n","/* eslint-disable */\r\n\r\n// MeterVibe Privacy Policy\r\n\r\n// To edit the Privacy Policy please use markdown syntax. For more details visit https://www.markdownguide.org/cheat-sheet/\r\n\r\n// to convert doc or docx to markdown, you can use: https://word2md.com/\r\n\r\nconst LAST_MODIFIED_DATE = 'Oct. 15, 2021';\r\n\r\nexport default `\r\n*Last modified: ${LAST_MODIFIED_DATE}*\r\n\r\n\r\n**PRIVACY POLICY**\r\n\r\nThis Privacy Policy describes our policies on the collection, use, and disclosure of information about you in connection with your use of our services (the "Service"). The term "MeterVibe" or "us" or "we" or "our" refers to XRobotix LLC which operates [http://metervibe.com](http://metervibe.com/) website (the "Service").\r\n\r\nWhen you use the Service, you consent to our collection, use, and disclosure of information about you as described in this Privacy Policy.\r\n\r\nThis privacy policy sets out how MeterVibe and our website, [http://metervibe.com](http://metervibe.com/) uses and protects any information that you give MeterVibe while using this website. MeterVibe is committed to ensuring that your privacy is protected. Should we ask you to provide certain information by which you can be identified when using this website, then you can be assured that it will only be used in accordance with this privacy statement. MeterVibe may change this policy from time to time by updating this page. You should check this page from time to time to ensure that you are happy with any changes. This page was last updated on (insert date of website once complete).\r\n\r\n**WHAT WE COLLECT**\r\n\r\nWe may collect the following information from you when you:\r\n\r\n- When registering we may collect your name and contact information including: email address, mailing address, phone number, credit card information, demographic information such as postcode, preferences and interests. However, You may visit our site anonymously.\r\n- Information about gift recipients to enable us fulfill the gift purchase.\r\n- other information relevant to customer surveys and/or offers.\r\n\r\n**HOW WE USE INFORMATION WE COLLECT**\r\n\r\nWe may use the information we collect from you when you register, purchase products, enter a contest or promotion, respond to a survey or marketing communication, surf the website, or use certain other site features in the following ways:\r\n\r\n- provide the Service's functionality,\r\n- fulfill your requests, improve the Service's quality, engage in research and analysis relating to the Service, personalize your experience,\r\n- quickly process your transactions,\r\n- personalize your site experience and to allow us to deliver the type of content and product offerings in which you are most interested,\r\n- display relevant advertising, market the Service,\r\n- track usage of the Service, provide feedback to third party businesses that are listed on the Service,\r\n- provide customer support, message you, back up our systems,\r\n- If you have opted-in to receive our e-mail newsletter, we may send you periodic e-mails. If you would no longer like to receive promotional e-mail from us, please refer to the "How can you opt-out, remove or modify information you have provided to us?" section below. If you have not opted-in to receive e-mail newsletters, you will not receive these e-mails. Visitors who register or participate in other site features such as marketing programs and 'members-only' content will be given a choice whether they would like to be on our e-mail list and receive e-mail communications from us.\r\n- allow for disaster recovery, enhance the security of the Service, and\r\n- comply with legal obligations.\r\n\r\nEven when we do not retain such information, it still must be transmitted to our servers initially and stored long enough to process.\r\n\r\n**SECURITY**\r\n\r\nWe use various safeguards to protect the personal information submitted to us, both during transmission and after we receive it. However, no method of transmission over the Internet or via mobile device, or method of electronic storage, is 100% secure. Therefore, while we strive to use commercially acceptable means to protect your personal information, we cannot guarantee its absolute security.\r\n\r\n**LINKS TO OTHER WEBSITES**\r\n\r\nIn an attempt to provide you with increased value, we may include third party links on our site. These linked sites contain independent and separate privacy policies that we do not have control over. Therefore, we cannot be responsible for the protection and privacy of any information which you provide while visiting such other sites and such sites are not governed by this privacy statement.\r\n\r\nWe therefore have no liability for the content and activities of these linked sites. Nonetheless, we seek to protect the integrity of our site and welcome any feedback about these linked sites. You should exercise caution and look at the privacy statement applicable to the website in question (including if a specific link does not work).\r\n\r\n**CONTROLLING YOUR PERSONAL INFORMATION**\r\n\r\nWe do not sell, trade, or otherwise transfer to outside parties your personally identifiable information unless we notify you in advance, except as described below. The term "outside parties" does not include MeterVibe. It also does not include website hosting partners and other parties who assist us in operating our website, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others' rights, property, or safety.\r\n\r\nHowever, non-personally identifiable visitor information may be provided to other parties for marketing, advertising, or other uses.\r\n\r\nHow can you opt-out, remove or modify information you have provided to us?\r\n\r\nTo modify your e-mail subscriptions, please let us know by modifying your preferences in the "My Account" section. Please note that due to email production schedules you may receive any emails already in production.\r\n\r\n**DATA RETENTION AND ACCOUNT TERMINATION**\r\n\r\nYou may also opt to delete your account. We will remove certain public content from view and/or dissociate them from your account profile, but we may retain information about you for the purposes authorized under this Privacy Policy unless prohibited by law. For example, we may retain information to prevent, investigate, or identify possible wrongdoing in connection with the Service or to comply with legal obligations. We may also maintain residual copies of your personal information in our backup systems. Please note that businesses cannot remove their business pages, ratings, or reviews by closing their accounts.\r\n\r\n**CONTACT INFORMATION**\r\n\r\nYou may contact us concerning our Privacy Policy, or write to us at the following address:\r\n\r\nSuite 100, 189 US 9, Englishtown NJ 07726\r\n\r\n**MODIFICATIONS TO THIS PRIVACY POLICY**\r\n\r\nWe may revise this Privacy Policy from time to time. The most current version of the Privacy Policy will govern our collection, use, and disclosure of information about you. If we make material changes to this Privacy Policy, we will notify you by email or by posting a notice on the Service prior to or on the effective date of the changes. By continuing to access or use the Service after those changes become effective, you acknowledge the revised Privacy Policy.\r\n\r\n**ONLINE POLICY ONLY**\r\n\r\nThis online privacy policy applies only to information collected through our website and not to information collected offline.\r\n `;\r\n","import React from 'react';\r\nimport { useHistory } from 'react-router-dom';\r\nimport { useMediaQuery, Grid, Box } from '@material-ui/core';\r\nimport { makeStyles, useTheme } from '@material-ui/core/styles';\r\nimport PublicLandingHeader from './PublicLandingHeader';\r\nimport PublicLandingFooter from './PublicLandingFooter';\r\nimport { PublicLandingText as PageTitle } from './shared/typography/PublicLandingText';\r\nimport MeterVibeButton from './shared/buttons/MeterVibeButton';\r\n\r\n// markdown\r\nimport markdown from '../markdown/PrivacyPolicyMarkdown';\r\nimport ReactMarkdown from 'react-markdown';\r\n\r\nconst COLORS = {\r\n DK_TEXT: '#015388',\r\n DEFAULT_TEXT: '#0272bc',\r\n LIGHT_TEXT: '#3d93cc',\r\n};\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n pageContent: {\r\n flexGrow: 1,\r\n },\r\n\r\n toolbarDistance: theme.mixins.toolbar, // create distance from toolbar.\r\n\r\n innerColumn: {\r\n width: '98%',\r\n maxWidth: '1100px',\r\n marginRight: 'auto',\r\n marginLeft: 'auto',\r\n padding: '10px',\r\n },\r\n\r\n markdown: {\r\n flexGrow: 1,\r\n // minHeight: '100vh',\r\n maxWidth: '100%',\r\n color: COLORS.DK_TEXT,\r\n '& h1': {\r\n fontSize: '48px',\r\n fontWeight: 700,\r\n },\r\n '& h2': {\r\n fontSize: '32px',\r\n fontWeight: 700,\r\n },\r\n '& h3': {\r\n fontSize: '20px',\r\n fontWeight: 700,\r\n lineHeight: '25px',\r\n },\r\n '& h4': {\r\n fontSize: '20px',\r\n fontWeight: 700,\r\n letterSpacing: '1.6pt',\r\n },\r\n '& a, a:active, a:visited': {\r\n color: COLORS.LIGHT_TEXT,\r\n },\r\n },\r\n}));\r\n\r\nexport default function TermsOfService() {\r\n const classes = useStyles();\r\n const history = useHistory();\r\n const theme = useTheme();\r\n const matchesSm = useMediaQuery(theme.breakpoints.down('sm'));\r\n\r\n return (\r\n <>\r\n \r\n \r\n
    \r\n
    \r\n
    \r\n \r\n MeterVibe Privacy Policy\r\n \r\n \r\n
    \r\n\r\n \r\n \r\n history.goBack()}\r\n />\r\n \r\n \r\n
    \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport {\r\n Grid,\r\n Tab,\r\n Tabs,\r\n useTheme,\r\n useMediaQuery,\r\n makeStyles,\r\n} from '@material-ui/core';\r\n\r\nconst useStyles = makeStyles({\r\n container: {\r\n marginLeft: '0px',\r\n marginRight: '0px',\r\n paddingTop: '20px',\r\n backgroundColor: '#FAFAFA',\r\n borderBottom: '1px solid #999',\r\n marginBottom: '2em',\r\n },\r\n\r\n tab: {\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n },\r\n});\r\n\r\nexport default function ReportsNavbar({ changeToTab, activeTab }) {\r\n const theme = useTheme();\r\n const matchesXs = useMediaQuery(theme.breakpoints.down('xs'));\r\n const classes = useStyles();\r\n\r\n return (\r\n <>\r\n \r\n \r\n changeToTab('UsageOverview')}\r\n />\r\n\r\n changeToTab('Readings')}\r\n />\r\n\r\n {/* changeToTab('PerAppliances')}\r\n /> */}\r\n\r\n {/* changeToTab('CustomReports')}\r\n /> */}\r\n \r\n \r\n \r\n );\r\n}\r\n","import moment from 'moment';\r\n\r\nexport const periodDates = (startPeriodDate, periodType = 'month') => {\r\n // TODO: do it for all period types, not just monthly.\r\n\r\n const startDateResult = moment(startPeriodDate).startOf(periodType);\r\n const endDateResult = moment(startPeriodDate).endOf(periodType);\r\n\r\n return [startDateResult, endDateResult];\r\n};\r\n\r\nexport const addRealMonth = (d) => {\r\n let futureMonth = moment(d).add(1, 'M');\r\n let futureMonthEnd = moment(futureMonth).endOf('month');\r\n return d.date() !== futureMonth.date() &&\r\n futureMonth.isSame(futureMonthEnd.format('YYYY-MM-DD'))\r\n ? futureMonth.add(1, 'd')\r\n : futureMonth;\r\n};\r\n\r\nexport const nextPeriodDates = (\r\n currentStartPeriodDate,\r\n currentEndPeriodDate,\r\n periodType = 'month'\r\n) => {\r\n let nextStartPeriodDate;\r\n let nextEndPeriodDate;\r\n\r\n if (periodType === 'month') {\r\n nextStartPeriodDate = addRealMonth(currentStartPeriodDate);\r\n nextEndPeriodDate = moment(nextStartPeriodDate).endOf('month');\r\n } else {\r\n nextStartPeriodDate = moment(currentStartPeriodDate).add(1, periodType);\r\n nextEndPeriodDate = moment(currentEndPeriodDate).add(1, periodType);\r\n }\r\n\r\n return [nextStartPeriodDate, nextEndPeriodDate];\r\n};\r\n\r\n// latestImagesAtBottom of arr.\r\n\r\n//use the point to the left and the right and take average delta\r\n//then add in first point, delta to right, and last point delta to left\r\n//ts = [[timestamp, value] ....[timestamp,value]]\r\nexport const computeDeltas = (tSeries) => {\r\n let result = [];\r\n const millisecsToHours = 1000 * 60 * 60;\r\n //first entry is (v(n+1) - v(n))/(t(n+1)-t(n))\r\n result.push([\r\n tSeries[0][0], //t(0)\r\n (millisecsToHours * (tSeries[1][1] - tSeries[0][1])) /\r\n (tSeries[1][0] - tSeries[0][0]), //\r\n ]);\r\n for (let idx = 1; idx < tSeries.length - 1; idx++) {\r\n result.push([\r\n tSeries[idx][0], //t(idx)\r\n (millisecsToHours * (tSeries[idx + 1][1] - tSeries[idx - 1][1])) /\r\n (tSeries[idx + 1][0] - tSeries[idx - 1][0]),\r\n ]);\r\n }\r\n //now the last entry is delta with next to l\r\n result.push([\r\n tSeries[tSeries.length - 1][0], //t(0)\r\n (millisecsToHours *\r\n (tSeries[tSeries.length - 1][1] - tSeries[tSeries.length - 2][1])) /\r\n (tSeries[tSeries.length - 1][0] - tSeries[tSeries.length - 2][0]), //\r\n ]);\r\n return result;\r\n};\r\n\r\n//remove outliers from this sublist\r\n//outlier is great than 2X the first and last quartile\r\n//[[timestamp,value].....[timestamp,value]]\r\nexport const removeOutliers = (sublistArray) => {\r\n const len = sublistArray.length;\r\n const lowerQuartileIdx = parseInt(len / 4);\r\n const upperQuartileIdx = parseInt((3 * len) / 4);\r\n //sort by the second 'value' element\r\n sublistArray.sort(function (a, b) {\r\n return a[1] - b[1];\r\n });\r\n const lowerBound = 0.5 * sublistArray[lowerQuartileIdx][1];\r\n const upperBound = 2 * sublistArray[upperQuartileIdx][1];\r\n // console.log(\r\n // 'sublist filtering, sublist, len, lowerBound, upperBound:',\r\n // sublistArray,\r\n // len,\r\n // lowerBound,\r\n // upperBound\r\n // );\r\n //sort back to timestamp order (works without function arg)\r\n sublistArray.sort(function (a, b) {\r\n return a[0] - b[0];\r\n });\r\n //remove outliers if not in bound range (2X)\r\n const filtered = sublistArray.filter(function (value, index, arr) {\r\n return value[1] > lowerBound && value[1] < upperBound;\r\n });\r\n return filtered;\r\n};\r\n\r\nexport const createDeltaProperties = (imgList) => {\r\n for (let i = 0; i < imgList.length - 1; i++) {\r\n //if (isNaN(imgList[i].digits)) { //looks like chart ignore null values\r\n // imgList[i].digits = 100; //temporary solution so no Null data\r\n //}\r\n imgList[i].deltaDigits = imgList[i].digits - imgList[i + 1].digits;\r\n imgList[i].deltaTimeMS =\r\n imgList[i].timestampSaved - imgList[i + 1].timestampSaved;\r\n }\r\n\r\n return imgList;\r\n};\r\n","import React, { useCallback, useState } from 'react';\r\nimport { useDispatch, useSelector } from 'react-redux';\r\n\r\n// components\r\nimport {\r\n Grid,\r\n makeStyles,\r\n Typography,\r\n // Button,\r\n useTheme,\r\n useMediaQuery,\r\n} from '@material-ui/core';\r\nimport ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup';\r\nimport ToggleButton from '@material-ui/lab/ToggleButton';\r\nimport MeterVibeButtonPrimary from './../shared/buttons/MeterVibeButtonPrimary';\r\nimport MeterVibeButtonSecondary from './../shared/buttons/MeterVibeButtonSecondary';\r\n\r\n// services\r\nimport { deleteTimestamp } from './../../services/cameras.services';\r\n\r\n// utils\r\nimport { REPORTS_ACTIONS } from './../../reducers/reports.reducer';\r\nimport moment from 'moment';\r\nimport { addRealMonth } from '../../utils/Reports.utils';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n buttonGroup: {\r\n // all children (buttons) inside button group\r\n '& > *': {\r\n fontSize: '12px !important',\r\n fontFamily: ['Public Sans', 'Roboto', 'Sans-Serif'].join(','), // fallbacks\r\n backgroundColor: '#F5F5F5',\r\n color: '#000',\r\n\r\n // have to do it this way to override Mui defaults.\r\n borderRight: '1px solid #3D93CC !important',\r\n borderLeft: '1px solid #3D93CC !important',\r\n borderTop: '1px solid #3D93CC !important',\r\n borderBottom: '1px solid #3D93CC !important',\r\n transition: 'all 250ms ease-in-out',\r\n\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n '&:hover': {\r\n background: '#fff',\r\n color: '#3D93CC',\r\n },\r\n '&.Mui-selected': {\r\n // selected button\r\n background: '#3D93CC',\r\n color: '#fff',\r\n\r\n '&:hover': {\r\n background: '#3D93CC',\r\n color: '#fff',\r\n },\r\n },\r\n },\r\n },\r\n sectionTitle: {\r\n userSelect: 'none',\r\n },\r\n updateInfoButton: {\r\n backgroundColor: 'rgb(2,114,188)',\r\n background:\r\n 'linear-gradient(90deg, rgba(2,114,188,1) 0%, rgba(1,83,136,1) 100%)',\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n },\r\n titleHidden: {\r\n visibility: 'hidden',\r\n userSelect: 'none',\r\n },\r\n}));\r\n\r\nconst {\r\n TOGGLE_SELECT_MODE_ENABLED,\r\n CLEAR_ALL_SELECTED_ROWS,\r\n SELECT_ALL_ROWS,\r\n DELETE_SELECTED_ROWS,\r\n SET_START_DATE,\r\n SET_END_DATE,\r\n SET_PERIOD_TYPE,\r\n RESET_TIME,\r\n} = REPORTS_ACTIONS;\r\n\r\nexport default function ReportsFilters({ cameraId }) {\r\n const [selectButtonsDisabled, setSelectButtonsDisabled] = useState(false);\r\n\r\n const [{ pageState, isSelectModeEnabled, selectedRows }, { admin }] =\r\n useSelector(({ reportsReducer, userReducer }) => [\r\n reportsReducer,\r\n userReducer,\r\n ]);\r\n\r\n const dispatch = useDispatch();\r\n\r\n const toggleSelectMode = useCallback(() => {\r\n dispatch({ type: TOGGLE_SELECT_MODE_ENABLED });\r\n }, [dispatch]);\r\n\r\n const onDeleteClick = async () => {\r\n setSelectButtonsDisabled(true);\r\n\r\n for await (const timestamp of selectedRows) {\r\n const result = await deleteTimestamp(cameraId, timestamp);\r\n\r\n if (result.status === true) {\r\n setTimeout(() => {\r\n dispatch({ type: DELETE_SELECTED_ROWS }); // delete rows on front end and render new state in UI\r\n }, 20);\r\n }\r\n }\r\n\r\n setSelectButtonsDisabled(false);\r\n };\r\n\r\n const selectAllItems = useCallback(() => {\r\n dispatch({ type: SELECT_ALL_ROWS });\r\n }, [dispatch]);\r\n\r\n const unSelectAllItems = useCallback(() => {\r\n dispatch({ type: CLEAR_ALL_SELECTED_ROWS });\r\n }, [dispatch]);\r\n\r\n // don't render if in readings tab and is not admin (admin can see select buttons in readings page)\r\n if (pageState.readingsTabSelected && !admin) return null;\r\n\r\n return (\r\n \r\n {/* first row */}\r\n\r\n \r\n \r\n {/* don't show date filters if in readings tab */}\r\n {!pageState.readingsTabSelected && }\r\n {/* only show period view buttons when there is a chart. */}\r\n {pageState.showChart && }\r\n \r\n\r\n {/* enable/disable select mode in readings page */}\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nconst DateFilters = () => {\r\n const classes = useStyles();\r\n const { startDate, endDate, chartData } = useSelector(\r\n ({ reportsReducer }) => reportsReducer\r\n );\r\n const dispatch = useDispatch();\r\n\r\n const minimumDate = moment(chartData[1][0]).format('YYYY-MM-DD') ?? moment();\r\n\r\n return (\r\n \r\n \r\n Select time period\r\n \r\n \r\n \r\n \r\n dispatch({ type: SET_START_DATE, payload: event.target.value })\r\n }\r\n style={{ width: '100%', height: '36px' }}\r\n />\r\n \r\n \r\n \r\n dispatch({ type: SET_END_DATE, payload: event.target.value })\r\n }\r\n style={{ width: '100%', height: '36px' }}\r\n />\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst SelectModeButtons = ({\r\n render,\r\n selectAllItems,\r\n unSelectAllItems,\r\n onDeleteClick,\r\n toggleSelectMode,\r\n isSelectModeEnabled,\r\n selectButtonsDisabled,\r\n}) => {\r\n const [allItemsSelected, setAllItemsSelected] = useState(false);\r\n\r\n if (!render) return null;\r\n return (\r\n \r\n {isSelectModeEnabled ? (\r\n <>\r\n \r\n  \r\n {\r\n if (allItemsSelected) {\r\n unSelectAllItems();\r\n setAllItemsSelected(false);\r\n } else {\r\n selectAllItems();\r\n setAllItemsSelected(true);\r\n }\r\n }}\r\n />\r\n  \r\n \r\n \r\n ) : (\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nconst PeriodTypeButtons = () => {\r\n const { currentPeriodType, startDate } = useSelector(\r\n ({ reportsReducer }) => reportsReducer\r\n );\r\n const dispatch = useDispatch();\r\n const classes = useStyles();\r\n const theme = useTheme();\r\n const matchesXs = useMediaQuery(theme.breakpoints.down('xs'));\r\n\r\n return (\r\n \r\n \r\n Period view\r\n \r\n\r\n {\r\n if (newValue === 'all') {\r\n dispatch({\r\n type: SET_END_DATE,\r\n payload: addRealMonth(moment(startDate)).format('YYYY-MM-DD'),\r\n });\r\n }\r\n\r\n if (newValue === 'reset') {\r\n return dispatch({ type: RESET_TIME });\r\n }\r\n\r\n dispatch({ type: SET_PERIOD_TYPE, payload: newValue });\r\n }}\r\n exclusive\r\n orientation={matchesXs ? 'vertical' : 'horizontal'}>\r\n \r\n All\r\n \r\n \r\n Daily\r\n \r\n \r\n Weekly\r\n \r\n \r\n Monthly\r\n \r\n\r\n \r\n Reset\r\n \r\n \r\n \r\n );\r\n};\r\n","import React from 'react';\r\nimport { Chart } from 'react-google-charts';\r\nimport { Grid } from '@material-ui/core';\r\n\r\nexport default function ReportsChart({ data, chartType, render, unitsLabel }) {\r\n return (\r\n \r\n \r\n {/* ****************** Bar Chart ****************** */}\r\n {render && (\r\n Loading Chart
    }\r\n data={data}\r\n options={{\r\n colors: ['#3d93cc'],\r\n hAxis: {\r\n title: 'Date/Time',\r\n format: 'MM yyyy',\r\n },\r\n vAxis: {\r\n title: unitsLabel,\r\n },\r\n chart: {},\r\n }}\r\n />\r\n )}\r\n
    \r\n
    \r\n );\r\n}\r\n","import React, { memo, useMemo, useState, useCallback, useEffect } from 'react';\r\nimport { makeStyles } from '@material-ui/core';\r\nimport { useTable, usePagination } from 'react-table';\r\nimport { useDispatch, useSelector } from 'react-redux';\r\n\r\n// components\r\nimport Table from '@material-ui/core/Table';\r\nimport Tooltip from '@material-ui/core/Tooltip';\r\nimport TableBody from '@material-ui/core/TableBody';\r\nimport TableCell from '@material-ui/core/TableCell';\r\nimport TableContainer from '@material-ui/core/TableContainer';\r\nimport TableHead from '@material-ui/core/TableHead';\r\nimport TableRow from '@material-ui/core/TableRow';\r\nimport TableFooter from '@material-ui/core/TableFooter';\r\nimport TablePagination from '@material-ui/core/TablePagination';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport ImageDetailsModal from '../../components/modals/camera_modals/ImageDetailsModal';\r\n\r\n// utils/services\r\nimport { putDigits } from './../../services/images.services';\r\nimport moment from 'moment';\r\nimport 'moment-timezone';\r\nimport { REPORTS_ACTIONS } from './../../reducers/reports.reducer';\r\n\r\n// icons\r\nimport FirstPageIcon from '@material-ui/icons/FirstPage';\r\nimport LastPageIcon from '@material-ui/icons/LastPage';\r\nimport KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft';\r\nimport KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n width: '100%',\r\n },\r\n tableContainer: {\r\n maxHeight: 500,\r\n },\r\n tableFooterRow: {\r\n display: 'flex',\r\n },\r\n paginationSpacer: {\r\n flex: '1 1 100%',\r\n [theme.breakpoints.down('md')]: {\r\n flex: '0 0',\r\n },\r\n },\r\n paginationActions: {\r\n flexShrink: 0,\r\n marginLeft: theme.spacing(2.5),\r\n [theme.breakpoints.down('sm')]: {\r\n flexShrink: 1, // direction buttons in a column in small screen\r\n },\r\n },\r\n}));\r\n\r\nconst Linebreak = ({ value }) => {\r\n // add in the style to \\n containing string to have multiple lines in cell\r\n return {value};\r\n};\r\n\r\n// Create an editable cell renderer\r\n//https://stackoverflow.com/questions/57419197/react-table-with-hooks-looses-focus-on-input-inside-table\r\n// this component is the cell for editing the digits (admin only)\r\nconst EditDigitsCell = memo(\r\n ({\r\n value: initialValue,\r\n row,\r\n column,\r\n handleCellInputChange, // This is a custom function that we supplied to our table instance\r\n }) => {\r\n // We need to keep and update the state of the cell normally\r\n const [value, setValue] = useState(initialValue);\r\n\r\n const onChange = (e) => {\r\n setValue(e.target.value);\r\n };\r\n\r\n // We'll only update the external data when the input is blurred\r\n const onBlur = async () => {\r\n await putDigits(\r\n value,\r\n row.original.cameraId,\r\n row.original.timestampSaved\r\n ); // update data in db when input is blurred\r\n\r\n handleCellInputChange(row, column, value); // rerender the page with the new state.\r\n };\r\n\r\n return ;\r\n }\r\n);\r\n\r\nconst { ROW_SELECTED, CLEAR_ALL_SELECTED_ROWS, SET_READINGS_DATA } =\r\n REPORTS_ACTIONS;\r\n\r\n// TABLE\r\nexport default function ReportsReadingsTable() {\r\n const classes = useStyles();\r\n const [isImageModalOpen, setIsImageModalOpen] = useState(false);\r\n const dispatch = useDispatch();\r\n\r\n const [\r\n {\r\n imagesList,\r\n startDate,\r\n endDate,\r\n selectedRows,\r\n isSelectModeEnabled,\r\n readingsData,\r\n pageState,\r\n reportInfo,\r\n isLoading,\r\n userSelectedCamera,\r\n },\r\n { admin },\r\n ] = useSelector(({ reportsReducer, userReducer }) => [\r\n reportsReducer,\r\n userReducer,\r\n ]);\r\n\r\n useEffect(() => {\r\n // clear all selected rows when select mode is disabled (kinda like how gmail clears all selected rows when disabling).\r\n if (!isSelectModeEnabled) {\r\n dispatch({ type: CLEAR_ALL_SELECTED_ROWS });\r\n }\r\n }, [isSelectModeEnabled, dispatch]);\r\n\r\n const showImageModal = useCallback(\r\n (timestampSaved) => setIsImageModalOpen(timestampSaved),\r\n [setIsImageModalOpen]\r\n );\r\n const closeImageModal = useCallback(\r\n () => setIsImageModalOpen(false),\r\n [setIsImageModalOpen]\r\n );\r\n\r\n // When our cell renderer calls handleCellInputChange, we'll use\r\n // the rowIndex, columnID and new value to update the\r\n // original data\r\n const handleCellInputChange = useCallback(\r\n (row, column, value) => {\r\n const newReadingsData = [...readingsData].map((item, index) => {\r\n if (index === row.index) {\r\n return {\r\n ...readingsData[row.index],\r\n [column.id]: value,\r\n };\r\n }\r\n return item;\r\n });\r\n\r\n dispatch({ type: SET_READINGS_DATA, payload: newReadingsData });\r\n },\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [readingsData]\r\n );\r\n\r\n useEffect(() => {\r\n // sorted imagesList that is filterable by date for readings table.\r\n\r\n const filteredReadingsData = imagesList\r\n .filter(({ timestampSaved }) => {\r\n let dateToCheck = moment(timestampSaved).format('YYYY-MM-DD');\r\n return moment(dateToCheck).isBetween(\r\n startDate,\r\n endDate,\r\n null, // can be year, month .... the granularity of your comaprison\r\n '[]' // inclusive in range\r\n );\r\n })\r\n .sort((a, b) => {\r\n // latest date first.\r\n // Sort the dates in descending order:\r\n return b.timestampSaved - a.timestampSaved;\r\n });\r\n\r\n dispatch({ type: SET_READINGS_DATA, payload: filteredReadingsData });\r\n\r\n // do it everytime these vars change.\r\n }, [startDate, endDate, imagesList, pageState, userSelectedCamera]); // eslint-disable-line react-hooks/exhaustive-deps\r\n\r\n const handleSelectRow = useCallback(\r\n (rowInfo) => {\r\n if (!isSelectModeEnabled) return;\r\n\r\n dispatch({ type: ROW_SELECTED, payload: rowInfo });\r\n },\r\n [isSelectModeEnabled, dispatch]\r\n );\r\n\r\n const rowFn = (rowInfo) => {\r\n return {\r\n onClick: (e, handleOriginal) => {\r\n console.log('It was in this row:', rowInfo);\r\n\r\n if (admin) {\r\n // only select row if user is an admin\r\n handleSelectRow(rowInfo);\r\n }\r\n // IMPORTANT! React-Table uses onClick internally to trigger\r\n // events like expanding SubComponents and pivots.\r\n // By default a custom 'onClick' handler will override this functionality.\r\n // If you want to fire the original onClick handler, call the\r\n // 'handleOriginal' function.\r\n\r\n // if (handleOriginal) {\r\n // handleOriginal();\r\n // }\r\n },\r\n };\r\n };\r\n\r\n const columns = useMemo(\r\n () => [\r\n // {\r\n // Header: \"Id\",\r\n // accessor: \"cameraId\", // String-based value accessors!\r\n // width: 70\r\n // },\r\n {\r\n Header: 'Date',\r\n width: 200,\r\n id: 'time',\r\n accessor: ({ timestampSaved }) =>\r\n moment(timestampSaved).format('hh:mm A MM/DD/YYYY'), //this gets the date formated\r\n\r\n Cell: (row) => , //format as 2 lines using \\n\r\n },\r\n {\r\n Header: 'Image',\r\n width: 280,\r\n Cell: ({ row }) => {\r\n let reading = (\r\n Number(row.original.digits) * Number(reportInfo.reportMult)\r\n ).toFixed(Math.max(0, -Math.log10(reportInfo.reportMult))); //set number of decimal places\r\n\r\n reading = Number(reading).toLocaleString(); // add commas with to localeString()\r\n\r\n return (\r\n <>\r\n \r\n
    \r\n showImageModal(row.original.timestampSaved)}\r\n height={40}\r\n alt=\"SignedUrl\"\r\n src={row.original.SignedUrl}\r\n />\r\n
    \r\n
    \r\n \r\n \r\n );\r\n },\r\n id: 'Image',\r\n },\r\n {\r\n Header: 'Digits', //props => Friend Age, // Custom header components!\r\n width: 100,\r\n accessor: 'digits',\r\n Cell: ({ cell, handleCellInputChange, data }) => {\r\n // makes this editable (renderEditable)\r\n const { row, column } = cell;\r\n const cellValue = data[row?.index][column?.id] || ''; // or could use undefined\r\n\r\n return admin ? (\r\n \r\n ) : (\r\n {cellValue}\r\n );\r\n }, //allow user to edit this cell\r\n },\r\n {\r\n // Gallons\r\n Header: `${reportInfo.reportLabel}`, // Gallons\r\n width: 100,\r\n id: 'reading',\r\n //accessor: d => new Date(d.timestampSaved).toDateString()\r\n //\"timestampSaved\",\r\n accessor: (d) => {\r\n // d.digits comes back as a string in response...\r\n let gallons = (\r\n Number(d.digits) * Number(reportInfo.reportMult)\r\n ).toFixed(Math.max(0, -Math.log10(reportInfo.reportMult))); //set number of decimal places\r\n\r\n return Number(gallons).toLocaleString(); // add commas with to localeString()\r\n },\r\n\r\n //Cell: props => {props.value} // Custom cell components!\r\n },\r\n {\r\n Header: 'Delta',\r\n width: 70,\r\n id: 'delta',\r\n //accessor: d => new Date(d.timestampSaved).toDateString()\r\n //\"timestampSaved\",\r\n accessor: (d) => {\r\n return `${(d.deltaDigits * reportInfo.reportMult)\r\n .toFixed(Math.max(0, -Math.log10(reportInfo.reportMult))) //set number of decimal places\r\n .toLocaleString()}`;\r\n },\r\n //Cell: props => {props.value} // Custom cell components!\r\n },\r\n {\r\n Header: 'Mins',\r\n width: 70,\r\n id: 'mins',\r\n //accessor: d => new Date(d.timestampSaved).toDateString()\r\n //\"timestampSaved\",\r\n accessor: (d) =>\r\n `${(d.deltaTimeMS / 1000 / 60).toFixed(1).toLocaleString()}`,\r\n\r\n //Cell: props => {props.value} // Custom cell components!\r\n },\r\n {\r\n Header: 'Per Hour',\r\n width: 70,\r\n id: 'flow',\r\n //accessor: d =>\r\n // `${((60 * d.deltaDigits) / d.deltaTimeMS).toLocaleString()}`,\r\n Cell: ({ row }) => {\r\n return (\r\n \r\n {((row.values.delta * 60) / row.values.mins).toFixed(2)}\r\n \r\n ); // Custom cell components!\r\n },\r\n },\r\n ],\r\n // check for these dependencies changing to rerender the data.\r\n // eslint-disable-next-line\r\n [\r\n reportInfo,\r\n admin,\r\n closeImageModal,\r\n isImageModalOpen,\r\n showImageModal,\r\n readingsData,\r\n userSelectedCamera,\r\n ]\r\n );\r\n\r\n const {\r\n gotoPage,\r\n setPageSize,\r\n // canPreviousPage,\r\n // canNextPage,\r\n pageOptions,\r\n state: { pageIndex, pageSize },\r\n getTableProps,\r\n getTableBodyProps,\r\n headerGroups,\r\n page: rows, // Instead of using 'rows', we'll use page,\r\n // which has only the rows for the active page\r\n prepareRow,\r\n } = useTable(\r\n {\r\n columns,\r\n data: readingsData,\r\n handleCellInputChange,\r\n autoResetPage: false, // When making changes to the external data you want to disable automatic resets to the state of the table\r\n initialState: { pageIndex: 0, pageSize: 100 },\r\n },\r\n usePagination\r\n ); // react-table hooks\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {headerGroups.map((headerGroup) => (\r\n // table headers\r\n \r\n {headerGroup.headers.map((column) => {\r\n return (\r\n \r\n {column.render('Header')}\r\n \r\n );\r\n })}\r\n \r\n ))}\r\n \r\n \r\n {rows.map((row, i) => {\r\n prepareRow(row);\r\n // table rows\r\n const isSelected = selectedRows.includes(\r\n row.original.timestampSaved\r\n );\r\n\r\n const selectedRowColorPrimary = '#357DAD';\r\n const selectedRowColorSecondary = '#FFF';\r\n\r\n return (\r\n \r\n {row.cells.map((cell, i) => {\r\n return (\r\n // cell of row.\r\n \r\n {cell.render('Cell')}\r\n \r\n );\r\n })}\r\n \r\n );\r\n })}\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n {/* PAGINATION */}\r\n\r\n {/* Material UI TablePagination component */}\r\n {!isLoading && (\r\n \r\n `${pageIndex + 1}-${pageOptions.length} of ${\r\n pageOptions.length\r\n }`\r\n }\r\n classes={{ spacer: classes.paginationSpacer }}\r\n onRowsPerPageChange={(e) => setPageSize(Number(e.target.value))}\r\n ActionsComponent={(props) => (\r\n \r\n )}\r\n />\r\n )}\r\n \r\n \r\n
    \r\n \r\n );\r\n}\r\n\r\nconst TableActions = (props) => {\r\n const { /*count, */ page, /*rowsPerPage*/ onPageChange, pageOptions } = props;\r\n const classes = useStyles();\r\n\r\n const canGoNext = page < pageOptions.length - 1;\r\n const canGoBack = page > 0;\r\n\r\n const handleFirstPageButtonClick = () => {\r\n onPageChange(0);\r\n };\r\n\r\n const handleBackButtonClick = () => {\r\n // if (!canPreviousPage) return;\r\n if (!canGoBack) return;\r\n const previousPage = page - 1;\r\n onPageChange(previousPage);\r\n };\r\n\r\n const handleNextButtonClick = () => {\r\n // if (!canNextPage) return;\r\n if (!canGoNext) return;\r\n\r\n const nextPage = page + 1;\r\n onPageChange(nextPage);\r\n };\r\n\r\n const handleLastPageButtonClick = () => {\r\n // onPageChange(Math.max(0, Math.ceil(count / rowsPerPage) - 1));\r\n onPageChange(pageOptions.length - 1);\r\n };\r\n\r\n return (\r\n
    \r\n \r\n \r\n \r\n \r\n \r\n \r\n = Math.ceil(count / rowsPerPage) - 1}\r\n disabled={!canGoNext}\r\n aria-label=\"next page\">\r\n \r\n \r\n = Math.ceil(count / rowsPerPage) - 1}\r\n disabled={!canGoNext}\r\n aria-label=\"last page\">\r\n \r\n \r\n
    \r\n );\r\n};\r\n","import React, { useState, useEffect, useCallback } from 'react';\r\nimport { useSelector, useDispatch } from 'react-redux';\r\nimport {\r\n Paper,\r\n Container,\r\n makeStyles,\r\n Grid,\r\n CircularProgress,\r\n Typography,\r\n Box,\r\n} from '@material-ui/core';\r\nimport moment from 'moment';\r\n\r\n// core components\r\nimport ReportsNavbar from '../components/reports_components/ReportsNavbar';\r\nimport ReportsFilters from '../components/reports_components/ReportsFilters';\r\nimport ReportsChart from '../components/reports_components/ReportsChart';\r\nimport ReportsReadingsTable from '../components/reports_components/ReportsReadingsTable';\r\n\r\n// services\r\nimport { getReportOnlyParams } from './../services/reports.services';\r\nimport { getAllImagesListProc } from '../services/images.services';\r\n\r\n// utils\r\nimport { REPORTS_ACTIONS } from './../reducers/reports.reducer';\r\nimport {\r\n removeOutliers,\r\n computeDeltas,\r\n nextPeriodDates,\r\n periodDates,\r\n createDeltaProperties,\r\n} from '../utils/Reports.utils';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n paper: {\r\n // padding: theme.spacing(2),\r\n display: 'flex',\r\n flexDirection: 'column',\r\n height: '100%',\r\n },\r\n container: {\r\n paddingTop: theme.spacing(4),\r\n paddingBottom: theme.spacing(4),\r\n },\r\n selectTable: {\r\n // this does nothing\r\n '&.rt-tr': {\r\n fontSize: '10px',\r\n fontWeight: 'bold',\r\n fontFamily: 'montserrat',\r\n },\r\n },\r\n}));\r\n\r\nconst PageSection = ({ children, marginBottom, gridItemStyles }) => {\r\n const classes = useStyles();\r\n return (\r\n \r\n \r\n \r\n {children}\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst {\r\n SET_PAGE_STATE,\r\n SET_BAR_CHART_DATA,\r\n SET_IS_LOADING,\r\n SET_CHART_DATA,\r\n SET_CAMERA_DATA,\r\n SET_IMAGES_LIST,\r\n SET_REPORT_INFO,\r\n SET_START_DATE,\r\n} = REPORTS_ACTIONS;\r\n\r\nexport default function Reports() {\r\n const dispatch = useDispatch();\r\n\r\n const [userSelectedCamera, reportsState] = useSelector(\r\n ({ camerasReducer, reportsReducer }) => [\r\n camerasReducer.userSelectedCamera,\r\n reportsReducer,\r\n ]\r\n );\r\n\r\n // using a reports reducer to remove some clutter\r\n const {\r\n pageState,\r\n activeTab,\r\n barChartData,\r\n isLoading,\r\n chartData,\r\n cameraData,\r\n reportInfo,\r\n startDate,\r\n endDate,\r\n currentPeriodType,\r\n } = reportsState;\r\n\r\n const setIsLoading = useCallback(\r\n (payload) => dispatch({ type: SET_IS_LOADING, payload }),\r\n [dispatch]\r\n );\r\n\r\n const classes = useStyles();\r\n\r\n // const [flowData, setFlowData] = useState([]); // we're not using flowData for now.\r\n\r\n const [noData, setNoData] = useState(false);\r\n\r\n const handlePeriodicFilter = useCallback(\r\n (data, startDate, label = 'Gallons', periodType = 'month') => {\r\n /* \r\n data = [\r\n ['timestamp', 'value'],\r\n [Sat Jan 09 2021 22:00:22 GMT-0500 (Eastern Standard Time), 740161.93],\r\n [Sun Jan 10 2021 03:00:22 GMT-0500 (Eastern Standard Time), 740161.93]\r\n ]\r\n */\r\n const result = [['Date/Time', label, 'Deltas']];\r\n\r\n if (periodType === 'all') {\r\n for (let i = 1; i < data.length; i++) {\r\n let [currentTimestamp, currentDigits] = data[i];\r\n currentTimestamp = moment(currentTimestamp);\r\n\r\n if (currentTimestamp.isAfter(moment(endDate))) {\r\n break;\r\n }\r\n\r\n if (!currentTimestamp.isBetween(moment(startDate), moment(endDate))) {\r\n continue;\r\n }\r\n\r\n const [, previousDigits] = result[result.length - 1];\r\n const delta = currentDigits - (previousDigits ?? 0);\r\n\r\n result.push([new Date(currentTimestamp), currentDigits, delta]);\r\n }\r\n\r\n console.log('periodType all result', result);\r\n\r\n // so we get an expected result but for some reason it's not being reflected on the graph\r\n return result;\r\n }\r\n\r\n let [startPeriodDate, endPeriodDate] = periodDates(\r\n moment(startDate),\r\n periodType\r\n );\r\n\r\n for (let i = 1; i < data.length; i++) {\r\n let [currentTimestamp, currentDigits] = data[i];\r\n currentTimestamp = moment(currentTimestamp);\r\n\r\n // past the end of our date range so return the answer\r\n if (currentTimestamp.isAfter(moment(endDate))) {\r\n // return result;\r\n break;\r\n }\r\n\r\n // found a date to use in this period\r\n if (currentTimestamp.isBetween(startPeriodDate, endPeriodDate)) {\r\n // result.push([new Date(currentTimestamp), currentDigits]);\r\n\r\n const [, previousDigits] = result[result.length - 1];\r\n\r\n const delta = currentDigits - (previousDigits ?? 0);\r\n\r\n result.push([new Date(startPeriodDate), currentDigits, delta]);\r\n\r\n [startPeriodDate, endPeriodDate] = nextPeriodDates(\r\n startPeriodDate,\r\n endPeriodDate,\r\n periodType\r\n );\r\n\r\n continue;\r\n }\r\n\r\n // no date date found within our current period, advanced into the next period\r\n if (currentTimestamp.isAfter(endPeriodDate)) {\r\n if (i - 1 > 0) {\r\n const [, prevResultDigits] = result[result.length - 1];\r\n\r\n const delta = currentDigits - (prevResultDigits ?? 0);\r\n\r\n const [, previousDigits] = data[i - 1];\r\n // result.push(data[i - 1]); // push previous timestamp and digits\r\n result.push([new Date(startPeriodDate), previousDigits, delta]);\r\n }\r\n\r\n [startPeriodDate, endPeriodDate] = nextPeriodDates(\r\n startPeriodDate,\r\n endPeriodDate,\r\n periodType\r\n ); // next time through loop look for the next period entry\r\n }\r\n }\r\n\r\n return result;\r\n },\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [endDate, barChartData, currentPeriodType]\r\n );\r\n\r\n //removes outlier data before diplaying the chart\r\n const cleanData = useCallback((imagesList) => {\r\n // console.log('cleaning data', imagesList, 'length list:', imagesList.length);\r\n let noZerosList = imagesList\r\n //reverse the order to earliest time to latest\r\n //also reverses input list imagesList\r\n .reverse()\r\n //filter out no digits value, or value=0\r\n .filter((elt) => 'digits' in elt && parseInt(elt.digits) > 0)\r\n //replce the digits string with integer\r\n .map((elt) => [elt.timestampSaved, parseInt(elt.digits)]);\r\n\r\n // if (noZerosList <= 0) {\r\n // setNoData(true);\r\n // return imagesList;\r\n // }\r\n\r\n console.log('with no Zeros, length is:', noZerosList.length);\r\n //group in groups of 20 data points\r\n let lIdx = 0;\r\n let cleanedData = [];\r\n for (let rIdx = 20; rIdx < noZerosList.length - 20; rIdx = rIdx + 20) {\r\n // console.log('concatenating from/to:', lIdx, rIdx);\r\n cleanedData = cleanedData.concat(\r\n removeOutliers(noZerosList.slice(lIdx, rIdx))\r\n );\r\n lIdx += 20;\r\n }\r\n //do last one with left over elemnts at end >=20 in length\r\n // console.log('concatenating from/to:', lIdx, noZerosList.length);\r\n cleanedData = cleanedData.concat(\r\n removeOutliers(noZerosList.slice(lIdx, noZerosList.length))\r\n );\r\n // console.log('cleanedData', cleanedData);\r\n\r\n return cleanedData;\r\n }, []);\r\n\r\n //user chose a camera, so set state, and also list of images for that camera from server\r\n //also get and set the report params for this camera\r\n const handleDeviceSelected = useCallback(async () => {\r\n setIsLoading(true);\r\n setNoData(false);\r\n\r\n // const eventKey = event.target.value;\r\n if (!userSelectedCamera?.cameraId) return;\r\n const { cameraId } = userSelectedCamera;\r\n\r\n dispatch({ type: SET_CAMERA_DATA, payload: userSelectedCamera });\r\n\r\n //get report params from ddb, and save them to state, and locally for use in this function\r\n let digitsMultiplier;\r\n\r\n let label;\r\n\r\n getReportOnlyParams(cameraId).then((params) => {\r\n // console.log('getting params for selected camera:', params);\r\n dispatch({\r\n type: SET_REPORT_INFO,\r\n payload: {\r\n reportCount: params.costPerUnit,\r\n reportLabel: params.units,\r\n reportMult: params.multiplier,\r\n },\r\n });\r\n digitsMultiplier = params.multiplier;\r\n\r\n label = params.units;\r\n });\r\n\r\n getAllImagesListProc(cameraId).then(async (imgList) => {\r\n try {\r\n console.log(\r\n 'before saving off images list, lets modify it with calculations for gpm'\r\n );\r\n\r\n imgList = createDeltaProperties(imgList);\r\n\r\n console.log('length', imgList.length, imgList);\r\n\r\n dispatch({ type: SET_IMAGES_LIST, payload: imgList });\r\n\r\n console.log('updated to add in deltaDigits and deltaTimeMS', imgList);\r\n\r\n const hasDigitsList = imgList.filter(({ digits }) => Boolean(digits));\r\n\r\n const cleanedData = cleanData(hasDigitsList);\r\n\r\n console.log('cleanedData', cleanedData);\r\n let chartD = cleanedData.map((elt) => [\r\n new Date(parseInt(elt[0])),\r\n parseInt(elt[1]) * digitsMultiplier,\r\n ]);\r\n\r\n let flowD = computeDeltas(chartD);\r\n console.log('flowData:', flowD);\r\n\r\n flowD.unshift(['timestamp', 'delta/time']); //add to front of list\r\n chartD.unshift(['timestamp', 'value']); //add to front of list\r\n // console.log('imagesList', imagesList);\r\n // console.log('chartData:', chartD);\r\n // console.log('flowData:', flowD);\r\n dispatch({ type: SET_CHART_DATA, payload: chartD }); // the original unfiltered chart data\r\n // setFlowData(flowD);\r\n\r\n let startDate = chartD[1][0];\r\n\r\n dispatch({\r\n type: SET_START_DATE,\r\n payload: moment(startDate).format('YYYY-MM-DD'),\r\n });\r\n\r\n const result = handlePeriodicFilter(chartD, startDate, label, 'month');\r\n\r\n dispatch({ type: SET_BAR_CHART_DATA, payload: result });\r\n setIsLoading(false);\r\n } catch (err) {\r\n setIsLoading(false);\r\n setNoData(true);\r\n }\r\n });\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [userSelectedCamera, reportInfo.reportLabel]);\r\n\r\n // Handle transfer between tabs\r\n const changeToTab = useCallback(\r\n (tab) => {\r\n dispatch({ type: SET_PAGE_STATE, payload: tab });\r\n },\r\n [dispatch]\r\n );\r\n\r\n // prevent the re-creation of a function when passed as dep to a useEffect with useCallback\r\n const onDateFilterChange = useCallback(\r\n (periodType) => {\r\n if (!startDate) return;\r\n let result = handlePeriodicFilter(\r\n chartData,\r\n startDate,\r\n reportInfo.reportLabel,\r\n periodType\r\n );\r\n dispatch({ type: SET_BAR_CHART_DATA, payload: result });\r\n },\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [chartData, startDate, endDate, reportInfo.reportLabel]\r\n );\r\n\r\n useEffect(() => {\r\n // this will also run on mount\r\n const onDeviceSelected = async () => {\r\n if (userSelectedCamera?.cameraId) {\r\n // run this function if there is a device selected when going to this page\r\n handleDeviceSelected();\r\n }\r\n };\r\n onDeviceSelected();\r\n /* run this function everytime the user selects a different camera on the dropdown\r\n no need for a different dropdown component here. */\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [userSelectedCamera]);\r\n\r\n useEffect(() => {\r\n // filter barchart data by time everytime user changes it\r\n onDateFilterChange(currentPeriodType);\r\n // run this everytime these change.\r\n }, [startDate, endDate, currentPeriodType, onDateFilterChange]);\r\n\r\n if (isLoading) {\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n \r\n Loading...\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n }\r\n\r\n if (noData) {\r\n return (\r\n <>\r\n \r\n \r\n No data\r\n \r\n \r\n );\r\n }\r\n\r\n return (\r\n <>\r\n {/* ****************** Report Top Navigation Bar ****************** */}\r\n \r\n\r\n {/* ****************** Filter Card ****************** */}\r\n {pageState.showFilter && (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n )}\r\n\r\n \r\n \r\n {/* ****************** Usage Overview START ****************** */}\r\n {pageState.showChart && (\r\n \r\n {/* Bar chart */}\r\n \r\n \r\n )}\r\n \r\n\r\n {/* readings table */}\r\n {pageState.readingsTabSelected && (\r\n \r\n {cameraData.cameraId !== '' && }\r\n \r\n )}\r\n \r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport {\r\n Grid,\r\n Tab,\r\n Tabs,\r\n useTheme,\r\n useMediaQuery,\r\n makeStyles,\r\n} from '@material-ui/core';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n container: {\r\n marginLeft: '0px',\r\n marginRight: '0px',\r\n paddingTop: '20px',\r\n backgroundColor: '#FAFAFA',\r\n borderBottom: '1px solid #999',\r\n marginBottom: '2em',\r\n },\r\n\r\n tab: {\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n },\r\n}));\r\n\r\nexport default function AlertsNavbar({ changeToTab, activeTab }) {\r\n const theme = useTheme();\r\n const classes = useStyles();\r\n const matchesXs = useMediaQuery(theme.breakpoints.down('xs'));\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport Container from '@material-ui/core/Container';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport makeStyles from '@material-ui/core/styles/makeStyles';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n paper: {\r\n // padding: theme.spacing(2),\r\n display: 'flex',\r\n flexDirection: 'column',\r\n height: '100%',\r\n },\r\n container: {\r\n paddingTop: theme.spacing(2),\r\n paddingBottom: theme.spacing(4),\r\n },\r\n}));\r\n\r\nexport default function PageSection({\r\n children,\r\n marginBottom,\r\n gridItemStyles,\r\n}) {\r\n const classes = useStyles();\r\n return (\r\n \r\n \r\n \r\n {children}\r\n \r\n \r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport makeStyles from '@material-ui/core/styles/makeStyles';\r\n\r\n// components\r\nimport MeterVibeButtonPrimary from '../../shared/buttons/MeterVibeButtonPrimary';\r\nimport MeterVibeButtonSecondary from '../../shared/buttons/MeterVibeButtonSecondary';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport Grid from '@material-ui/core/Grid';\r\n\r\n// icons\r\nimport AlertsIcon from '@material-ui/icons/ErrorTwoTone';\r\n\r\nconst IssueFoundSection = ({\r\n issueFound,\r\n closeIssueFound,\r\n openDetailsModal,\r\n}) => {\r\n const classes = useStyles();\r\n\r\n const { message, type } = issueFound;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n {type}\r\n \r\n \r\n\r\n \r\n \r\n Potential issue found\r\n \r\n \r\n \r\n \r\n\r\n
    \r\n \r\n {/* message = 'Water has been running for 3 hours. You have used 240 gallons of water' */}\r\n {message}\r\n \r\n
    \r\n\r\n \r\n \r\n openDetailsModal(issueFound)}\r\n />\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst useStyles = makeStyles({\r\n issueTypeText: {\r\n fontSize: '14px',\r\n color: '#7A7A7A',\r\n fontWeight: 700,\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n\r\n issueHeaderText: {\r\n fontSize: '18px',\r\n color: '#363636',\r\n fontWeight: 700,\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n\r\n issueMessageText: {\r\n fontFamily: ['Public Sans', 'Roboto', 'Sans-Serif'].join(','),\r\n fontSize: '14px',\r\n color: '#363636',\r\n },\r\n\r\n textBold: {\r\n fontWeight: 700,\r\n },\r\n});\r\n\r\nexport default React.memo(IssueFoundSection);\r\n","import React from 'react';\r\n\r\n// components\r\nimport Typography from '@material-ui/core/Typography';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Moment from 'react-moment';\r\n\r\nimport makeStyles from '@material-ui/core/styles/makeStyles';\r\n\r\nconst AlertsSection = ({ alerts, handleClearAlerts, openDetailsModal }) => {\r\n const classes = useStyles();\r\n\r\n return (\r\n <>\r\n \r\n Alerts\r\n \r\n\r\n
    \r\n\r\n {alerts.length ? (\r\n alerts.map((alert, key) => (\r\n // AlertRow defined in line 57\r\n \r\n ))\r\n ) : (\r\n \r\n No Alerts\r\n \r\n )}\r\n\r\n
    \r\n\r\n \r\n {alerts.length ? (\r\n \r\n Clear all\r\n \r\n ) : null}\r\n \r\n \r\n );\r\n};\r\n\r\nconst AlertRow = ({ alert, openDetailsModal }) => {\r\n const { severity, message, timestamp } = alert;\r\n\r\n const classes = useStyles({ alertSeverity: severity });\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n\r\n {message}\r\n\r\n openDetailsModal(alert)}\r\n className={classes.viewDetailsButton}>\r\n View details\r\n \r\n \r\n\r\n \r\n \r\n {timestamp}\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst ALERT_SEVERITIES = {\r\n info: '#3D93CC',\r\n success: '#5FB200',\r\n warning: '#FF9F00',\r\n danger: '#D0021B',\r\n};\r\n\r\nconst buttonStyles = {\r\n border: 0,\r\n padding: 0,\r\n transition: 'all 250ms ease-in-out',\r\n background: 'none',\r\n cursor: 'pointer',\r\n color: '#0272BC',\r\n\r\n '&:hover': {\r\n transform: 'scale(1.01)',\r\n },\r\n\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n\r\n '&:active': {\r\n color: '#00224B',\r\n },\r\n};\r\n\r\nconst useStyles = makeStyles({\r\n alertsSectionHeader: {\r\n borderBottom: '1px solid #DBDBDB',\r\n padding: '10px 16px',\r\n\r\n '& > h1': {\r\n color: '#01070F',\r\n fontSize: '14px',\r\n fontWeight: 700,\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n },\r\n\r\n verticalSpacer: {\r\n display: 'flex',\r\n padding: '10px',\r\n flexGrow: 1,\r\n },\r\n\r\n alertsSectionFooter: {\r\n padding: '10px',\r\n backgroundColor: '#FAFAFA',\r\n },\r\n\r\n alertsClearAllButton: {\r\n ...buttonStyles,\r\n fontSize: '14px',\r\n fontWeight: 700,\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n border: 0,\r\n padding: 0,\r\n transition: 'all 250ms ease-in-out',\r\n },\r\n\r\n alertRowItemsContainer: {\r\n backgroundColor: '#FAFAFA',\r\n margin: '10px 20px',\r\n padding: '10px',\r\n },\r\n\r\n alertRowSeverityCircle: {\r\n backgroundColor: ({ alertSeverity }) => ALERT_SEVERITIES[alertSeverity],\r\n borderRadius: '50%',\r\n width: '16px',\r\n height: '16px',\r\n marginRight: '10px',\r\n },\r\n\r\n alertRowMessage: {\r\n fontSize: '12px',\r\n fontFamily: ['Public Sans', 'Roboto', 'Sans-Serif'].join(','),\r\n color: '#363636',\r\n padding: 0,\r\n marginRight: '10px',\r\n },\r\n\r\n alertRowTimestamp: {\r\n fontSize: '12px',\r\n fontFamily: ['Public Sans', 'Roboto', 'Sans-Serif'].join(','),\r\n color: '#363636',\r\n },\r\n\r\n viewDetailsButton: {\r\n ...buttonStyles,\r\n fontSize: '12px',\r\n fontFamily: ['Public Sans', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n});\r\n\r\nexport default React.memo(AlertsSection);\r\n","import React from 'react';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport MeterVibeButtonSecondary from '../../shared/buttons/MeterVibeButtonSecondary';\r\nimport MeterVibeButtonPrimary from '../../shared/buttons/MeterVibeButtonPrimary';\r\nimport {\r\n DialogTitle,\r\n DialogContent,\r\n DialogActions,\r\n DraggableModal,\r\n} from '../../shared/modal/ModalComponents';\r\nimport moment from 'moment';\r\nimport 'moment-timezone';\r\nimport {\r\n makeStyles,\r\n Table,\r\n TableCell,\r\n TableHead,\r\n TableRow,\r\n TableBody,\r\n} from '@material-ui/core';\r\n\r\nconst useStyles = makeStyles({\r\n imageSectionRoot: {\r\n overflow: 'hidden',\r\n padding: '20px',\r\n },\r\n\r\n breakdownSectionRoot: {\r\n overflow: 'hidden',\r\n padding: '20px',\r\n },\r\n\r\n altText: {\r\n color: '#363636',\r\n fontSize: '14px',\r\n fontWeight: 400,\r\n fontFamily: ['Public Sans', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n\r\n snapshotImg: {\r\n width: '100%',\r\n },\r\n\r\n digitsText: {\r\n fontSize: '16px',\r\n color: '#363636',\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n fontWeight: 700,\r\n marginTop: '10px',\r\n },\r\n\r\n breakdownTableHead: {\r\n '& > th': {\r\n fontWeight: 700,\r\n color: '#242424',\r\n padding: '5px 10px',\r\n },\r\n },\r\n\r\n breakdownTableRow: {\r\n ' & > td': {\r\n color: '#363636',\r\n padding: '15px 10px',\r\n },\r\n },\r\n\r\n buttonsContainer: {\r\n padding: '20px',\r\n display: 'flex',\r\n justifyContent: 'space-evenly',\r\n },\r\n\r\n closeBtn: {\r\n width: '50%',\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n },\r\n\r\n resolveBtn: {\r\n width: '100%',\r\n '&:focus': {\r\n outline: 'none',\r\n },\r\n },\r\n});\r\n\r\nconst SEVERITY_TITLES = {\r\n info: 'Info',\r\n danger: 'Potential issue found',\r\n warning: 'Potential issue found',\r\n success: 'Success',\r\n};\r\n\r\nconst SEVERITY_RATINGS = {\r\n info: 0,\r\n success: 0,\r\n warning: 1,\r\n danger: 2,\r\n};\r\n\r\nfunction AlertDetailsModal({\r\n open,\r\n onClose,\r\n imageData,\r\n previousImageData,\r\n label,\r\n message,\r\n severity,\r\n resolveIssue,\r\n}) {\r\n const currentDigits = imageData?.digits;\r\n const previousDigits = previousImageData?.digits;\r\n\r\n const classes = useStyles();\r\n\r\n // danger || warning = \"Issue Details\" : \"Info || Success Details\"\r\n const modalTitle =\r\n SEVERITY_RATINGS[severity] >= 1\r\n ? 'Issue Details'\r\n : `${SEVERITY_TITLES[severity]} Details`;\r\n\r\n return (\r\n \r\n {modalTitle}\r\n\r\n \r\n \r\n \r\n {SEVERITY_TITLES[severity]}\r\n \r\n {message}\r\n \r\n\r\n {/* if the severity is warning or danger, show the images, else don't */}\r\n {SEVERITY_RATINGS[severity] >= 1 && (\r\n <>\r\n {previousDigits && (\r\n \r\n )}\r\n {currentDigits && (\r\n \r\n )}\r\n\r\n \r\n \r\n )}\r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n}\r\n\r\n// a section with the image, timestamp and the digits\r\nconst ImageSection = ({ imageSource, timeStampSaved, digits, category }) => {\r\n const classes = useStyles();\r\n\r\n return (\r\n \r\n {/* recent snapshot: 10-20-2021 */}\r\n \r\n \r\n {category} snapshot:{' '}\r\n {moment(timeStampSaved).format('hh:mmA MM/DD/yyyy')}\r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n {digits}\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst BreakdownSection = ({ label, timestamp, digits }) => {\r\n const classes = useStyles();\r\n const formattedTime = moment(timestamp).format('hh:mmA MM/DD/yyyy');\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n Breakdown per minute\r\n {[1, 2].map((_emptyCell, key) => (\r\n \r\n ))}\r\n \r\n \r\n\r\n \r\n \r\n {[formattedTime, digits, `0 ${label}`].map((cellText, key) => (\r\n {cellText}\r\n ))}\r\n \r\n \r\n
    \r\n \r\n );\r\n};\r\n\r\nexport default React.memo(AlertDetailsModal);\r\n","import React, { useState, useCallback } from 'react';\r\n\r\n// components\r\nimport PageSection from '../../shared/containers/PageSection';\r\nimport IssueFoundSection from './IssueFoundSection';\r\n\r\n// utils\r\nimport AlertsSection from './AlertsSection';\r\nimport AlertDetailsModal from './AlertDetailsModal';\r\n\r\nexport default function StatusAndAlerts({\r\n alerts,\r\n issueFound,\r\n closeIssueFound,\r\n handleClearAlerts,\r\n clearOneAlert,\r\n}) {\r\n const [isDetailsModalOpen, setIsDetailsModalOpen] = useState(false);\r\n const [modalData, setModalData] = useState(null);\r\n\r\n const openDetailsModal = useCallback(\r\n (alert) => {\r\n setIsDetailsModalOpen(alert.timestamp);\r\n setModalData(alert);\r\n },\r\n [setIsDetailsModalOpen, setModalData]\r\n );\r\n\r\n const closeDetailsModal = useCallback(() => {\r\n setIsDetailsModalOpen(false);\r\n }, [setIsDetailsModalOpen]);\r\n\r\n const onIssueResolved = useCallback(() => {\r\n clearOneAlert(modalData);\r\n closeDetailsModal();\r\n setModalData(null);\r\n }, [closeDetailsModal, clearOneAlert, modalData]);\r\n\r\n return (\r\n <>\r\n {issueFound && (\r\n \r\n \r\n \r\n )}\r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n );\r\n}\r\n","import React, { useState, useEffect } from 'react';\r\n\r\nimport {\r\n Grid,\r\n Checkbox,\r\n FormGroup,\r\n FormControlLabel,\r\n Select,\r\n MenuItem,\r\n} from '@material-ui/core';\r\nimport makeStyles from '@material-ui/core/styles/makeStyles';\r\n\r\nconst useStyles = makeStyles({\r\n separator: {\r\n backgroundColor: '#DBDBDB',\r\n height: '1px',\r\n width: '100%',\r\n },\r\n});\r\n\r\nexport default function CheckboxesSection() {\r\n const classes = useStyles();\r\n\r\n // this state is for the very left side of each row, it decideds if to enable the right side.\r\n const [enabledCheckboxes, setEnabledCheckboxes] = useState({\r\n potentialLeakageAlerts: false,\r\n dailyWaterUsageAlerts: [false, '15% more than average'],\r\n dailyWaterUsageReport: false,\r\n monthlyWaterUsageReport: false,\r\n });\r\n\r\n const initialCheckboxesState = {\r\n onEmail: false,\r\n onMobilePhone: false,\r\n inWebApplication: false,\r\n };\r\n\r\n // these states are for the right side of each row\r\n const [sendPotentialLeakageAlerts, setSendPotentialLeakageAlerts] = useState(\r\n initialCheckboxesState\r\n );\r\n const [sendAlertDaily, setSendAlertDaily] = useState(initialCheckboxesState);\r\n const [sendDailyWaterUsageReport, setSendDailyWaterUsageReport] = useState(\r\n initialCheckboxesState\r\n );\r\n const [sendMonthlyWaterUsageReport, setSendMonthlyWaterUsageReport] =\r\n useState(initialCheckboxesState);\r\n\r\n const toggleEnabledCheckboxes = (e) => {\r\n const { name, value } = e.target;\r\n\r\n // the left side of daily water usage has 2 things, so it's an array in the state, 0 is a boolean and 1 is the avg value\r\n if (name === 'dailyWaterUsageAlerts.bool') {\r\n setEnabledCheckboxes((prevState) => ({\r\n ...prevState,\r\n dailyWaterUsageAlerts: [\r\n !prevState.dailyWaterUsageAlerts[0],\r\n prevState.dailyWaterUsageAlerts[1],\r\n ],\r\n }));\r\n\r\n return;\r\n }\r\n\r\n if (name === 'dailyWaterUsageAlerts.average') {\r\n setEnabledCheckboxes((prevState) => ({\r\n ...prevState,\r\n dailyWaterUsageAlerts: [prevState.dailyWaterUsageAlerts[0], value],\r\n }));\r\n\r\n return;\r\n }\r\n\r\n // toggle the boolean\r\n setEnabledCheckboxes((prevState) => ({\r\n ...prevState,\r\n [name]: !prevState[name],\r\n }));\r\n };\r\n\r\n const handleSubmit = async () => {\r\n let reqBody = {\r\n potentialLeakageAlerts: {\r\n // do the same thing for the other sections\r\n send: enabledCheckboxes.potentialLeakageAlerts, // back-end should prioritize send, if other values are true but send is false, just don't send\r\n ...sendPotentialLeakageAlerts, // onEmail, onMobilePhone, inWebApplication\r\n },\r\n\r\n dailyAlerts: {\r\n send: enabledCheckboxes.dailyWaterUsageAlerts[0],\r\n average: enabledCheckboxes.dailyWaterUsageAlerts[1],\r\n ...sendAlertDaily, // onEmail, onMobilePhone, inWebApplication\r\n },\r\n };\r\n\r\n console.log({ reqBody });\r\n return;\r\n };\r\n\r\n useEffect(() => {\r\n window._testSubmit = () => handleSubmit(); // test handleSubmit\r\n });\r\n\r\n return (\r\n \r\n {/* potential leakage alerts */}\r\n \r\n\r\n
    \r\n\r\n {/* Daily Water Alerts */}\r\n \r\n
    \r\n {/* End of daily water alerts */}\r\n\r\n {/* Send daily water usage report */}\r\n \r\n\r\n
    \r\n {/* End of daily usage report */}\r\n\r\n {/* Send monthly water usage report */}\r\n \r\n {/* end of Send monthly water usage report */}\r\n \r\n );\r\n}\r\n\r\nconst checkboxAliases = {\r\n onEmail: 'On email',\r\n onMobilePhone: 'On mobile phone',\r\n inWebApplication: 'In Web Application',\r\n};\r\n\r\n// the checkbox group at the right side of every row\r\nconst CheckboxGroup = ({ state, setState, disabled }) => (\r\n \r\n {['onEmail', 'onMobilePhone', 'inWebApplication'].map((name, key) => {\r\n const labelText = checkboxAliases[name];\r\n\r\n return (\r\n \r\n setState((prevState) => ({\r\n ...prevState,\r\n [name]: !prevState[name],\r\n }))\r\n }\r\n checked={state[name]}\r\n />\r\n }\r\n label={labelText}\r\n />\r\n );\r\n })}\r\n \r\n);\r\n\r\nconst CheckboxRow = ({\r\n state,\r\n setState,\r\n stateName,\r\n onChange,\r\n enabledCheckboxes,\r\n label,\r\n marginTop,\r\n}) => (\r\n \r\n \r\n \r\n }\r\n label={label}\r\n />\r\n \r\n\r\n {/* CheckboxGroup contains the 'On email', 'On Mobile Phone', 'In Web Application' checkboxes */}\r\n \r\n \r\n);\r\n\r\nconst DailyWaterAlertsRow = ({\r\n enabledCheckboxes,\r\n onChange,\r\n sendAlertDaily,\r\n setSendAlertDaily,\r\n}) => (\r\n \r\n \r\n \r\n \r\n }\r\n label=\"Send alert if daily water usage is\"\r\n />\r\n \r\n\r\n \r\n \r\n {['15% more than average', '35% more than average'].map(\r\n (value, key) => (\r\n \r\n {value}\r\n \r\n )\r\n )}\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n);\r\n","import React, { useState } from 'react';\r\nimport { Typography, Grid, TextField } from '@material-ui/core';\r\nimport makeStyles from '@material-ui/core/styles/makeStyles';\r\nimport moment from 'moment';\r\n\r\nconst useStyles = makeStyles({\r\n defaultParagraph: {\r\n fontSize: '14px',\r\n color: '#363636',\r\n fontFamily: ['Public Sans', 'Roboto', 'Sans-Serif'].join(','),\r\n marginBottom: 0,\r\n },\r\n});\r\n\r\n// leakage system working hours\r\nexport default function HoursSection() {\r\n const classes = useStyles();\r\n\r\n // browser time inputs don't take hh:mm A, they take HH:mm which means 1 PM would be 13:00 (military time)\r\n const [hours, setHours] = useState({\r\n min: moment().format('HH:mm'), // left input\r\n max: moment(Date.now() + 1000 * 60 * 60).format('HH:mm'), // right input\r\n });\r\n\r\n const handleChange = (e) => {\r\n const { name, value } = e.target;\r\n\r\n setHours((prevState) => ({\r\n ...prevState,\r\n [name]: value,\r\n }));\r\n };\r\n\r\n return (\r\n \r\n \r\n Leakage system working hours. This is the time when our system will do\r\n regular leakage test. You can change this time periods to your\r\n preference.\r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport PageWrapper from '../../shared/containers/PageSection';\r\nimport { Typography, Grid } from '@material-ui/core';\r\nimport makeStyles from '@material-ui/core/styles/makeStyles';\r\n\r\n// sections\r\nimport CheckboxesSection from './CheckboxesSection';\r\nimport HoursSection from './HoursSection';\r\n\r\nconst useStyles = makeStyles({\r\n defaultParagraph: {\r\n fontSize: '14px',\r\n color: '#363636',\r\n fontFamily: ['Public Sans', 'Roboto', 'Sans-Serif'].join(','),\r\n marginBottom: 0,\r\n },\r\n\r\n link: {\r\n color: '#0272BC',\r\n cursor: 'pointer',\r\n },\r\n\r\n verticalSpacer: {\r\n display: 'flex',\r\n flexGrow: 1,\r\n padding: '10px',\r\n },\r\n\r\n separator: {\r\n backgroundColor: '#DBDBDB',\r\n height: '1px',\r\n width: '100%',\r\n },\r\n});\r\n\r\nexport default function AlertsSettings() {\r\n return (\r\n \r\n {[IntroSection, HoursSection, CheckboxesSection].map(\r\n (SectionComponent, idx, arr) => (\r\n \r\n \r\n {idx !== arr.length - 1 ? : null}\r\n \r\n )\r\n )}\r\n \r\n );\r\n}\r\n\r\nconst SectionSeparator = () => {\r\n const classes = useStyles();\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst IntroSection = () => {\r\n const classes = useStyles();\r\n\r\n return (\r\n \r\n \r\n Here you can configure what types of alerts you want to recieve. Each\r\n type of alert can be send to different channels (Email, Phone, Web\r\n application). You can change email or mobile phone number in{' '}\r\n User settings.\r\n \r\n \r\n );\r\n};\r\n","import mockSnapshotSRC from '../assets/mock_images/cam32_concat.jpg';\r\n\r\n// this is just for creating mock dates\r\nconst SECONDS_IN_DAY = 60 * 60 * 24; // not in MS\r\nconst ONE_DAY_IN_MS = 1000 * SECONDS_IN_DAY; // one day in milliseconds\r\nconst ONE_HOUR_IN_MS = 1000 * 60 * 60; // one hour in milliseconds\r\n\r\nconst mockSnapshotRecent = {\r\n signedUrl: mockSnapshotSRC,\r\n digits: '0,000,292.88',\r\n timestampSaved: Date.now() - ONE_HOUR_IN_MS,\r\n};\r\n\r\nconst mockSnapshotPrior = {\r\n signedUrl: mockSnapshotSRC,\r\n digits: '140,149,222.88',\r\n timestampSaved: Date.now() - ONE_HOUR_IN_MS * 4,\r\n};\r\n\r\nexport const mockAlerts = [\r\n {\r\n type: 'Leakage',\r\n message:\r\n 'Potential leakage: Water have been running for 3 hours. You have used 240 gallons of water',\r\n timestamp: Date.now(),\r\n isCleared: false,\r\n severity: 'danger', // severity is used for the color of circles at the AlertRow component (inside AlertsSection.js)\r\n\r\n // snapshots for details modal\r\n firstSnapshot: mockSnapshotPrior,\r\n recentSnapshot: mockSnapshotRecent,\r\n },\r\n {\r\n type: 'Leakage',\r\n\r\n message: 'You used 45% more water today compared to your average daily use',\r\n timestamp: Date.now() - ONE_HOUR_IN_MS,\r\n isCleared: false,\r\n severity: 'warning',\r\n\r\n firstSnapshot: mockSnapshotPrior,\r\n recentSnapshot: mockSnapshotRecent,\r\n },\r\n {\r\n type: 'Leakage',\r\n\r\n message: 'You used 15% more water today compared to your average daily use',\r\n timestamp: Date.now() - ONE_DAY_IN_MS,\r\n isCleared: false,\r\n severity: 'info',\r\n\r\n firstSnapshot: mockSnapshotPrior,\r\n recentSnapshot: mockSnapshotRecent,\r\n },\r\n {\r\n type: 'Leakage',\r\n\r\n message: 'New device (code 235235252) was successfuly activated',\r\n timestamp: Date.now() - ONE_DAY_IN_MS * 2,\r\n isCleared: false,\r\n severity: 'success',\r\n\r\n firstSnapshot: mockSnapshotPrior,\r\n recentSnapshot: mockSnapshotRecent,\r\n },\r\n];\r\n","import React, { useState, useEffect, useCallback } from 'react';\r\n\r\n// components\r\nimport AlertsNavbar from '../components/alerts_components/AlertsNavbar';\r\nimport StatusAndAlerts from '../components/alerts_components/StatusAndAlerts/StatusAndAlerts';\r\nimport AlertsSettings from '../components/alerts_components/AlertsSettings/AlertsSettings';\r\n\r\nimport { mockAlerts } from '../mocks/alerts.mock';\r\n\r\nconst SEVERITY_RATINGS = {\r\n info: 0,\r\n success: 0,\r\n warning: 1,\r\n danger: 2,\r\n};\r\n\r\nconst toggleAlertCleared = (alert) => {\r\n return {\r\n ...alert,\r\n isCleared: !alert.isCleared,\r\n };\r\n};\r\n\r\nconst checkNewIssueFound = (alerts) => {\r\n const newIssueFound = alerts.find(\r\n ({ severity }) => SEVERITY_RATINGS[severity] >= 1 // warning || danger\r\n );\r\n\r\n return newIssueFound ?? false;\r\n};\r\n\r\nexport default function Alerts() {\r\n const [activeTab, setActiveTab] = useState('StatusAndAlerts');\r\n const [issueFound, setIssueFound] = useState(null);\r\n const [allVisibleAlerts, setAllVisibleAlerts] = useState([]);\r\n\r\n useEffect(() => {\r\n // API.get('/user/allAlerts')\r\n let responseData = {\r\n alerts: mockAlerts,\r\n };\r\n\r\n const { alerts } = responseData;\r\n\r\n const unclearedAlerts = alerts.filter((alert) => !alert.isCleared);\r\n\r\n setAllVisibleAlerts(unclearedAlerts);\r\n }, []);\r\n\r\n const changeToTab = useCallback(\r\n (_e, newTab) => {\r\n setActiveTab(newTab);\r\n },\r\n [setActiveTab]\r\n );\r\n\r\n const closeIssueFound = useCallback(() => {\r\n // API.post(\"/alerts/issues/issueid\")\r\n setIssueFound(false);\r\n }, [setIssueFound]);\r\n\r\n const handleClearAlerts = useCallback(() => {\r\n // API.post(\"/alerts/clearAll\")\r\n setAllVisibleAlerts([]);\r\n }, [setAllVisibleAlerts]);\r\n\r\n // this runs everytime an alert is cleared.\r\n // toggleAlertCleared will change the isCleared value (so if it's false it'll be true)\r\n const clearOneAlert = useCallback(\r\n (alert) => {\r\n // API.post(alerts/clear/alert.timestamp)\r\n\r\n // toggleAlertCleared will change the isCleared value (so if it's false it'll be true)\r\n const updatedAlert = toggleAlertCleared(alert);\r\n\r\n // map though the state and if timestamp is even that means thats the alert we want to update\r\n const updatedAlerts = [...allVisibleAlerts].map((mappedAlert) =>\r\n mappedAlert.timestamp === alert.timestamp ? updatedAlert : mappedAlert\r\n );\r\n\r\n // get the alerts that aren't cleared\r\n const unclearedAlerts = updatedAlerts.filter((alert) => !alert.isCleared);\r\n\r\n setAllVisibleAlerts(unclearedAlerts);\r\n },\r\n [setAllVisibleAlerts, allVisibleAlerts]\r\n );\r\n\r\n useEffect(() => {\r\n // check if there's a new issue found everytime alerts change\r\n const newIssueFound = checkNewIssueFound(allVisibleAlerts);\r\n setIssueFound(newIssueFound);\r\n }, [allVisibleAlerts]);\r\n\r\n return (\r\n <>\r\n \r\n\r\n {activeTab === 'StatusAndAlerts' ? (\r\n \r\n ) : (\r\n \r\n )}\r\n \r\n );\r\n}\r\n","import React, { useState, useEffect, useCallback } from 'react';\r\nimport { useSelector } from 'react-redux';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\n\r\n// components\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport FormGroup from '@material-ui/core/FormGroup';\r\nimport FormControl from '@material-ui/core/FormControl';\r\nimport InputLabel from '@material-ui/core/InputLabel';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport Select from '@material-ui/core/Select';\r\nimport Box from '@material-ui/core/Box';\r\n\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport FormHelperText from '@material-ui/core/FormHelperText';\r\nimport MeterVibeButtonPrimary from '../components/shared/buttons/MeterVibeButtonPrimary';\r\n\r\nexport default function UserSettings() {\r\n const { user } = useSelector(({ userReducer }) => userReducer);\r\n\r\n if (!user?.id) return null; // or loading\r\n\r\n return (\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nconst PersonalDetails = () => {\r\n const { userEmail } = useSelector(({ userReducer }) => userReducer);\r\n\r\n const [personalDetails, setPersonalDetails] = useState({\r\n // name: user.name, // doesn't exist\r\n name: '',\r\n email: '',\r\n phoneNumber: '',\r\n });\r\n\r\n const classes = useStyles();\r\n\r\n const handleChange = (e) => {\r\n const { name, value } = e.target;\r\n setPersonalDetails((prevState) => ({\r\n ...prevState,\r\n [name]: value,\r\n }));\r\n };\r\n\r\n useEffect(() => {\r\n setPersonalDetails((prevState) => ({\r\n ...prevState,\r\n email: userEmail,\r\n }));\r\n // set the email to what is the userEmail when mounted\r\n\r\n return () => {\r\n setPersonalDetails((prevState) => ({\r\n ...prevState,\r\n email: userEmail,\r\n }));\r\n };\r\n }, [userEmail]);\r\n\r\n const onSavePersonalDetails = useCallback(() => {\r\n alert(JSON.stringify(personalDetails));\r\n }, [personalDetails]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n Personal details\r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n Will be used to send alerts on your mobile phone. You can\r\n customize what you want to receive in Alerts settings.\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst ChangePassword = () => {\r\n const [passwordData, setPasswordData] = useState({\r\n oldPassword: '',\r\n newPassword: '',\r\n });\r\n\r\n const classes = useStyles();\r\n\r\n const handleChange = (e) => {\r\n const { name, value } = e.target;\r\n\r\n setPasswordData((prevState) => ({\r\n ...prevState,\r\n [name]: value,\r\n }));\r\n };\r\n\r\n const onSaveNewPassword = useCallback(() => {\r\n alert(JSON.stringify(passwordData));\r\n }, [passwordData]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n Change password\r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst DefaultPreferences = () => {\r\n const classes = useStyles();\r\n\r\n const [defaultPreferences, setDefaultPreferences] = useState({\r\n showDataType: 'Gallons',\r\n gallonPrice: '',\r\n });\r\n\r\n const handleChange = (e) => {\r\n const { name, value } = e.target;\r\n\r\n setDefaultPreferences((prevState) => ({\r\n ...prevState,\r\n [name]: value,\r\n }));\r\n };\r\n\r\n const onSaveDefaultPreferences = useCallback(() => {\r\n alert(JSON.stringify(defaultPreferences));\r\n }, [defaultPreferences]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n Default preferences\r\n \r\n\r\n \r\n \r\n \r\n Show data in\r\n \r\n\r\n \r\n Gallons\r\n Cubic Feet\r\n \r\n \r\n\r\n \r\n \r\n Gallon Price\r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n sectionItems: {\r\n padding: '30px',\r\n },\r\n\r\n sectionTitle: {\r\n fontWeight: 700,\r\n color: '#01070F',\r\n fontSize: '18px',\r\n fontFamily: ['Montserrat', 'Roboto', 'Sans-Serif'].join(','),\r\n },\r\n\r\n inputLabel: {\r\n color: '#363636',\r\n fontFamily: ['Public Sans', 'Roboto', 'Sans-Serif'].join(','),\r\n fontSize: '14px',\r\n },\r\n\r\n saveButton: {\r\n maxWidth: '40%',\r\n marginTop: '10px',\r\n [theme.breakpoints.down('md')]: {\r\n maxWidth: '100%',\r\n },\r\n },\r\n}));\r\n","import React from 'react';\r\nimport { Route, Switch } from 'react-router-dom';\r\nimport Dashboard from './containers/Dashboard';\r\nimport Activate from './containers/Activate';\r\nimport Admin from './containers/Admin';\r\nimport Device from './containers/Device';\r\nimport NotFound from './components/NotFound';\r\nimport PublicLanding from './components/PublicLanding';\r\nimport MeterVibeAppLayout from './layouts/MeterVibeAppLayout';\r\nimport TermsOfService from './components/TermsOfService';\r\nimport PrivacyPolicy from './components/PrivacyPolicy';\r\nimport Reports from './containers/Reports';\r\nimport Alerts from './containers/Alerts';\r\nimport UserSettings from './containers/UserSettings';\r\n\r\nimport { useSelector } from 'react-redux';\r\n\r\nexport default () => {\r\n const user = useSelector(({ userReducer }) => userReducer.user);\r\n\r\n return (\r\n \r\n {/* commenting out this because now after changes everytime going to '/' redirects to dashboard, doesn't seem needed... */}\r\n {/* */}\r\n {/* redirects root path to /dashboard so Dashboard NavLink always shows bold in drawer */}\r\n\r\n \r\n \r\n \r\n\r\n {/* wrap the authenticated-section of the app with the app layout */}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {/*\r\n doing this because when the user isn't authenticated the useScript hook in Admin.js will still run\r\n so I'm blocking this route from existing if we don't have a user\r\n */}\r\n {user && }\r\n \r\n\r\n {/* Finally, catch all unmatched routes */}\r\n \r\n \r\n );\r\n};\r\n","import { useEffect } from 'react';\r\nimport { useLocation } from 'react-router-dom';\r\n// https://reactrouter.com/web/guides/scroll-restoration\r\nexport default function ScrollToTopOnMount() {\r\n const { pathname } = useLocation();\r\n // scroll to top on mount or page change\r\n useEffect(() => {\r\n window.scrollTo(0, 0);\r\n }, [pathname]);\r\n\r\n return null;\r\n}\r\n","import React, { useEffect } from 'react';\r\nimport { useHistory } from 'react-router-dom';\r\nimport { useDispatch } from 'react-redux';\r\nimport { onAuthUIStateChange } from '@aws-amplify/ui-components';\r\nimport { Auth } from 'aws-amplify';\r\nimport { Hub } from '@aws-amplify/core';\r\n\r\nimport Routes from './Routes';\r\nimport './App.css';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport CssBaseline from '@material-ui/core/CssBaseline';\r\nimport ScrollToTopOnMount from './components/shared/helper_components/ScrollToTopOnMount';\r\n\r\n// reducer actions\r\nimport { USER_ACTIONS } from './reducers/user.reducer';\r\nimport { AUTH_ACTIONS } from './reducers/auth.reducer';\r\nimport { CAMERA_ACTIONS } from './reducers/cameras.reducer';\r\nimport { API_ACTIONS } from './reducers/general.reducer';\r\n\r\n// services\r\nimport { apiCameras } from './services/cameras.services';\r\n\r\nconst useStyles = makeStyles({\r\n root: {\r\n display: 'flex',\r\n minHeight: '100vh', // doing this so MUI paper reaches from top to bottom and doesn't get cut off\r\n },\r\n});\r\n\r\nconst { SET_USER, SET_USER_EMAIL, SET_ADMIN } = USER_ACTIONS;\r\nconst { SET_AUTH_STATE } = AUTH_ACTIONS;\r\nconst { SET_CAMERAS, SET_USER_SELECTED_CAMERA } = CAMERA_ACTIONS;\r\nconst { SET_AWAITING_API } = API_ACTIONS;\r\n\r\nexport default function App() {\r\n const history = useHistory();\r\n\r\n const dispatch = useDispatch();\r\n\r\n const classes = useStyles();\r\n\r\n //add in Hub listener to dispatch on Auth events\r\n //this way we can clear out user data on logout\r\n //and set up user data on login\r\n useEffect(() => {\r\n //run this after the auth user login event to set the list of devices\r\n //set this users Admin level\r\n //set the currently selected device\r\n const getCameras = async () => {\r\n try {\r\n const apiCamerasResponse = await apiCameras();\r\n console.log('apiCamerasResponse:', apiCamerasResponse);\r\n // setAdmin in App.js to whatever value comes back from API\r\n dispatch({ type: SET_ADMIN, payload: apiCamerasResponse.admin });\r\n // sort the cameras and set them to state\r\n const sortedCameras = apiCamerasResponse.data.sort((a, b) =>\r\n a.cameraId.localeCompare(b.cameraId)\r\n );\r\n\r\n dispatch({ type: SET_CAMERAS, payload: sortedCameras });\r\n\r\n // console.log('sortedCameras:', sortedCameras);\r\n\r\n dispatch({\r\n type: SET_USER_SELECTED_CAMERA,\r\n payload: sortedCameras[0],\r\n });\r\n // console.log('userSelectedCamera:', userSelectedCamera);\r\n // allow Dashboard.js to map the cameras\r\n dispatch({ type: SET_AWAITING_API, payload: false });\r\n } catch (e) {\r\n console.log(e);\r\n }\r\n };\r\n const authListener = (data) => {\r\n //callback function dispatched by auth publish when authentication event\r\n switch (data.payload.event) {\r\n case 'signIn':\r\n console.log('user signed in');\r\n console.log('data:', data);\r\n console.log('email:', data.payload.data.attributes.email);\r\n\r\n dispatch({ type: SET_USER, payload: data.payload.data });\r\n\r\n dispatch({\r\n type: SET_USER_EMAIL,\r\n payload: data.payload.data.attributes.email,\r\n });\r\n\r\n getCameras();\r\n\r\n history.push('/dashboard'); // push the user to the app after signing in\r\n break;\r\n case 'signUp':\r\n console.log('user signed up');\r\n break;\r\n case 'signOut':\r\n console.log('user signed out');\r\n console.log('data:', data);\r\n console.log('email:', data.payload.data.attributes.email);\r\n history.push('/'); //logging out, so go to / on login.\r\n break;\r\n case 'signIn_failure':\r\n console.log('user sign in failed');\r\n break;\r\n case 'configured':\r\n console.log('the Auth module is configured');\r\n break;\r\n default: //get rid of compiler warning of expected default case\r\n }\r\n };\r\n\r\n //on page reload, there is no signIn or Signout, but the state is reset\r\n //const userInfo = await Auth.currentUserInfo();\r\n Auth.currentUserInfo().then((data) => {\r\n console.log('auth current credentials:', data);\r\n if (data) {\r\n // when this is run at start, there is no currentUserInfo, so data.attributs.email undefined and errored\r\n dispatch({ type: SET_USER, payload: data });\r\n\r\n dispatch({\r\n type: SET_USER_EMAIL,\r\n payload: data.attributes.email,\r\n });\r\n }\r\n });\r\n getCameras();\r\n\r\n //create a listener that runs on auth changes\r\n Hub.listen('auth', authListener); //subscribe to the auth events\r\n return () => {\r\n Hub.remove('auth', authListener); //useEffect cleanup, remove the listener\r\n };\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []);\r\n\r\n // this useEffect handles authentication changes and the history array\r\n useEffect(() => {\r\n //return onAuthUIStateChange((nextAuthState, authData) => {\r\n onAuthUIStateChange((nextAuthState, authData) => {\r\n dispatch({ type: SET_AUTH_STATE, payload: nextAuthState });\r\n dispatch({\r\n type: SET_USER,\r\n payload: authData,\r\n });\r\n });\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []); // Only re-run the effect if user or history changes\r\n\r\n return (\r\n <>\r\n \r\n \r\n
    \r\n \r\n
    \r\n \r\n );\r\n}\r\n","// In production, we register a service worker to serve assets from local cache.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on the \"N+1\" visit to a page, since previously\r\n// cached resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.\r\n// This link also includes instructions on opting out of this behavior.\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.1/8 is considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\nexport default function register() {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location);\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our page is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Lets check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl);\r\n\r\n // Add some additional logging to localhost, pointing developers to the\r\n // service worker/PWA documentation.\r\n navigator.serviceWorker.ready.then(() => {\r\n console.log(\r\n 'This web app is being served cache-first by a service ' +\r\n 'worker. To learn more, visit https://goo.gl/SC7cgQ'\r\n );\r\n });\r\n } else {\r\n // Is not local host. Just register service worker\r\n registerValidSW(swUrl);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing;\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the old content will have been purged and\r\n // the fresh content will have been added to the cache.\r\n // It's the perfect time to display a \"New content is\r\n // available; please refresh.\" message in your web app.\r\n console.log('New content is available; please refresh.');\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n }\r\n }\r\n };\r\n };\r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl) {\r\n // Check if the service worker can be found. If it can't reload the page.\r\n fetch(swUrl)\r\n .then(response => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n if (\r\n response.status === 404 ||\r\n response.headers.get('content-type').indexOf('javascript') === -1\r\n ) {\r\n // No service worker found. Probably a different app. Reload the page.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(swUrl);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister();\r\n });\r\n }\r\n}\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport { BrowserRouter as Router } from 'react-router-dom';\r\nimport Amplify from 'aws-amplify';\r\nimport config from './config';\r\nimport App from './App';\r\nimport registerServiceWorker from './registerServiceWorker';\r\nimport { Provider as ReduxStoreProvider } from 'react-redux';\r\nimport configureStore from './store'; // index.js\r\n\r\nconst reduxStore = configureStore();\r\n\r\nAmplify.configure({\r\n Auth: {\r\n mandatorySignIn: true,\r\n region: config.cognito.REGION,\r\n userPoolId: config.cognito.USER_POOL_ID,\r\n identityPoolId: config.cognito.IDENTITY_POOL_ID,\r\n userPoolWebClientId: config.cognito.APP_CLIENT_ID,\r\n },\r\n Storage: {\r\n region: config.s3.REGION,\r\n bucket: config.s3.BUCKET,\r\n identityPoolId: config.cognito.IDENTITY_POOL_ID,\r\n },\r\n API: {\r\n endpoints: [\r\n {\r\n name: 'dev-iotvid-app',\r\n endpoint: config.apiGateway.URL,\r\n region: config.apiGateway.REGION,\r\n },\r\n {\r\n name: 'dev-iotvid-ml',\r\n endpoint: config.apiGateway.URL_ML,\r\n region: config.apiGateway.REGION,\r\n },\r\n ],\r\n },\r\n});\r\n\r\nReactDOM.render(\r\n \r\n \r\n \r\n \r\n ,\r\n document.getElementById('root')\r\n);\r\nregisterServiceWorker();\r\n","import { combineReducers } from 'redux';\r\n\r\nimport userReducer from './user.reducer';\r\nimport authReducer from './auth.reducer';\r\nimport camerasReducer from './cameras.reducer';\r\nimport generalReducer from './general.reducer';\r\nimport reportsReducer from './reports.reducer';\r\n\r\n// this reducer combines all other specific reducers.\r\nexport default combineReducers({\r\n userReducer,\r\n authReducer,\r\n camerasReducer,\r\n generalReducer,\r\n reportsReducer,\r\n});\r\n","import { createStore } from 'redux';\r\nimport rootReducer from '../reducers/root.reducer';\r\n\r\nexport default function configureStore() {\r\n const store = createStore(\r\n rootReducer // will give us access to reducer and initial state.\r\n );\r\n\r\n return store;\r\n}\r\n","export const CAMERA_ACTIONS = {\r\n SET_USER_SELECTED_CAMERA: 'SET_USER_SELECTED_CAMERA',\r\n SET_CAMERAS: 'SET_CAMERAS',\r\n};\r\n\r\nconst { SET_USER_SELECTED_CAMERA, SET_CAMERAS } = CAMERA_ACTIONS;\r\n\r\nconst initialState = {\r\n cameras: [],\r\n userSelectedCamera: null,\r\n};\r\n\r\nexport default function camerasReducer(state = initialState, action) {\r\n const { type, payload } = action;\r\n\r\n switch (type) {\r\n case SET_CAMERAS: {\r\n return {\r\n ...state,\r\n cameras: payload,\r\n };\r\n }\r\n\r\n case SET_USER_SELECTED_CAMERA: {\r\n return {\r\n ...state,\r\n userSelectedCamera: payload,\r\n };\r\n }\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n\r\n// returns the cameraObject by passing selectedCameraId (for CameraDropdown.js)\r\nexport const getCameraObject = (cameras, selectedCameraId) =>\r\n cameras.find(({ cameraId }) => cameraId === selectedCameraId);\r\n"],"sourceRoot":""}