Skip to content

Instantly share code, notes, and snippets.

@naydav
Created October 1, 2021 16:33
Show Gist options
  • Save naydav/b87cd7fa17e7db70a807c6893948283a to your computer and use it in GitHub Desktop.
Save naydav/b87cd7fa17e7db70a807c6893948283a to your computer and use it in GitHub Desktop.
Custommer App - ActionsForm.js
/*
* <license header>
*/
import React, { useState } from 'react'
import PropTypes from 'prop-types'
import ErrorBoundary from 'react-error-boundary'
import {
Flex,
Heading,
Form,
Picker,
TextArea,
TextField,
Button,
ActionButton,
StatusLight,
ProgressCircle,
Item,
Text,
View
} from '@adobe/react-spectrum'
import Function from '@spectrum-icons/workflow/Function'
import actions from '../config.json' // ADD notice
import actionWebInvoke from '../utils'
const ActionsForm = (props) => {
const [state, setState] = useState({
formValid: null,
actionResponse: null,
actionResponseError: null,
parkingSpaceNumber: '',
parkingSpaceNumberValid: null,
orderNumber: '',
orderNumberValid: null,
customerEmail: '',
customerEmailValid: null,
actionImHereInProgress: false,
actionResult: ''
})
return (
<View width={{base: 'auto', L: 'size-6000'}}
minWidth={'350px'}
margin={'0 auto'}
>
<Heading level={1}>Curbside Pickup Customer App</Heading>
{Object.keys(actions).length > 0 && (
<Form necessityIndicator="label">
<TextField
label="Parking space #"
placeholder='your parking space number'
validationState={state.parkingSpaceNumberValid}
isRequired
value={state.parkingSpaceNumber}
onChange={(input) =>
setNumberInput(input, 'parkingSpaceNumber', 'parkingSpaceNumberValid')
}
/>
<TextField
label="Order #"
placeholder='your order number'
validationState={state.orderNumberValid}
isRequired
value={state.orderNumber}
onChange={(input) =>
setNumberInput(input, 'orderNumber', 'orderNumberValid')
}
/>
<TextField
type="email"
label="Email"
placeholder='customer email'
validationState={state.customerEmailValid}
isRequired
value={state.customerEmail}
onChange={(input) =>
setEmailInput(input, 'customerEmail', 'customerEmailValid')
}
/>
</Form>
)}
{state.actionResponseError && (
<View padding={`size-100`} marginTop={`size-100`} marginBottom={`size-100`} borderRadius={`small `}>
<StatusLight variant="negative">Failure! See the complete error in your browser console.</StatusLight>
</View>
)}
{!state.actionResponseError && state.actionResponse && (
<View padding={`size-100`} marginTop={`size-100`} marginBottom={`size-100`} borderRadius={`small `}>
<StatusLight variant="positive">Success! See the complete response in your browser console.</StatusLight>
</View>
)}
<Flex>
<Button
variant="primary"
type="button"
width="100%"
isDisabled={!formValid()}
onPress={invokeAction.bind(this)}
><Text>I'm here</Text></Button>
<ProgressCircle
aria-label="loading"
isIndeterminate
isHidden={!state.actionImHereInProgress}
marginStart="size-100"
/>
</Flex>
</View>
)
// Methods
// parses a number input and adds it to the state
async function setNumberInput (input, stateNumber, stateValid) {
let content
let validStr = null
if (input) {
content = parseInt(input) || input
validStr = Number.isInteger(content) ? 'valid' : 'invalid'
}
setState({ ...state, [stateNumber]: content, [stateValid]: validStr })
}
// check the email input and adds it to the state
async function setEmailInput (input, stateName, stateValid) {
let validStr = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(input) ? 'valid' : 'invalid' ;
setState({ ...state, [stateName]: input, [stateValid]: validStr })
}
// checks if form is valid
function formValid () {
return !!(state.parkingSpaceNumber && state.parkingSpaceNumberValid
&& state.orderNumber && state.orderNumberValid
&& state.customerEmail && state.customerEmailValid)
}
// invokes a the selected backend actions with input headers and params
async function invokeAction () {
setState({ ...state, actionInvokeInProgress: true, actionResult: 'calling action ... ' })
const actionName = 'i-am-here'
const parkingSpaceNumber = state.parkingSpaceNumber || ''
const orderNumber = state.orderNumber || ''
const customerEmail = state.customerEmail || ''
const params = {
parkingSpaceNumber: parkingSpaceNumber,
orderNumber: orderNumber,
customerEmail: customerEmail
}
const startTime = Date.now()
let formattedResult = ""
try {
// invoke backend action
const actionResponse = await actionWebInvoke(actions[actionName], {}, params)
formattedResult = `time: ${Date.now() - startTime} ms\n` + JSON.stringify(actionResponse,0,2)
// store the response
setState({
...state,
actionResponse,
actionResult:formattedResult,
actionResponseError: null,
actionInvokeInProgress: false,
parkingSpaceNumber: '',
parkingSpaceNumberValid: null,
orderNumber: '',
orderNumberValid: null,
customerEmail: '',
customerEmailValid: null
})
console.log(`Response from ${actionName}:`, actionResponse)
} catch (e) {
// log and store any error message
formattedResult = `time: ${Date.now() - startTime} ms\n` + e.message
console.error(e)
setState({
...state,
actionResponse: null,
actionResult:formattedResult,
actionResponseError: e.message,
actionInvokeInProgress: false
})
}
}
}
ActionsForm.propTypes = {
runtime: PropTypes.any,
ims: PropTypes.any
}
export default ActionsForm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment