fix basic form.
6
Accounts/.babelrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"presets": ["es2015", "stage-0", "react"],
|
||||
"plugins": [
|
||||
["transform-decorators-legacy"]
|
||||
]
|
||||
}
|
||||
1271
Accounts/package-lock.json
generated
@@ -3,6 +3,8 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
||||
"@babel/plugin-proposal-decorators": "^7.17.9",
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "^13.2.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
@@ -10,13 +12,14 @@
|
||||
"@types/node": "^16.11.35",
|
||||
"@types/react": "^18.0.9",
|
||||
"@types/react-dom": "^18.0.4",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"typescript": "^4.6.4",
|
||||
"Common": "file:../Common",
|
||||
"CommonServer": "file:../CommonServer",
|
||||
"CommonUI": "file:../CommonUI"
|
||||
"CommonUI": "file:../CommonUI",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"typescript": "^4.6.4"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "PORT=3003 react-scripts start",
|
||||
@@ -46,5 +49,8 @@
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-transform-decorators-legacy": "^1.3.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Accounts/public/assets/fonts/camphor/font1.woff2
Executable file
BIN
Accounts/public/assets/fonts/camphor/font2.woff2
Executable file
BIN
Accounts/public/assets/fonts/camphor/font3.woff2
Executable file
BIN
Accounts/public/assets/fonts/camphor/font4.woff2
Executable file
BIN
Accounts/public/assets/fonts/rw-widgets/rw-widgets.eot
Executable file
24
Accounts/public/assets/fonts/rw-widgets/rw-widgets.svg
Executable file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Copyright (C) 2017 by original authors @ fontello.com</metadata>
|
||||
<defs>
|
||||
<font id="rw-widgets" horiz-adv-x="1000" >
|
||||
<font-face font-family="rw-widgets" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
||||
<missing-glyph horiz-adv-x="1000" />
|
||||
<glyph glyph-name="up-dir" unicode="" d="M571 171q0-14-10-25t-25-10h-500q-15 0-25 10t-11 25 11 26l250 250q10 10 25 10t25-10l250-250q10-11 10-26z" horiz-adv-x="571.4" />
|
||||
|
||||
<glyph glyph-name="search" unicode="" d="M643 386q0 103-73 176t-177 74-177-74-73-176 73-177 177-73 177 73 73 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 153-31 125-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
|
||||
|
||||
<glyph glyph-name="down-dir" unicode="" d="M571 457q0-14-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 11-11 25t11 25 25 11h500q14 0 25-11t10-25z" horiz-adv-x="571.4" />
|
||||
|
||||
<glyph glyph-name="calendar" unicode="" d="M71-79h161v161h-161v-161z m197 0h178v161h-178v-161z m-197 197h161v178h-161v-178z m197 0h178v178h-178v-178z m-197 214h161v161h-161v-161z m411-411h179v161h-179v-161z m-214 411h178v161h-178v-161z m428-411h161v161h-161v-161z m-214 197h179v178h-179v-178z m-196 482v161q0 7-6 12t-12 6h-36q-7 0-12-6t-6-12v-161q0-7 6-13t12-5h36q7 0 12 5t6 13z m410-482h161v178h-161v-178z m-214 214h179v161h-179v-161z m214 0h161v161h-161v-161z m18 268v161q0 7-5 12t-13 6h-35q-7 0-13-6t-5-12v-161q0-7 5-13t13-5h35q8 0 13 5t5 13z m215 36v-715q0-29-22-50t-50-21h-786q-29 0-50 21t-21 50v715q0 29 21 50t50 21h72v54q0 37 26 63t63 26h36q37 0 63-26t26-63v-54h214v54q0 37 27 63t63 26h35q37 0 64-26t26-63v-54h71q29 0 50-21t22-50z" horiz-adv-x="928.6" />
|
||||
|
||||
<glyph glyph-name="clock" unicode="" d="M500 546v-250q0-7-5-12t-13-5h-178q-8 0-13 5t-5 12v36q0 8 5 13t13 5h125v196q0 8 5 13t12 5h36q8 0 13-5t5-13z m232-196q0 83-41 152t-110 111-152 41-153-41-110-111-41-152 41-152 110-111 153-41 152 41 110 111 41 152z m125 0q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="angle-left" unicode="" d="M350 546q0-7-6-12l-219-220 219-219q6-6 6-13t-6-13l-28-28q-5-5-12-5t-13 5l-260 261q-6 5-6 12t6 13l260 260q5 6 13 6t12-6l28-28q6-5 6-13z" horiz-adv-x="357.1" />
|
||||
|
||||
<glyph glyph-name="angle-right" unicode="" d="M332 314q0-7-5-12l-261-261q-5-5-12-5t-13 5l-28 28q-6 6-6 13t6 13l219 219-219 220q-6 5-6 12t6 13l28 28q5 6 13 6t12-6l261-260q5-5 5-13z" horiz-adv-x="357.1" />
|
||||
</font>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
BIN
Accounts/public/assets/fonts/rw-widgets/rw-widgets.ttf
Executable file
BIN
Accounts/public/assets/fonts/rw-widgets/rw-widgets.woff
Executable file
BIN
Accounts/public/assets/fonts/rw-widgets/rw-widgets.woff2
Executable file
BIN
Accounts/public/assets/img/favicons/android-chrome-144x144.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
Accounts/public/assets/img/favicons/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
Accounts/public/assets/img/favicons/android-chrome-256x256.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
Accounts/public/assets/img/favicons/android-chrome-36x36.png
Normal file
|
After Width: | Height: | Size: 764 B |
BIN
Accounts/public/assets/img/favicons/android-chrome-384x384.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
Accounts/public/assets/img/favicons/android-chrome-48x48.png
Normal file
|
After Width: | Height: | Size: 870 B |
BIN
Accounts/public/assets/img/favicons/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
Accounts/public/assets/img/favicons/android-chrome-72x72.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
Accounts/public/assets/img/favicons/android-chrome-96x96.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Accounts/public/assets/img/favicons/apple-touch-icon-114x114.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Accounts/public/assets/img/favicons/apple-touch-icon-120x120.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
BIN
Accounts/public/assets/img/favicons/apple-touch-icon-144x144.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
BIN
Accounts/public/assets/img/favicons/apple-touch-icon-152x152.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
BIN
Accounts/public/assets/img/favicons/apple-touch-icon-180x180.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
BIN
Accounts/public/assets/img/favicons/apple-touch-icon-57x57.png
Normal file
|
After Width: | Height: | Size: 902 B |
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Accounts/public/assets/img/favicons/apple-touch-icon-60x60.png
Normal file
|
After Width: | Height: | Size: 924 B |
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Accounts/public/assets/img/favicons/apple-touch-icon-72x72.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
BIN
Accounts/public/assets/img/favicons/apple-touch-icon-76x76.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
BIN
Accounts/public/assets/img/favicons/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
9
Accounts/public/assets/img/favicons/browserconfig.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<TileColor>#121212</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
BIN
Accounts/public/assets/img/favicons/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 804 B |
BIN
Accounts/public/assets/img/favicons/favicon-194x194.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Accounts/public/assets/img/favicons/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
Accounts/public/assets/img/favicons/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
9
Accounts/public/assets/img/favicons/html_code.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="194x194" href="/favicon-194x194.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/android-chrome-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#121212">
|
||||
<meta name="theme-color" content="#121212">
|
||||
BIN
Accounts/public/assets/img/favicons/mstile-144x144.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
Accounts/public/assets/img/favicons/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
Accounts/public/assets/img/favicons/mstile-310x150.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
Accounts/public/assets/img/favicons/mstile-310x310.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
Accounts/public/assets/img/favicons/mstile-70x70.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
31
Accounts/public/assets/img/favicons/safari-pinned-tab.svg
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M864 4667 c-7 -19 2 -1540 9 -1567 4 -13 9 -42 12 -63 14 -91 70
|
||||
-225 138 -331 28 -44 106 -121 162 -162 103 -73 173 -100 368 -144 72 -16 315
|
||||
-4 402 19 268 72 459 246 551 498 31 85 41 129 59 253 5 34 10 1314 6 1482
|
||||
l-1 27 -210 -1 c-208 0 -210 0 -211 -22 0 -11 -2 -340 -4 -731 -1 -390 -5
|
||||
-728 -9 -750 -29 -182 -125 -315 -258 -361 -74 -26 -252 -26 -325 -1 -135 47
|
||||
-231 205 -249 409 -4 45 -8 391 -8 768 l-1 685 -213 2 c-154 1 -215 -2 -218
|
||||
-10z"/>
|
||||
<path d="M3663 4169 c-125 -14 -257 -70 -354 -149 l-46 -38 -38 40 c-68 69
|
||||
-161 105 -294 114 l-87 6 -42 -154 c-23 -84 -45 -167 -48 -184 l-6 -31 50 5
|
||||
c62 5 118 -12 134 -41 9 -17 13 -257 14 -992 1 -533 2 -972 3 -975 0 -3 94 -5
|
||||
208 -5 l208 1 0 359 c1 198 4 361 8 362 4 2 35 -10 69 -26 114 -51 159 -62
|
||||
283 -66 169 -7 323 46 454 155 310 258 414 756 241 1161 -131 309 -435 493
|
||||
-757 458z m169 -412 c75 -34 140 -102 182 -191 46 -97 60 -163 59 -286 0 -251
|
||||
-105 -431 -280 -483 -57 -17 -157 -16 -221 2 -44 12 -139 66 -181 102 l-25 20
|
||||
0 357 -1 357 30 28 c50 47 114 88 168 107 75 27 193 21 269 -13z"/>
|
||||
<path d="M4932 4013 c-18 -6 -35 -13 -36 -15 -24 -27 -26 -83 -26 -688 l0
|
||||
-642 29 -29 29 -29 650 0 649 0 26 25 c13 14 26 36 28 48 3 12 4 303 4 647 -1
|
||||
587 -2 627 -19 653 -10 15 -30 30 -43 33 -49 13 -1255 10 -1291 -3z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
56
Accounts/public/assets/img/favicons/site.webmanifest
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "OneUptime Account",
|
||||
"short_name": "OneUptime",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"theme_color": "#121212",
|
||||
"background_color": "#121212",
|
||||
"display": "standalone"
|
||||
}
|
||||
|
||||
11
Accounts/public/assets/js/landing.base.js
Executable file
@@ -0,0 +1,11 @@
|
||||
|
||||
$(document).ready(function() {
|
||||
setTimeout(()=>{
|
||||
|
||||
$('div.bar').tipsy({
|
||||
gravity: 'se',
|
||||
html: true,
|
||||
offset: 1
|
||||
});
|
||||
},1000);
|
||||
});
|
||||
@@ -9,7 +9,52 @@
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta charSet='utf-8' />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<meta name="slack-app-id" content="ACVBMTPJQ">
|
||||
<meta name="description" content="This is the login page for OneUptime Dashboard">
|
||||
|
||||
<link rel="manifest" href="/accounts/manifest.json">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/accounts/assests/img/favicons/apple-touch-icon.png">
|
||||
<link rel="shortcut icon" href="/accounts/favicon.ico">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/accounts/assests/img/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="194x194" href="/accounts/assests/img/favicons/favicon-194x194.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/accounts/assests/img/favicons/android-chrome-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/accounts/assests/img/favicons/favicon-16x16.png">
|
||||
<link rel="mask-icon" href="/accounts/assests/img/favicons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#121212">
|
||||
<meta name="msapplication-TileImage" content="/accounts/assests/img/favicons/mstile-144x144.png">
|
||||
<meta name="theme-color" content="#121212">
|
||||
|
||||
|
||||
<title>OneUptime Accounts</title>
|
||||
|
||||
<link rel="stylesheet" href="/accounts/assets/css/dashboard.css" media="none" onload="if(media!='all')media='all'">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/dashboard.css">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/newdashboard.css" media="none" onload="if(media!='all')media='all'">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/newdashboard.css">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/sail.css" media="none" onload="if(media!='all')media='all'">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/sail.css">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/loader.css" media="none" onload="if(media!='all')media='all'">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/loader.css">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/blockchart.css" media="none" onload="if(media!='all')media='all'">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/blockchart.css">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/Selector.css" media="none" onload="if(media!='all')media='all'">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/Selector.css">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/tutorial.css" media="none" onload="if(media!='all')media='all'">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/tutorial.css">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/reactwidgets.css" media="none" onload="if(media!='all')media='all'">
|
||||
<link rel="stylesheet" href="/accounts/assets/css/reactwidgets.css">
|
||||
|
||||
|
||||
<!-- Preload light, regular, medium and bold, which are fonts that are used on home -->
|
||||
<link rel="preload" href="/accounts/assets/fonts/camphor/font1.woff2" as="font" type="font/woff2" crossorigin="">
|
||||
<link rel="preload" href="/accounts/assets/fonts/camphor/font2.woff2" as="font" type="font/woff2" crossorigin="">
|
||||
<link rel="preload" href="/accounts/assets/fonts/camphor/font3.woff2" as="font" type="font/woff2" crossorigin="">
|
||||
<link rel="preload" href="/accounts/assets/fonts/camphor/font4.woff2" as="font" type="font/woff2" crossorigin="">
|
||||
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
@@ -24,7 +69,7 @@
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
<title>OneUptime | Account</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
import React from 'react';
|
||||
import './App.css';
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
Routes,
|
||||
Route,
|
||||
} from "react-router-dom";
|
||||
import LoginPage from './Pages/Login';
|
||||
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<p>
|
||||
Edit <code>src/App.tsx</code> and save to reload.
|
||||
</p>
|
||||
<a
|
||||
className="App-link"
|
||||
href="https://reactjs.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Learn React
|
||||
</a>
|
||||
</header>
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path="/login" element={<LoginPage/>}/>
|
||||
<Route path="/forgot-password" element={<LoginPage />} />
|
||||
<Route path="/register" element={<LoginPage />} />
|
||||
<Route path="/login/sso" element={<LoginPage />} />
|
||||
<Route path="/verify-email" element={<LoginPage />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
7
Accounts/src/Pages/ForgotPassword.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
const ForgotPasswordPage = () => {
|
||||
return (<div>ForgotPassword</div>)
|
||||
};
|
||||
|
||||
export default ForgotPasswordPage;
|
||||
32
Accounts/src/Pages/Login.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import BasicModelForm from 'CommonUI/src/Components/Forms/BasicModelForm';
|
||||
import User from 'Common/Models/User';
|
||||
import FormValues from 'CommonUI/src/Components/Forms/Types/FormValues';
|
||||
|
||||
const LoginPage = () => {
|
||||
const user: User = new User();
|
||||
return (
|
||||
<BasicModelForm
|
||||
model={user}
|
||||
id="login-form"
|
||||
fields={[
|
||||
{
|
||||
field: {
|
||||
email: true
|
||||
}
|
||||
},
|
||||
{
|
||||
field: {
|
||||
password: true
|
||||
}
|
||||
}
|
||||
]}
|
||||
|
||||
onSubmit={(values: FormValues<User>) => {
|
||||
console.log(values);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export default LoginPage;
|
||||
0
Accounts/src/Pages/Register.tsx
Normal file
0
Accounts/src/Pages/SsoLogin.tsx
Normal file
0
Accounts/src/Pages/VerifyEmail.tsx
Normal file
@@ -14,28 +14,29 @@ import { JSONArray, JSONObject } from '../Types/JSON';
|
||||
import ObjectID from '../Types/ObjectID';
|
||||
|
||||
export default class BaseModel extends BaseEntity {
|
||||
@TableColumn()
|
||||
@TableColumn({title: "ID"})
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
public _id!: string;
|
||||
|
||||
@TableColumn()
|
||||
@TableColumn({title: "Created"})
|
||||
@CreateDateColumn()
|
||||
public createdAt!: Date;
|
||||
|
||||
@TableColumn()
|
||||
@TableColumn({title: "Updated"})
|
||||
@UpdateDateColumn()
|
||||
public updatedAt!: Date;
|
||||
|
||||
@TableColumn()
|
||||
@TableColumn({title: "Deleted"})
|
||||
@DeleteDateColumn()
|
||||
public deletedAt?: Date;
|
||||
|
||||
@TableColumn()
|
||||
@TableColumn({title: "Version"})
|
||||
@VersionColumn()
|
||||
public version!: number;
|
||||
|
||||
|
||||
private displayColumnAs: Dictionary<string> = {};
|
||||
private displayColumnTitleAs: Dictionary<string> = {};
|
||||
private displayColumnDescriptionAs: Dictionary<string> = {};
|
||||
|
||||
private encryptedColumns: Columns = new Columns([]);
|
||||
private uniqueColumns: Columns = new Columns([]);
|
||||
@@ -131,13 +132,25 @@ export default class BaseModel extends BaseEntity {
|
||||
return this.hashedColumns;
|
||||
}
|
||||
|
||||
public addDisplayColumnAs(columnName: string, displayAs: string): void {
|
||||
this.displayColumnAs[columnName] = displayAs;
|
||||
public addDisplayColumnTitleAs(columnName: string, title: string): void {
|
||||
this.displayColumnTitleAs[columnName] = title;
|
||||
}
|
||||
|
||||
public getDisplayColumnAs(columnName: string): string | null {
|
||||
if (this.displayColumnAs[columnName]) {
|
||||
return this.displayColumnAs[columnName] as string;
|
||||
public getDisplayColumnTitleAs(columnName: string): string | null {
|
||||
if (this.displayColumnTitleAs[columnName]) {
|
||||
return this.displayColumnTitleAs[columnName] as string;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public addDisplayColumnDescriptionAs(columnName: string, description: string): void {
|
||||
this.displayColumnDescriptionAs[columnName] = description;
|
||||
}
|
||||
|
||||
public getDisplayColumnDescriptionAs(columnName: string): string | null {
|
||||
if (this.displayColumnDescriptionAs[columnName]) {
|
||||
return this.displayColumnDescriptionAs[columnName] as string;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import BaseModel from '../../Models/BaseModel';
|
||||
|
||||
export default () => {
|
||||
export default (props?: {title?: string, description?: string}) => {
|
||||
return (target: Object, propertyKey: string) => {
|
||||
const baseModel: BaseModel = target as BaseModel;
|
||||
baseModel.addTableColumn(propertyKey);
|
||||
|
||||
if (props && props.title) {
|
||||
baseModel.addDisplayColumnTitleAs(propertyKey, props.title);
|
||||
}
|
||||
|
||||
if (props && props.description) {
|
||||
baseModel.addDisplayColumnTitleAs(propertyKey, props.description);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { FunctionComponent, ReactElement, useEffect } from 'react';
|
||||
import { MouseOnClick, KeyboardEventProp } from '../../../Types/HtmlEvents';
|
||||
import ShortcutKey from '../ShortcutKey/ShortcutKey';
|
||||
import ButtonType from './ButtonTypes';
|
||||
|
||||
export interface ComponentProps {
|
||||
title: string;
|
||||
|
||||
@@ -2,4 +2,6 @@ enum ButtonType {
|
||||
Submit = "submit",
|
||||
Reset = "reset",
|
||||
Button = "button"
|
||||
}
|
||||
}
|
||||
|
||||
export default ButtonType;
|
||||
@@ -1,25 +1,46 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import React, { ReactElement } from 'react';
|
||||
import { Formik, Form, Field, ErrorMessage, FormikErrors } from 'formik';
|
||||
import Button from '../Basic/Button/Button';
|
||||
import FormValues from './Types/FormValues'
|
||||
import RequiredFormFields from './Types/RequiredFormFields';
|
||||
import Fields from './Types/Fields';
|
||||
import DataField from './Types/Field';
|
||||
import ButtonTypes from '../Basic/Button/ButtonTypes';
|
||||
import BadDataException from 'Common/Types/Exception/BadDataException';
|
||||
|
||||
export interface ComponentProps<T> {
|
||||
id: string,
|
||||
initialValues: FormValues<T>,
|
||||
onSubmit: (values: FormValues<T>) => void
|
||||
onValidate: (values: FormValues<T>) => FormikErrors<FormValues<T>>,
|
||||
onSubmit: (values: FormValues<T>) => void
|
||||
onValidate?: (values: FormValues<T>) => FormikErrors<FormValues<T>>,
|
||||
requiredfields: RequiredFormFields<T>,
|
||||
fields: Array<keyof T>
|
||||
fields: Fields<T>,
|
||||
model: T
|
||||
}
|
||||
|
||||
const BasicForm = <T,>(props: ComponentProps<T>) => {
|
||||
|
||||
const getFormField = (field: DataField<T>): ReactElement => {
|
||||
|
||||
let fieldType = "text";
|
||||
if (Object.keys(field.field).length === 0) {
|
||||
throw new BadDataException("Object cannot be without Field")
|
||||
}
|
||||
return (<div>
|
||||
<Field type={fieldType} name={Object.keys(field.field)[0] as string} />
|
||||
<ErrorMessage name={Object.keys(field.field)[0] as string} component="div" />
|
||||
</div>)
|
||||
}
|
||||
|
||||
return (<div>
|
||||
<Formik
|
||||
initialValues={props.initialValues}
|
||||
validate={(values: FormValues<T>) => {
|
||||
return props.onValidate(values);
|
||||
if (props.onValidate) {
|
||||
return props.onValidate(values);
|
||||
}
|
||||
|
||||
return {};
|
||||
}}
|
||||
onSubmit={(values: FormValues<T>) => {
|
||||
props.onSubmit(values);
|
||||
@@ -28,11 +49,10 @@ const BasicForm = <T,>(props: ComponentProps<T>) => {
|
||||
|
||||
{({ isSubmitting }) => (
|
||||
<Form>
|
||||
<Field type="email" name="email" />
|
||||
<ErrorMessage name="email" component="div" />
|
||||
<Field type="password" name="password" />
|
||||
<ErrorMessage name="password" component="div" />
|
||||
<Button title='Submit' disabled={isSubmitting} type={ButtonType.Submit} id={`${props.id}-submit-button`} />
|
||||
{props.fields && props.fields.map((field: DataField<T>) => {
|
||||
return getFormField(field);
|
||||
})}
|
||||
<Button title='Submit' disabled={isSubmitting} type={ButtonTypes.Submit} id={`${props.id}-submit-button`} />
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
|
||||
@@ -1,47 +1,45 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { Formik, Form, Field, ErrorMessage, FormikErrors } from 'formik';
|
||||
import Button from '../Basic/Button/Button';
|
||||
import React from 'react';
|
||||
import { FormikErrors } from 'formik';
|
||||
import BaseModel from 'Common/Models/BaseModel';
|
||||
import Columns from 'Common/Types/Database/Columns';
|
||||
import Dictionary from 'Common/Types/Dictionary';
|
||||
import FormValues from './FormValues';
|
||||
import FormValues from './Types/FormValues';
|
||||
import Fields from './Types/Fields';
|
||||
import BasicForm from './BasicForm';
|
||||
|
||||
export interface ComponentProps<T extends BaseModel> {
|
||||
model: T,
|
||||
id: string,
|
||||
fieldsInForm: Dictionary<boolean>,
|
||||
initialValues: Dictionary<string | number>,
|
||||
onSubmit: (values: FormValues) => void
|
||||
onValidate: (values: FormValues) => FormikErrors<FormValues>
|
||||
onSubmit: (values: FormValues<T>) => void
|
||||
onValidate?: (values: FormValues<T>) => FormikErrors<FormValues<T>>,
|
||||
fields: Fields<T>
|
||||
}
|
||||
|
||||
const BasicForm: FunctionComponent = <TBaseModel extends BaseModel>(props: ComponentProps<TBaseModel>) => {
|
||||
const BasicModelForm = <TBaseModel extends BaseModel>(props: ComponentProps<TBaseModel>) => {
|
||||
|
||||
const columns: Columns = props.model.getTableColumns();
|
||||
const requiredColumns: Columns = props.model.getTableColumns();
|
||||
const initialValues: FormValues<TBaseModel> = {};
|
||||
|
||||
return (<div>
|
||||
<Formik
|
||||
initialValues={{ email: '', password: '' }}
|
||||
validate={(values: FormValues) => {
|
||||
return props.onValidate(values);
|
||||
}}
|
||||
onSubmit={(values: FormValues) => {
|
||||
props.onSubmit(values);
|
||||
}}
|
||||
>
|
||||
|
||||
{({ isSubmitting }) => (
|
||||
<Form>
|
||||
<Field type="email" name="email" />
|
||||
<ErrorMessage name="email" component="div" />
|
||||
<Field type="password" name="password" />
|
||||
<ErrorMessage name="password" component="div" />
|
||||
<Button title='Submit' disabled={isSubmitting} type={ButtonType.Submit} id={`${props.id}-submit-button`} />
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</div>)
|
||||
// Prep
|
||||
for (const field of props.fields) {
|
||||
|
||||
if (Object.keys(field.field).length > 0){
|
||||
if (props.model.getDisplayColumnTitleAs(Object.keys(field.field)[0] as string)) {
|
||||
field.title = props.model.getDisplayColumnTitleAs(Object.keys(field.field)[0] as string) as string;
|
||||
}
|
||||
|
||||
if (props.model.getDisplayColumnDescriptionAs(Object.keys(field.field)[0] as string)) {
|
||||
field.description = props.model.getDisplayColumnDescriptionAs(Object.keys(field.field)[0] as string) as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (<BasicForm
|
||||
fields={props.fields}
|
||||
id={props.id}
|
||||
onSubmit={props.onSubmit}
|
||||
initialValues={initialValues}
|
||||
requiredfields={{}}
|
||||
model={props.model}
|
||||
/>)
|
||||
};
|
||||
|
||||
export default BasicForm;
|
||||
export default BasicModelForm;
|
||||
7
CommonUI/src/Components/Forms/Types/Field.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import SelectFormFields from './SelectFormField';
|
||||
|
||||
export default interface Field<TEntity> {
|
||||
title?: string,
|
||||
description?: string,
|
||||
field: SelectFormFields<TEntity>
|
||||
}
|
||||
5
CommonUI/src/Components/Forms/Types/Fields.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import Field from "./Field"
|
||||
|
||||
type Fields<T> = Array<Field<T>>
|
||||
|
||||
export default Fields
|
||||
@@ -1,11 +1,11 @@
|
||||
import FormFieldSchemaTypes from './FormFieldType'
|
||||
|
||||
type FormFields<Property> = Property extends FormFieldSchemaTypes
|
||||
export type FormField<Property> = Property extends FormFieldSchemaTypes
|
||||
? Property
|
||||
: unknown;
|
||||
|
||||
declare type FormValues<Entity> = {
|
||||
[P in keyof Entity]?: FormFields<NonNullable<Entity[P]>>;
|
||||
[P in keyof Entity]?: FormField<NonNullable<Entity[P]>>;
|
||||
};
|
||||
|
||||
export default FormValues;
|
||||
@@ -1,6 +1,6 @@
|
||||
import FormFieldSchemaTypes from "./FormFieldType";
|
||||
|
||||
type SelectFormField<Property> = Property extends FormFieldSchemaTypes
|
||||
export type SelectFormField<Property> = Property extends FormFieldSchemaTypes
|
||||
? boolean
|
||||
: unknown;
|
||||
|
||||
|
||||