<file_sep>import {connect} from 'react-redux';
import {ContactView} from "./list/contact-list";

const mapStateToProps = (state) => {
    return {
        contacts: state.contacts ? state.contacts : [],
        query: state.query ? state.query : null
    };

};

const mapDispatchToProps = dispatch => {
    return {
        fetchContacts: (contacts) => dispatch({type: 'FETCH_CONTACTS', contacts}),
        updateQuery: (query) => dispatch({type: 'UPDATE_QUERY', query})
    }
};

export const ContactContainer = connect(mapStateToProps, mapDispatchToProps)(ContactView);
<file_sep># Content

Via -Task

steps : 
  - clone project
  - npm install 
  - npm start
<file_sep>import React, {useEffect} from 'react';
import axios from "axios";
import {Contact} from "../contact/contact";
import styled from 'styled-components'
import {Header} from "../header/header";


const Container = styled.div`
    background: #8080807a;
`;

const FlexGrid = styled.div`
    display: flex;
	flex-wrap: wrap;
	width: 45%;
    margin-left: auto;
    margin-right: auto;
  `;
const Col = styled.div`
    box-sizing: border-box;
    color: #171e42;
    padding: 10px;
    text-align: center;
    border-radius: 5px;
`;
export const ContactView = ({contacts, query, fetchContacts, updateQuery}) => {

    /*******************************************************************
        fetch contacts details on page loading , and update redux store
     *******************************************************************/
    useEffect(() => {
        const fetchContactsUrl = 'http://private-05627-frontendnewhire.apiary-mock.com/contact_list';
        axios.get(fetchContactsUrl, {crossdomain: true})
            .then(response => {
                console.log(response.data)
                fetchContacts(response.data);
            })
    }, []);


    /******************************************************************************************
        filter contacts by user search input only filter when input is more than 3 characters
     *****************************************************************************************/
    const filteredContacts = () => {
        if (contacts && query !== null) {
            return contacts.filter((item) => {
                return item.name.toLowerCase().indexOf(query.toLowerCase()) !== -1;
            })
        }
        return contacts;
    };

    return (
        <div>
            <Header updateQuery={updateQuery}/>
            <Container>
                {contacts && contacts.length ? (
                    <FlexGrid>
                        {
                            filteredContacts().map((contact, index) => {
                                return <Col><Contact data={contact} key={index}/></Col>
                            })
                        }
                    </FlexGrid>
                ) : null}
            </Container>
        </div>
    );
}
<file_sep>import React, {useState} from 'react';
import styled from "styled-components";

const ContractContainer = styled.div`
    background: white;
    padding: 15px;
    border-radius: 10px;
    display: -webkit-box; 
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    width: 165px;
    height: 270px;
  `;

const ContractInfo = styled.div`
    text-align : left;
    color: gray
  `;

const ImgContainer = styled.div`
    display: flex;
    flex-flow: column nowrap;
    height: calc(35vh);
    width: 100%;
    max-height: 200px;
     
    &:hover {
        height: calc(15vh);
    } 
`;

const ContractInformationContainer = styled.div`
    margin-top: 20px;
`;

const TypeIcon = styled.img`
    position: absolute;
    margin-left: 20px; 
`;

const TypeIconContainer = styled.div`
    display: flex;
    flex-flow: column nowrap;
    height: calc(35vh);
    width: 100%;
    max-height: 200px;
     margin-top: -20px;
    &:hover {
        height: calc(15vh);
    } 
`;

const ExtraContactInfo = styled.div`
    font-size: 13px;
    color: gray;
    text-align: left;
    margin-top: 5px;
`

export const Contact = ({data}) => {
    const [isShowExtraContractInfo, setIsShowExtraContractInfo] = useState(false);

    /*********************************************
     get contact icon according to driven type
     ********************************************/
    const getContactIcon = (driverType) => {
        const type = driverType.toLowerCase().trim();
        return type == 'professional' ? `../../../src/professional.svg` : `../../../src/citizen.svg`;
    };


    return (
        data ? (
            <ContractContainer>
                <ImgContainer>
                    <img
                        onMouseEnter={() => setIsShowExtraContractInfo(true)}
                        onMouseLeave={() => setIsShowExtraContractInfo(false)}
                        style={{
                            display: 'flex',
                            justifyContent: 'center',
                            height: '100%'
                        }}
                        src={data.profile_image}
                    />
                    <TypeIconContainer>
                        <TypeIcon src={getContactIcon(data.driverType)}
                                  isShowExtraContractInfo={isShowExtraContractInfo}/>
                    </TypeIconContainer>
                </ImgContainer>

                <ContractInformationContainer>
                    <ContractInfo><span
                        style={{fontSize: '18px', fontFamily: 'cursive'}}> Full name</span></ContractInfo>
                    {data.name && <ContractInfo>{data.name}</ContractInfo>}
                    {isShowExtraContractInfo ?
                        <ExtraContactInfo>
                            <div>Phone Number: {data.phone}</div>
                            <div>Email: {data.email}</div>
                        </ExtraContactInfo> : null

                    }
                </ContractInformationContainer>

            </ContractContainer>
        ) : null

    );
};
<file_sep>export const contactReducer = function (state = 0, action) {
    switch (action.type) {
        case "FETCH_CONTACTS": {
            return {
                query: state.query,
                contacts: action.contacts
            }
        }
        case "UPDATE_QUERY" : {
            return {
                query: action.query,
                contacts: state.contacts
            }
        }
        default:
            return state;
    }
};
<file_sep>import { createStore } from 'redux';
import {contactReducer} from "./contacts/contacts.reducer";


export const store = createStore(contactReducer);

