Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update SignUp component to handle user sign-up and display Snackbar messages #22

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/node_modules
/package-lock.json
/package-lock.json
/config.env
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "client",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:4000",
"dependencies": {
"@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1",
Expand Down
6 changes: 4 additions & 2 deletions client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import './App.css';
import { Route, Routes } from "react-router-dom";
import Header from './componets/Header';
import React from 'react';
import Login from './componets/Login';
import SingIn from './componets/Auth/SingIn';
import SingUp from './componets/Auth/SingUp';
import Blogs from './componets/Blogs';
import UserBlogs from './componets/UserBlogs'
import AddBlogs from './componets/AddBlogs'
Expand All @@ -17,7 +18,8 @@ function App() {
</header>
<main>
<Routes>
<Route path="/login" element={<Login/>}></Route>
<Route path="/SingIn" element={<SingIn/>}></Route>
<Route path="/SingUp" element={<SingUp/>}></Route>
<Route path="/blogs" element={<Blogs/>}></Route>
<Route path="/myBlogs" element={<UserBlogs/>}></Route>
<Route path="/myBlogs/:id" element={<BlogDetail/>}></Route>
Expand Down
27 changes: 27 additions & 0 deletions client/src/actions/userActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import axios from 'axios'



export const signUp = async (userData) => {
try {
const res = await axios.post('/api/v1/signup', userData);
console.log(res.data)
return res.data;

} catch (error) {
console.error('Error signing up:', error);
throw error;
}
};


export const signIn = async (userData) => {
try {
const res = await axios.post('/api/v1/signin', userData);
return res.data;
} catch (error) {
console.error('Error signing in:', error);
throw error;
}
};

17 changes: 17 additions & 0 deletions client/src/componets/Auth/Copyright.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Typography from '@mui/material/Typography';
import Link from '@mui/material/Link';

function Copyright(props) {
return (
<Typography variant="body2" color="text.secondary" align="center" {...props}>
{'Copyright © '}
<Link color="inherit" href="https://mui.com/">
SafEarth
</Link>{' '}
{new Date().getFullYear()}
{'.'}
</Typography>
);
}

export default Copyright
112 changes: 112 additions & 0 deletions client/src/componets/Auth/SingIn.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import React, { useState } from 'react';
import Avatar from '@mui/material/Avatar';
import Button from '@mui/material/Button';
import CssBaseline from '@mui/material/CssBaseline';
import TextField from '@mui/material/TextField';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import Link from '@mui/material/Link';
import Grid from '@mui/material/Grid';
import Box from '@mui/material/Box';
import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { signIn } from '../../actions/userActions';

const defaultTheme = createTheme();

const SignInPage = () => {
const [signInError, setSignInError] = useState(null);

const handleSubmit = async (event) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const email = formData.get('email');
const password = formData.get('password');

try {
const signInData = await signIn({ email, password });
console.log('Sign In Successful:', signInData);
// Handle successful sign-in, such as redirecting to a new page
} catch (error) {
console.error('Error signing in:', error.message);
setSignInError('Invalid email or password. Please try again.');
}
};

return (
<ThemeProvider theme={defaultTheme}>
<Container component="main" maxWidth="xs">
<CssBaseline />
<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="email"
label="Email Address"
name="email"
autoComplete="email"
/>
<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"
/>
{signInError && (
<Typography variant="body2" color="error">
{signInError}
</Typography>
)}
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
>
Sign In
</Button>
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Link href="/SingUp" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</Box>
</Box>
</Container>
</ThemeProvider>
);
};

export default SignInPage;
171 changes: 171 additions & 0 deletions client/src/componets/Auth/SingUp.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import * as React from 'react';
import Avatar from '@mui/material/Avatar';
import Button from '@mui/material/Button';
import CssBaseline from '@mui/material/CssBaseline';
import TextField from '@mui/material/TextField';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import Link from '@mui/material/Link';
import Grid from '@mui/material/Grid';
import Box from '@mui/material/Box';
import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container';
import Snackbar from '@mui/material/Snackbar';
import MuiAlert from '@mui/material/Alert';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { signUp } from '../../actions/userActions'
import { useState } from 'react';
import Copyright from './Copyright';


// TODO remove, this demo shouldn't need to reset the theme.

const defaultTheme = createTheme();

const SingUp = () => {
const [openSnackbar, setOpenSnackbar] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState('');
const [snackbarSeverity, setSnackbarSeverity] = useState('success');

const handleCloseSnackbar = () => {
setOpenSnackbar(false);
};

const handleSubmit = async (event) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
const userData = {
firstName: data.get('firstName'),
lastName: data.get('lastName'),
email: data.get('email'),
password: data.get('password'),
};
console.log(userData)
try {
const response = await signUp(userData);
console.log('Signed up successfully:', response);
setSnackbarSeverity('success');
setSnackbarMessage('User created successfully');
setOpenSnackbar(true);
} catch (error) {
console.error('Error signing up:', error);
if (error.response && error.response.data.message === 'User already exists') {
setSnackbarSeverity('error');
setSnackbarMessage('The email is already in use. Please use a different email.');
} else {
setSnackbarSeverity('error');
setSnackbarMessage('Error signing up. Please try again.');
}
setOpenSnackbar(true);
}
};


return (
<ThemeProvider theme={defaultTheme}>
<Container component="main" maxWidth="xs">
<CssBaseline />
<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 up
</Typography>
<Box component="form" noValidate onSubmit={handleSubmit} sx={{ mt: 3 }}>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
autoComplete="given-name"
name="firstName"
required
fullWidth
id="firstName"
label="First Name"
// autoFocus
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
required
fullWidth
id="lastName"
label="Last Name"
name="lastName"
autoComplete="family-name"
/>
</Grid>
<Grid item xs={12}>
<TextField
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
/>
</Grid>
<Grid item xs={12}>
<TextField
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="new-password"
/>
</Grid>
<Grid item xs={12}>
<FormControlLabel
control={<Checkbox value="allowExtraEmails" color="primary" />}
label="I want to receive inspiration, marketing promotions and updates via email."
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
>
Sign Up
</Button>
<Grid container justifyContent="flex-end">
<Grid item>
<Link href="SingIn" variant="body2">
Already have an account? Sign in
</Link>
</Grid>
</Grid>
</Box>
</Box>
<Snackbar
open={openSnackbar}
autoHideDuration={6000}
onClose={handleCloseSnackbar}
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
>
<MuiAlert
elevation={6}
variant="filled"
onClose={handleCloseSnackbar}
severity={snackbarSeverity}
>
{snackbarMessage}
</MuiAlert>
</Snackbar>
<Copyright sx={{ mt: 5 }} />
</Container>
</ThemeProvider>
);
}
export default SingUp
8 changes: 4 additions & 4 deletions client/src/componets/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ const Header = () => {
{!isLoggedIn && (
<> <Button
LinkComponent={Link}
to="login/"
to="SingIn/"
sx={{ margin: 1, fontWeight : 'bold' , color:"white" , borderRadius: 10 }}
>
Login
SingIn
</Button>
<Button
LinkComponent={Link}
to="login/"
to="SingUp/"
sx={{ margin: 1, fontWeight : 'bold' , color:"white" , borderRadius: 10 }}
>

Expand All @@ -76,7 +76,7 @@ const Header = () => {
<Button
onClick={() => dispath(authActions.logout())}
LinkComponent={Link}
to="/login"
to="/SingIn"
variant="contained"
sx={{ margin: 1, borderRadius: 10 }}
color="warning"
Expand Down
Loading