This commit is contained in:
E
2021-03-10 19:17:23 -07:00
parent 15023b0e24
commit c29a64b1cc
24 changed files with 220 additions and 155 deletions

View File

@@ -1,4 +1,6 @@
import { Button, Divider, message, PageHeader } from 'antd'
import { Button, Divider, Form, Input, message, PageHeader, Row } from 'antd'
import FormItem from 'antd/lib/form/FormItem'
import { Store } from 'antd/lib/form/interface'
import { Content } from 'antd/lib/layout/layout'
import React, { FormEvent } from 'react'
import { useState } from 'react'
@@ -8,21 +10,11 @@ import { createClient } from '../api'
export const Dashboard = () => {
const history = useHistory()
const [error, setError] = useState<string | null>(null)
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [phone, setPhone] = useState('')
const handleReset = () => {
//
setName('')
setEmail('')
setPhone('')
}
const handleReset = () => {}
const handleSubmit = async (e: FormEvent) => {
e.preventDefault()
if (phone.length < 10) {
const handleSubmit = async (values: Store) => {
if (values.phone.length < 10) {
// helpful message
message.error('Check all fields!')
setError('Phone number needs to be a length of at least 10')
@@ -30,9 +22,9 @@ export const Dashboard = () => {
}
const client_id = await createClient({
name,
email,
phone: parseInt(phone),
name: values.name,
email: values.email,
phone: parseInt(values.phone.replace(/\D/g, '')),
})
history.push(`/sessions/${client_id}`)
@@ -45,42 +37,31 @@ export const Dashboard = () => {
subTitle="Enter the name, email and phone number of the subject"
></PageHeader>
<Divider />
<form onSubmit={handleSubmit}>
<label htmlFor="name">
Name:
<input
minLength={3}
value={name}
onChange={(e) => setName(e.target.value)}
name="name"
/>
</label>
<label htmlFor="email">
Email:
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
type="email"
name="email"
/>
</label>
<label htmlFor="phone">
Phone:
<input
value={phone}
onChange={(e) => setPhone(e.target.value)}
type="tel"
name="phone"
/>
</label>
<Button danger onClick={handleReset}>
Reset
</Button>
<Button htmlType="submit" type="primary">
Start Session
</Button>
<Form
className="dashboard-form"
onFinish={handleSubmit}
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
>
<FormItem label="name" name="name">
<Input minLength={3} />
</FormItem>
<FormItem label="email" name="email">
<Input type="email" />
</FormItem>
<FormItem label="phone" name="phone">
<Input type="tel" minLength={10} />
</FormItem>
<Row justify="space-between">
<Button danger onClick={handleReset}>
Reset
</Button>
<Button htmlType="submit" type="primary">
Start Session
</Button>
</Row>
{error && <p className="error">{error}</p>}
</form>
</Form>
</Content>
)
}

View File

@@ -1,16 +1,10 @@
import React, { useEffect, useState } from 'react'
import { RouteComponentProps, useHistory } from 'react-router-dom'
import { getClient, killSession, restartSession, startSession } from '../api'
import { SessionPictures } from './SessionPictures'
import {
Button,
Divider,
message,
PageHeader,
Popconfirm,
Row,
Tag,
} from 'antd'
import { SessionPictures } from '../components/SessionPictures'
import { StatusChip } from '../components/StatusChip'
import { Button, Divider, message, Popconfirm, Row, Typography } from 'antd'
import { Content } from 'antd/lib/layout/layout'
import { Client } from '../types'
@@ -59,50 +53,61 @@ export const Session = (props: Props) => {
return (
<Content>
<PageHeader
ghost={false}
onBack={() => history.goBack()}
title={`Session for ${clientId}`}
tags={active ? <Tag color="lime">Active</Tag> : <Tag>Inactive</Tag>}
subTitle={`session has ${active ? 'started' : 'not started'}`}
extra={[
<Button
key="startsession"
disabled={active}
type="primary"
onClick={handleStartSession}
>
Capture
</Button>,
<Popconfirm
key="retry"
title="Re-capture set?"
onConfirm={handleRestartSession}
>
<Button type="default" disabled={!active}>
Retry Capture
</Button>
</Popconfirm>,
<Popconfirm
key="nuke"
title="Delete all photos and return to dashboard?"
onConfirm={handleNuke}
>
<Button danger disabled={!active}>
Abort Session
</Button>
</Popconfirm>,
<Button
key="finish"
ghost
type="primary"
disabled={!active}
onClick={handleExit}
>
Finish Session
</Button>,
]}
></PageHeader>
<Row justify="center">
<Typography.Title>Client: {client?.name}</Typography.Title>
</Row>
<Row justify="space-around" style={{ width: '60%', margin: 'auto' }}>
<Typography.Text>
<strong>email:</strong> {client?.email}
</Typography.Text>
<Typography.Text>
<strong>phone:</strong> {client?.phone}
</Typography.Text>
</Row>
<Divider />
<Row justify="center" className="session-header">
<Button
key="startsession"
disabled={active}
type="primary"
onClick={handleStartSession}
>
Capture
</Button>
<Popconfirm
disabled={!active}
key="retry"
title="Re-capture set?"
onConfirm={handleRestartSession}
>
<Button type="default" disabled={!active}>
Retry Capture
</Button>
</Popconfirm>
<Popconfirm
key="nuke"
disabled={!active}
title="Delete all photos and return to dashboard?"
onConfirm={handleNuke}
>
<Button danger disabled={!active}>
Abort Session
</Button>
</Popconfirm>
<Button
key="finish"
ghost
type="primary"
disabled={!active}
onClick={handleExit}
>
Finish Session
</Button>
<StatusChip poll={true} />
</Row>
<Divider />
<Row className="controls">
{active && <SessionPictures clientId={clientId} />}

View File

@@ -1,84 +0,0 @@
import React, { useEffect, useState } from 'react'
import { Card, message, Modal, PageHeader, Spin } from 'antd'
import { getSession } from '../api'
type Props = {
clientId: string
}
export const SessionPictures = ({ clientId }: Props) => {
const [urls, setUrls] = useState<string[] | null>(null)
const [activeUrl, setActiveUrl] = useState<string | null>(null)
const [loading, setLoading] = useState(true)
const handleSync = async () => {
message.info('Syncing photos...')
const { photos } = await getSession(clientId)
if (photos.length) setUrls(photos)
}
useEffect(() => {
const get = async () => {
if (urls && urls.length >= 89 * 2) {
setLoading(false)
return
}
const { photos } = await getSession(clientId)
if (photos.length) setUrls(photos)
}
const interval = setInterval(get, 250)
return () => clearInterval(interval)
}, [clientId, urls])
const closeModal = () => setActiveUrl(null)
const host =
process.env.NODE_ENV === 'development' ? 'http://192.168.1.107:5000' : ''
if (!urls?.length) return null
return (
<>
<Modal
visible={!!activeUrl}
onOk={closeModal}
cancelText={null}
onCancel={closeModal}
width="50%"
>
<img
width="100%"
onClick={closeModal}
src={`${host}/output/${clientId}/${activeUrl}`}
alt="large image"
></img>
</Modal>
<PageHeader
title="Session Pictures"
subTitle={`${urls.length}/${89 * 2} loaded`}
></PageHeader>
<div className="photo-wall">
{urls ? (
urls
.sort((a, b) => a.split('_')[0].localeCompare(b.split('_')[0]))
.map((src) => (
<Card className="photo" title={src.split('_')[0]}>
<img
onClick={() => setActiveUrl(src)}
key={src}
id={src}
src={`${host}/output/${clientId}/${src}`}
alt="lol"
/>
</Card>
))
) : (
<Spin />
)}
</div>
</>
)
}