Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- run: yarn install --frozen-lockfile
- run: yarn run build --if-present
- run: yarn test
env:
env:
REACT_APP_BACKEND_URL: ${{ secrets.REACT_APP_BACKEND_URL }}
- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v1.1.2
Expand Down
Binary file added Assets/forgot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/reset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@fortawesome/free-brands-svg-icons": "^5.15.1",
"@fortawesome/free-regular-svg-icons": "^5.15.1",
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/react-fontawesome": "^0.1.12",
"@fortawesome/react-fontawesome": "^0.1.13",
"axios": "^0.21.0",
"babel-loader": "8.0.6",
"babel-plugin-transform-class-properties": "^6.24.1",
Expand Down
23 changes: 23 additions & 0 deletions redux/actions/forgotPassword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as actions from "./types";
import http from '../../src/utils/axios';

export const forgotAction = (data) => (dispatch) =>{
dispatch({ type: actions.SET_FORGOT_LOADING });
http.post(
"/api/forgotPassword",
data
)

.then((res) => {
dispatch({
type: actions.SET_FORGOT_SUCCESS,
payload: res.data.message,
});
})
.catch((error) => {
dispatch({
type: actions.SET_FORGOT_ERROR,
payload: error.response.data.err,
});
});
};
24 changes: 24 additions & 0 deletions redux/actions/resetPassword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as actions from "./types";
import http from '../../src/utils/axios';

export const resetAction = (data) => (dispatch) => {
let token = data.token.token
let password = data.password
let confirmPassword = data.confirmPassword
let resetData = {password, confirmPassword}
dispatch({ type: actions.SET_RESET_LOADING });
http
.post(`/api/resetPassword/${token}`, resetData)
.then((res) => {
dispatch({
type: actions.SET_RESET_SUCCESS,
payload: res.data.message,
});
})
.catch((error) => {
dispatch({
type: actions.SET_RESET_INVALID,
payload: error.response.data.err,
});
});
};
7 changes: 7 additions & 0 deletions redux/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ export const SET_RESOLVED = "SET_RESOLVED";
export const SET_SUCCESS = "SET_SUCCESS";
export const GET_REQUESTS= 'GET_REQUESTS'
export const GET_REQUESTS_ERROR= 'GET_REQUESTS_ERROR'
export const SET_FORGOT_LOADING = 'SET_FORGOT_LOADING';
export const SET_FORGOT_ERROR = 'SET_FORGOT_ERROR';
export const SET_FORGOT_SUCCESS = 'SET_FORGOT_SUCCESS';
export const SET_RESET_INVALID = 'SET_RESET_INVALID';
export const SET_RESET_ERROR = 'SET_RESET_ERROR';
export const SET_RESET_SUCCESS = 'SET_RESET_SUCCESS';
export const SET_RESET_LOADING = 'SET_RESET_LOADING';
31 changes: 31 additions & 0 deletions redux/reducers/forgotPassword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as actions from "../actions/types";

const initialState = {
error: null,
message: null,
loading: false,
};

export default (state = initialState, action) => {
switch (action.type) {
case actions.SET_FORGOT_LOADING:
return {
...state,
loading: true,
};
case actions.SET_FORGOT_ERROR:
return {
...state,
error: action.payload,
loading: false,
};
case actions.SET_FORGOT_SUCCESS:
return {
...state,
message: action.payload,
loading: false,
};
default:
return state;
}
};
6 changes: 5 additions & 1 deletion redux/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import users from "./users";
import statuses from "./statuses";
import alerts from "./alerts";
import adminRequests from './adminRequests'
import forgot from './forgotPassword';
import resetPassword from './resetPassword'

// function that contains all reducer objects.
const allReducers = combineReducers({
Expand All @@ -22,7 +24,9 @@ const allReducers = combineReducers({
users,
alerts,
signup,
adminRequests
adminRequests,
forgot,
resetPassword
});

export default allReducers;
32 changes: 32 additions & 0 deletions redux/reducers/resetPassword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as actions from "../actions/types";

const initialState = {
error: null,
message: null,
err: null,
loading: false,
};

export default (state = initialState, action) => {
switch (action.type) {
case actions.SET_RESET_LOADING:
return {
...state,
loading: true,
};
case actions.SET_RESET_SUCCESS:
return {
...state,
message: action.payload,
loading: false,
};
case actions.SET_RESET_INVALID:
return {
...state,
err: action.payload,
loading: false,
};
default:
return state;
}
};
9 changes: 9 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ import Signup from "./Views/Signup";
import ViewProfile from "./components/profile/View";
import CompleteProfile from "./components/profile/Complete";
import UpdateProfile from "./components/profile/Update";
import {
ForgotPassword,
Success,
} from "./components/resetPassword/forgotPassword";
import ResetPassword from "./components/resetPassword/resetPassword";
import Navigation from "./components/Navigation";
import Footer from "./components/Footer";

import Roles from "./views/Roles/Roles";

import "./App.scss";
Expand Down Expand Up @@ -39,6 +45,9 @@ const App = () => (
<Route exact path="/request/manager" component={AdminRequests} />
<Route exact path="/profile/update/:slug" component={UpdateProfile} />
<Route exact path="/roles" component={Roles} />
<Route exact path="/forgot/success" component={Success} />
<Route exact path="/forgot" component={ForgotPassword} />
<Route exact path="/reset/:token" component={ResetPassword} />
</Switch>
<Footer />
</Router>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Container, Row, Col } from 'reactstrap';

const Navigation = () => {
return (
<Container fluid>
<Container fluid className='nav-bar'>
<Row className='navigation-title'>
<Col>
<h1 className='nav-title text-warning'>barefoot NOMAD</h1>
Expand Down
18 changes: 17 additions & 1 deletion src/components/homepage.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,23 @@
font-size: 1.5em;
}
}

.search-input{
background-color: variables.$navFooterColor;;
border: 0;
border-bottom: 2px solid variables.$mainTextColor;
outline: none;
color: variables.$mainBgColor;
font-size: .9em;
padding-left: 5px;
padding-bottom: -10px;
height: 2.5em;
font-family: FontAwesome;
}
.nav-bar ::placeholder{
color: variables.$mainTextColor;
text-align: end;
font-size: 1.5em;
}
.book-btn, .start-btn{
background-color: variables.$btnBgColor;
color: variables.$mainBgColor;
Expand Down
9 changes: 9 additions & 0 deletions src/components/resetPassword/button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';
import {Button} from 'reactstrap';

const Mybutton = ({label})=>{
return(
<Button type="submit">{label}</Button>
)
}
export default Mybutton;
115 changes: 115 additions & 0 deletions src/components/resetPassword/forgotPassword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import React, { useState, useEffect } from "react";
import image from "../../../Assets/forgot.png";
import "./reset.scss";
import { useDispatch, useSelector } from "react-redux";
import { forgotAction } from "../../../redux/actions/forgotPassword";
import "bootstrap/dist/css/bootstrap.min.css";
import Mybutton from "./button";
import {
Col,
Button,
Form,
Label,
Input,
Spinner,
Alert,
Container,
Row,
} from "reactstrap";

const ForgotPassword = () => {
//Create states
const dispatch = useDispatch();
const [message, setMessage] = useState("");
const [visible, setVisible] = useState(false);
const [color, setColor] = useState("");
const [email, setEmail] = useState("");

//Add function to dispatch data when submitted and make input an object
const handleSubmit = (e) => {
const newEmail = { email };
e.preventDefault();
if (!email) setMessage(error);
setEmail("");
dispatch(forgotAction(newEmail));
};

//Get data from API
const error = useSelector((state) => state.forgot.error);
const response = useSelector((state) => state.forgot.message);
const loading = useSelector((state) => state.forgot.loading);

//Add changes incase a state changes
useEffect(() => {
if (error) {
setMessage(error);
setVisible("true");
setColor("danger");
}

if (response) {
setMessage(response);
setVisible("true");
setColor("success");
setTimeout(() => {
window.location = "./forgot/success";
}, 3000);
}
}, [error, response]);

return (
<Container fluid>
<div className="forgotPassword">
<Row>
<Col md="6">
<Form id="forgotForm" onSubmit={handleSubmit}>
<center>
<h1>Forgot Password?</h1>
</center>
<div className="forgotContainer">
<Label>Email</Label>
<Input
id="emailinput"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Enter your email"
></Input>
<center>
<br></br>
<div>{loading && <Spinner color="primary" />}</div>
<Alert isOpen={visible} color={color}>
{message}
</Alert>
<Mybutton label="Submit"></Mybutton>
</center>
</div>
</Form>
</Col>
<Col md="6">
<img src={image} alt="image"></img>
</Col>
</Row>
</div>
</Container>
);
};
const Success = () => {
return (
<Container>
<div className="success">
<center>
<Form id="successForm">
<center>
<h1>
Please Click On The Link Sent In Your Email To Reset Your
Password .
</h1>
</center>
</Form>
</center>
</div>
</Container>
);
};

export { ForgotPassword, Success };
Loading