faloker/purify

View on GitHub
web/src/views/AccountSettings.vue

Summary

Maintainability
Test Coverage
<template>
  <v-container>
    <!-- <v-row justify="space-between" align="center">
      <v-col>
        <p class="text-h4 font-weight-bold">
          Settings
        </p>
      </v-col>
      <v-spacer />
    </v-row>-->
    <v-row no-gutters dense>
      <v-col cols="4">
        <v-card outlined>
          <v-card-title>Your Info</v-card-title>
          <v-card-text>
            <v-col>
              <v-row align="center" justify="start">
                <v-avatar size="62">
                  <img :src="user.image">
                </v-avatar>
                <v-btn
                  class="mt-2 ml-3"
                  color="primary"
                  small
                  @click="changeAvatarDialog = true"
                >
                  Change avatar
                </v-btn>
              </v-row>
            </v-col>
            <v-col>
              <v-row>
                <v-text-field
                  v-model="name"
                  label="Name"
                  dense
                  outlined
                />
              </v-row>
              <v-row>
                <v-text-field
                  v-model="email"
                  label="Email"
                  dense
                  outlined
                />
              </v-row>
            </v-col>
          </v-card-text>
          <v-card-actions>
            <v-btn
              v-if="!systemConfig.saml || user.ssoBypass"
              color="primary"
              @click="dialog = true"
            >
              Change password
            </v-btn>
            <v-spacer />
            <v-btn color="primary" @click="changeName">
              Save
            </v-btn>
          </v-card-actions>
        </v-card>
      </v-col>
    </v-row>
    <v-dialog
      v-model="dialog"
      max-width="400"
      @click:outside="dialog = false"
      @keydown.esc="dialog = false"
    >
      <v-card>
        <v-card-title>
          <span>Change password</span>
        </v-card-title>
        <v-card-text>
          <v-col>
            <v-row>
              <v-text-field
                id="oldPassword"
                v-model="oldPassword"
                label="Old Password"
                required
                type="password"
                dense
                outlined
              />
            </v-row>
            <v-row>
              <v-text-field
                id="newPassword"
                v-model="password1"
                label="New Password"
                required
                outlined
                dense
                type="password"
                @keydown.enter="changePassword"
              />
            </v-row> 
            <v-row>
              <v-text-field
                id="repeat-password"
                v-model="password2"
                label="Repeat Password"
                required
                outlined
                dense
                type="password"
                @keydown.enter="changePassword"
              />
            </v-row>
          </v-col>
        </v-card-text>
        <v-divider />
        <v-card-actions>
          <v-btn
            color="quinary"
            text
            @click.stop="dialog = false"
          >
            Close
          </v-btn>
          <v-spacer />
          <v-btn
            color="quinary"
            text
            :disabled="password1 !== password2"
            @click.stop="changePwd"
          >
            Save
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>   
    <v-dialog
      v-model="changeAvatarDialog"
      max-width="400"
      @click:outside="changeAvatarDialog = false"
      @keydown.esc="changeAvatarDialog = false"
    >
      <v-card>
        <v-card-title>
          <span>Change avatar</span>
        </v-card-title>
        <v-card-subtitle>
          <span>Feel free to use any public image hosting, but take a look at 
            <a
              href="https://avatars.dicebear.com/"
              target="_blank"
            >avatars.dicebear.com</a> first.</span>
        </v-card-subtitle>
        <v-card-text>
          <v-col>
            <v-row>
              <v-text-field
                id="newAvatarUrl"
                v-model="newAvatarUrl"
                label="New avatar URL"
                required
                dense
                outlined
              />
            </v-row>
          </v-col>
        </v-card-text>
        <v-divider />
        <v-card-actions>
          <v-btn
            color="quinary"
            text
            @click="changeAvatarDialog = false"
          >
            Close
          </v-btn>
          <v-spacer />
          <v-btn
            color="quinary"
            text
            @click="changeAvatar"
          >
            Save
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </v-container>
</template>
<script lang="ts">
import store from '@/store';
import {
  PROFILE_FETCH,
  SELF_CHANGE,
  SELF_CHANGE_PASSWORD,
  SHOW_SUCCESS_MSG,
} from '@/store/actions';
/* eslint-disable @typescript-eslint/no-use-before-define */
import { defineComponent, ref, computed } from '@vue/composition-api';

export default defineComponent({
  name: 'AccountSettings',

  setup() {
    const user = computed(() => store.state.profile.user);
    const systemConfig = computed(() => store.state.system.config);
    const name = ref(user.value.name);
    const email = ref(user.value.email);
    const dialog = ref(false);
    const changeAvatarDialog = ref(false);
    const oldPassword = ref('');
    const password1 = ref('');
    const password2 = ref('');
    const newAvatarUrl = ref('');

    async function changePwd() {
      store
        .dispatch(SELF_CHANGE_PASSWORD, {
          oldPassword: oldPassword.value,
          newPassword: password2.value,
        })
        .then(async () => {
          dialog.value = false;
          await store.dispatch(
            SHOW_SUCCESS_MSG,
            'Your password has been changed'
          );
        })
        .catch(() => {});
    }

    async function changeName() {
      store
        .dispatch(SELF_CHANGE, { name: name.value, email: email.value })
        .then(async () => {
          await store.dispatch(SHOW_SUCCESS_MSG, 'Your data has been changed');
          await store.dispatch(PROFILE_FETCH).catch(() => {});
        })
        .catch(() => {});
    }

    async function changeAvatar() {
      store
        .dispatch(SELF_CHANGE, { image: newAvatarUrl.value })
        .then(async () => {
          changeAvatarDialog.value = false;

          await store.dispatch(
            SHOW_SUCCESS_MSG,
            'Your avatar has been changed'
          );

          await store.dispatch(PROFILE_FETCH).catch(() => {});
        })
        .catch(() => {});
    }

    return {
      user,
      changeAvatarDialog,
      changeAvatar,
      newAvatarUrl,
      systemConfig,
      name,
      email,
      changeName,
      dialog,
      password2,
      password1,
      oldPassword,
      changePwd,
    };
  },
});
</script>