Compare commits
40 Commits
b0aec2cfd1
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 4e7fa44301 | |||
| 104d39b4c6 | |||
| 88e62bdf48 | |||
| b9c8b6c1e6 | |||
| 66f86827ff | |||
| 8ca4d55045 | |||
| 2b495779d3 | |||
| ce46f006d5 | |||
| 5f8aad7355 | |||
| c975432b73 | |||
| be140b4c22 | |||
| 3c5855ecd3 | |||
| 1499ee5736 | |||
| a07d4469c0 | |||
| 5e565f84c2 | |||
| b2cc6f4723 | |||
| 6720816a97 | |||
| 5c15c8fcf5 | |||
| 738e688c51 | |||
| 19352bf409 | |||
| a632034751 | |||
| fa6809b507 | |||
| c29a64b1cc | |||
| d1486b61df | |||
| ecb8c1f815 | |||
| ec8128d96a | |||
| 15023b0e24 | |||
| 534a3fe632 | |||
| f338e14577 | |||
| d5cfbafbde | |||
| b213f4cb18 | |||
| 612f47d551 | |||
| 14395bdbdd | |||
| be284b9acb | |||
| 9fe790ed9c | |||
| 91e26fe9fc | |||
| 0760c93ce4 | |||
| b1aaffa4db | |||
| 0f0f6b1f7f | |||
| e8822a8d3a |
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2021 Tanner and Elijah
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,22 +1,25 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.cada1265.chunk.css",
|
||||
"main.js": "/static/js/main.3f5ea67c.chunk.js",
|
||||
"main.js.map": "/static/js/main.3f5ea67c.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.e7edc0d2.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.e7edc0d2.js.map",
|
||||
"static/js/2.6c19819d.chunk.js": "/static/js/2.6c19819d.chunk.js",
|
||||
"static/js/2.6c19819d.chunk.js.map": "/static/js/2.6c19819d.chunk.js.map",
|
||||
"static/js/3.feab56bb.chunk.js": "/static/js/3.feab56bb.chunk.js",
|
||||
"static/js/3.feab56bb.chunk.js.map": "/static/js/3.feab56bb.chunk.js.map",
|
||||
"main.css": "/static/css/main.895ab0f5.chunk.css",
|
||||
"main.js": "/static/js/main.4388b0cf.chunk.js",
|
||||
"main.js.map": "/static/js/main.4388b0cf.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.8d7962eb.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.8d7962eb.js.map",
|
||||
"static/css/2.015dc0ab.chunk.css": "/static/css/2.015dc0ab.chunk.css",
|
||||
"static/js/2.6d12aa16.chunk.js": "/static/js/2.6d12aa16.chunk.js",
|
||||
"static/js/2.6d12aa16.chunk.js.map": "/static/js/2.6d12aa16.chunk.js.map",
|
||||
"static/js/3.8e9312c3.chunk.js": "/static/js/3.8e9312c3.chunk.js",
|
||||
"static/js/3.8e9312c3.chunk.js.map": "/static/js/3.8e9312c3.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/css/main.cada1265.chunk.css.map": "/static/css/main.cada1265.chunk.css.map",
|
||||
"static/js/2.6c19819d.chunk.js.LICENSE.txt": "/static/js/2.6c19819d.chunk.js.LICENSE.txt"
|
||||
"static/css/2.015dc0ab.chunk.css.map": "/static/css/2.015dc0ab.chunk.css.map",
|
||||
"static/css/main.895ab0f5.chunk.css.map": "/static/css/main.895ab0f5.chunk.css.map",
|
||||
"static/js/2.6d12aa16.chunk.js.LICENSE.txt": "/static/js/2.6d12aa16.chunk.js.LICENSE.txt"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.e7edc0d2.js",
|
||||
"static/js/2.6c19819d.chunk.js",
|
||||
"static/css/main.cada1265.chunk.css",
|
||||
"static/js/main.3f5ea67c.chunk.js"
|
||||
"static/js/runtime-main.8d7962eb.js",
|
||||
"static/css/2.015dc0ab.chunk.css",
|
||||
"static/js/2.6d12aa16.chunk.js",
|
||||
"static/css/main.895ab0f5.chunk.css",
|
||||
"static/js/main.4388b0cf.chunk.js"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<text y=".9em" font-size="90">
|
||||
💩
|
||||
</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 110 B |
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>React App</title><link href="/static/css/main.cada1265.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);p.length;)p.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"feab56bb"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpclient=this.webpackJsonpclient||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([])</script><script src="/static/js/2.6c19819d.chunk.js"></script><script src="/static/js/main.3f5ea67c.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="3D Shock by Tanner and Elijah enterprises"/><link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚡</text></svg>"><link rel="manifest" href="/manifest.json"/><title>3D Shock!</title><link href="/static/css/2.015dc0ab.chunk.css" rel="stylesheet"><link href="/static/css/main.895ab0f5.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);p.length;)p.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"8e9312c3"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpclient=this.webpackJsonpclient||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([])</script><script src="/static/js/2.6d12aa16.chunk.js"></script><script src="/static/js/main.4388b0cf.chunk.js"></script></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
|
||||
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}form{max-width:500px;-webkit-flex-direction:column;flex-direction:column}form,form label{display:-webkit-flex;display:flex;margin:auto}form label{width:100%;-webkit-flex-direction:row;flex-direction:row;-webkit-justify-content:space-between;justify-content:space-between}:root{--color-primary:#282c34}.App-header{background-color:#282c34;background-color:var(--color-primary);min-height:100vh;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;font-size:calc(10px + 2vmin);color:#fff}.App-link{color:#61dafb}@-webkit-keyframes App-logo-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes App-logo-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.error{color:red}.photo-wall{display:-webkit-flex;display:flex;-webkit-justify-content:center;justify-content:center;-webkit-flex-wrap:wrap;flex-wrap:wrap;margin:2rem}.dashboard-form{margin:auto}.ant-card{margin:1rem}.ant-card img{max-width:250px}.loading-bar-container{background:#282c34;background:var(--color-primary);width:100%;height:30px;min-height:30px}.loading-bar{transition:all .5s linear;background:#6f6;height:100%}.page-head{background:#282c34;background:var(--color-primary);color:#fff!important;margin-top:0;padding:1rem}.session-toolbar button{margin:0 .5rem;padding:.5rem 1rem;height:100%;font-weight:700;text-transform:uppercase;letter-spacing:.05rem}.ant-modal-content{border-radius:1rem;padding:0!important}.ant-modal-body img{border-radius:.5rem}.ant-modal-close{font-weight:700}.ant-card{border:1px solid #282c34;border:1px solid var(--color-primary);border-radius:.2rem}.ant-card-head{background:#282c34;background:var(--color-primary);color:#fff;font-weight:700;text-transform:uppercase;letter-spacing:.2rem}.session-toolbar{-webkit-justify-content:center;justify-content:center;width:60%;margin:1rem auto}.session-toolbar h3{font-weight:700;color:#fff;margin-right:1rem}.slider{width:400px;margin:auto 1rem}.toolbar{padding:.5rem;background:#282c34;background:var(--color-primary)}.client-info{-webkit-justify-content:center;justify-content:center;width:60%;margin:1rem auto}.client-info span{margin:auto 1rem}
|
||||
/*# sourceMappingURL=main.895ab0f5.chunk.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack://src/index.css","webpack://src/App.css"],"names":[],"mappings":"AAAA,KACE,QAAS,CACT,mJAEY,CACZ,kCAAmC,CACnC,iCACF,CAEA,KACE,yEAEF,CAEA,KAEE,eAAgB,CAEhB,6BAAsB,CAAtB,qBACF,CAEA,gBANE,oBAAa,CAAb,YAAa,CAEb,WAUF,CANA,WACE,UAAW,CAEX,0BAAmB,CAAnB,kBAAmB,CACnB,qCAA8B,CAA9B,6BAEF,CC3BA,MACE,uBACF,CAEA,YACE,wBAAsC,CAAtC,qCAAsC,CACtC,gBAAiB,CACjB,oBAAa,CAAb,YAAa,CACb,6BAAsB,CAAtB,qBAAsB,CACtB,0BAAmB,CAAnB,kBAAmB,CACnB,8BAAuB,CAAvB,sBAAuB,CACvB,4BAA6B,CAC7B,UACF,CAEA,UACE,aACF,CAEA,iCACE,GACE,8BAAuB,CAAvB,sBACF,CACA,GACE,+BAAyB,CAAzB,uBACF,CACF,CAPA,yBACE,GACE,8BAAuB,CAAvB,sBACF,CACA,GACE,+BAAyB,CAAzB,uBACF,CACF,CAEA,OACE,SACF,CAEA,YACE,oBAAa,CAAb,YAAa,CACb,8BAAuB,CAAvB,sBAAuB,CACvB,sBAAe,CAAf,cAAe,CACf,WACF,CAEA,gBACE,WACF,CAEA,UACE,WACF,CAEA,cACE,eACF,CAEA,uBACE,kBAAgC,CAAhC,+BAAgC,CAChC,UAAW,CACX,WAAY,CACZ,eACF,CAEA,aACE,yBAA2B,CAC3B,eAAmB,CACnB,WACF,CAEA,WACE,kBAAgC,CAAhC,+BAAgC,CAChC,oBAAuB,CACvB,YAAa,CACb,YACF,CAEA,wBACE,cAAgB,CAChB,kBAAoB,CACpB,WAAY,CACZ,eAAiB,CACjB,wBAAyB,CACzB,qBACF,CAEA,mBACE,kBAAmB,CACnB,mBACF,CAEA,oBACE,mBACF,CAEA,iBACE,eACF,CAEA,UACE,wBAAsC,CAAtC,qCAAsC,CACtC,mBACF,CAEA,eACE,kBAAgC,CAAhC,+BAAgC,CAChC,UAAY,CACZ,eAAiB,CACjB,wBAAyB,CACzB,oBACF,CAEA,iBACE,8BAAuB,CAAvB,sBAAuB,CACvB,SAAU,CACV,gBACF,CAEA,oBACE,eAAiB,CACjB,UAAY,CACZ,iBACF,CAEA,QACE,WAAY,CACZ,gBACF,CAEA,SACE,aAAe,CACf,kBAAgC,CAAhC,+BACF,CAEA,aACE,8BAAuB,CAAvB,sBAAuB,CACvB,SAAU,CACV,gBACF,CAEA,kBACE,gBACF","file":"main.895ab0f5.chunk.css","sourcesContent":["body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n monospace;\n}\n\nform {\n display: flex;\n max-width: 500px;\n margin: auto;\n flex-direction: column;\n}\n\nform label {\n width: 100%; \n display: flex;\n flex-direction: row;\n justify-content: space-between;\n margin: auto;\n}\n\n",":root {\n --color-primary: #282c34;\n}\n\n.App-header {\n background-color: var(--color-primary);\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n.error {\n color: red;\n}\n\n.photo-wall {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n margin: 2rem;\n}\n\n.dashboard-form {\n margin: auto;\n}\n\n.ant-card {\n margin: 1rem;\n}\n\n.ant-card img {\n max-width: 250px;\n}\n\n.loading-bar-container {\n background: var(--color-primary);\n width: 100%;\n height: 30px;\n min-height: 30px;\n}\n\n.loading-bar {\n transition: all 0.5s linear;\n background: #66ff66;\n height: 100%;\n}\n\n.page-head {\n background: var(--color-primary);\n color: white !important;\n margin-top: 0;\n padding: 1rem;\n}\n\n.session-toolbar button {\n margin: 0 0.5rem;\n padding: 0.5rem 1rem;\n height: 100%;\n font-weight: bold;\n text-transform: uppercase;\n letter-spacing: 0.05rem;\n}\n\n.ant-modal-content {\n border-radius: 1rem;\n padding: 0 !important;\n}\n\n.ant-modal-body img {\n border-radius: 0.5rem;\n}\n\n.ant-modal-close {\n font-weight: bold;\n}\n\n.ant-card {\n border: 1px solid var(--color-primary);\n border-radius: 0.2rem;\n}\n\n.ant-card-head {\n background: var(--color-primary);\n color: white;\n font-weight: bold;\n text-transform: uppercase;\n letter-spacing: 0.2rem;\n}\n\n.session-toolbar {\n justify-content: center;\n width: 60%;\n margin: 1rem auto;\n}\n\n.session-toolbar h3 {\n font-weight: bold;\n color: white;\n margin-right: 1rem;\n}\n\n.slider {\n width: 400px;\n margin: auto 1rem;\n}\n\n.toolbar {\n padding: 0.5rem;\n background: var(--color-primary);\n}\n\n.client-info {\n justify-content: center;\n width: 60%;\n margin: 1rem auto;\n}\n\n.client-info span {\n margin: auto 1rem;\n}\n"]}
|
||||
@@ -1,2 +0,0 @@
|
||||
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}form{max-width:500px;-webkit-flex-direction:column;flex-direction:column}form,form label{display:-webkit-flex;display:flex;margin:auto}form label{width:100%;-webkit-flex-direction:row;flex-direction:row;-webkit-justify-content:space-between;justify-content:space-between}.App{text-align:center}.App-logo{height:40vmin;pointer-events:none}@media (prefers-reduced-motion:no-preference){.App-logo{-webkit-animation:App-logo-spin 20s linear infinite;animation:App-logo-spin 20s linear infinite}}.App-header{background-color:#282c34;min-height:100vh;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;font-size:calc(10px + 2vmin);color:#fff}.App-link{color:#61dafb}@-webkit-keyframes App-logo-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes App-logo-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}
|
||||
/*# sourceMappingURL=main.cada1265.chunk.css.map */
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":["webpack://src/index.css","webpack://src/App.css"],"names":[],"mappings":"AAAA,KACE,QAAS,CACT,mJAEY,CACZ,kCAAmC,CACnC,iCACF,CAEA,KACE,yEAEF,CAEA,KAEE,eAAgB,CAEhB,6BAAsB,CAAtB,qBACF,CAEA,gBANE,oBAAa,CAAb,YAAa,CAEb,WAUF,CANA,WACE,UAAW,CAEX,0BAAmB,CAAnB,kBAAmB,CACnB,qCAA8B,CAA9B,6BAEF,CC3BA,KACE,iBACF,CAEA,UACE,aAAc,CACd,mBACF,CAEA,8CACE,UACE,mDAA4C,CAA5C,2CACF,CACF,CAEA,YACE,wBAAyB,CACzB,gBAAiB,CACjB,oBAAa,CAAb,YAAa,CACb,6BAAsB,CAAtB,qBAAsB,CACtB,0BAAmB,CAAnB,kBAAmB,CACnB,8BAAuB,CAAvB,sBAAuB,CACvB,4BAA6B,CAC7B,UACF,CAEA,UACE,aACF,CAEA,iCACE,GACE,8BAAuB,CAAvB,sBACF,CACA,GACE,+BAAyB,CAAzB,uBACF,CACF,CAPA,yBACE,GACE,8BAAuB,CAAvB,sBACF,CACA,GACE,+BAAyB,CAAzB,uBACF,CACF","file":"main.cada1265.chunk.css","sourcesContent":["body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n monospace;\n}\n\nform {\n display: flex;\n max-width: 500px;\n margin: auto;\n flex-direction: column;\n}\n\nform label {\n width: 100%; \n display: flex;\n flex-direction: row;\n justify-content: space-between;\n margin: auto;\n}\n\n",".App {\n text-align: center;\n}\n\n.App-logo {\n height: 40vmin;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .App-logo {\n animation: App-logo-spin infinite 20s linear;\n }\n}\n\n.App-header {\n background-color: #282c34;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n"]}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6
@@ -4,6 +4,12 @@ object-assign
|
||||
@license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
Copyright (c) 2017 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
|
||||
/** @license React v0.20.1
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
|
||||
(this.webpackJsonpclient=this.webpackJsonpclient||[]).push([[3],{399:function(t,n,e){"use strict";e.r(n),e.d(n,"getCLS",(function(){return v})),e.d(n,"getFCP",(function(){return y})),e.d(n,"getFID",(function(){return k})),e.d(n,"getLCP",(function(){return C})),e.d(n,"getTTFB",(function(){return P}));var i,a,r,o,c=function(t,n){return{name:t,value:void 0===n?-1:n,delta:0,entries:[],id:"v1-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},u=function(t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var e=new PerformanceObserver((function(t){return t.getEntries().map(n)}));return e.observe({type:t,buffered:!0}),e}}catch(t){}},f=!1,s=function(t,n){f||"undefined"!=typeof InstallTrigger||(addEventListener("beforeunload",(function(){})),f=!0),addEventListener("visibilitychange",(function e(i){"hidden"===document.visibilityState&&(t(i),n&&removeEventListener("visibilitychange",e,!0))}),!0)},d=function(t){addEventListener("pageshow",(function(n){n.persisted&&t(n)}),!0)},m="function"==typeof WeakSet?new WeakSet:new Set,p=function(t,n,e){var i;return function(){n.value>=0&&(e||m.has(n)||"hidden"===document.visibilityState)&&(n.delta=n.value-(i||0),(n.delta||void 0===i)&&(i=n.value,t(n)))}},v=function(t,n){var e,i=c("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},r=u("layout-shift",a);r&&(e=p(t,i,n),s((function(){r.takeRecords().map(a),e()})),d((function(){i=c("CLS",0),e=p(t,i,n)})))},l=-1,h=function(){return"hidden"===document.visibilityState?0:1/0},S=function(){s((function(t){var n=t.timeStamp;l=n}),!0)},g=function(){return l<0&&(l=h(),S(),d((function(){setTimeout((function(){l=h(),S()}),0)}))),{get timeStamp(){return l}}},y=function(t,n){var e,i=g(),a=c("FCP"),r=u("paint",(function(t){"first-contentful-paint"===t.name&&(r&&r.disconnect(),t.startTime<i.timeStamp&&(a.value=t.startTime,a.entries.push(t),m.add(a),e()))}));r&&(e=p(t,a,n),d((function(i){a=c("FCP"),e=p(t,a,n),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),e()}))}))})))},w={passive:!0,capture:!0},E=new Date,L=function(t,n){i||(i=n,a=t,r=new Date,F(removeEventListener),T())},T=function(){if(a>=0&&a<r-E){var t={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+a};o.forEach((function(n){n(t)})),o=[]}},b=function(t){if(t.cancelable){var n=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,n){var e=function(){L(t,n),a()},i=function(){a()},a=function(){removeEventListener("pointerup",e,w),removeEventListener("pointercancel",i,w)};addEventListener("pointerup",e,w),addEventListener("pointercancel",i,w)}(n,t):L(n,t)}},F=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return t(n,b,w)}))},k=function(t,n){var e,r=g(),f=c("FID"),v=function(t){t.startTime<r.timeStamp&&(f.value=t.processingStart-t.startTime,f.entries.push(t),m.add(f),e())},l=u("first-input",v);e=p(t,f,n),l&&s((function(){l.takeRecords().map(v),l.disconnect()}),!0),l&&d((function(){var r;f=c("FID"),e=p(t,f,n),o=[],a=-1,i=null,F(addEventListener),r=v,o.push(r),T()}))},C=function(t,n){var e,i=g(),a=c("LCP"),r=function(t){var n=t.startTime;n<i.timeStamp&&(a.value=n,a.entries.push(t)),e()},o=u("largest-contentful-paint",r);if(o){e=p(t,a,n);var f=function(){m.has(a)||(o.takeRecords().map(r),o.disconnect(),m.add(a),e())};["keydown","click"].forEach((function(t){addEventListener(t,f,{once:!0,capture:!0})})),s(f,!0),d((function(i){a=c("LCP"),e=p(t,a,n),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),e()}))}))}))}},P=function(t){var n,e=c("TTFB");n=function(){try{var n=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,n={entryType:"navigation",startTime:0};for(var e in t)"navigationStart"!==e&&"toJSON"!==e&&(n[e]=Math.max(t[e]-t.navigationStart,0));return n}();e.value=e.delta=n.responseStart,e.entries=[n],t(e)}catch(t){}},"complete"===document.readyState?setTimeout(n,0):addEventListener("pageshow",n)}}}]);
|
||||
//# sourceMappingURL=3.8e9312c3.chunk.js.map
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
||||
(this.webpackJsonpclient=this.webpackJsonpclient||[]).push([[3],{64:function(t,n,e){"use strict";e.r(n),e.d(n,"getCLS",(function(){return v})),e.d(n,"getFCP",(function(){return y})),e.d(n,"getFID",(function(){return k})),e.d(n,"getLCP",(function(){return C})),e.d(n,"getTTFB",(function(){return P}));var i,a,r,o,c=function(t,n){return{name:t,value:void 0===n?-1:n,delta:0,entries:[],id:"v1-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},u=function(t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var e=new PerformanceObserver((function(t){return t.getEntries().map(n)}));return e.observe({type:t,buffered:!0}),e}}catch(t){}},f=!1,s=function(t,n){f||"undefined"!=typeof InstallTrigger||(addEventListener("beforeunload",(function(){})),f=!0),addEventListener("visibilitychange",(function e(i){"hidden"===document.visibilityState&&(t(i),n&&removeEventListener("visibilitychange",e,!0))}),!0)},d=function(t){addEventListener("pageshow",(function(n){n.persisted&&t(n)}),!0)},m="function"==typeof WeakSet?new WeakSet:new Set,p=function(t,n,e){var i;return function(){n.value>=0&&(e||m.has(n)||"hidden"===document.visibilityState)&&(n.delta=n.value-(i||0),(n.delta||void 0===i)&&(i=n.value,t(n)))}},v=function(t,n){var e,i=c("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},r=u("layout-shift",a);r&&(e=p(t,i,n),s((function(){r.takeRecords().map(a),e()})),d((function(){i=c("CLS",0),e=p(t,i,n)})))},l=-1,h=function(){return"hidden"===document.visibilityState?0:1/0},S=function(){s((function(t){var n=t.timeStamp;l=n}),!0)},g=function(){return l<0&&(l=h(),S(),d((function(){setTimeout((function(){l=h(),S()}),0)}))),{get timeStamp(){return l}}},y=function(t,n){var e,i=g(),a=c("FCP"),r=u("paint",(function(t){"first-contentful-paint"===t.name&&(r&&r.disconnect(),t.startTime<i.timeStamp&&(a.value=t.startTime,a.entries.push(t),m.add(a),e()))}));r&&(e=p(t,a,n),d((function(i){a=c("FCP"),e=p(t,a,n),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),e()}))}))})))},w={passive:!0,capture:!0},E=new Date,L=function(t,n){i||(i=n,a=t,r=new Date,F(removeEventListener),T())},T=function(){if(a>=0&&a<r-E){var t={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+a};o.forEach((function(n){n(t)})),o=[]}},b=function(t){if(t.cancelable){var n=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,n){var e=function(){L(t,n),a()},i=function(){a()},a=function(){removeEventListener("pointerup",e,w),removeEventListener("pointercancel",i,w)};addEventListener("pointerup",e,w),addEventListener("pointercancel",i,w)}(n,t):L(n,t)}},F=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return t(n,b,w)}))},k=function(t,n){var e,r=g(),f=c("FID"),v=function(t){t.startTime<r.timeStamp&&(f.value=t.processingStart-t.startTime,f.entries.push(t),m.add(f),e())},l=u("first-input",v);e=p(t,f,n),l&&s((function(){l.takeRecords().map(v),l.disconnect()}),!0),l&&d((function(){var r;f=c("FID"),e=p(t,f,n),o=[],a=-1,i=null,F(addEventListener),r=v,o.push(r),T()}))},C=function(t,n){var e,i=g(),a=c("LCP"),r=function(t){var n=t.startTime;n<i.timeStamp&&(a.value=n,a.entries.push(t)),e()},o=u("largest-contentful-paint",r);if(o){e=p(t,a,n);var f=function(){m.has(a)||(o.takeRecords().map(r),o.disconnect(),m.add(a),e())};["keydown","click"].forEach((function(t){addEventListener(t,f,{once:!0,capture:!0})})),s(f,!0),d((function(i){a=c("LCP"),e=p(t,a,n),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),e()}))}))}))}},P=function(t){var n,e=c("TTFB");n=function(){try{var n=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,n={entryType:"navigation",startTime:0};for(var e in t)"navigationStart"!==e&&"toJSON"!==e&&(n[e]=Math.max(t[e]-t.navigationStart,0));return n}();e.value=e.delta=n.responseStart,e.entries=[n],t(e)}catch(t){}},"complete"===document.readyState?setTimeout(n,0):addEventListener("pageshow",n)}}}]);
|
||||
//# sourceMappingURL=3.feab56bb.chunk.js.map
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,2 +1,2 @@
|
||||
!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);p.length;)p.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"feab56bb"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpclient=this.webpackJsonpclient||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([]);
|
||||
//# sourceMappingURL=runtime-main.e7edc0d2.js.map
|
||||
!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);p.length;)p.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"8e9312c3"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpclient=this.webpackJsonpclient||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([]);
|
||||
//# sourceMappingURL=runtime-main.8d7962eb.js.map
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Generated
+1
-175
@@ -49,9 +49,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ant-design/icons-svg": {
|
||||
@@ -1618,7 +1615,6 @@
|
||||
"jest-resolve": "^26.6.2",
|
||||
"jest-util": "^26.6.2",
|
||||
"jest-worker": "^26.6.2",
|
||||
"node-notifier": "^8.0.0",
|
||||
"slash": "^3.0.0",
|
||||
"source-map": "^0.6.0",
|
||||
"string-length": "^4.0.1",
|
||||
@@ -3011,14 +3007,6 @@
|
||||
"rc-util": "^5.8.1",
|
||||
"scroll-into-view-if-needed": "^2.2.25",
|
||||
"warning": "^4.0.3"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/ant-design"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/anymatch": {
|
||||
@@ -5387,18 +5375,8 @@
|
||||
"integrity": "sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg==",
|
||||
"engines": {
|
||||
"node": ">=0.11"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/date-fns"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.10.4",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz",
|
||||
"integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
@@ -9601,7 +9579,6 @@
|
||||
"@types/node": "*",
|
||||
"anymatch": "^3.0.3",
|
||||
"fb-watchman": "^2.0.0",
|
||||
"fsevents": "^2.1.2",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-regex-util": "^26.0.0",
|
||||
"jest-serializer": "^26.6.2",
|
||||
@@ -10898,10 +10875,6 @@
|
||||
"dependencies": {
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"shallowequal": "^1.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/minimalistic-assert": {
|
||||
@@ -13622,10 +13595,6 @@
|
||||
"dom-align": "^1.7.0",
|
||||
"rc-util": "^5.3.0",
|
||||
"resize-observer-polyfill": "^1.5.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-cascader": {
|
||||
@@ -13638,10 +13607,6 @@
|
||||
"rc-trigger": "^5.0.4",
|
||||
"rc-util": "^5.0.1",
|
||||
"warning": "^4.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-checkbox": {
|
||||
@@ -13651,10 +13616,6 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.10.1",
|
||||
"classnames": "^2.2.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-collapse": {
|
||||
@@ -13667,10 +13628,6 @@
|
||||
"rc-motion": "^2.3.4",
|
||||
"rc-util": "^5.2.1",
|
||||
"shallowequal": "^1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-dialog": {
|
||||
@@ -13682,10 +13639,6 @@
|
||||
"classnames": "^2.2.6",
|
||||
"rc-motion": "^2.3.0",
|
||||
"rc-util": "^5.6.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-drawer": {
|
||||
@@ -13696,10 +13649,6 @@
|
||||
"@babel/runtime": "^7.10.1",
|
||||
"classnames": "^2.2.6",
|
||||
"rc-util": "^5.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-dropdown": {
|
||||
@@ -13710,10 +13659,6 @@
|
||||
"@babel/runtime": "^7.10.1",
|
||||
"classnames": "^2.2.6",
|
||||
"rc-trigger": "^5.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-dom": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-field-form": {
|
||||
@@ -13727,10 +13672,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">= 16.9.0",
|
||||
"react-dom": ">= 16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-image": {
|
||||
@@ -13742,10 +13683,6 @@
|
||||
"classnames": "^2.2.6",
|
||||
"rc-dialog": "~8.5.0",
|
||||
"rc-util": "^5.0.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-input-number": {
|
||||
@@ -13756,10 +13693,6 @@
|
||||
"@babel/runtime": "^7.10.1",
|
||||
"classnames": "^2.2.5",
|
||||
"rc-util": "^5.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-mentions": {
|
||||
@@ -13773,10 +13706,6 @@
|
||||
"rc-textarea": "^0.3.0",
|
||||
"rc-trigger": "^5.0.4",
|
||||
"rc-util": "^5.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-menu": {
|
||||
@@ -13792,10 +13721,6 @@
|
||||
"rc-util": "^5.7.0",
|
||||
"resize-observer-polyfill": "^1.5.0",
|
||||
"shallowequal": "^1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-motion": {
|
||||
@@ -13806,10 +13731,6 @@
|
||||
"@babel/runtime": "^7.11.1",
|
||||
"classnames": "^2.2.1",
|
||||
"rc-util": "^5.2.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-notification": {
|
||||
@@ -13824,10 +13745,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-overflow": {
|
||||
@@ -13839,10 +13756,6 @@
|
||||
"classnames": "^2.2.1",
|
||||
"rc-resize-observer": "^1.0.0",
|
||||
"rc-util": "^5.5.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-pagination": {
|
||||
@@ -13852,10 +13765,6 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.10.1",
|
||||
"classnames": "^2.2.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-picker": {
|
||||
@@ -13873,11 +13782,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"dayjs": "^1.8.30",
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-progress": {
|
||||
@@ -13887,10 +13791,6 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.10.1",
|
||||
"classnames": "^2.2.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-rate": {
|
||||
@@ -13904,10 +13804,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-resize-observer": {
|
||||
@@ -13919,10 +13815,6 @@
|
||||
"classnames": "^2.2.1",
|
||||
"rc-util": "^5.0.0",
|
||||
"resize-observer-polyfill": "^1.5.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-select": {
|
||||
@@ -13940,10 +13832,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-dom": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-slider": {
|
||||
@@ -13959,10 +13847,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-steps": {
|
||||
@@ -13976,10 +13860,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-switch": {
|
||||
@@ -13990,10 +13870,6 @@
|
||||
"@babel/runtime": "^7.10.1",
|
||||
"classnames": "^2.2.1",
|
||||
"rc-util": "^5.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-table": {
|
||||
@@ -14009,10 +13885,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-tabs": {
|
||||
@@ -14029,10 +13901,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-textarea": {
|
||||
@@ -14044,10 +13912,6 @@
|
||||
"classnames": "^2.2.1",
|
||||
"rc-resize-observer": "^1.0.0",
|
||||
"rc-util": "^5.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-tooltip": {
|
||||
@@ -14057,10 +13921,6 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"rc-trigger": "^5.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-tree": {
|
||||
@@ -14076,10 +13936,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-dom": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-tree-select": {
|
||||
@@ -14092,10 +13948,6 @@
|
||||
"rc-select": "^12.0.0",
|
||||
"rc-tree": "^4.0.0",
|
||||
"rc-util": "^5.0.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-dom": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-trigger": {
|
||||
@@ -14111,10 +13963,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-upload": {
|
||||
@@ -14125,10 +13973,6 @@
|
||||
"@babel/runtime": "^7.10.1",
|
||||
"classnames": "^2.2.5",
|
||||
"rc-util": "^5.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-util": {
|
||||
@@ -14139,10 +13983,6 @@
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"react-is": "^16.12.0",
|
||||
"shallowequal": "^1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.9.0",
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc-util/node_modules/react-is": {
|
||||
@@ -14161,10 +14001,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.x"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-dom": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
@@ -14485,7 +14321,6 @@
|
||||
"eslint-webpack-plugin": "^2.5.2",
|
||||
"file-loader": "6.1.1",
|
||||
"fs-extra": "^9.0.1",
|
||||
"fsevents": "^2.1.3",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"jest": "26.6.0",
|
||||
@@ -17652,10 +17487,8 @@
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
|
||||
"integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==",
|
||||
"dependencies": {
|
||||
"chokidar": "^3.4.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"neo-async": "^2.5.0",
|
||||
"watchpack-chokidar2": "^2.0.1"
|
||||
"neo-async": "^2.5.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"chokidar": "^3.4.1",
|
||||
@@ -18151,7 +17984,6 @@
|
||||
"anymatch": "^2.0.0",
|
||||
"async-each": "^1.0.1",
|
||||
"braces": "^2.3.2",
|
||||
"fsevents": "^1.2.7",
|
||||
"glob-parent": "^3.1.0",
|
||||
"inherits": "^2.0.3",
|
||||
"is-binary-path": "^1.0.0",
|
||||
@@ -24165,12 +23997,6 @@
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.19.0.tgz",
|
||||
"integrity": "sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg=="
|
||||
},
|
||||
"dayjs": {
|
||||
"version": "1.10.4",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz",
|
||||
"integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==",
|
||||
"peer": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
|
||||
+109
-14
@@ -1,20 +1,9 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
:root {
|
||||
--color-primary: #282c34;
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
background-color: var(--color-primary);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -40,3 +29,109 @@
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.photo-wall {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin: 2rem;
|
||||
}
|
||||
|
||||
.dashboard-form {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.ant-card {
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.ant-card img {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.loading-bar-container {
|
||||
background: var(--color-primary);
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.loading-bar {
|
||||
transition: all 0.5s linear;
|
||||
background: #66ff66;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page-head {
|
||||
background: var(--color-primary);
|
||||
color: white !important;
|
||||
margin-top: 0;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.session-toolbar button {
|
||||
margin: 0 0.5rem;
|
||||
padding: 0.5rem 1rem;
|
||||
height: 100%;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05rem;
|
||||
}
|
||||
|
||||
.ant-modal-content {
|
||||
border-radius: 1rem;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.ant-modal-body img {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.ant-modal-close {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.ant-card {
|
||||
border: 1px solid var(--color-primary);
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
.ant-card-head {
|
||||
background: var(--color-primary);
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.2rem;
|
||||
}
|
||||
|
||||
.session-toolbar {
|
||||
justify-content: center;
|
||||
width: 60%;
|
||||
margin: 1rem auto;
|
||||
}
|
||||
|
||||
.session-toolbar h3 {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.slider {
|
||||
width: 400px;
|
||||
margin: auto 1rem;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
padding: 0.5rem;
|
||||
background: var(--color-primary);
|
||||
}
|
||||
|
||||
.client-info {
|
||||
justify-content: center;
|
||||
width: 60%;
|
||||
margin: 1rem auto;
|
||||
}
|
||||
|
||||
.client-info span {
|
||||
margin: auto 1rem;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import { BrowserRouter, Switch, Route } from 'react-router-dom'
|
||||
import { Dashboard } from './pages/Dashboard'
|
||||
import { Session } from './pages/Session'
|
||||
|
||||
console.log('ENV', process.env.NODE_ENV)
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
|
||||
+53
-17
@@ -1,36 +1,72 @@
|
||||
import { Client } from '../types'
|
||||
import { Client, Timings } from '../types'
|
||||
import axios from 'axios'
|
||||
import { client, clients } from '../data'
|
||||
import settings from '../settings'
|
||||
import { message } from 'antd'
|
||||
import { Status } from '../components/StatusChip'
|
||||
|
||||
const apiUrl = '/api'
|
||||
const dev = process.env.NODE_ENV === 'development'
|
||||
|
||||
export const createClient = async (body: Omit<Client, 'photos'>) => {
|
||||
await axios.post(`${apiUrl}/clients`, body)
|
||||
if (dev) {
|
||||
const host = 'http://192.168.1.114:5000'
|
||||
axios.defaults.baseURL = host
|
||||
}
|
||||
|
||||
export const getClients = async (): Promise<Client[]> => {
|
||||
if (settings.env === 'jank') return clients
|
||||
const res = await axios.post<Client[]>(`${apiUrl}/clients`)
|
||||
return res.data
|
||||
const mock = false
|
||||
|
||||
export const createClient = async (body: Omit<Client, 'has_photos'>) => {
|
||||
if (mock) return 'test'
|
||||
const res = await axios.post<{ client_id: string }>(`/api/clients`, body)
|
||||
return res.data.client_id
|
||||
}
|
||||
|
||||
export const getClient = async (id: string): Promise<Client> => {
|
||||
if (settings.env === 'jank') return client
|
||||
const res = await axios.post<Client>(`${apiUrl}/client/${id}`)
|
||||
if (mock)
|
||||
return {
|
||||
name: 'Test Client',
|
||||
has_photos: false,
|
||||
email: 'test@test.test',
|
||||
phone: 1234567890,
|
||||
}
|
||||
const res = await axios.get<Client>(`/api/clients/${id}`)
|
||||
return res.data
|
||||
}
|
||||
export const startSession = async (clientId: string) => {
|
||||
const res = await axios.post(`${apiUrl}/clients/${clientId}`)
|
||||
export const startSession = async (clientId: string, timings: Timings) => {
|
||||
try {
|
||||
const res = await axios.post(`/api/clients/${clientId}/session`, timings)
|
||||
return res.data
|
||||
} catch (err) {
|
||||
message.error('Something went wrong, check connection with the machine')
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
export const getSession = async (clientId: string) => {
|
||||
const res = await axios.get<{ photos: string[] }>(
|
||||
`/api/clients/${clientId}/session`,
|
||||
)
|
||||
return res.data // session data
|
||||
}
|
||||
|
||||
export const killSession = async (clientId: string) => {
|
||||
await axios.delete(`${apiUrl}/clients/${clientId}`)
|
||||
await axios.delete(`/api/clients/${clientId}/session`)
|
||||
}
|
||||
|
||||
export const restartSession = async (clientId: string) => {
|
||||
export const restartSession = async (clientId: string, timings: Timings) => {
|
||||
await killSession(clientId)
|
||||
await startSession(clientId)
|
||||
await startSession(clientId, timings)
|
||||
}
|
||||
|
||||
// TOOD: Get status
|
||||
|
||||
export const getStatus = async (): Promise<Status> => {
|
||||
const res = await axios.get<{ status: Status }>('/api/status')
|
||||
return res.data.status
|
||||
}
|
||||
|
||||
// Someday
|
||||
|
||||
export const getClients = async (): Promise<Client[]> => {
|
||||
const res = await axios.get<Client[]>(`/api/clients`)
|
||||
return res.data
|
||||
}
|
||||
|
||||
export const cleanup = () => {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Button } from 'antd'
|
||||
import React from 'react'
|
||||
|
||||
export const ScrollToTop = () => {
|
||||
const handleClick = () => {
|
||||
window.scrollTo(0, 0)
|
||||
console.log('')
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
type="link"
|
||||
style={{
|
||||
position: 'fixed',
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
}}
|
||||
onClick={handleClick}
|
||||
>
|
||||
⤴️ Scroll To Top
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { Card, Modal, Row, Select, Typography } from 'antd'
|
||||
import { getSession } from '../api'
|
||||
import { ScrollToTop } from './ScrollToTop'
|
||||
|
||||
type Props = {
|
||||
clientId: string
|
||||
}
|
||||
|
||||
export const SessionPictures = ({ clientId }: Props) => {
|
||||
const [urls, setUrls] = useState<string[] | null>(null)
|
||||
const [activeUrl, setActiveUrl] = useState<string | null>(null)
|
||||
const [focusPhotos, setFocusPhotos] = useState<string[]>(
|
||||
JSON.parse(window.localStorage.getItem('focusPhotos') || '[]'),
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const get = async () => {
|
||||
if (urls && urls.length >= 89 * 1) {
|
||||
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
|
||||
|
||||
const photos = urls.sort((a, b) =>
|
||||
a.split('_')[0].localeCompare(b.split('_')[0]),
|
||||
)
|
||||
|
||||
const u = urls.length / 89
|
||||
|
||||
const handleSelect = (v: string[]) => {
|
||||
console.log('SEelcted', v)
|
||||
window.localStorage.setItem('focusPhotos', JSON.stringify(v))
|
||||
setFocusPhotos(v)
|
||||
}
|
||||
|
||||
const filteredPhotos = photos.filter((name) => {
|
||||
const num = name.split('_')[0]
|
||||
return focusPhotos.includes(num)
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
visible={!!activeUrl}
|
||||
onOk={closeModal}
|
||||
footer={null}
|
||||
onCancel={closeModal}
|
||||
width="50%"
|
||||
>
|
||||
<img
|
||||
width="100%"
|
||||
onClick={closeModal}
|
||||
src={`${host}/output/${clientId}/${activeUrl}`}
|
||||
alt="large modal"
|
||||
></img>
|
||||
</Modal>
|
||||
<Row
|
||||
align="middle"
|
||||
justify="space-around"
|
||||
style={{ display: 'flex', width: '100%' }}
|
||||
>
|
||||
<Typography.Title style={{ margin: '0.5rem 1rem 0.7rem' }} level={3}>
|
||||
Session Pictures
|
||||
</Typography.Title>
|
||||
<Typography.Text>{urls.length}/ 89 loaded</Typography.Text>
|
||||
<Typography.Text>Select Featured Photos:</Typography.Text>
|
||||
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
placeholder="Please select featured"
|
||||
style={{ width: '35%' }}
|
||||
defaultValue={focusPhotos}
|
||||
value={focusPhotos}
|
||||
onChange={handleSelect}
|
||||
>
|
||||
{photos.map((name) => {
|
||||
const val = name.split('_')[0]
|
||||
return <Select.Option value={val}>{val}</Select.Option>
|
||||
})}
|
||||
</Select>
|
||||
</Row>
|
||||
|
||||
<div className="loading-bar-container">
|
||||
<div
|
||||
className="loading-bar"
|
||||
style={{
|
||||
width: `${u * 100}%`,
|
||||
background: `hsl(${Math.floor(u * 120)}, 90%, 70%)`,
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
<div className="featured-photos" style={{ marginTop: '2rem' }}>
|
||||
{filteredPhotos.map((src) => (
|
||||
<img
|
||||
onClick={() => setActiveUrl(src)}
|
||||
src={`${host}/output/${clientId}/${src}`}
|
||||
alt="lol"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="photo-wall">
|
||||
{photos.map((src) => (
|
||||
<Card key={src} className="photo" title={src.split('_')[0]}>
|
||||
<img
|
||||
onClick={() => setActiveUrl(src)}
|
||||
src={`${host}/output/${clientId}/${src}`}
|
||||
alt="lol"
|
||||
/>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
<ScrollToTop />
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { Tag } from 'antd'
|
||||
import { PresetColorType } from 'antd/lib/_util/colors'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { getStatus } from '../api'
|
||||
|
||||
export enum Status {
|
||||
'Standing By...',
|
||||
'Warming Up...',
|
||||
'Capturing Photo',
|
||||
'Capturing Grid',
|
||||
'Writing To Disk',
|
||||
'Downloading!',
|
||||
}
|
||||
|
||||
const colors: Partial<PresetColorType>[] = [
|
||||
'lime',
|
||||
'gold',
|
||||
'volcano',
|
||||
'magenta',
|
||||
'geekblue',
|
||||
]
|
||||
|
||||
type Props = {
|
||||
poll: boolean
|
||||
}
|
||||
|
||||
export const StatusChip = ({ poll }: Props) => {
|
||||
const [status, setStatus] = useState<Status>(Status['Standing By...'])
|
||||
|
||||
useEffect(() => {
|
||||
const get = async () => {
|
||||
if (!poll) return
|
||||
const status = await getStatus()
|
||||
setStatus(status)
|
||||
}
|
||||
|
||||
const interval = setInterval(get, 1000 / 4)
|
||||
|
||||
return () => clearInterval(interval)
|
||||
}, [poll])
|
||||
|
||||
return (
|
||||
<Tag color={colors[status]} style={{ display: 'flex' }}>
|
||||
<span style={{ margin: 'auto' }}>{Status[status]}</span>
|
||||
</Tag>
|
||||
)
|
||||
}
|
||||
@@ -5,18 +5,17 @@ export const clients: Client[] = [
|
||||
name: 'Elijah',
|
||||
email: 'elijah@elijah.com',
|
||||
phone: 4039876543,
|
||||
photos: [],
|
||||
has_photos: false,
|
||||
},
|
||||
{
|
||||
name: 'Tanner',
|
||||
email: 'tanner@tanner.com',
|
||||
phone: 4031234567,
|
||||
photos: [
|
||||
'/images/1.jpg',
|
||||
'/images/2.jpg',
|
||||
'/images/3.jpg',
|
||||
'/images/4.jpg',
|
||||
],
|
||||
has_photos: true,
|
||||
},
|
||||
]
|
||||
export const client: Client = clients[0]
|
||||
|
||||
export const session: { photos: string[] } = {
|
||||
photos: ['/images/1.jpg', '/images/2.jpg', '/images/3.jpg', '/images/4.jpg'],
|
||||
}
|
||||
|
||||
@@ -1,81 +1,78 @@
|
||||
import { message } from 'antd'
|
||||
import React from 'react'
|
||||
import { Button, Divider, Form, Input, message, Row, Typography } from 'antd'
|
||||
import FormItem from 'antd/lib/form/FormItem'
|
||||
import { Content } from 'antd/lib/layout/layout'
|
||||
import React, { FormEvent } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import { createClient } from '../api'
|
||||
import settings from '../settings'
|
||||
|
||||
type FormData = {
|
||||
name: string
|
||||
email: string
|
||||
phone: string
|
||||
}
|
||||
|
||||
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 [form] = Form.useForm<FormData>()
|
||||
|
||||
const handleReset = () => {
|
||||
//
|
||||
setName('')
|
||||
setEmail('')
|
||||
setPhone('')
|
||||
form.resetFields()
|
||||
}
|
||||
|
||||
const handleSubmit = async (e: FormEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
if (phone.length < 10) {
|
||||
const handleSubmit = async (values: FormData) => {
|
||||
if (values.phone.length < 10) {
|
||||
// helpful message
|
||||
message.error('Check all fields!')
|
||||
setError('Phone number needs to be a length of at least 10')
|
||||
return
|
||||
}
|
||||
|
||||
if (settings.env === 'jank') {
|
||||
history.push(`/sessions/${phone}`)
|
||||
return
|
||||
}
|
||||
const client_id = await createClient({
|
||||
name: values.name,
|
||||
email: values.email,
|
||||
phone: parseInt(values.phone.replace(/\D/g, '')),
|
||||
})
|
||||
|
||||
await createClient({ name, email, phone: parseInt(phone) })
|
||||
history.push(`/sessions/${phone}`)
|
||||
history.push(`/sessions/${client_id}`)
|
||||
}
|
||||
|
||||
return (
|
||||
<Content>
|
||||
<h1>Dashboard</h1>
|
||||
<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 type="submit">Start Session</button>
|
||||
<button type="button" onClick={handleReset}>
|
||||
<Typography.Title className="page-head" level={3}>
|
||||
Dashboard
|
||||
</Typography.Title>
|
||||
<Divider />
|
||||
<Form
|
||||
form={form}
|
||||
className="dashboard-form"
|
||||
onFinish={handleSubmit}
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
>
|
||||
<Typography.Paragraph style={{ textAlign: 'center' }}>
|
||||
Enter the name, email and phone number of the subject
|
||||
</Typography.Paragraph>
|
||||
<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>
|
||||
<Button htmlType="submit" type="primary">
|
||||
Start Session
|
||||
</Button>
|
||||
</Row>
|
||||
{error && <p className="error">{error}</p>}
|
||||
</form>
|
||||
</Form>
|
||||
</Content>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,24 +1,49 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { RouteComponentProps, useHistory } from 'react-router-dom'
|
||||
import { getClient, killSession, restartSession } from '../api'
|
||||
import { SessionPictures } from './SessionPictures'
|
||||
import { Button, Divider, message, PageHeader, Popconfirm, Row } from 'antd'
|
||||
import { getClient, killSession, restartSession, startSession } from '../api'
|
||||
import { SessionPictures } from '../components/SessionPictures'
|
||||
import { StatusChip } from '../components/StatusChip'
|
||||
|
||||
import {
|
||||
Button,
|
||||
Input,
|
||||
InputNumber,
|
||||
message,
|
||||
Popconfirm,
|
||||
Row,
|
||||
Typography,
|
||||
} from 'antd'
|
||||
import { Content } from 'antd/lib/layout/layout'
|
||||
import { Client } from '../types'
|
||||
|
||||
type Props = RouteComponentProps<{ clientId: string }>
|
||||
|
||||
export const Session = (props: Props) => {
|
||||
const history = useHistory()
|
||||
const { clientId } = props.match.params
|
||||
const [client, setClient] = useState<Client | null>(null)
|
||||
const [active, setActive] = useState(false)
|
||||
const [lightTime, setLightTime] = useState(
|
||||
parseInt(window.localStorage.getItem('lightTime') || '5000'),
|
||||
)
|
||||
|
||||
const handleTimingUpdate = (n: number) => {
|
||||
window.localStorage.setItem('lightTime', n.toString())
|
||||
setLightTime(n)
|
||||
}
|
||||
|
||||
const handleStartSession = async () => {
|
||||
message.loading('Photo sequence starting! Stand by...')
|
||||
await startSession(clientId, { light_time: lightTime })
|
||||
setActive(true)
|
||||
}
|
||||
|
||||
const handleRestartSession = async () => {
|
||||
setActive(false)
|
||||
await restartSession(clientId)
|
||||
message.loading(
|
||||
'Deleting photos & restarting capture sequence! Stand by...',
|
||||
)
|
||||
await restartSession(clientId, { light_time: lightTime })
|
||||
setActive(true)
|
||||
}
|
||||
|
||||
@@ -28,27 +53,42 @@ export const Session = (props: Props) => {
|
||||
|
||||
const handleNuke = async () => {
|
||||
await killSession(clientId)
|
||||
message.success('Photos Deleted! Going back to dashboard')
|
||||
history.push('/')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const get = async () => {
|
||||
const { photos } = await getClient(clientId)
|
||||
if (photos.length) setActive(true)
|
||||
else message.info("Click 'Capture' to take a photo set!")
|
||||
const client = await getClient(clientId)
|
||||
setClient(client)
|
||||
if (client.has_photos) setActive(true)
|
||||
}
|
||||
|
||||
get()
|
||||
})
|
||||
}, [clientId])
|
||||
|
||||
return (
|
||||
<Content>
|
||||
<PageHeader
|
||||
ghost={false}
|
||||
onBack={() => history.goBack()}
|
||||
title={`Session for ${clientId}`}
|
||||
subTitle={`session has ${active ? 'started' : 'not started'}`}
|
||||
extra={[
|
||||
<Typography.Title className="page-head" level={3}>
|
||||
Session View
|
||||
</Typography.Title>
|
||||
|
||||
<Row className="client-info">
|
||||
<Typography.Text>
|
||||
<strong>Name:</strong> {client?.name}
|
||||
</Typography.Text>
|
||||
<Typography.Text>
|
||||
<strong>Email:</strong> {client?.email}
|
||||
</Typography.Text>
|
||||
<Typography.Text>
|
||||
<strong>Phone:</strong> {client?.phone}
|
||||
</Typography.Text>
|
||||
</Row>
|
||||
<div className="toolbar">
|
||||
<Row justify="center" className="session-toolbar">
|
||||
<Button key="finish" onClick={handleExit}>
|
||||
Back To Dashboard
|
||||
</Button>
|
||||
<Button
|
||||
key="startsession"
|
||||
disabled={active}
|
||||
@@ -56,8 +96,9 @@ export const Session = (props: Props) => {
|
||||
onClick={handleStartSession}
|
||||
>
|
||||
Capture
|
||||
</Button>,
|
||||
</Button>
|
||||
<Popconfirm
|
||||
disabled={!active}
|
||||
key="retry"
|
||||
title="Re-capture set?"
|
||||
onConfirm={handleRestartSession}
|
||||
@@ -65,28 +106,34 @@ export const Session = (props: Props) => {
|
||||
<Button type="default" disabled={!active}>
|
||||
Retry Capture
|
||||
</Button>
|
||||
</Popconfirm>,
|
||||
</Popconfirm>
|
||||
<Popconfirm
|
||||
key="nuke"
|
||||
title="Delete all photos?"
|
||||
disabled={!active}
|
||||
title="Delete all photos and return to dashboard?"
|
||||
onConfirm={handleNuke}
|
||||
>
|
||||
<Button danger disabled={!active}>
|
||||
Nuke Session
|
||||
Abort Session
|
||||
</Button>
|
||||
</Popconfirm>,
|
||||
<Button
|
||||
key="finish"
|
||||
ghost
|
||||
type="primary"
|
||||
disabled={!active}
|
||||
onClick={handleExit}
|
||||
>
|
||||
Finish Session
|
||||
</Button>,
|
||||
]}
|
||||
></PageHeader>
|
||||
<Divider />
|
||||
</Popconfirm>
|
||||
|
||||
<StatusChip poll={true} />
|
||||
</Row>
|
||||
<Row className="session-toolbar">
|
||||
<h3>Light Duration (ms)</h3>
|
||||
<InputNumber value={lightTime} onChange={handleTimingUpdate} />
|
||||
<Input
|
||||
className="slider"
|
||||
type="range"
|
||||
onChange={(e) => handleTimingUpdate(parseInt(e.target.value))}
|
||||
value={lightTime}
|
||||
min={500}
|
||||
max={10000}
|
||||
step={500}
|
||||
/>
|
||||
</Row>
|
||||
</div>
|
||||
<Row className="controls">
|
||||
{active && <SessionPictures clientId={clientId} />}
|
||||
</Row>
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import { Spin } from 'antd'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { getClient } 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 { photos } = await getClient(clientId)
|
||||
if (photos.length) setPics(photos)
|
||||
}
|
||||
|
||||
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} alt="lol" />)
|
||||
) : (
|
||||
<Spin />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export default {
|
||||
env: 'jank',
|
||||
}
|
||||
@@ -2,9 +2,13 @@ export type Client = {
|
||||
name: string
|
||||
email: string
|
||||
phone: number
|
||||
photos: string[]
|
||||
has_photos: boolean
|
||||
}
|
||||
|
||||
export type Session = {
|
||||
timestamp: number
|
||||
}
|
||||
|
||||
export type Timings = {
|
||||
light_time: number // 5000
|
||||
}
|
||||
|
||||
+2
-13
@@ -1364,7 +1364,6 @@
|
||||
"jest-resolve" "^26.6.2"
|
||||
"jest-util" "^26.6.2"
|
||||
"jest-worker" "^26.6.2"
|
||||
"node-notifier" "^8.0.0"
|
||||
"slash" "^3.0.0"
|
||||
"source-map" "^0.6.0"
|
||||
"string-length" "^4.0.1"
|
||||
@@ -3385,7 +3384,6 @@
|
||||
"anymatch" "^2.0.0"
|
||||
"async-each" "^1.0.1"
|
||||
"braces" "^2.3.2"
|
||||
"fsevents" "^1.2.7"
|
||||
"glob-parent" "^3.1.0"
|
||||
"inherits" "^2.0.3"
|
||||
"is-binary-path" "^1.0.0"
|
||||
@@ -4140,11 +4138,6 @@
|
||||
"resolved" "https://registry.npmjs.org/date-fns/-/date-fns-2.19.0.tgz"
|
||||
"version" "2.19.0"
|
||||
|
||||
"dayjs@^1.8.30":
|
||||
"integrity" "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw=="
|
||||
"resolved" "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz"
|
||||
"version" "1.10.4"
|
||||
|
||||
"debug@^2.2.0":
|
||||
"integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="
|
||||
"resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
|
||||
@@ -6667,7 +6660,6 @@
|
||||
"@types/node" "*"
|
||||
"anymatch" "^3.0.3"
|
||||
"fb-watchman" "^2.0.0"
|
||||
"fsevents" "^2.1.2"
|
||||
"graceful-fs" "^4.2.4"
|
||||
"jest-regex-util" "^26.0.0"
|
||||
"jest-serializer" "^26.6.2"
|
||||
@@ -9757,7 +9749,7 @@
|
||||
"strip-ansi" "6.0.0"
|
||||
"text-table" "0.2.0"
|
||||
|
||||
"react-dom@*", "react-dom@^17.0.1", "react-dom@>= 16.9.0", "react-dom@>=16.9.0":
|
||||
"react-dom@^17.0.1":
|
||||
"integrity" "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug=="
|
||||
"resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz"
|
||||
"version" "17.0.1"
|
||||
@@ -9863,7 +9855,6 @@
|
||||
"eslint-webpack-plugin" "^2.5.2"
|
||||
"file-loader" "6.1.1"
|
||||
"fs-extra" "^9.0.1"
|
||||
"fsevents" "^2.1.3"
|
||||
"html-webpack-plugin" "4.5.0"
|
||||
"identity-obj-proxy" "3.0.0"
|
||||
"jest" "26.6.0"
|
||||
@@ -9897,7 +9888,7 @@
|
||||
optionalDependencies:
|
||||
"fsevents" "^2.1.3"
|
||||
|
||||
"react@*", "react@^17.0.1", "react@>= 16.9.0", "react@>=16.0.0", "react@>=16.9.0":
|
||||
"react@^17.0.1":
|
||||
"integrity" "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w=="
|
||||
"resolved" "https://registry.npmjs.org/react/-/react-17.0.1.tgz"
|
||||
"version" "17.0.1"
|
||||
@@ -12018,10 +12009,8 @@
|
||||
"resolved" "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz"
|
||||
"version" "1.7.5"
|
||||
dependencies:
|
||||
"chokidar" "^3.4.1"
|
||||
"graceful-fs" "^4.1.2"
|
||||
"neo-async" "^2.5.0"
|
||||
"watchpack-chokidar2" "^2.0.1"
|
||||
optionalDependencies:
|
||||
"chokidar" "^3.4.1"
|
||||
"watchpack-chokidar2" "^2.0.1"
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
@@ -103,3 +103,4 @@ ENV/
|
||||
*.swo
|
||||
|
||||
paramiko.log
|
||||
output/
|
||||
|
||||
@@ -28,3 +28,7 @@ def trigger_capture():
|
||||
sock.sendto(SEND.encode('utf-8'), (MCAST_GRP, MCAST_PORT))
|
||||
sock.close()
|
||||
print('Sent.')
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('Triggering test capture...')
|
||||
trigger_capture()
|
||||
|
||||
+19
-5
@@ -5,7 +5,18 @@ import paramiko
|
||||
import time
|
||||
paramiko.util.log_to_file('paramiko.log')
|
||||
|
||||
def fake_download(ip, dest):
|
||||
import requests, random
|
||||
num = ip.split('.')[3]
|
||||
r = requests.get('https://picsum.photos/400/300?random=' + num)
|
||||
time.sleep(random.uniform(2, 10))
|
||||
with open(dest / (num + '_420.jpg'), 'wb') as f:
|
||||
f.write(r.content)
|
||||
|
||||
def download(ip, dest):
|
||||
if settings.DEBUG:
|
||||
fake_download(ip, dest)
|
||||
|
||||
print('Downloading from', ip)
|
||||
|
||||
port = 22
|
||||
@@ -18,10 +29,12 @@ def download(ip, dest):
|
||||
|
||||
for f in files:
|
||||
source_file = '/3dscan/' + f
|
||||
dest_file = dest + f
|
||||
dest_file = dest / (f + '.tmp')
|
||||
print('Grabbing file', source_file)
|
||||
sftp.get(source_file, dest_file)
|
||||
sftp.remove(source_file)
|
||||
done_file = dest / f
|
||||
dest_file.rename(done_file)
|
||||
|
||||
if sftp: sftp.close()
|
||||
if transport: transport.close()
|
||||
@@ -29,10 +42,7 @@ def download(ip, dest):
|
||||
print('Finished downloading from', ip)
|
||||
|
||||
def download_all_photos(dest):
|
||||
if not dest.endswith('/'):
|
||||
raise Exception('Destination must end with /')
|
||||
|
||||
if not os.path.exists(dest):
|
||||
if not dest.exists():
|
||||
raise Exception('Destination does not exist')
|
||||
|
||||
print('Downloading all photos to', dest)
|
||||
@@ -40,3 +50,7 @@ def download_all_photos(dest):
|
||||
for ip in settings.RASPBERRY_IPS:
|
||||
t = threading.Thread(target=download, args=(ip, dest))
|
||||
t.start()
|
||||
|
||||
if __name__ == '__main__':
|
||||
from pathlib import Path
|
||||
download_all_photos(Path('test/'))
|
||||
|
||||
+160
-4
@@ -1,12 +1,168 @@
|
||||
from flask import Flask
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from flask import Flask, request, abort, send_from_directory
|
||||
from flask_cors import CORS
|
||||
|
||||
build_folder = '../client/build'
|
||||
app = Flask(__name__, static_folder=build_folder, static_url_path='')
|
||||
import power, capture, download, settings
|
||||
|
||||
import logging
|
||||
log = logging.getLogger('werkzeug')
|
||||
if not settings.DEBUG:
|
||||
log.setLevel(logging.ERROR)
|
||||
|
||||
build_folder = Path('../client/build')
|
||||
output_folder = Path('./output')
|
||||
app = Flask(__name__, static_folder=str(build_folder), static_url_path='')
|
||||
CORS(app)
|
||||
|
||||
STANDBY = 0
|
||||
WARMUP = 1
|
||||
CAPTURING_PHOTO = 2
|
||||
CAPTURING_GRID = 3
|
||||
WRITING = 4
|
||||
DOWNLOADING = 5
|
||||
|
||||
status = STANDBY
|
||||
|
||||
@app.route('/api/status', methods=['GET'])
|
||||
def status_get():
|
||||
return {'status': status}
|
||||
|
||||
@app.route('/api/clients', methods=['POST'])
|
||||
def clients_post():
|
||||
content = request.json
|
||||
|
||||
phone = str(content['phone'])
|
||||
|
||||
for i in range(1, 100):
|
||||
suffix = str(i).zfill(2)
|
||||
folder = phone + '_' + suffix
|
||||
path = output_folder / folder
|
||||
if not path.exists():
|
||||
break
|
||||
|
||||
content['date'] = datetime.now().strftime('%Y-%m-%d')
|
||||
content['time'] = datetime.now().strftime('%H:%M:%S')
|
||||
|
||||
path.mkdir()
|
||||
info_file = path / 'info.txt'
|
||||
info_file.touch()
|
||||
info_file.write_text(json.dumps(content, indent=4))
|
||||
|
||||
client_id = folder
|
||||
|
||||
print('POST client:', content, 'cid:', client_id)
|
||||
return {'client_id': client_id}
|
||||
|
||||
@app.route('/api/clients/<cid>', methods=['GET'])
|
||||
def clients_get(cid):
|
||||
folder = cid
|
||||
path = output_folder / cid
|
||||
|
||||
if not path.exists():
|
||||
abort(404)
|
||||
|
||||
info_file = path / 'info.txt'
|
||||
info_text = info_file.read_text()
|
||||
res = json.loads(info_text)
|
||||
photo_glob = path.glob('*.jpg')
|
||||
res['has_photos'] = bool(list(photo_glob))
|
||||
|
||||
print('GET client:', cid, 'res:', res)
|
||||
return res
|
||||
|
||||
@app.route('/api/clients/<cid>/session', methods=['GET'])
|
||||
def session_get(cid):
|
||||
folder = cid
|
||||
path = output_folder / cid
|
||||
|
||||
if not path.exists():
|
||||
abort(404)
|
||||
|
||||
photo_glob = path.glob('*.jpg')
|
||||
res = {}
|
||||
res['photos'] = sorted([x.name for x in photo_glob])
|
||||
|
||||
return res
|
||||
|
||||
@app.route('/api/clients/<cid>/session', methods=['DELETE'])
|
||||
def session_delete(cid):
|
||||
folder = cid
|
||||
path = output_folder / cid
|
||||
|
||||
if not path.exists():
|
||||
abort(404)
|
||||
|
||||
photo_glob = path.glob('*.jpg')
|
||||
|
||||
for p in photo_glob:
|
||||
p.unlink()
|
||||
|
||||
print('DELETE session:', cid)
|
||||
return ''
|
||||
|
||||
@app.route('/api/clients/<cid>/session', methods=['POST'])
|
||||
def session_post(cid):
|
||||
content = request.json
|
||||
light_time = content.get('light_time', 5000)
|
||||
|
||||
global status
|
||||
|
||||
print('POST session:', cid)
|
||||
folder = cid
|
||||
path = output_folder / cid
|
||||
|
||||
if not path.exists():
|
||||
abort(404)
|
||||
|
||||
# go through the photo taking process
|
||||
|
||||
try:
|
||||
# warmup
|
||||
status = WARMUP
|
||||
power.lights_on()
|
||||
time.sleep(2)
|
||||
power.lights_off()
|
||||
time.sleep(1)
|
||||
except BaseException as e:
|
||||
print('Problem with lights: {} - {}'.format(e.__class__.__name__, str(e)))
|
||||
print()
|
||||
print('Are you sure the system is connected?')
|
||||
print()
|
||||
abort(500)
|
||||
|
||||
# capture
|
||||
status = CAPTURING_PHOTO
|
||||
power.lights_on()
|
||||
time.sleep(0.1)
|
||||
capture.trigger_capture()
|
||||
time.sleep(light_time / 1000)
|
||||
power.lights_off()
|
||||
|
||||
status = WRITING
|
||||
time.sleep(max(5 - light_time / 1000, 1))
|
||||
|
||||
status = DOWNLOADING
|
||||
download.download_all_photos(path)
|
||||
time.sleep(3)
|
||||
|
||||
status = STANDBY
|
||||
print('Finished.')
|
||||
return ''
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return app.send_static_file('index.html')
|
||||
|
||||
app.run()
|
||||
@app.errorhandler(404)
|
||||
def not_found(e):
|
||||
return app.send_static_file('index.html')
|
||||
|
||||
@app.route('/output/<path:filename>')
|
||||
def output(filename):
|
||||
return send_from_directory('output/', filename)
|
||||
|
||||
app.run(host='0.0.0.0')
|
||||
|
||||
@@ -3,6 +3,8 @@ import settings
|
||||
import time
|
||||
|
||||
def np_02B_api(ip, username, password, is_on):
|
||||
if settings.DEBUG: return
|
||||
|
||||
if is_on:
|
||||
endpoint = '/cmd.cgi?grp=0'
|
||||
else:
|
||||
|
||||
+36
-5
@@ -1,5 +1,36 @@
|
||||
certifi==2020.12.5
|
||||
chardet==4.0.0
|
||||
idna==2.10
|
||||
requests==2.25.1
|
||||
urllib3==1.26.3
|
||||
appdirs==1.4.3
|
||||
bcrypt==3.2.0
|
||||
CacheControl==0.12.6
|
||||
certifi==2019.11.28
|
||||
cffi==1.14.5
|
||||
chardet==3.0.4
|
||||
click==7.1.2
|
||||
colorama==0.4.3
|
||||
contextlib2==0.6.0
|
||||
cryptography==3.4.6
|
||||
distlib==0.3.0
|
||||
distro==1.4.0
|
||||
Flask==1.1.2
|
||||
Flask-Cors==3.0.10
|
||||
html5lib==1.0.1
|
||||
idna==2.8
|
||||
ipaddr==2.2.0
|
||||
itsdangerous==1.1.0
|
||||
Jinja2==2.11.3
|
||||
lockfile==0.12.2
|
||||
MarkupSafe==1.1.1
|
||||
msgpack==0.6.2
|
||||
packaging==20.3
|
||||
paramiko==2.7.2
|
||||
pep517==0.8.2
|
||||
progress==1.5
|
||||
pycparser==2.20
|
||||
PyNaCl==1.4.0
|
||||
pyparsing==2.4.6
|
||||
pytoml==0.1.21
|
||||
requests==2.22.0
|
||||
retrying==1.3.3
|
||||
six==1.14.0
|
||||
urllib3==1.25.8
|
||||
webencodings==0.5.1
|
||||
Werkzeug==1.0.1
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import os
|
||||
DEBUG = os.environ.get('FLASK_ENV', None) == 'development'
|
||||
|
||||
LIGHT_IP = '192.168.99.25'
|
||||
LIGHT_USER = 'admin'
|
||||
LIGHT_PASS = 'admin'
|
||||
|
||||
Reference in New Issue
Block a user