Create separate LoginLayout component

Create a separate layout for the login page so it can be reused
for first time password reset form.

Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: Ia2da0e8d29f7d6ad77c5277193c7535f2d00a97d
diff --git a/src/layouts/LoginLayout.vue b/src/layouts/LoginLayout.vue
new file mode 100644
index 0000000..bb89f25
--- /dev/null
+++ b/src/layouts/LoginLayout.vue
@@ -0,0 +1,51 @@
+<template>
+  <main>
+    <b-container class="login-container" fluid>
+      <b-row class="login-row" align-v="center">
+        <b-col class="login-branding mt-5 mb-5 text-center" md="6">
+          <div class="login-branding__container">
+            <img
+              class="logo"
+              width="200px"
+              src="@/assets/images/openbmc-logo.svg"
+              alt=""
+            />
+            <h1>OpenBMC</h1>
+          </div>
+        </b-col>
+        <b-col md="6">
+          <router-view />
+        </b-col>
+      </b-row>
+    </b-container>
+  </main>
+</template>
+
+<script>
+export default {
+  name: 'LoginLayout'
+};
+</script>
+
+<style lang="scss" scoped>
+@import 'src/assets/styles/helpers';
+
+.login-container {
+  @include media-breakpoint-up(md) {
+    background: linear-gradient(to right, $light 50%, $container-bgd 50%);
+  }
+}
+
+.login-row {
+  @include media-breakpoint-up(md) {
+    min-height: 100vh;
+  }
+}
+
+.login-branding__container {
+  @include media-breakpoint-up(md) {
+    float: right;
+    margin-right: 4rem;
+  }
+}
+</style>
diff --git a/src/router/index.js b/src/router/index.js
index 22662d7..73f3186 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -2,6 +2,7 @@
 import VueRouter from 'vue-router';
 import store from '../store/index';
 import AppLayout from '../layouts/AppLayout.vue';
+import LoginLayout from '@/layouts/LoginLayout';
 
 Vue.use(VueRouter);
 
@@ -131,11 +132,17 @@
   },
   {
     path: '/login',
-    name: 'login',
-    component: () => import('@/views/Login'),
-    meta: {
-      title: 'appPageTitle.login'
-    }
+    component: LoginLayout,
+    children: [
+      {
+        path: '',
+        name: 'login',
+        component: () => import('@/views/Login'),
+        meta: {
+          title: 'appPageTitle.login'
+        }
+      }
+    ]
   }
 ];
 
diff --git a/src/views/Login/Login.vue b/src/views/Login/Login.vue
index 730c7a9..369c56d 100644
--- a/src/views/Login/Login.vue
+++ b/src/views/Login/Login.vue
@@ -1,89 +1,68 @@
 <template>
-  <main>
-    <b-container class="login-container" fluid>
-      <b-row class="login-row" align-v="center">
-        <b-col class="login-branding mt-5 mb-5" md="6">
-          <div class="login-branding__container">
-            <img
-              class="logo"
-              width="200px"
-              src="@/assets/images/openbmc-logo.svg"
-              alt=""
-            />
-            <h1>OpenBMC</h1>
-          </div>
-        </b-col>
-        <b-col md="6">
-          <b-form class="login-form" novalidate @submit.prevent="login">
-            <alert class="login-error" :show="authError" variant="danger">
-              <p id="login-error-alert">
-                {{ $t('pageLogin.alert.message') }}
-              </p>
-            </alert>
-            <b-form-group
-              label-for="language"
-              :label="$t('pageLogin.language')"
-            >
-              <b-form-select
-                id="language"
-                v-model="$i18n.locale"
-                :options="languages"
-                data-test-id="login-select-language"
-              ></b-form-select>
-            </b-form-group>
-            <b-form-group
-              label-for="username"
-              :label="$t('pageLogin.username')"
-            >
-              <b-form-input
-                id="username"
-                v-model="userInfo.username"
-                aria-describedby="login-error-alert username-required"
-                :state="getValidationState($v.userInfo.username)"
-                type="text"
-                autofocus="autofocus"
-                data-test-id="login-input-username"
-                @input="$v.userInfo.username.$touch()"
-              >
-              </b-form-input>
-              <b-form-invalid-feedback id="username-required" role="alert">
-                <template v-if="!$v.userInfo.username.required">
-                  {{ $t('global.form.fieldRequired') }}
-                </template>
-              </b-form-invalid-feedback>
-            </b-form-group>
-            <div class="login-form__section">
-              <label for="password">{{ $t('pageLogin.password') }}</label>
-              <b-form-input
-                id="password"
-                v-model="userInfo.password"
-                aria-describedby="login-error-alert password-required"
-                :state="getValidationState($v.userInfo.password)"
-                type="password"
-                data-test-id="login-input-password"
-                @input="$v.userInfo.password.$touch()"
-              >
-              </b-form-input>
-              <b-form-invalid-feedback id="password-required" role="alert">
-                <template v-if="!$v.userInfo.password.required">
-                  {{ $t('global.form.fieldRequired') }}
-                </template>
-              </b-form-invalid-feedback>
-            </div>
-            <b-button
-              block
-              class="mt-5"
-              type="submit"
-              variant="primary"
-              data-test-id="login-button-submit"
-              :disabled="disableSubmitButton"
-              >{{ $t('pageLogin.logIn') }}</b-button
-            >
-          </b-form>
-        </b-col>
-      </b-row>
-    </b-container>
-  </main>
+  <b-form
+    class="login-form  mx-auto ml-md-5 mb-3"
+    novalidate
+    @submit.prevent="login"
+  >
+    <alert class="login-error mb-4" :show="authError" variant="danger">
+      <p id="login-error-alert">
+        {{ $t('pageLogin.alert.message') }}
+      </p>
+    </alert>
+    <b-form-group label-for="language" :label="$t('pageLogin.language')">
+      <b-form-select
+        id="language"
+        v-model="$i18n.locale"
+        :options="languages"
+        data-test-id="login-select-language"
+      ></b-form-select>
+    </b-form-group>
+    <b-form-group label-for="username" :label="$t('pageLogin.username')">
+      <b-form-input
+        id="username"
+        v-model="userInfo.username"
+        aria-describedby="login-error-alert username-required"
+        :state="getValidationState($v.userInfo.username)"
+        type="text"
+        autofocus="autofocus"
+        data-test-id="login-input-username"
+        @input="$v.userInfo.username.$touch()"
+      >
+      </b-form-input>
+      <b-form-invalid-feedback id="username-required" role="alert">
+        <template v-if="!$v.userInfo.username.required">
+          {{ $t('global.form.fieldRequired') }}
+        </template>
+      </b-form-invalid-feedback>
+    </b-form-group>
+    <div class="login-form__section mb-3">
+      <label for="password">{{ $t('pageLogin.password') }}</label>
+      <b-form-input
+        id="password"
+        v-model="userInfo.password"
+        aria-describedby="login-error-alert password-required"
+        :state="getValidationState($v.userInfo.password)"
+        type="password"
+        data-test-id="login-input-password"
+        @input="$v.userInfo.password.$touch()"
+      >
+      </b-form-input>
+      <b-form-invalid-feedback id="password-required" role="alert">
+        <template v-if="!$v.userInfo.password.required">
+          {{ $t('global.form.fieldRequired') }}
+        </template>
+      </b-form-invalid-feedback>
+    </div>
+    <b-button
+      block
+      class="mt-5"
+      type="submit"
+      variant="primary"
+      data-test-id="login-button-submit"
+      :disabled="disableSubmitButton"
+      >{{ $t('pageLogin.logIn') }}</b-button
+    >
+  </b-form>
 </template>
 
 <script>
@@ -154,46 +133,7 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
-.login-container {
-  @include media-breakpoint-up(md) {
-    background: linear-gradient(to right, $light 50%, $container-bgd 50%);
-  }
-}
-
-.login-row {
-  @include media-breakpoint-up(md) {
-    min-height: 100vh;
-  }
-}
-
-.login-branding__container {
-  @include media-breakpoint-up(md) {
-    float: right;
-    margin-right: 4rem;
-  }
-}
-
 .login-form {
   max-width: 360px;
-  margin-right: auto;
-  margin-left: auto;
-
-  @include media-breakpoint-up(md) {
-    margin-left: 4rem;
-  }
-}
-
-.login-form__section {
-  margin-bottom: $spacer;
-}
-
-.alert.login-error {
-  margin-bottom: $spacer * 2;
-}
-
-.login-branding {
-  text-align: center;
 }
 </style>