diff --git a/web/src/components/App.js b/web/src/components/App.js index f0c48dec..36c90f76 100644 --- a/web/src/components/App.js +++ b/web/src/components/App.js @@ -30,6 +30,7 @@ import api from "../app/Api"; import prefs from "../app/Prefs"; import session from "../app/Session"; import Pricing from "./Pricing"; +import Signup from "./Signup"; // TODO races when two tabs are open // TODO investigate service workers @@ -45,6 +46,7 @@ const App = () => { <Route path={routes.home} element={<Home/>}/> <Route path={routes.pricing} element={<Pricing/>}/> <Route path={routes.login} element={<Login/>}/> + <Route path={routes.signup} element={<Signup/>}/> <Route element={<Layout/>}> <Route path={routes.app} element={<AllSubscriptions/>}/> <Route path={routes.settings} element={<Preferences/>}/> diff --git a/web/src/components/Login.js b/web/src/components/Login.js index 7f1469d3..eefc4b36 100644 --- a/web/src/components/Login.js +++ b/web/src/components/Login.js @@ -1,29 +1,14 @@ import * as React from 'react'; -import {Avatar, Checkbox, FormControlLabel, Grid, Link, Stack} from "@mui/material"; +import {Avatar, Checkbox, FormControlLabel, Grid, Link} from "@mui/material"; import Typography from "@mui/material/Typography"; -import Container from "@mui/material/Container"; import LockOutlinedIcon from '@mui/icons-material/LockOutlined'; import TextField from "@mui/material/TextField"; import Button from "@mui/material/Button"; import Box from "@mui/material/Box"; import api from "../app/Api"; -import {useNavigate} from "react-router-dom"; import routes from "./routes"; import session from "../app/Session"; -const Copyright = (props) => { - return ( - <Typography variant="body2" color="text.secondary" align="center" {...props}> - {'Copyright © '} - <Link color="inherit" href="https://mui.com/"> - Your Website - </Link>{' '} - {new Date().getFullYear()} - {'.'} - </Typography> - ); -}; - const Login = () => { const handleSubmit = async (event) => { event.preventDefault(); @@ -93,14 +78,13 @@ const Login = () => { </Link> </Grid> <Grid item> - <Link href="#" variant="body2"> + <Link to={routes.signup} variant="body2"> {"Don't have an account? Sign Up"} </Link> </Grid> </Grid> </Box> </Box> - <Copyright sx={{mt: 8, mb: 4}}/> </> ); } diff --git a/web/src/components/Signup.js b/web/src/components/Signup.js new file mode 100644 index 00000000..408ca6ae --- /dev/null +++ b/web/src/components/Signup.js @@ -0,0 +1,94 @@ +import * as React from 'react'; +import {Avatar, Checkbox, FormControlLabel, Grid, Link, Stack} from "@mui/material"; +import Typography from "@mui/material/Typography"; +import Container from "@mui/material/Container"; +import LockOutlinedIcon from '@mui/icons-material/LockOutlined'; +import TextField from "@mui/material/TextField"; +import Button from "@mui/material/Button"; +import Box from "@mui/material/Box"; +import api from "../app/Api"; +import {useNavigate} from "react-router-dom"; +import routes from "./routes"; +import session from "../app/Session"; + +const Signup = () => { + const handleSubmit = async (event) => { + event.preventDefault(); + const data = new FormData(event.currentTarget); + const user = { + username: data.get('username'), + password: data.get('password'), + } + const token = await api.login("http://localhost:2586"/*window.location.origin*/, user); + console.log(`[Api] User auth for user ${user.username} successful, token is ${token}`); + session.store(user.username, token); + window.location.href = routes.app; + }; + + return ( + <> + <Box + sx={{ + marginTop: 8, + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + }} + > + <Avatar sx={{m: 1, bgcolor: 'secondary.main'}}> + <LockOutlinedIcon/> + </Avatar> + <Typography component="h1" variant="h5"> + Sign in + </Typography> + <Box component="form" onSubmit={handleSubmit} noValidate sx={{mt: 1}}> + <TextField + margin="normal" + required + fullWidth + id="username" + label="Username" + name="username" + autoFocus + /> + <TextField + margin="normal" + required + fullWidth + name="password" + label="Password" + type="password" + id="password" + autoComplete="current-password" + /> + <FormControlLabel + control={<Checkbox value="remember" color="primary"/>} + label="Remember me" + /> + <Button + type="submit" + fullWidth + variant="contained" + sx={{mt: 3, mb: 2}} + > + Sign up + </Button> + <Grid container> + <Grid item xs> + <Link href="#" variant="body2"> + Forgot password? + </Link> + </Grid> + <Grid item> + <Link to={routes.signup} variant="body2"> + {"Don't have an account? Sign Up"} + </Link> + </Grid> + </Grid> + </Box> + </Box> + </> + ); +} + +export default Signup; diff --git a/web/src/img/ntfy2.svg b/web/src/img/ntfy2.svg new file mode 100644 index 00000000..cd5f908e --- /dev/null +++ b/web/src/img/ntfy2.svg @@ -0,0 +1,255 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + width="50mm" + height="50mm" + viewBox="0 0 50 50" + version="1.1" + id="svg8" + inkscape:version="1.1.1 (3bf5ae0, 2021-09-20)" + sodipodi:docname="appstore_ios.svg" + inkscape:export-filename="/home/pheckel/Code/ntfy-android/assets/appstore_ios.png" + inkscape:export-xdpi="520.19202" + inkscape:export-ydpi="520.19202" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <defs + id="defs2"> + <linearGradient + inkscape:collect="always" + id="linearGradient4714"> + <stop + style="stop-color:#348878;stop-opacity:1" + offset="0" + id="stop4710" /> + <stop + style="stop-color:#52bca6;stop-opacity:1" + offset="1" + id="stop4712" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient28858-5"> + <stop + style="stop-color:#348878;stop-opacity:1" + offset="0" + id="stop28854-3" /> + <stop + style="stop-color:#56bda8;stop-opacity:1" + offset="1" + id="stop28856-5" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient28858-5" + id="linearGradient3255" + x1="160.72209" + y1="128.53317" + x2="168.41153" + y2="134.32626" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(3.7495873,0,0,3.7495873,-541.79055,-387.59852)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4714" + id="linearGradient4633" + x1="0.034492966" + y1="-0.0003150744" + x2="50.319355" + y2="50.284546" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.99433502,0,0,0.99433502,-0.03429756,-1.7848888e-6)" /> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Drop Shadow" + id="filter3958" + x="-0.076083149" + y="-0.091641662" + width="1.1759423" + height="1.2114791"> + <feFlood + flood-opacity="0.192157" + flood-color="rgb(0,0,0)" + result="flood" + id="feFlood3948" /> + <feComposite + in="flood" + in2="SourceGraphic" + operator="in" + result="composite1" + id="feComposite3950" /> + <feGaussianBlur + in="composite1" + stdDeviation="4" + result="blur" + id="feGaussianBlur3952" /> + <feOffset + dx="3" + dy="2.95367" + result="offset" + id="feOffset3954" /> + <feComposite + in="SourceGraphic" + in2="offset" + operator="over" + result="composite2" + id="feComposite3956" /> + </filter> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.8244841" + inkscape:cx="4.6588512" + inkscape:cy="174.84395" + inkscape:document-units="mm" + inkscape:current-layer="layer3" + showgrid="false" + inkscape:measure-start="0,0" + inkscape:measure-end="0,0" + inkscape:snap-text-baseline="true" + inkscape:window-width="1863" + inkscape:window-height="1025" + inkscape:window-x="57" + inkscape:window-y="27" + inkscape:window-maximized="1" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + showguides="false" + inkscape:guide-bbox="true" + inkscape:pagecheckerboard="0"> + <sodipodi:guide + position="10.173514,67.718331" + orientation="1,0" + id="guide1770" /> + <sodipodi:guide + position="39.965574,62.077508" + orientation="1,0" + id="guide1772" /> + <sodipodi:guide + position="10.173514,39.789015" + orientation="0,-1" + id="guide1774" /> + <sodipodi:guide + position="-2.3077334,9.9462015" + orientation="0,-1" + id="guide1776" /> + <sodipodi:guide + position="14.990626,36.198285" + orientation="1,0" + id="guide4020" /> + <sodipodi:guide + position="34.930725,39.789015" + orientation="1,0" + id="guide4022" /> + <sodipodi:guide + position="12.7026,32.00465" + orientation="0,-1" + id="guide4024" /> + <sodipodi:guide + position="11.377711,17.981227" + orientation="0,-1" + id="guide4026" /> + </sodipodi:namedview> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="background" + style="display:inline"> + <rect + style="fill:url(#linearGradient4633);fill-opacity:1;stroke:none;stroke-width:0.286502;stroke-linejoin:bevel" + id="rect4545" + width="50" + height="50" + x="0" + y="-0.0003150744" /> + </g> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="drop shadow" + style="display:inline"> + <path + id="path3646" + style="color:#000000;display:inline;fill:#ffffff;stroke:none;stroke-width:1.93113;-inkscape-stroke:none;filter:url(#filter3958)" + d="m 50.400391,46.882812 c -9.16879,0 -17.023438,7.2146 -17.023438,16.386719 v 0.0078 l 0.08984,71.369139 -2.302735,16.99219 31.3125,-8.31836 h 77.841802 c 9.16877,0 17.02344,-7.22425 17.02344,-16.39648 V 63.269531 c 0,-9.169496 -7.85031,-16.382463 -17.01563,-16.386719 h -0.008 z m 0,11.566407 h 89.917969 0.008 c 3.22151,0.0033 5.44922,2.346918 5.44922,4.820312 v 63.654299 c 0,2.47551 -2.23164,4.82031 -5.45703,4.82031 H 60.779297 l -15.908203,4.80664 0.162109,-0.9375 -0.08789,-72.343749 c 0,-2.475337 2.229739,-4.820312 5.455078,-4.820312 z" + transform="scale(0.26458333)" /> + </g> + <g + inkscape:label="foreground" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-51.147327,-81.515579)" + style="display:inline"> + <path + style="color:#000000;fill:url(#linearGradient3255);stroke:none;stroke-width:2.49558;-inkscape-stroke:none" + d="M 88.200706,95.308804 H 64.918622 c -1.600657,0 -2.910245,1.235977 -2.910245,2.74661 l 0.02224,18.601596 -0.434711,2.5057 6.231592,-1.88118 h 20.371766 c 1.600658,0 2.910282,-1.23597 2.910282,-2.74664 V 98.055414 c 0,-1.510633 -1.309624,-2.74661 -2.910282,-2.74661 z" + id="path7368" /> + <path + id="path2498" + style="color:#000000;fill:#ffffff;stroke:none;stroke-width:1.93113;-inkscape-stroke:none" + d="m 50.400391,46.882812 c -9.16879,0 -17.023438,7.2146 -17.023438,16.386719 v 0.0078 l 0.08984,71.369139 -2.302735,16.99219 31.3125,-8.31836 h 77.841802 c 9.16877,0 17.02344,-7.22425 17.02344,-16.39648 V 63.269531 c 0,-9.169496 -7.85031,-16.382463 -17.01563,-16.386719 h -0.008 z m 0,11.566407 h 89.917969 0.008 c 3.22151,0.0033 5.44922,2.346918 5.44922,4.820312 v 63.654299 c 0,2.47551 -2.23164,4.82031 -5.45703,4.82031 H 60.779297 l -15.908203,4.80664 0.162109,-0.9375 -0.08789,-72.343749 c 0,-2.475337 2.229739,-4.820312 5.455078,-4.820312 z" + transform="matrix(0.26458333,0,0,0.26458333,51.147327,81.515579)" /> + <g + id="path1011-6-2" + transform="matrix(1.4536603,0,0,1.728146,-23.97473,-90.437157)" + style="font-size:8.48274px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;stroke:none;stroke-width:0.525121"> + <path + style="color:#000000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#ffffff;stroke:none;-inkscape-stroke:none" + d="m 62.57046,116.77004 v -1.31201 l 3.280018,-1.45904 q 0.158346,-0.0679 0.305381,-0.1018 0.158346,-0.0452 0.282761,-0.0679 0.135725,-0.0113 0.271449,-0.0226 v -0.0905 q -0.135724,-0.0113 -0.271449,-0.0452 -0.124415,-0.0226 -0.282761,-0.0566 -0.147035,-0.0452 -0.305381,-0.1131 l -3.280018,-1.45904 v -1.32332 l 5.067063,2.31863 v 1.4138 z" + id="path7553" /> + <path + style="color:#000000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#ffffff;stroke:none;-inkscape-stroke:none" + d="m 62.308594,110.31055 v 1.90234 l 3.4375,1.5293 c 0.0073,0.003 0.0142,0.005 0.02148,0.008 -0.0073,0.003 -0.0142,0.005 -0.02148,0.008 l -3.4375,1.5293 v 1.89258 l 0.371093,-0.16992 5.220704,-2.39063 v -1.75 z m 0.52539,0.8164 4.541016,2.08008 v 1.07617 l -4.541016,2.07813 v -0.73242 l 3.119141,-1.38868 0.0039,-0.002 c 0.09141,-0.0389 0.178343,-0.0676 0.257813,-0.0859 h 0.0059 l 0.0078,-0.002 c 0.09483,-0.0271 0.176055,-0.0474 0.246093,-0.0606 l 0.498047,-0.041 v -0.57422 l -0.240234,-0.0195 c -0.07606,-0.006 -0.153294,-0.0198 -0.230469,-0.0391 l -0.0078,-0.002 -0.0078,-0.002 c -0.07608,-0.0138 -0.16556,-0.0318 -0.263672,-0.0527 -0.08398,-0.0262 -0.172736,-0.058 -0.265625,-0.0977 l -0.0039,-0.002 -3.119141,-1.38868 z" + id="path7555" /> + </g> + <g + id="g1224" + transform="matrix(1.4493527,0,0,1.6641427,-22.956963,-85.389973)" + style="font-size:8.48274px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;stroke:none;stroke-width:0.525121"> + <path + style="color:#000000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#ffffff;stroke:none;-inkscape-stroke:none" + d="m 69.17132,117.75404 h 5.428996 v 1.27808 H 69.17132 Z" + id="path1220" /> + <path + style="color:#000000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#ffffff;stroke:none;-inkscape-stroke:none" + d="m 68.908203,117.49219 v 0.26172 1.54101 h 5.955078 v -1.80273 z m 0.525391,0.52344 h 4.904297 v 0.7539 h -4.904297 z" + id="path1222" /> + </g> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="round icon preview" + style="display:none"> + <path + id="path18850-8-1" + style="display:inline;fill:#ffffff;fill-opacity:1;stroke-width:0.255654" + d="M 50.337488,80.973198 V 131.61213 H 101.65302 V 80.973198 Z m 25.676545,1.442307 h 0.555989 a 24.369387,24.369387 0 0 1 23.860308,21.232925 v 6.09963 a 24.369387,24.369387 0 0 1 -21.288308,21.19336 h 21.288308 v 0.0138 H 51.963792 v -0.0158 H 73.428179 A 24.369387,24.369387 0 0 1 51.963792,107.97535 v -2.49089 A 24.369387,24.369387 0 0 1 76.014033,82.415508 Z" + transform="translate(-51.147326,-81.51558)" /> + </g> +</svg>