import { useMutation, useQuery, gql } from "@apollo/client"; import { Dialog, DialogContent, SvgIcon, IconButton } from '@mui/material' import { makeStyles } from '@mui/material/styles' import classnames from 'classnames' import { Form, Formik, FastField } from 'formik' import {QRCodeSVG as QRCode} from 'qrcode.react' import * as R from 'ramda' import React, { memo, useState, useEffect, useRef } from 'react' import Title from 'src/components/Title' import Sidebar from 'src/components/layout/Sidebar' import { Info2, P } from 'src/components/typography' import CameraIcon from 'src/styling/icons/ID/photo/zodiac.svg?react' import CloseIcon from 'src/styling/icons/action/close/zodiac.svg?react' import CompleteStageIconSpring from 'src/styling/icons/stage/spring/complete.svg?react' import CompleteStageIconZodiac from 'src/styling/icons/stage/zodiac/complete.svg?react' import CurrentStageIconZodiac from 'src/styling/icons/stage/zodiac/current.svg?react' import EmptyStageIconZodiac from 'src/styling/icons/stage/zodiac/empty.svg?react' import WarningIcon from 'src/styling/icons/warning-icon/comet.svg?react' import * as Yup from 'yup' import { Button } from 'src/components/buttons' import { TextInput } from 'src/components/inputs/formik' import { primaryColor } from 'src/styling/variables' import styles from './styles' const SAVE_CONFIG = gql` mutation createPairingTotem($name: String!) { createPairingTotem(name: $name) } ` const GET_MACHINES = gql` { machines { name deviceId } } ` const useStyles = makeStyles(styles) const getSize = R.compose(R.length, R.pathOr([], ['machines'])) const QrCodeComponent = ({ classes, qrCode, name, count, onPaired }) => { const timeout = useRef(null) const CLOSE_SCREEN_TIMEOUT = 2000 const { data } = useQuery(GET_MACHINES, { pollInterval: 10000 }) useEffect(() => { return () => { if (timeout.current) { clearTimeout(timeout.current) } } }, []) const addedMachine = data?.machines?.find(m => m.name === name) const hasNewMachine = getSize(data) > count && addedMachine if (hasNewMachine) { timeout.current = setTimeout( () => onPaired(addedMachine), CLOSE_SCREEN_TIMEOUT ) } return ( <> Scan QR code with your new cryptomat

Snap a picture and scan

To pair the machine you need scan the QR code with your machine. To do this either snap a picture of this QR code or download it through the button above and scan it with the scanning bay on your machine.

{hasNewMachine && (
Machine has been successfully paired!
)}
) } const initialValues = { name: '' } const validationSchema = Yup.object().shape({ name: Yup.string() .required('Machine name is required.') .max(50) .test( 'unique-name', 'Machine name is already in use.', (value, context) => !R.includes( R.toLower(value), R.map(R.toLower, context.options.context.machineNames) ) ) }) const MachineNameComponent = ({ nextStep, classes, setQrCode, setName }) => { const [register] = useMutation(SAVE_CONFIG, { onCompleted: ({ createPairingTotem }) => { if (process.env.NODE_ENV === 'development') { console.log(`totem: "${createPairingTotem}" `) } setQrCode(createPairingTotem) nextStep() }, onError: e => console.log(e) }) const { data } = useQuery(GET_MACHINES) const machineNames = R.map(R.prop('name'), data?.machines || {}) const uniqueNameValidator = value => { try { validationSchema.validateSync(value, { context: { machineNames: machineNames } }) } catch (error) { return error } } return ( <> Machine Name (ex: Coffee shop 01) { setName(name) register({ variables: { name } }) }}> {({ errors }) => (
{errors &&

{errors.message}

}
)}
) } const steps = [ { label: 'Machine name', component: MachineNameComponent }, { label: 'Scan QR code', component: QrCodeComponent } ] const renderStepper = (step, it, idx, classes) => { const active = step === idx const past = idx < step const future = idx > step return (
{it.label} {active && } {past && } {future && } {idx < steps.length - 1 && (
)}
) } const AddMachine = memo(({ close, onPaired }) => { const classes = useStyles() const { data } = useQuery(GET_MACHINES) const [qrCode, setQrCode] = useState('') const [name, setName] = useState('') const [step, setStep] = useState(0) const count = getSize(data) const Component = steps[step].component return (
Add Machine
{steps.map((it, idx) => renderStepper(step, it, idx, classes))}
setStep(1)} count={count} onPaired={onPaired} qrCode={qrCode} setQrCode={setQrCode} name={name} setName={setName} />
) }) export default AddMachine