🥳
This commit is contained in:
parent
11cf67b594
commit
d1e5b0310b
|
@ -2,6 +2,31 @@
|
||||||
|
|
||||||
# Requirements (pages)
|
# Requirements (pages)
|
||||||
|
|
||||||
|
# Routes
|
||||||
|
|
||||||
|
Client Datatype
|
||||||
|
|
||||||
|
```ts
|
||||||
|
type Client = {
|
||||||
|
name: string
|
||||||
|
email: string
|
||||||
|
phone: number
|
||||||
|
active_session: boolean
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
post /api/clients -> create new client
|
||||||
|
get /api/clients -> get client list
|
||||||
|
get /api/clients/:id -> get client
|
||||||
|
|
||||||
|
```ts
|
||||||
|
type Session = string[] | null
|
||||||
|
```
|
||||||
|
|
||||||
|
post /api/clients/:id/session -> begin capture
|
||||||
|
get /api/clients/:id/session -> get active sesion (list of preview photo locations)
|
||||||
|
delete /api/clients/:id/session -> delete all current photos (for new capture)
|
||||||
|
|
||||||
## Create Session
|
## Create Session
|
||||||
|
|
||||||
Information gathering
|
Information gathering
|
||||||
|
|
18636
client/package-lock.json
generated
18636
client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
BIN
client/public/1.jpg
Normal file
BIN
client/public/1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
client/public/2.jpg
Normal file
BIN
client/public/2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
client/public/3.jpg
Normal file
BIN
client/public/3.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
client/public/4.jpg
Normal file
BIN
client/public/4.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
|
@ -10,10 +10,8 @@ function App() {
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/" component={Dashboard} />
|
|
||||||
<Route path="/sessions/:clientId" component={Session} />
|
<Route path="/sessions/:clientId" component={Session} />
|
||||||
<p>landing page</p>
|
<Route exact path="/" component={Dashboard} />
|
||||||
<p>session</p>
|
|
||||||
</Switch>
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
|
|
@ -1,33 +1,44 @@
|
||||||
import settings from '../settings'
|
|
||||||
import { Client } from '../types'
|
import { Client } from '../types'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import { client, clients, session } from '../data'
|
||||||
|
|
||||||
const { apiUrl } = settings
|
const apiUrl = '/api'
|
||||||
|
|
||||||
export const createClient = async (body: Client) => {
|
export const createClient = async (body: Client) => {
|
||||||
await axios.post(`${apiUrl}/clients`, body)
|
await axios.post(`${apiUrl}/clients`, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getClients = async (): Promise<Client[]> => {
|
export const getClients = async (): Promise<Client[]> => {
|
||||||
|
return clients
|
||||||
const res = await axios.post<Client[]>(`${apiUrl}/clients`)
|
const res = await axios.post<Client[]>(`${apiUrl}/clients`)
|
||||||
return res.data as Client[]
|
return res.data
|
||||||
}
|
}
|
||||||
|
export const getClient = async (id: string): Promise<Client> => {
|
||||||
export const beginCapture = async (clientId: string) => {
|
return client
|
||||||
|
const res = await axios.post<Client>(`${apiUrl}/client/${id}`)
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
export const startSession = async (clientId: string) => {
|
||||||
|
//
|
||||||
const res = await axios.post(`${apiUrl}/clients/${clientId}/session`)
|
const res = await axios.post(`${apiUrl}/clients/${clientId}/session`)
|
||||||
return res.data as string // capture id
|
return res.data // session data
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getCapture = async (
|
export const getSession = async (
|
||||||
clientId: string,
|
clientId: string,
|
||||||
): Promise<null | string[]> => {
|
): Promise<null | string[]> => {
|
||||||
|
return session
|
||||||
const res = await axios.get(`${apiUrl}/clients/${clientId}/session`)
|
const res = await axios.get(`${apiUrl}/clients/${clientId}/session`)
|
||||||
return res.data as null | string[]
|
return res.data as null | string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const retryCapture = async (clientId: string) => {
|
export const killSession = async (clientId: string) => {
|
||||||
await axios.delete(`${apiUrl}/clients/${clientId}/session`)
|
await axios.delete(`${apiUrl}/clients/${clientId}/session`)
|
||||||
await axios.post(`${apiUrl}/clients/${clientId}/session`)
|
}
|
||||||
|
|
||||||
|
export const restartSession = async (clientId: string) => {
|
||||||
|
await killSession(clientId)
|
||||||
|
await startSession(clientId)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const cleanup = () => {
|
export const cleanup = () => {
|
||||||
|
|
23
client/src/data/index.ts
Normal file
23
client/src/data/index.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { Client } from '../types'
|
||||||
|
|
||||||
|
export const clients: Client[] = [
|
||||||
|
{
|
||||||
|
name: 'Elijah',
|
||||||
|
email: 'elijah@elijah.com',
|
||||||
|
phone: 4039876543,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Tanner',
|
||||||
|
email: 'tanner@tanner.com',
|
||||||
|
phone: 4031234567,
|
||||||
|
activeSession: true,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
export const client: Client = clients[0]
|
||||||
|
|
||||||
|
export const session = [
|
||||||
|
'/images/1.jpg',
|
||||||
|
'/images/2.jpg',
|
||||||
|
'/images/3.jpg',
|
||||||
|
'/images/4.jpg',
|
||||||
|
]
|
|
@ -11,3 +11,19 @@ code {
|
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||||
monospace;
|
monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
max-width: 500px;
|
||||||
|
margin: auto;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
form label {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import React from 'react'
|
import { env } from 'process'
|
||||||
|
import React, { FormEvent } from 'react'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useHistory } from 'react-router-dom'
|
import { useHistory } from 'react-router-dom'
|
||||||
import { createClient } from '../api'
|
import { createClient } from '../api'
|
||||||
|
import settings from '../settings'
|
||||||
|
|
||||||
export const Dashboard = () => {
|
export const Dashboard = () => {
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
|
@ -11,12 +13,20 @@ export const Dashboard = () => {
|
||||||
|
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
//
|
//
|
||||||
|
setName('')
|
||||||
|
setEmail('')
|
||||||
|
setPhone('')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async (e: FormEvent) => {
|
||||||
// phone number is stripped for numbers
|
e.preventDefault()
|
||||||
|
|
||||||
await createClient({ name, email, phone })
|
if (settings.env === 'jank') {
|
||||||
|
history.push(`/sessions/${phone}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await createClient({ name, email, phone: parseInt(phone) })
|
||||||
history.push(`/sessions/${phone}`)
|
history.push(`/sessions/${phone}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,18 +36,34 @@ export const Dashboard = () => {
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<label htmlFor="name">
|
<label htmlFor="name">
|
||||||
Name:
|
Name:
|
||||||
<input type="text" name="name" />
|
<input
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
name="name"
|
||||||
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label htmlFor="email">
|
<label htmlFor="email">
|
||||||
Email:
|
Email:
|
||||||
<input type="email" name="email" />
|
<input
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
type="email"
|
||||||
|
name="email"
|
||||||
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label htmlFor="phone">
|
<label htmlFor="phone">
|
||||||
Phone:
|
Phone:
|
||||||
<input type="phone" name="phone" />
|
<input
|
||||||
|
value={phone}
|
||||||
|
onChange={(e) => setPhone(e.target.value)}
|
||||||
|
type="tel"
|
||||||
|
name="phone"
|
||||||
|
/>
|
||||||
</label>
|
</label>
|
||||||
<button type="submit">Start Session</button>
|
<button type="submit">Start Session</button>
|
||||||
<button onClick={handleReset}>Reset</button>
|
<button type="button" onClick={handleReset}>
|
||||||
|
Reset
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<div>TODO: List of past sessions for review?</div>
|
<div>TODO: List of past sessions for review?</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,15 +1,43 @@
|
||||||
import React from 'react'
|
import axios from 'axios'
|
||||||
import { useEffect } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { RouteComponentProps } from 'react-router-dom'
|
import { RouteComponentProps, useHistory } from 'react-router-dom'
|
||||||
|
import { getClient, killSession } from '../api'
|
||||||
|
import { SessionPictures } from './SessionPictures'
|
||||||
|
|
||||||
type Props = RouteComponentProps<{ clientId: string }>
|
type Props = RouteComponentProps<{ clientId: string }>
|
||||||
|
|
||||||
export const Session = (props: Props) => {
|
export const Session = (props: Props) => {
|
||||||
|
const history = useHistory()
|
||||||
const { clientId } = props.match.params
|
const { clientId } = props.match.params
|
||||||
|
|
||||||
const [submitted, setSubmitted] = useState(false)
|
const [submitted, setSubmitted] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {})
|
const handleExit = async () => {
|
||||||
|
history.push('/')
|
||||||
return <div>Session {clientId}</div>
|
}
|
||||||
|
|
||||||
|
const handleNuke = async () => {
|
||||||
|
await killSession(clientId)
|
||||||
|
history.push('/')
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const get = async () => {
|
||||||
|
const { activeSession } = await getClient(clientId)
|
||||||
|
if (activeSession) setSubmitted(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
get()
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Session for {clientId}</h1>
|
||||||
|
<button>Capture</button>
|
||||||
|
{submitted && <SessionPictures clientId={clientId} />}
|
||||||
|
<div className="controls">
|
||||||
|
<button onClick={handleNuke}>Nuke Session</button>
|
||||||
|
<button onClick={handleExit}>Exit Session</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
29
client/src/pages/SessionPictures.tsx
Normal file
29
client/src/pages/SessionPictures.tsx
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { getSession } from '../api'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
clientId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SessionPictures = ({ clientId }: Props) => {
|
||||||
|
const [pics, setPics] = useState<string[] | null>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const get = async () => {
|
||||||
|
if (pics) return
|
||||||
|
const previewPics = await getSession(clientId)
|
||||||
|
if (previewPics) setPics(previewPics)
|
||||||
|
}
|
||||||
|
|
||||||
|
const interval = setInterval(get, 300)
|
||||||
|
|
||||||
|
return () => clearInterval(interval)
|
||||||
|
}, [clientId, pics])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3>Session Pictures</h3>
|
||||||
|
{pics && pics.map((src) => <img id={src} src={src} />)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
export default {
|
export default {
|
||||||
apiUrl: "http://localhost/api",
|
env: 'jank',
|
||||||
port: 4442,
|
port: 4442,
|
||||||
};
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ export type Client = {
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
phone: number;
|
phone: number;
|
||||||
|
activeSession?: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Session = {
|
export type Session = {
|
||||||
|
|
18379
client/yarn.lock
18379
client/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user