firebase connected GET POST
This commit is contained in:
parent
800dda5e4c
commit
e4e218a910
1
.eslintcache
Normal file
1
.eslintcache
Normal file
File diff suppressed because one or more lines are too long
22
src/App.tsx
22
src/App.tsx
@ -5,6 +5,7 @@ import SideDrawer from "./components/SideDrawer";
|
|||||||
import { Switch, Route } from "react-router-dom";
|
import { Switch, Route } from "react-router-dom";
|
||||||
import Login from "./components/Login";
|
import Login from "./components/Login";
|
||||||
import CreateTask from "./components/CreateTask";
|
import CreateTask from "./components/CreateTask";
|
||||||
|
import TodoList from "./components/TodoList";
|
||||||
|
|
||||||
const StyledApp = styled.div`
|
const StyledApp = styled.div`
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
@ -29,6 +30,27 @@ function App() {
|
|||||||
<Route exact path="/login">
|
<Route exact path="/login">
|
||||||
<Login />
|
<Login />
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route exact path="/all">
|
||||||
|
<TodoList />
|
||||||
|
</Route>
|
||||||
|
<Route exact path="/finished">
|
||||||
|
<TodoList />
|
||||||
|
</Route>
|
||||||
|
<Route exact path="/current">
|
||||||
|
<TodoList />
|
||||||
|
</Route>
|
||||||
|
<Route exact path="/business">
|
||||||
|
<TodoList />
|
||||||
|
</Route>
|
||||||
|
<Route exact path="/personal">
|
||||||
|
<TodoList />
|
||||||
|
</Route>
|
||||||
|
<Route exact path="/important">
|
||||||
|
<TodoList />
|
||||||
|
</Route>
|
||||||
|
<Route exact path="/Canceled">
|
||||||
|
<TodoList />
|
||||||
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
</StyledApp>
|
</StyledApp>
|
||||||
);
|
);
|
||||||
|
@ -17,6 +17,12 @@ const StyledButton = styled.button`
|
|||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(18, 18, 18, 0.6);
|
background-color: rgba(18, 18, 18, 0.6);
|
||||||
}
|
}
|
||||||
|
&:focus, &:active {
|
||||||
|
border-color: inherit;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
outline:none;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Button: React.FC<Props> = (props) => {
|
const Button: React.FC<Props> = (props) => {
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import React from "react";
|
import React, { ReactEventHandler, useState } from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
|
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import * as actions from "../store/actions/actions";
|
||||||
|
import { withRouter } from "react-router-dom";
|
||||||
|
|
||||||
const StyledTasks = styled.div`
|
const StyledTasks = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -16,13 +19,49 @@ const StyledTasks = styled.div`
|
|||||||
color: blue !important;
|
color: blue !important;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
textarea{
|
textarea {
|
||||||
resize:none;
|
resize: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const CreateTask = () => {
|
const CreateTask = (props: any) => {
|
||||||
|
const [taskName, setTaskName] = useState<string>("");
|
||||||
|
const [taskDesc, setTaskDesc] = useState<string>("");
|
||||||
|
const [taskType, setTaskType] = useState<string>("bussiness");
|
||||||
|
const [isImportant, setIsImportant] = useState<boolean>(false);
|
||||||
|
const [date, setDate] = useState<string>("");
|
||||||
|
|
||||||
|
const addTaskHandler = () => {
|
||||||
|
const isValid = formValidator();
|
||||||
|
if (isValid) {
|
||||||
|
props.isAuth
|
||||||
|
? props.addToDo(
|
||||||
|
taskName,
|
||||||
|
taskDesc,
|
||||||
|
taskType,
|
||||||
|
isImportant,
|
||||||
|
date,
|
||||||
|
props.idToken,
|
||||||
|
props.userId
|
||||||
|
)
|
||||||
|
: props.history.push("/login");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const radioButtonsHandler = (type: string) => {
|
||||||
|
setTaskType(type);
|
||||||
|
};
|
||||||
|
|
||||||
|
const importantButtonsHandler = (e: any) => {
|
||||||
|
if (e.target.value === "true") setIsImportant(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const formValidator = () => {
|
||||||
|
if (taskName.length > 1 && taskDesc.length > 1 && date.length > 1)
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledTasks>
|
<StyledTasks>
|
||||||
<form>
|
<form>
|
||||||
@ -30,7 +69,13 @@ const CreateTask = () => {
|
|||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>Task Name</label>
|
<label>Task Name</label>
|
||||||
<input type="text" className="form-control" placeholder="Task Name" />
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
placeholder="Task Name"
|
||||||
|
value={taskName}
|
||||||
|
onChange={(e) => setTaskName(e.target.value)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
@ -39,6 +84,8 @@ const CreateTask = () => {
|
|||||||
className="form-control"
|
className="form-control"
|
||||||
id="exampleFormControlTextarea1"
|
id="exampleFormControlTextarea1"
|
||||||
rows={4}
|
rows={4}
|
||||||
|
value={taskDesc}
|
||||||
|
onChange={(e) => setTaskDesc(e.target.value)}
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -51,6 +98,7 @@ const CreateTask = () => {
|
|||||||
value="bussiness"
|
value="bussiness"
|
||||||
checked
|
checked
|
||||||
readOnly
|
readOnly
|
||||||
|
onClick={() => radioButtonsHandler("bussiness")}
|
||||||
/>
|
/>
|
||||||
<label className="form-check-label" htmlFor="bussiness">
|
<label className="form-check-label" htmlFor="bussiness">
|
||||||
Bussiness
|
Bussiness
|
||||||
@ -64,6 +112,7 @@ const CreateTask = () => {
|
|||||||
id="personal"
|
id="personal"
|
||||||
value="personal"
|
value="personal"
|
||||||
readOnly
|
readOnly
|
||||||
|
onClick={() => radioButtonsHandler("personal")}
|
||||||
/>
|
/>
|
||||||
<label className="form-check-label" htmlFor="personal">
|
<label className="form-check-label" htmlFor="personal">
|
||||||
Personal
|
Personal
|
||||||
@ -73,20 +122,30 @@ const CreateTask = () => {
|
|||||||
<input
|
<input
|
||||||
className="form-check-input"
|
className="form-check-input"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
value=""
|
value="true"
|
||||||
id="important"
|
id="important"
|
||||||
|
onChange={(e) => importantButtonsHandler(e)}
|
||||||
/>
|
/>
|
||||||
<label className="form-check-label" htmlFor="important">
|
<label className="form-check-label" htmlFor="important">
|
||||||
Important
|
Important
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<hr/>
|
<hr />
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>End Date</label>
|
<label>End Date</label>
|
||||||
<input type="date" className="form-control" placeholder="Date" />
|
<input
|
||||||
|
type="date"
|
||||||
|
className="form-control"
|
||||||
|
placeholder="Date"
|
||||||
|
onChange={(e) => setDate(e.target.value)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" className="btn btn-primary btn-block">
|
<button
|
||||||
|
onClick={addTaskHandler}
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-block"
|
||||||
|
>
|
||||||
Create Task
|
Create Task
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
@ -94,4 +153,35 @@ const CreateTask = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CreateTask;
|
interface RootState {
|
||||||
|
isAuth: boolean;
|
||||||
|
idToken: string;
|
||||||
|
userId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state: RootState) => {
|
||||||
|
return {
|
||||||
|
isAuth: state.isAuth,
|
||||||
|
idToken: state.idToken,
|
||||||
|
userId: state.userId,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch: any) => {
|
||||||
|
return {
|
||||||
|
addToDo: (
|
||||||
|
name: string,
|
||||||
|
desc: string,
|
||||||
|
type: string,
|
||||||
|
important: boolean,
|
||||||
|
date: string,
|
||||||
|
token: string,
|
||||||
|
userId: string,
|
||||||
|
) => dispatch(actions.addToDo(name, desc, type, important, date, token, userId)),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(withRouter(CreateTask));
|
||||||
|
@ -2,6 +2,8 @@ import React from "react";
|
|||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { NavLink } from "react-router-dom";
|
import { NavLink } from "react-router-dom";
|
||||||
import Button from "./Button";
|
import Button from "./Button";
|
||||||
|
import * as actions from "../store/actions/actions";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
const StyledHeader = styled.div`
|
const StyledHeader = styled.div`
|
||||||
height: 8%;
|
height: 8%;
|
||||||
@ -12,6 +14,7 @@ const StyledHeader = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
outline:none;
|
||||||
.menu-icon {
|
.menu-icon {
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
@ -32,9 +35,16 @@ const StyledHeader = styled.div`
|
|||||||
interface Props {
|
interface Props {
|
||||||
sideDrawer: () => void;
|
sideDrawer: () => void;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
isAuth: boolean;
|
||||||
|
logout: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Header: React.FC<Props> = (props) => {
|
const Header: React.FC<Props> = (props: Props) => {
|
||||||
|
|
||||||
|
const logoutHandler = ()=>{
|
||||||
|
props.isAuth && props.logout();
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledHeader>
|
<StyledHeader>
|
||||||
<Button onClick={props.sideDrawer}>
|
<Button onClick={props.sideDrawer}>
|
||||||
@ -51,10 +61,27 @@ const Header: React.FC<Props> = (props) => {
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<NavLink to={process.env.PUBLIC_URL + "/login"}>
|
<NavLink to={process.env.PUBLIC_URL + "/login"}>
|
||||||
<Button>Login</Button>
|
<Button onClick={logoutHandler}>{props.isAuth?'Logout': 'Login'}</Button>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</StyledHeader>
|
</StyledHeader>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Header;
|
interface RootState {
|
||||||
|
isAuth: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state: RootState) => {
|
||||||
|
return {
|
||||||
|
isAuth: state.isAuth,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch: any) => {
|
||||||
|
return {
|
||||||
|
auth: (email: string, password: string, isSignupMode: boolean) => dispatch(actions.auth(email, password, isSignupMode)),
|
||||||
|
logout: () => dispatch(actions.authLogout())
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(Header);
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { connect } from "react-redux";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
|
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
|
||||||
|
import * as actions from "../store/actions/actions";
|
||||||
|
import { Redirect } from "react-router-dom";
|
||||||
|
|
||||||
const StyledForm = styled.div`
|
const StyledForm = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -12,26 +15,24 @@ const StyledForm = styled.div`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 40rem;
|
max-width: 40rem;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
a {
|
.login-button {
|
||||||
color: blue !important;
|
color: blue !important;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Login = () => {
|
const Login = (props: any) => {
|
||||||
const [signUp, setSignUp] = useState<boolean>(false);
|
const [signUp, setSignUp] = useState<boolean>(false);
|
||||||
const [email, setEmail] = useState<string>("");
|
const [email, setEmail] = useState<string>("");
|
||||||
const [password, setPassword] = useState<string>("");
|
const [password, setPassword] = useState<string>("");
|
||||||
|
|
||||||
const authorizationHandler = (e:React.FormEvent) => {
|
const authorizationHandler = (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (signUp) {
|
signUp
|
||||||
console.log('rejestracja', email, password);
|
? props.auth(email, password, true)
|
||||||
|
: props.auth(email, password, false);
|
||||||
} else {
|
|
||||||
console.log('log', email, password);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -73,14 +74,38 @@ const Login = () => {
|
|||||||
<p className="forgot-password text-right">
|
<p className="forgot-password text-right">
|
||||||
Already registered{" "}
|
Already registered{" "}
|
||||||
{signUp ? (
|
{signUp ? (
|
||||||
<a onClick={() => setSignUp(false)}>sign in?</a>
|
<button className="login-button" onClick={() => setSignUp(false)}>
|
||||||
|
sign in?
|
||||||
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<a onClick={() => setSignUp(true)}>sign up?</a>
|
<button className="login-button" onClick={() => setSignUp(true)}>
|
||||||
|
sign up?
|
||||||
|
</button>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
{props.isAuth && <Redirect to={props.redirectTo} />}
|
||||||
</StyledForm>
|
</StyledForm>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Login;
|
interface RootState {
|
||||||
|
isAuth: boolean;
|
||||||
|
redirectTo: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state: RootState) => {
|
||||||
|
return {
|
||||||
|
isAuth: state.isAuth,
|
||||||
|
redirectTo: state.redirectTo,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch: any) => {
|
||||||
|
return {
|
||||||
|
auth: (email: string, password: string, isSignupMode: boolean) =>
|
||||||
|
dispatch(actions.auth(email, password, isSignupMode)),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(Login);
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
import { NavLink } from "react-router-dom";
|
||||||
|
|
||||||
const StyledSidedrawer = styled.div`
|
const StyledSidedrawer = styled.div`
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index:8;
|
z-index: 8;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -29,14 +30,21 @@ const StyledSidedrawer = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-right:1rem;
|
padding-right: 1rem;
|
||||||
i {
|
i {
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
span {
|
span {
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
display:contents;
|
display: contents;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.active {
|
||||||
|
color: #4153af;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,28 +58,46 @@ const SideDrawer = () => {
|
|||||||
<StyledSidedrawer>
|
<StyledSidedrawer>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
|
<NavLink to={process.env.PUBLIC_URL + "/all"}>
|
||||||
|
<i className="fas fa-box-open"></i>
|
||||||
|
<span>All</span>
|
||||||
|
</NavLink>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<NavLink to={process.env.PUBLIC_URL + "/finished"}>
|
||||||
<i className="fas fa-hourglass-end"></i>
|
<i className="fas fa-hourglass-end"></i>
|
||||||
<span>Finished</span>
|
<span>Finished</span>
|
||||||
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
<NavLink to={process.env.PUBLIC_URL + "/current"}>
|
||||||
<i className="fas fa-stopwatch"></i>
|
<i className="fas fa-stopwatch"></i>
|
||||||
<span>On going</span>
|
<span>On going</span>
|
||||||
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
<NavLink to={process.env.PUBLIC_URL + "/business"}>
|
||||||
<i className="fas fa-briefcase"></i>
|
<i className="fas fa-briefcase"></i>
|
||||||
<span>Bussiness</span>
|
<span>Bussiness</span>
|
||||||
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
<NavLink to={process.env.PUBLIC_URL + "/personal"}>
|
||||||
<i className="fas fa-lock"></i>
|
<i className="fas fa-lock"></i>
|
||||||
<span>Personal</span>
|
<span>Personal</span>
|
||||||
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
<NavLink to={process.env.PUBLIC_URL + "/important"}>
|
||||||
<i className="fas fa-flag"></i>
|
<i className="fas fa-flag"></i>
|
||||||
<span>Important</span>
|
<span>Important</span>
|
||||||
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
<NavLink to={process.env.PUBLIC_URL + "/canceled"}>
|
||||||
<i className="fas fa-ban"></i>
|
<i className="fas fa-ban"></i>
|
||||||
<span>Canceled</span>
|
<span>Canceled</span>
|
||||||
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</StyledSidedrawer>
|
</StyledSidedrawer>
|
||||||
|
78
src/components/TodoList.tsx
Normal file
78
src/components/TodoList.tsx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import * as actions from "../store/actions/actions";
|
||||||
|
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
interface TODOtype {
|
||||||
|
date: string;
|
||||||
|
taskName: string;
|
||||||
|
taskDesc: string;
|
||||||
|
isImportant: string;
|
||||||
|
taskType: string;
|
||||||
|
hash: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TodosStyled = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction:column;
|
||||||
|
height:92%;
|
||||||
|
overflow: scroll;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TodoList = (props: any) => {
|
||||||
|
useEffect(() => {
|
||||||
|
props.isAuth && props.loadToDos(props.userId, props.idToken);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
let cards = [];
|
||||||
|
if (props.isLoading === false) {
|
||||||
|
cards = props.todos.map((todo: TODOtype) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="card text-white bg-info mb-3"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
key={todo.hash}
|
||||||
|
>
|
||||||
|
<div className="card-header">{todo.date}</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<h5 className="card-title">{todo.taskName}</h5>
|
||||||
|
<p className="card-text">{todo.taskDesc}</p>
|
||||||
|
<hr />
|
||||||
|
<p className="card-text">{todo.isImportant && "important"}</p>
|
||||||
|
<hr />
|
||||||
|
<p className="card-text">{todo.taskType}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return <TodosStyled>{cards}</TodosStyled>;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface RootState {
|
||||||
|
isAuth: boolean;
|
||||||
|
todos: [];
|
||||||
|
userId: boolean;
|
||||||
|
idToken: string;
|
||||||
|
isLoading: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state: RootState) => {
|
||||||
|
return {
|
||||||
|
todos: state.todos,
|
||||||
|
userId: state.userId,
|
||||||
|
idToken: state.idToken,
|
||||||
|
isAuth: state.isAuth,
|
||||||
|
isLoading: state.isLoading,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch: any) => {
|
||||||
|
return {
|
||||||
|
loadToDos: (userId: string, idToken: string) =>
|
||||||
|
dispatch(actions.loadToDos(userId, idToken)),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(TodoList);
|
@ -1,3 +1,10 @@
|
|||||||
export const ADD_TODO = 'ADD_TODO';
|
export const ADD_TODO = 'ADD_TODO';
|
||||||
export const DELETE_TODO = 'DELETE_TODO';
|
export const DELETE_TODO = 'DELETE_TODO';
|
||||||
export const LOAD_TODOS = 'LOAD_TODOS';
|
export const LOAD_TODOS = 'LOAD_TODOS';
|
||||||
|
export const AUTH_SUCCESS = 'AUTH_SUCCESS';
|
||||||
|
export const AUTH_FAIL = 'AUTH_FAIL';
|
||||||
|
export const AUTH_LOGOUT = 'AUTH_LOGOUT';
|
||||||
|
export const ADD_SUCCESS = 'ADD_SUCCESS';
|
||||||
|
export const ADD_FAIL = 'ADD_FAIL';
|
||||||
|
export const LOAD_FAIL = 'LOAD_FAIL';
|
||||||
|
export const LOAD_SUCCESS = 'LOAD_SUCCESS';
|
@ -1,5 +1,135 @@
|
|||||||
export const loadToDos = ()=>{
|
import * as actionType from "../actions/actionTypes";
|
||||||
return dispatch =>{
|
|
||||||
|
|
||||||
|
type ILoadToDos = {
|
||||||
|
type: string;
|
||||||
|
todos: Array<object>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const loadToDos = (userId: string, token: string) => {
|
||||||
|
return (dispatch: any) => {
|
||||||
|
let url = `https://to-do-studia.firebaseio.com/todos.json?auth=${token}&orderBy="userId"&equalTo="${userId}"`;
|
||||||
|
fetch(url)
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => {
|
||||||
|
if (data.error) {
|
||||||
|
throw new Error(data.error.message);
|
||||||
}
|
}
|
||||||
}
|
let todos = [];
|
||||||
|
for (let key in data) {
|
||||||
|
todos.push({
|
||||||
|
hash: key,
|
||||||
|
taskName: data[key].name,
|
||||||
|
taskDesc: data[key].desc,
|
||||||
|
taskType: data[key].type,
|
||||||
|
isImportant: data[key].important,
|
||||||
|
date: data[key].date,
|
||||||
|
userId: data[key].userId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
dispatch({
|
||||||
|
type: actionType.LOAD_SUCCESS,
|
||||||
|
todos: todos,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
dispatch({
|
||||||
|
type: actionType.LOAD_FAIL,
|
||||||
|
error: err,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const auth = (
|
||||||
|
email: string,
|
||||||
|
password: string,
|
||||||
|
isSignupMode: boolean
|
||||||
|
) => {
|
||||||
|
return (dispatch: any) => {
|
||||||
|
const data = {
|
||||||
|
email: email,
|
||||||
|
password: password,
|
||||||
|
returnSecureToken: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
let url = `https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=AIzaSyBq4PiZ3S-qQnXK3LBw_8CvfBMSkQU6obY`;
|
||||||
|
|
||||||
|
if (!isSignupMode) {
|
||||||
|
url = `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=AIzaSyBq4PiZ3S-qQnXK3LBw_8CvfBMSkQU6obY`;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => {
|
||||||
|
if (data.error) {
|
||||||
|
throw new Error(data.error.message);
|
||||||
|
}
|
||||||
|
dispatch({
|
||||||
|
type: actionType.AUTH_SUCCESS,
|
||||||
|
idToken: data.idToken,
|
||||||
|
userId: data.localId,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
dispatch({ type: actionType.AUTH_FAIL, error: error.message });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const authLogout = () => {
|
||||||
|
return {
|
||||||
|
type: actionType.AUTH_LOGOUT,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addToDo = (
|
||||||
|
name: string,
|
||||||
|
desc: string,
|
||||||
|
type: string,
|
||||||
|
important: boolean,
|
||||||
|
date: string,
|
||||||
|
token: string,
|
||||||
|
userId: string
|
||||||
|
) => {
|
||||||
|
return (dispatch: any) => {
|
||||||
|
const data = {
|
||||||
|
name: name,
|
||||||
|
desc: desc,
|
||||||
|
type: type,
|
||||||
|
important: important,
|
||||||
|
date: date,
|
||||||
|
userId: userId,
|
||||||
|
};
|
||||||
|
|
||||||
|
let url = `https://to-do-studia.firebaseio.com/todos.json?auth=${token}`;
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => {
|
||||||
|
if (data.error) {
|
||||||
|
throw new Error(data.error.message);
|
||||||
|
}
|
||||||
|
dispatch({
|
||||||
|
type: actionType.ADD_SUCCESS,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
dispatch({
|
||||||
|
type: actionType.ADD_FAIL,
|
||||||
|
error: err,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
export {loadToDos, addToDo, auth, authLogout} from './actions';
|
@ -1,21 +1,72 @@
|
|||||||
import * as actionType from "../actions/actionTypes";
|
import * as actionType from "../actions/actionTypes";
|
||||||
import produce from "immer"
|
import produce from "immer";
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
todos: [],
|
todos: [],
|
||||||
isAuth: false,
|
isAuth: false,
|
||||||
|
apiError: null,
|
||||||
|
error: null,
|
||||||
|
userId: null,
|
||||||
|
idToken: null,
|
||||||
|
redirectTo: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ActionType{
|
interface ActionType {
|
||||||
type:string
|
type: any;
|
||||||
|
userId: any;
|
||||||
|
idToken: any;
|
||||||
|
error: any;
|
||||||
|
todos: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const reducer = (state = initialState, action:ActionType) => {
|
const reducer = (state = initialState, action: ActionType) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case actionType.LOAD_TODOS: {
|
case actionType.LOAD_TODOS: {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
case actionType.AUTH_SUCCESS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isAuth: true,
|
||||||
|
error: null,
|
||||||
|
userId: action.userId,
|
||||||
|
idToken: action.idToken,
|
||||||
|
redirectTo: "/",
|
||||||
|
};
|
||||||
|
case actionType.AUTH_FAIL:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
error: action.error,
|
||||||
|
};
|
||||||
|
case actionType.ADD_SUCCESS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
};
|
||||||
|
case actionType.ADD_FAIL:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
error: action.error,
|
||||||
|
};
|
||||||
|
case actionType.AUTH_LOGOUT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isAuth: false,
|
||||||
|
userId: null,
|
||||||
|
idToken: null,
|
||||||
|
rateData: null,
|
||||||
|
};
|
||||||
|
case actionType.LOAD_SUCCESS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
todos: action.todos,
|
||||||
|
isLoading: false,
|
||||||
|
};
|
||||||
|
case actionType.LOAD_FAIL:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
error: action.error,
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user