Commit 81342981 authored by zarina's avatar zarina 🌊

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

parent 59934c59
......@@ -7,7 +7,7 @@
# testing
/coverage
.idea
# production
/build
......
......@@ -4,7 +4,7 @@ import {NavLink} from "react-router-dom";
const FormToFill = props => {
return (
<Form onSubmit={props.submit}>
<Form className='mb-5' onSubmit={props.submit}>
<FormGroup>
<Label for="name">Name</Label>
<Input type="text"
......
......@@ -4,9 +4,9 @@ import {Button} from "reactstrap";
const FullContact = props => {
return (
<div className='FullContact d-flex justify-content-around p-5'>
<div className='FullContact d-flex justify-content-around '>
<div>
<img src={props.photo} alt="contact"/>
<img src={props.photo} width='220' alt="contact"/>
</div>
<div>
<div> name: {props.name} </div>
......@@ -14,7 +14,8 @@ const FullContact = props => {
<div> phone: {props.phone} </div>
<div className='mt-3'>
<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>
......
.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";
import FormToFill from "../../components/FormToFill/FormToFill";
import {createContact} from "../../store/actions";
import {connect} from "react-redux";
import Spinner from "../../components/UI/Spinner/Spinner";
const AddContactForm = props => {
......@@ -29,6 +30,7 @@ const AddContactForm = props => {
return (
<>
{props.loading? <Spinner/> : null}
<h2 className='mb-4'>Add new contact</h2>
<div>
<FormToFill
......@@ -44,10 +46,17 @@ const AddContactForm = props => {
);
};
const mapStateToProps = state => {
return {
loading: state.loading
}
};
const mapDispatchToProps = dispatch => {
return {
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 {connect} from "react-redux";
import {getContacts} from "../../store/actions";
import {deleteContact, getContacts} from "../../store/actions";
import Contact from "../../components/Contact/Contact";
import Modal from "../../components/UI/Modal/Modal";
import FullContact from "../../components/FullContact/FullContact";
import Spinner from "../../components/UI/Spinner/Spinner";
class Contacts extends Component {
......@@ -19,6 +20,10 @@ class Contacts extends Component {
this.setState({selectContact: value})
}
deleteHandler = (id) => {
this.props.deleteContact(id, this.selectHandler)
}
printContacts = () => {
let contacts = this.props.contacts
return Object.keys(contacts).map(contact => {
......@@ -33,19 +38,21 @@ class Contacts extends Component {
render() {
return (
<>
{this.props.loading? <Spinner/> : null}
{this.props.contacts ? <div className='Contacts'>{this.printContacts()}</div> : null}
{
this.state.selectContact ?
<Modal backdrop={true}>
<>
<FullContact
name={this.props.contacts[this.state.selectContact].name}
phone={this.props.contacts[this.state.selectContact].phone}
email={this.props.contacts[this.state.selectContact].email}
photo={this.props.contacts[this.state.selectContact].photo}
id={this.state.selectContact}
selectHandler={this.selectHandler}
/>
<FullContact
name={this.props.contacts[this.state.selectContact].name}
phone={this.props.contacts[this.state.selectContact].phone}
email={this.props.contacts[this.state.selectContact].email}
photo={this.props.contacts[this.state.selectContact].photo}
id={this.state.selectContact}
selectHandler={this.selectHandler}
delete={this.deleteHandler}
/>
</>
</Modal>
: null
......@@ -57,13 +64,15 @@ class Contacts extends Component {
const mapStateToProps = state => {
return {
contacts: state.contacts
contacts: state.contacts,
loading: state.loading
}
};
const mapDispatchToProps = dispatch => {
return {
getContacts: () => dispatch(getContacts())
getContacts: () => dispatch(getContacts()),
deleteContact: (id, selectHandler) => dispatch(deleteContact(id, selectHandler))
}
};
......
import React, {useEffect, useState} from "react";
import FormToFill from "../../components/FormToFill/FormToFill";
import {createContact, editContact} from "../../store/actions";
import {editContact} from "../../store/actions";
import {connect} from "react-redux";
import Spinner from "../../components/UI/Spinner/Spinner";
const EditContactForm = props => {
......@@ -24,7 +25,7 @@ const EditContactForm = props => {
})
};
const addContact = e => {
const editContact = e => {
e.preventDefault();
const contact = {
...contactInfo
......@@ -34,6 +35,7 @@ const EditContactForm = props => {
return (
<>
{props.loading? <Spinner/> : null}
<h2 className='mb-4'>Edit contact</h2>
<div>
<FormToFill
......@@ -42,7 +44,7 @@ const EditContactForm = props => {
phone={contactInfo.phone}
email={contactInfo.email}
photo={contactInfo.photo}
submit={addContact}
submit={editContact}
/>
</div>
</>
......@@ -52,13 +54,14 @@ const EditContactForm = props => {
const mapStateToProps = state => {
return {
contacts: state.contacts
contacts: state.contacts,
loading: state.loading
}
};
const mapDispatchToProps = dispatch => {
return {
onEditContact: (id, history, contact ) => dispatch(editContact(id, history, contact))
onEditContact: (id, history, contact) => dispatch(editContact(id, history, contact))
}
};
......
export const FETCH_REQUEST = 'FETCH_REQUEST';
export const FETCH_ERROR = 'FETCH_ERROR';
export const FETCH_SUCCESS = 'FETCH_SUCCESS'
export const FETCH_GET_CONTACTS_SUCCESS = 'FETCH_GET_CONTACTS_SUCCESS'
\ No newline at end of file
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 {
FETCH_DELETE_CONTACT_SUCCESS,
FETCH_ERROR,
FETCH_GET_CONTACTS_SUCCESS,
FETCH_REQUEST, FETCH_SUCCESS
......@@ -17,10 +18,13 @@ const fetchSuccess = () => {
return {type: FETCH_SUCCESS}
};
const fetchGetContactsSuccess = (contacts) => {
const fetchGetContactsSuccess = contacts => {
return {type: FETCH_GET_CONTACTS_SUCCESS, contacts}
}
const fetchDeleteContactSuccess = id => {
return {type: FETCH_DELETE_CONTACT_SUCCESS, id}
}
export const createContact = (contact, history) => {
return dispatch => {
......@@ -53,10 +57,23 @@ export const editContact = (id, history, contact) => {
return dispatch => {
dispatch(fetchRequest());
axios.put(`/contacts/${id}.json`, contact)
.then((response) => {
console.log(response)
.then(() => {
dispatch(fetchSuccess());
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 => {
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 = {
error: null,
loading: false,
contacts: {},
contacts: {}
};
const reducer = (state = initialState, action) => {
......@@ -20,7 +26,11 @@ const reducer = (state = initialState, action) => {
case FETCH_GET_CONTACTS_SUCCESS: {
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: {
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