Commit 81342981 authored by zarina's avatar zarina 🌊

#4, Реализована возможность удаления контакта, добавлен лоадер

parent 59934c59
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# testing # testing
/coverage /coverage
.idea
# production # production
/build /build
......
...@@ -4,7 +4,7 @@ import {NavLink} from "react-router-dom"; ...@@ -4,7 +4,7 @@ import {NavLink} from "react-router-dom";
const FormToFill = props => { const FormToFill = props => {
return ( return (
<Form onSubmit={props.submit}> <Form className='mb-5' onSubmit={props.submit}>
<FormGroup> <FormGroup>
<Label for="name">Name</Label> <Label for="name">Name</Label>
<Input type="text" <Input type="text"
......
...@@ -4,9 +4,9 @@ import {Button} from "reactstrap"; ...@@ -4,9 +4,9 @@ import {Button} from "reactstrap";
const FullContact = props => { const FullContact = props => {
return ( return (
<div className='FullContact d-flex justify-content-around p-5'> <div className='FullContact d-flex justify-content-around '>
<div> <div>
<img src={props.photo} alt="contact"/> <img src={props.photo} width='220' alt="contact"/>
</div> </div>
<div> <div>
<div> name: {props.name} </div> <div> name: {props.name} </div>
...@@ -14,7 +14,8 @@ const FullContact = props => { ...@@ -14,7 +14,8 @@ const FullContact = props => {
<div> phone: {props.phone} </div> <div> phone: {props.phone} </div>
<div className='mt-3'> <div className='mt-3'>
<Button color='info' className='mr-3' tag={NavLink} to={`/contacts/${props.id}/edit`}>edit</Button> <Button color='info' className='mr-3' tag={NavLink} to={`/contacts/${props.id}/edit`}>edit</Button>
<Button onClick={() => props.selectHandler(null)} color='danger'>cancel</Button> <Button onClick={() => props.selectHandler(null)} className='mr-3' >cancel</Button>
<Button onClick={() => props.delete(props.id)} color='danger'>delete</Button>
</div> </div>
</div> </div>
</div> </div>
......
.Spinner,
.Spinner:after {
border-radius: 50%;
width: 60px;
height: 60px;
position: absolute;
top: calc( 50% - 30px);
left: calc( 50% - 30px);
z-index: 100000000000000;
}
.Spinner{
border: 7px solid rgba(255, 255, 255, 0.2);
border-left: 7px solid #ffffff;
animation: load 1s infinite linear;
}
@keyframes load {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg) ;
}
}
import React from "react";
import "./Spinner.css";
import Backdrop from "../Backdrop/Backdrop";
const Spinner = () => {
return (
<>
<div className="Spinner"/>
<Backdrop show={true}/>
</>
)
};
export default Spinner;
...@@ -2,6 +2,7 @@ import React, {useState} from "react"; ...@@ -2,6 +2,7 @@ import React, {useState} from "react";
import FormToFill from "../../components/FormToFill/FormToFill"; import FormToFill from "../../components/FormToFill/FormToFill";
import {createContact} from "../../store/actions"; import {createContact} from "../../store/actions";
import {connect} from "react-redux"; import {connect} from "react-redux";
import Spinner from "../../components/UI/Spinner/Spinner";
const AddContactForm = props => { const AddContactForm = props => {
...@@ -29,6 +30,7 @@ const AddContactForm = props => { ...@@ -29,6 +30,7 @@ const AddContactForm = props => {
return ( return (
<> <>
{props.loading? <Spinner/> : null}
<h2 className='mb-4'>Add new contact</h2> <h2 className='mb-4'>Add new contact</h2>
<div> <div>
<FormToFill <FormToFill
...@@ -44,10 +46,17 @@ const AddContactForm = props => { ...@@ -44,10 +46,17 @@ const AddContactForm = props => {
); );
}; };
const mapStateToProps = state => {
return {
loading: state.loading
}
};
const mapDispatchToProps = dispatch => { const mapDispatchToProps = dispatch => {
return { return {
onContactCreated: (contact, history) => dispatch(createContact(contact, history)) onContactCreated: (contact, history) => dispatch(createContact(contact, history))
} }
}; };
export default connect(null, mapDispatchToProps)(AddContactForm); export default connect(mapStateToProps, mapDispatchToProps)(AddContactForm);
import React, {Component} from "react"; import React, {Component} from "react";
import {connect} from "react-redux"; import {connect} from "react-redux";
import {getContacts} from "../../store/actions"; import {deleteContact, getContacts} from "../../store/actions";
import Contact from "../../components/Contact/Contact"; import Contact from "../../components/Contact/Contact";
import Modal from "../../components/UI/Modal/Modal"; import Modal from "../../components/UI/Modal/Modal";
import FullContact from "../../components/FullContact/FullContact"; import FullContact from "../../components/FullContact/FullContact";
import Spinner from "../../components/UI/Spinner/Spinner";
class Contacts extends Component { class Contacts extends Component {
...@@ -19,6 +20,10 @@ class Contacts extends Component { ...@@ -19,6 +20,10 @@ class Contacts extends Component {
this.setState({selectContact: value}) this.setState({selectContact: value})
} }
deleteHandler = (id) => {
this.props.deleteContact(id, this.selectHandler)
}
printContacts = () => { printContacts = () => {
let contacts = this.props.contacts let contacts = this.props.contacts
return Object.keys(contacts).map(contact => { return Object.keys(contacts).map(contact => {
...@@ -33,6 +38,7 @@ class Contacts extends Component { ...@@ -33,6 +38,7 @@ class Contacts extends Component {
render() { render() {
return ( return (
<> <>
{this.props.loading? <Spinner/> : null}
{this.props.contacts ? <div className='Contacts'>{this.printContacts()}</div> : null} {this.props.contacts ? <div className='Contacts'>{this.printContacts()}</div> : null}
{ {
this.state.selectContact ? this.state.selectContact ?
...@@ -45,6 +51,7 @@ class Contacts extends Component { ...@@ -45,6 +51,7 @@ class Contacts extends Component {
photo={this.props.contacts[this.state.selectContact].photo} photo={this.props.contacts[this.state.selectContact].photo}
id={this.state.selectContact} id={this.state.selectContact}
selectHandler={this.selectHandler} selectHandler={this.selectHandler}
delete={this.deleteHandler}
/> />
</> </>
</Modal> </Modal>
...@@ -57,13 +64,15 @@ class Contacts extends Component { ...@@ -57,13 +64,15 @@ class Contacts extends Component {
const mapStateToProps = state => { const mapStateToProps = state => {
return { return {
contacts: state.contacts contacts: state.contacts,
loading: state.loading
} }
}; };
const mapDispatchToProps = dispatch => { const mapDispatchToProps = dispatch => {
return { return {
getContacts: () => dispatch(getContacts()) getContacts: () => dispatch(getContacts()),
deleteContact: (id, selectHandler) => dispatch(deleteContact(id, selectHandler))
} }
}; };
......
import React, {useEffect, useState} from "react"; import React, {useEffect, useState} from "react";
import FormToFill from "../../components/FormToFill/FormToFill"; import FormToFill from "../../components/FormToFill/FormToFill";
import {createContact, editContact} from "../../store/actions"; import {editContact} from "../../store/actions";
import {connect} from "react-redux"; import {connect} from "react-redux";
import Spinner from "../../components/UI/Spinner/Spinner";
const EditContactForm = props => { const EditContactForm = props => {
...@@ -24,7 +25,7 @@ const EditContactForm = props => { ...@@ -24,7 +25,7 @@ const EditContactForm = props => {
}) })
}; };
const addContact = e => { const editContact = e => {
e.preventDefault(); e.preventDefault();
const contact = { const contact = {
...contactInfo ...contactInfo
...@@ -34,6 +35,7 @@ const EditContactForm = props => { ...@@ -34,6 +35,7 @@ const EditContactForm = props => {
return ( return (
<> <>
{props.loading? <Spinner/> : null}
<h2 className='mb-4'>Edit contact</h2> <h2 className='mb-4'>Edit contact</h2>
<div> <div>
<FormToFill <FormToFill
...@@ -42,7 +44,7 @@ const EditContactForm = props => { ...@@ -42,7 +44,7 @@ const EditContactForm = props => {
phone={contactInfo.phone} phone={contactInfo.phone}
email={contactInfo.email} email={contactInfo.email}
photo={contactInfo.photo} photo={contactInfo.photo}
submit={addContact} submit={editContact}
/> />
</div> </div>
</> </>
...@@ -52,13 +54,14 @@ const EditContactForm = props => { ...@@ -52,13 +54,14 @@ const EditContactForm = props => {
const mapStateToProps = state => { const mapStateToProps = state => {
return { return {
contacts: state.contacts contacts: state.contacts,
loading: state.loading
} }
}; };
const mapDispatchToProps = dispatch => { const mapDispatchToProps = dispatch => {
return { return {
onEditContact: (id, history, contact ) => dispatch(editContact(id, history, contact)) onEditContact: (id, history, contact) => dispatch(editContact(id, history, contact))
} }
}; };
......
...@@ -2,3 +2,4 @@ export const FETCH_REQUEST = 'FETCH_REQUEST'; ...@@ -2,3 +2,4 @@ export const FETCH_REQUEST = 'FETCH_REQUEST';
export const FETCH_ERROR = 'FETCH_ERROR'; export const FETCH_ERROR = 'FETCH_ERROR';
export const FETCH_SUCCESS = 'FETCH_SUCCESS' export const FETCH_SUCCESS = 'FETCH_SUCCESS'
export const FETCH_GET_CONTACTS_SUCCESS = 'FETCH_GET_CONTACTS_SUCCESS' export const FETCH_GET_CONTACTS_SUCCESS = 'FETCH_GET_CONTACTS_SUCCESS'
export const FETCH_DELETE_CONTACT_SUCCESS = 'FETCH_DELETE_CONTACT_SUCCESS'
\ No newline at end of file
import { import {
FETCH_DELETE_CONTACT_SUCCESS,
FETCH_ERROR, FETCH_ERROR,
FETCH_GET_CONTACTS_SUCCESS, FETCH_GET_CONTACTS_SUCCESS,
FETCH_REQUEST, FETCH_SUCCESS FETCH_REQUEST, FETCH_SUCCESS
...@@ -17,10 +18,13 @@ const fetchSuccess = () => { ...@@ -17,10 +18,13 @@ const fetchSuccess = () => {
return {type: FETCH_SUCCESS} return {type: FETCH_SUCCESS}
}; };
const fetchGetContactsSuccess = (contacts) => { const fetchGetContactsSuccess = contacts => {
return {type: FETCH_GET_CONTACTS_SUCCESS, contacts} return {type: FETCH_GET_CONTACTS_SUCCESS, contacts}
} }
const fetchDeleteContactSuccess = id => {
return {type: FETCH_DELETE_CONTACT_SUCCESS, id}
}
export const createContact = (contact, history) => { export const createContact = (contact, history) => {
return dispatch => { return dispatch => {
...@@ -53,10 +57,23 @@ export const editContact = (id, history, contact) => { ...@@ -53,10 +57,23 @@ export const editContact = (id, history, contact) => {
return dispatch => { return dispatch => {
dispatch(fetchRequest()); dispatch(fetchRequest());
axios.put(`/contacts/${id}.json`, contact) axios.put(`/contacts/${id}.json`, contact)
.then((response) => { .then(() => {
console.log(response) dispatch(fetchSuccess());
history.push('/') history.push('/')
fetchSuccess() })
.catch(err => {
dispatch(fetchError(err));
});
}
}
export const deleteContact = (id, selectHandler) =>{
return dispatch => {
dispatch(fetchRequest());
axios.delete(`/contacts/${id}.json`)
.then(() => {
selectHandler(null)
dispatch(fetchDeleteContactSuccess(id));
}) })
.catch(err => { .catch(err => {
dispatch(fetchError(err)); dispatch(fetchError(err));
......
import {FETCH_ERROR, FETCH_GET_CONTACTS_SUCCESS, FETCH_REQUEST, FETCH_SUCCESS} from "./actionTypes"; import {
FETCH_DELETE_CONTACT_SUCCESS,
FETCH_ERROR,
FETCH_GET_CONTACTS_SUCCESS,
FETCH_REQUEST,
FETCH_SUCCESS
} from "./actionTypes";
const initialState = { const initialState = {
error: null, error: null,
loading: false, loading: false,
contacts: {}, contacts: {}
}; };
const reducer = (state = initialState, action) => { const reducer = (state = initialState, action) => {
...@@ -20,7 +26,11 @@ const reducer = (state = initialState, action) => { ...@@ -20,7 +26,11 @@ const reducer = (state = initialState, action) => {
case FETCH_GET_CONTACTS_SUCCESS: { case FETCH_GET_CONTACTS_SUCCESS: {
return {...state, contacts: action.contacts, loading: false} return {...state, contacts: action.contacts, loading: false}
} }
case FETCH_DELETE_CONTACT_SUCCESS: {
let contacts = {...state.contacts}
delete contacts[action.id]
return {...state, contacts, loading: false}
}
default: { default: {
return state return state
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment