{"data":{"content":{"fields":{"slug":"/labs/capstone","type":"lab"},"frontmatter":{"title":"Capstone"},"html":"<h1>Lab Six - Capstone</h1>\n<h2>Switch to Lab06</h2>\n<ul>\n<li>In a terminal:</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">cd ../ # presuming still in previous lab\ncd lab-06\nyarn start</code></pre></div>\n<h3>Are we done yet?</h3>\n<p>The application is pretty much feature-complete at this point. Nice work!</p>\n<p>…but then you notice that just about anybody can modify data. Not good.\nWe need to add some security to this app, fast!</p>\n<h3>What do we need?</h3>\n<p>We need to restrict access by requiring the user log in using valid credentials.\nThe good news is that our server team has put together a simple set of Rest services to support a login/logout capability.</p>\n<p><strong>Note</strong>: This is a very naïve login/logout capability as a simple example. Don’t use it in production code!</p>\n<h3>How are we going to do it?</h3>\n<p>There aren’t any new concepts in this section - we’re just applying all the things you’ve learned from previous labs.\n<strong>Try and implement each step yourself</strong> - don’t be afraid to ask questions or collaborate with classmates to work out a solution.\nIf you truly get stuck then each section has a code hint you can refer to.</p>\n<blockquote>\n<p>Note that many of the files you’ll be working with don’t exist in the baseline yet, so you’ll need to create them. In addition, you’ll need to keep an eye out for any missing <code class=\"language-text\">import</code> statements and get those fixed. Just another bit of fun in modern JS development 😃</p>\n</blockquote>\n<h3>Build the Action Types for Auth</h3>\n<p>Our app is going to have to accept credentials, log the user in, and pull the current user from the server\nso we can get info about them.</p>\n<p>We need to define our types for Authentication actions.</p>\n<ul>\n<li>One type for when we get a copy of the user from the server and need to save it into State</li>\n<li>A second type to track whether we encountered an error when logging in so we can tell the user.</li>\n</ul>\n<details>\n  <summary>Code hint:</summary>\n<div class=\"gatsby-code-title\">AuthActionTypes.js</div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token constant\">SET_USER</span> <span class=\"token operator\">=</span> <span class=\"token string\">'SET_USER'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token constant\">ERROR</span> <span class=\"token operator\">=</span> <span class=\"token string\">'ERROR'</span><span class=\"token punctuation\">;</span></code></pre></div>\n</details>\n<p> </p>\n<h3>Build the Actions</h3>\n<p>Now we need a way to fire off login &#x26; logout actions based on user interaction.</p>\n<p>We need async actions for making API calls to the following endpoints:</p>\n<ul>\n<li>POST <code class=\"language-text\">/api/login</code>, request body of { username: value, password: value }</li>\n<li>POST <code class=\"language-text\">/api/logout</code>, no request body</li>\n</ul>\n<p>Then we need actions:</p>\n<ul>\n<li>To handle getting a copy of the user after login &#x26; clearing the user after logout</li>\n<li>To track errors on login</li>\n</ul>\n<details>\n  <summary>Code hint:</summary>\n<div class=\"gatsby-code-title\">AuthActionCreator.js</div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">setUser</span> <span class=\"token operator\">=</span> user <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n    type<span class=\"token punctuation\">:</span> AuthActionTypes<span class=\"token punctuation\">.</span><span class=\"token constant\">SET_USER</span><span class=\"token punctuation\">,</span>\n    user<span class=\"token punctuation\">:</span> user\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">error</span> <span class=\"token operator\">=</span> error <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n    type<span class=\"token punctuation\">:</span> AuthActionTypes<span class=\"token punctuation\">.</span><span class=\"token constant\">ERROR</span><span class=\"token punctuation\">,</span>\n    error<span class=\"token punctuation\">:</span> error\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">login</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>credentials<span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> dispatch <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> Axios<span class=\"token punctuation\">.</span><span class=\"token function\">post</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/api/login'</span><span class=\"token punctuation\">,</span> credentials<span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span>response <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">dispatch</span><span class=\"token punctuation\">(</span><span class=\"token function\">setUser</span><span class=\"token punctuation\">(</span>response<span class=\"token punctuation\">.</span>data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Login successful'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">.</span><span class=\"token keyword\">catch</span><span class=\"token punctuation\">(</span>err <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n        console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'There was an error logging in.'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">dispatch</span><span class=\"token punctuation\">(</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Failed to login'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">logout</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> dispatch <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> Axios<span class=\"token punctuation\">.</span><span class=\"token function\">post</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/api/logout'</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span>response <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">dispatch</span><span class=\"token punctuation\">(</span><span class=\"token function\">setUser</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Logout successful'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">.</span><span class=\"token keyword\">catch</span><span class=\"token punctuation\">(</span>err <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n        console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'There was an error logging out.'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n</details>\n<p> </p>\n<h3>Build the Reducer</h3>\n<p>We need a reducer to handle our actions</p>\n<ul>\n<li>One case needs to save the new active User (which could be null if the user is logging out)</li>\n<li>A second case needs to save an error message if login failed.</li>\n</ul>\n<details>\n  <summary>Code hint:</summary>\n<div class=\"gatsby-code-title\">auth-reducer.js</div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">import</span> <span class=\"token operator\">*</span> <span class=\"token keyword\">as</span> AuthActionTypes <span class=\"token keyword\">from</span> <span class=\"token string\">'../actions/AuthActionTypes'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">(</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> user<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> action<span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>action<span class=\"token punctuation\">.</span>type<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">case</span> AuthActionTypes<span class=\"token punctuation\">.</span><span class=\"token constant\">SET_USER</span><span class=\"token punctuation\">:</span>\n      <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span> <span class=\"token operator\">...</span>state<span class=\"token punctuation\">,</span> user<span class=\"token punctuation\">:</span> action<span class=\"token punctuation\">.</span>user <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">case</span> AuthActionTypes<span class=\"token punctuation\">.</span><span class=\"token constant\">ERROR</span><span class=\"token punctuation\">:</span>\n      <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span> <span class=\"token operator\">...</span>state<span class=\"token punctuation\">,</span> error<span class=\"token punctuation\">:</span> action<span class=\"token punctuation\">.</span>error <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">default</span><span class=\"token punctuation\">:</span>\n      <span class=\"token keyword\">return</span> state<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n</details>\n<p> </p>\n<ul>\n<li>Don’t forget to hook up the new reducer in <strong>src/reducers/index.js</strong></li>\n</ul>\n<h3>Create a Login form</h3>\n<ul>\n<li>We need a form that will accept a username and password as well as supply a “Login” button.</li>\n<li>The form needs validation to ensure that a username and password are provided before enabling the login button.</li>\n<li>Look at the existing forms in the rest of the app for examples.</li>\n</ul>\n<details>\n  <summary>Code hint:</summary>\n<div class=\"gatsby-code-title\">Login.js</div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> PropTypes <span class=\"token keyword\">from</span> <span class=\"token string\">'prop-types'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> Form<span class=\"token punctuation\">,</span> Formik <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'formik'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> FieldWrapper <span class=\"token keyword\">from</span> <span class=\"token string\">'../form/FieldWrapper'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> FormControls <span class=\"token keyword\">from</span> <span class=\"token string\">'../form/FormControls'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">LoginForm</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n\n  <span class=\"token function-variable function\">validate</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>values<span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> errors <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>values<span class=\"token punctuation\">.</span>username<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      errors<span class=\"token punctuation\">.</span>username <span class=\"token operator\">=</span> <span class=\"token string\">'Required'</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>values<span class=\"token punctuation\">.</span>password<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      errors<span class=\"token punctuation\">.</span>password <span class=\"token operator\">=</span> <span class=\"token string\">'Required'</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> errors<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function-variable function\">login</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>values<span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span><span class=\"token function\">onLogin</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n      username<span class=\"token punctuation\">:</span> values<span class=\"token punctuation\">.</span>username<span class=\"token punctuation\">,</span>\n      password<span class=\"token punctuation\">:</span> values<span class=\"token punctuation\">.</span>password\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> loginError <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Formik</span>\n          <span class=\"token attr-name\">validate</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>validate<span class=\"token punctuation\">}</span></span>\n          <span class=\"token attr-name\">onSubmit</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>login<span class=\"token punctuation\">}</span></span>\n          <span class=\"token attr-name\">initialValues</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span>\n            username<span class=\"token punctuation\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n            password<span class=\"token punctuation\">:</span> <span class=\"token string\">''</span>\n          <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n          </span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> isValid<span class=\"token punctuation\">,</span> errors<span class=\"token punctuation\">,</span> touched<span class=\"token punctuation\">,</span> handleSubmit<span class=\"token punctuation\">,</span> handleReset <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\n            <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Form</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n              </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>FieldWrapper</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>username<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">label</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>Username<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">invalid</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>errors<span class=\"token punctuation\">.</span>username<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">touched</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>touched<span class=\"token punctuation\">.</span>username<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n              </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>FieldWrapper</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>password<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>password<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">label</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>Password<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">invalid</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>errors<span class=\"token punctuation\">.</span>password<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">touched</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>touched<span class=\"token punctuation\">.</span>password<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n\n              </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>FormControls</span>\n                <span class=\"token attr-name\">action</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>Login<span class=\"token punctuation\">\"</span></span>\n                <span class=\"token attr-name\">allowSubmit</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>isValid<span class=\"token punctuation\">}</span></span>\n                <span class=\"token attr-name\">onSubmit</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>handleSubmit<span class=\"token punctuation\">}</span></span>\n                <span class=\"token attr-name\">onReset</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>handleReset<span class=\"token punctuation\">}</span></span>\n              <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n            </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>Form</span><span class=\"token punctuation\">></span></span>\n          <span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span><span class=\"token plain-text\">\n        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>Formik</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        </span><span class=\"token punctuation\">{</span>loginError <span class=\"token operator\">&amp;&amp;</span> <span class=\"token punctuation\">(</span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>p</span> <span class=\"token attr-name\">style</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span> color<span class=\"token punctuation\">:</span> <span class=\"token string\">'red'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>loginError<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>p</span><span class=\"token punctuation\">></span></span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\nLoginForm<span class=\"token punctuation\">.</span>propTypes <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  onLogin<span class=\"token punctuation\">:</span> PropTypes<span class=\"token punctuation\">.</span>func<span class=\"token punctuation\">.</span>isRequired<span class=\"token punctuation\">,</span>\n  loginError<span class=\"token punctuation\">:</span> PropTypes<span class=\"token punctuation\">.</span>string\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> LoginForm<span class=\"token punctuation\">;</span></code></pre></div>\n</details>\n<p> </p>\n<h3>Get data for Login Form</h3>\n<ul>\n<li>\n<p>We need to get the <code class=\"language-text\">onLogin</code> and <code class=\"language-text\">loginError</code> props somewhere and pass them down into our Form</p>\n</li>\n<li>\n<p>We’re going to render our LoginForm in <strong>App.js</strong>, so open that file, get it hooked up to Redux, and grab the following:</p>\n<ul>\n<li>Get the async method you created to log the user in</li>\n<li>Get the current user and whether there was an error on login from Redux state</li>\n</ul>\n</li>\n</ul>\n<details>\n  <summary>Code hint:</summary>\n<div class=\"gatsby-code-title\">App.js</div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">mapStateToProps</span> <span class=\"token operator\">=</span> state <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  user<span class=\"token punctuation\">:</span> state<span class=\"token punctuation\">.</span>auth<span class=\"token punctuation\">.</span>user<span class=\"token punctuation\">,</span>\n  loginError<span class=\"token punctuation\">:</span> state<span class=\"token punctuation\">.</span>auth<span class=\"token punctuation\">.</span>error\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">const</span> mapDispatchToProps <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  login<span class=\"token punctuation\">:</span> AuthActionCreators<span class=\"token punctuation\">.</span>login\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token function\">connect</span><span class=\"token punctuation\">(</span>mapStateToProps<span class=\"token punctuation\">,</span> mapDispatchToProps<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>App<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n</details>\n<p> </p>\n<h3>Add a Logout button</h3>\n<p>We want to let the user log out from the navbar, so we’ll need to add a new link that can fire off the ‘Logout’ action.</p>\n<ul>\n<li>First, add a ‘onLogout’ prop to the Navigation component</li>\n</ul>\n<details>\n  <summary>Code hint:</summary>\n<div class=\"gatsby-code-title\">Navigation.js</div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">Navigation<span class=\"token punctuation\">.</span>propTypes <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  onLogout<span class=\"token punctuation\">:</span> PropTypes<span class=\"token punctuation\">.</span>func<span class=\"token punctuation\">.</span>isRequired\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n</details>\n<p> </p>\n<ul>\n<li>Next, add a link to the NavBar with a click listener that calls the ‘onLogout’ prop</li>\n</ul>\n<details>\n  <summary>Code hint:</summary>\n<div class=\"gatsby-code-title\">Navigation.js</div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Nav</span> <span class=\"token attr-name\">pullRight</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>NavItem</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n   </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Button</span> <span class=\"token attr-name\">onClick</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>onLogout<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Logout</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>Button</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>NavItem</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>Nav</span><span class=\"token punctuation\">></span></span></code></pre></div>\n</details>\n<p> </p>\n<h3>Grab props to pass into Navigation</h3>\n<p>Now that Navigation needs a ‘onLogout’ function to call, we need to get that from Redux and pass it in.</p>\n<ul>\n<li>In <strong>app.js</strong>, grab the Logout async action method in addition to the bindings we add a few steps ago</li>\n</ul>\n<details>\n  <summary>Code hint:</summary>\n<div class=\"gatsby-code-title\">App.js</div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">mapStateToProps</span> <span class=\"token operator\">=</span> state <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  user<span class=\"token punctuation\">:</span> state<span class=\"token punctuation\">.</span>auth<span class=\"token punctuation\">.</span>user<span class=\"token punctuation\">,</span>\n  loginError<span class=\"token punctuation\">:</span> state<span class=\"token punctuation\">.</span>auth<span class=\"token punctuation\">.</span>error\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">const</span> mapDispatchToProps <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  login<span class=\"token punctuation\">:</span> AuthActionCreators<span class=\"token punctuation\">.</span>login<span class=\"token punctuation\">,</span>\n  logout<span class=\"token punctuation\">:</span> AuthActionCreators<span class=\"token punctuation\">.</span>logout\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token function\">connect</span><span class=\"token punctuation\">(</span>mapStateToProps<span class=\"token punctuation\">,</span> mapDispatchToProps<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>App<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n</details>\n<p> </p>\n<ul>\n<li>Pass the ‘logout’ action from our AuthActionCreators into Navigation as the ‘onLogout’ prop</li>\n</ul>\n<details>\n  <summary>Code hint:</summary>\n<div class=\"gatsby-code-title\">App.js</div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Navigation</span> <span class=\"token attr-name\">onLogout</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>logout<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">/></span></span></code></pre></div>\n</details>\n<p> </p>\n<h3>Render login form until user successfully logs in</h3>\n<p>We have all the pieces in place, now we just need to prevent the user from accessing the application until they’ve logged in.</p>\n<ul>\n<li>In <strong>app.js</strong>, look for a good way to render our LoginForm anytime there isn’t valid <em>User</em> object in our Redux state.</li>\n</ul>\n<details>\n  <summary>Code hint:</summary>\n<div class=\"gatsby-code-title\">App.js</div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token punctuation\">{</span><span class=\"token operator\">!</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>user <span class=\"token operator\">?</span> <span class=\"token punctuation\">(</span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>LoginForm</span> <span class=\"token attr-name\">onLogin</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>login<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">loginError</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>loginError<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">:</span> <span class=\"token punctuation\">(</span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Switch</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n    ...\n  </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>Switch</span><span class=\"token punctuation\">></span></span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></code></pre></div>\n</details>\n<p> </p>\n<h3>Try it out</h3>\n<p>Let’s see if the app does what we want.</p>\n<table>\n<thead>\n<tr>\n<th>Username</th>\n<th>Password</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>admin</td>\n<td>password</td>\n</tr>\n<tr>\n<td>user</td>\n<td>password</td>\n</tr>\n</tbody>\n</table>\n<ul>\n<li>Try accessing any route (employees, projects, etc) - you should be restricted to the login form.</li>\n<li>Try a bad login. Do you get an error message?</li>\n<li>Try a good login - can you access the app?</li>\n<li>Logout of the app - do you get sent back to the login form?</li>\n</ul>\n<h3>Commit your changes to Git.</h3>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">git add .\ngit commit -m &quot;We are React masters&quot;</code></pre></div>\n<h2>Extra Credit</h2>\n<ul>\n<li>\n<p>Unit tests! Our new and changed components need tests.</p>\n</li>\n<li>\n<p>Do you think we should test our actions &#x26; reducers? Any ideas on how to do it?</p>\n</li>\n<li>\n<p>Try to figure out a way to tie in <code class=\"language-text\">react-router</code> to provide a <code class=\"language-text\">/login</code> route while still securing the other routes</p>\n</li>\n</ul>\n<p><code class=\"language-text\">git add .</code> and <code class=\"language-text\">git commit -m &quot;extra credit&quot;</code> when you are done</p>"}},"pageContext":{"next":{},"slug":"/labs/capstone"}}