Skip to content

Commit 40e1611

Browse files
committed
initial frontend setup with vite, react, firebase-auth. This initial setup has signup and signin with email and password working. The authentication is handle by firebase/auth
0 parents  commit 40e1611

File tree

12 files changed

+3784
-0
lines changed

12 files changed

+3784
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
dist-ssr
5+
*.local

frontend/index.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
6+
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8+
<title>Vite App</title>
9+
</head>
10+
<body>
11+
<div id="root"></div>
12+
<script type="module" src="/src/main.jsx"></script>
13+
</body>
14+
</html>

frontend/package-lock.json

Lines changed: 3262 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"version": "0.0.0",
3+
"scripts": {
4+
"dev": "vite",
5+
"build": "vite build",
6+
"serve": "vite preview"
7+
},
8+
"dependencies": {
9+
"@material-ui/core": "^4.11.4",
10+
"@material-ui/icons": "^4.11.2",
11+
"firebase": "^8.6.3",
12+
"react": "^17.0.0",
13+
"react-dom": "^17.0.0",
14+
"react-router-dom": "^5.2.0"
15+
},
16+
"devDependencies": {
17+
"@vitejs/plugin-react-refresh": "^1.3.1",
18+
"vite": "^2.3.5"
19+
}
20+
}

frontend/src/App.jsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React, { useState } from 'react'
2+
import {
3+
BrowserRouter as Router,
4+
Switch,
5+
Route,
6+
Link
7+
} from "react-router-dom";
8+
9+
//components
10+
import SignIn from './components/signin'
11+
import SignUp from './components/signup'
12+
import Home from './components/Home'
13+
14+
// context
15+
import { AuthProvider } from './context/AuthContext'
16+
17+
function App() {
18+
19+
return (
20+
<Router>
21+
<AuthProvider>
22+
<Switch>
23+
<Route path="/signin">
24+
<SignIn/>
25+
</Route>
26+
<Route path="/signup">
27+
<SignUp />
28+
</Route>
29+
<Route path="/">
30+
<Home/>
31+
</Route>
32+
</Switch>
33+
</AuthProvider>
34+
</Router>
35+
)
36+
}
37+
38+
export default App

frontend/src/components/Home.jsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React, {useEffect} from 'react'
2+
import { Link, useHistory } from "react-router-dom"
3+
import { useAuth } from '../context/AuthContext'
4+
5+
//components
6+
import Button from '@material-ui/core/Button';
7+
8+
export default function Home() {
9+
const { currentUser, logout } = useAuth()
10+
const history = useHistory()
11+
12+
useEffect(()=> {
13+
console.log('currentUser: ', currentUser);
14+
if(!currentUser) {
15+
history.push("/signin")
16+
} else {
17+
history.push("/")
18+
}
19+
},[currentUser])
20+
21+
function handleLogout (e) {
22+
logout()
23+
}
24+
25+
return (
26+
<div>
27+
{
28+
currentUser?
29+
(
30+
<div>
31+
<h1>My home</h1>
32+
<Button variant="contained" color="primary" onClick={handleLogout}>
33+
Logout
34+
</Button>
35+
</div>
36+
):
37+
<h1>Loading...</h1>
38+
}
39+
</div>
40+
)
41+
}

frontend/src/components/signin.jsx

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import React, { useState } from 'react';
2+
import Avatar from '@material-ui/core/Avatar';
3+
import Button from '@material-ui/core/Button';
4+
import CssBaseline from '@material-ui/core/CssBaseline';
5+
import TextField from '@material-ui/core/TextField';
6+
import FormControlLabel from '@material-ui/core/FormControlLabel';
7+
import Checkbox from '@material-ui/core/Checkbox';
8+
import Link from '@material-ui/core/Link';
9+
import Grid from '@material-ui/core/Grid';
10+
import Box from '@material-ui/core/Box';
11+
import LockOutlinedIcon from '@material-ui/icons/LockOutlined';
12+
import Typography from '@material-ui/core/Typography';
13+
import { makeStyles } from '@material-ui/core/styles';
14+
import Container from '@material-ui/core/Container';
15+
import { useHistory } from "react-router-dom"
16+
17+
// context
18+
import { useAuth } from '../context/AuthContext'
19+
20+
function Copyright() {
21+
return (
22+
<Typography variant="body2" color="textSecondary" align="center">
23+
{'Copyright © '}
24+
<Link color="inherit" href="https://material-ui.com/">
25+
Your Website
26+
</Link>{' '}
27+
{new Date().getFullYear()}
28+
{'.'}
29+
</Typography>
30+
);
31+
}
32+
33+
const useStyles = makeStyles((theme) => ({
34+
paper: {
35+
marginTop: theme.spacing(8),
36+
display: 'flex',
37+
flexDirection: 'column',
38+
alignItems: 'center',
39+
},
40+
avatar: {
41+
margin: theme.spacing(1),
42+
backgroundColor: theme.palette.secondary.main,
43+
},
44+
form: {
45+
width: '100%', // Fix IE 11 issue.
46+
marginTop: theme.spacing(1),
47+
},
48+
submit: {
49+
margin: theme.spacing(3, 0, 2),
50+
},
51+
}));
52+
53+
export default function SignIn() {
54+
const classes = useStyles();
55+
const { login } = useAuth()
56+
const history = useHistory()
57+
58+
async function handleSubmit(e) {
59+
e.preventDefault()
60+
61+
const signinFields = {
62+
email: e.target.email.value,
63+
password: e.target.password.value
64+
}
65+
66+
try {
67+
await login(signinFields.email, signinFields.password)
68+
history.push("/")
69+
} catch {
70+
console.log("Failed to log in")
71+
}
72+
}
73+
74+
return (
75+
<Container component="main" maxWidth="xs">
76+
<CssBaseline />
77+
<div className={classes.paper}>
78+
<Avatar className={classes.avatar}>
79+
<LockOutlinedIcon />
80+
</Avatar>
81+
<Typography component="h1" variant="h5">
82+
Sign in
83+
</Typography>
84+
<form className={classes.form} onSubmit={handleSubmit} noValidate>
85+
<TextField
86+
variant="outlined"
87+
margin="normal"
88+
required
89+
fullWidth
90+
id="email"
91+
label="Email Address"
92+
name="email"
93+
autoComplete="email"
94+
autoFocus
95+
/>
96+
<TextField
97+
variant="outlined"
98+
margin="normal"
99+
required
100+
fullWidth
101+
name="password"
102+
label="Password"
103+
type="password"
104+
id="password"
105+
autoComplete="current-password"
106+
/>
107+
<FormControlLabel
108+
control={<Checkbox value="remember" color="primary" />}
109+
label="Remember me"
110+
/>
111+
<Button
112+
type="submit"
113+
fullWidth
114+
variant="contained"
115+
color="primary"
116+
className={classes.submit}
117+
>
118+
Sign In
119+
</Button>
120+
<Grid container>
121+
<Grid item xs>
122+
<Link href="#" variant="body2">
123+
Forgot password?
124+
</Link>
125+
</Grid>
126+
<Grid item>
127+
<Link href="/signup" variant="body2">
128+
{"Don't have an account? Sign Up"}
129+
</Link>
130+
</Grid>
131+
</Grid>
132+
</form>
133+
</div>
134+
<Box mt={8}>
135+
<Copyright />
136+
</Box>
137+
</Container>
138+
);
139+
}

0 commit comments

Comments
 (0)