├── .gitignore ├── README.md ├── package.json ├── public ├── favicon.ico ├── img │ └── profile_img.png ├── index.html └── manifest.json ├── src ├── App.js ├── actions │ └── index.js ├── index.js ├── reducers │ ├── contactsReducer.js │ ├── index.js │ ├── initialState.js │ └── uiReducer.js └── store │ └── configureStore.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This code is part of the Getting Started with Redux tutorial series on Tutsplus. This is the v2 of the contact list application built using React and Redux. Navigate through the branch list to find the latest version of this code. 2 | 3 | ## Steps to Install application 4 | 5 | 1. Navigate to the correct branch and clone it. Alternatively, download the zip. 6 | 2. Run `yarn install` to install all the dependencies. 7 | 3. Run `yarn start` to run the application in development mode. 8 | 4. Happy hacking. Enjoy. 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ver1", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "axios": "^0.18.0", 7 | "react": "^16.2.0", 8 | "react-dom": "^16.2.0", 9 | "react-redux": "^5.0.7", 10 | "react-scripts": "1.0.17", 11 | "redux": "^3.7.2", 12 | "redux-logger": "^3.0.6", 13 | "redux-thunk": "^2.2.0" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test --env=jsdom", 19 | "eject": "react-scripts eject" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blizzerand/react-redux-demo/32a3735c4011b01b8ea07efa9c0bb2623994d653/public/favicon.ico -------------------------------------------------------------------------------- /public/img/profile_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blizzerand/react-redux-demo/32a3735c4011b01b8ea07efa9c0bb2623994d653/public/img/profile_img.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 25 | React App 26 | 27 | 28 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | /*App component starts here */ 4 | class App extends Component { 5 | 6 | render() { 7 | return ( 8 |
9 |
10 |
11 | Contacts 12 | {/* To be completed */ } 13 |
14 |
15 |
16 | 17 | 18 | 19 | ); 20 | } 21 | } 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /src/actions/index.js: -------------------------------------------------------------------------------- 1 | export const addContact =() => { 2 | return { 3 | type: "ADD_CONTACT", 4 | 5 | } 6 | } 7 | 8 | export const handleInputChange = (name, value) => { 9 | return { 10 | 11 | type: "HANDLE_INPUT_CHANGE", 12 | payload: { [name]: value} 13 | } 14 | } 15 | 16 | export const toggleContactForm = () => { 17 | return { 18 | type: "TOGGLE_CONTACT_FORM", 19 | } 20 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {render}from 'react-dom'; 3 | import App from './App'; 4 | import configureStore from './store/configureStore'; 5 | import {toggleContactForm, 6 | handleInputChange} from './actions'; 7 | render( 8 | , 9 | document.getElementById('root') 10 | ) 11 | 12 | const store = configureStore(); 13 | 14 | store.subscribe(() => 15 | console.log(store.getState()) 16 | ) 17 | 18 | /* returns isContactFormHidden returns false */ 19 | store.dispatch(toggleContactForm()); 20 | /* returns isContactFormHidden returns false */ 21 | store.dispatch(toggleContactForm()); 22 | store.dispatch(handleInputChange('email', 'manjunath@redmonark.com')) 23 | 24 | -------------------------------------------------------------------------------- /src/reducers/contactsReducer.js: -------------------------------------------------------------------------------- 1 | import initialState from './initialState'; 2 | 3 | 4 | export default function contactReducer(state = initialState.contacts, action) { 5 | switch(action.type) { 6 | 7 | /* Add contacts to the state array */ 8 | 9 | case "ADD_CONTACT": { 10 | return { 11 | ...state, 12 | contactList: [...state.contactList, state.newContact] 13 | } 14 | } 15 | 16 | /* Handle input for the contact form. 17 | The payload (input changes) gets merged with the newContact object 18 | */ 19 | 20 | case "HANDLE_INPUT_CHANGE": { 21 | 22 | return { 23 | ...state, newContact: { 24 | ...state.newContact, ...action.payload } 25 | } 26 | } 27 | 28 | default: return state; 29 | } 30 | } -------------------------------------------------------------------------------- /src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux' 2 | import contactsReducer from './contactsReducer'; 3 | import uiReducer from './uiReducer'; 4 | 5 | const rootReducer =combineReducers({ 6 | 7 | contacts: contactsReducer, 8 | ui: uiReducer, 9 | 10 | }) 11 | 12 | export default rootReducer; -------------------------------------------------------------------------------- /src/reducers/initialState.js: -------------------------------------------------------------------------------- 1 | const initialState = { 2 | contacts: { 3 | contactList: [], 4 | newContact: { 5 | name: '', 6 | surname: '', 7 | email: '', 8 | address: '', 9 | phone: '' 10 | }, 11 | }, 12 | ui: { 13 | isContactFormHidden: true 14 | } 15 | } 16 | 17 | export default initialState; -------------------------------------------------------------------------------- /src/reducers/uiReducer.js: -------------------------------------------------------------------------------- 1 | import initialState from './initialState'; 2 | 3 | 4 | 5 | export default function uiReducer(state = initialState.ui, action) { 6 | switch(action.type) { 7 | /* Show/hide the form 8 | */ 9 | case "TOGGLE_CONTACT_FORM": { 10 | return { 11 | ...state, isContactFormHidden: !state.isContactFormHidden 12 | } 13 | 14 | } 15 | default: return state; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/store/configureStore.js: -------------------------------------------------------------------------------- 1 | import {createStore} from 'redux'; 2 | import rootReducer from '../reducers/'; 3 | 4 | /*Create a function called configureStore */ 5 | 6 | export default function configureStore() { 7 | return createStore(rootReducer); 8 | } 9 | 10 | --------------------------------------------------------------------------------