<commit_before>{% extends "main.html" %}
{% include "smartapi-head.html" %}
{% block content %}
{% include "header.html" %}
{% raw %}
<main id="dashApp" style="padding-top:20px;min-height:90vh;" class="blue-grey darken-3" v-cloak>
  <!-- IF NO USER INFO DISPLAY LOGIN-->
  <div v-if="!userInfo.login" class="padding20 card-panel white center-align">
    <h5 class="text_h3 blue-grey-text-text">
      You Must Be Signed In To Use Your Dashboard
    </h5>
    <a href="/oauth" class="btn green">
      Login
    </a>
  </div>
  <!-- LOADING -->
  <div id="loading-overlay" class="center-align" style="background-color: rgba(18, 52, 84, 0.5); cursor: default;">
    <div class="center-align" style="padding-top: 300px;">
      <object width="100px"  alt="Loading" data="/static/img/fly.gif" class=""></object>
      <h3 class="white-text logoFont">Loading...</h3>
    </div>
  </div>
  <!-- Loading END -->
  <!-- IF USER INFO DISPLAY DASHBOARD -->
  <div id="tippyParent" v-if="userInfo.login" class="row" style="margin-bottom: 0; width: 100%;min-height:70vh;">
      <div class="col s12 m4 l3 xl3 transparent">
        <ul class="collection" style="border: none;">
          <li class="collection-item center-align transparent" style="border-bottom: none;">
            <img v-if="userInfo.avatar_url" id="dashboardPhoto" width="70%" :src="userInfo.avatar_url" class="responsive-img hideOnSmall hide-on-med-and-down" alt="user image" style="box-shadow: 5px 5px 5px #273238; margin-bottom: -25px; border-radius: 10px; border: 2px white solid; max-width:250px;">
            <img v-else id="dashboardPhoto" width="70%" src="/static/img/user-default.png" class="responsive-img hideOnSmall" alt="user image" style="box-shadow: 5px 5px 5px #273238; margin-bottom: -25px; border-radius: 10px; border: 2px white solid; max-width:250px;">
          </li>
          <li class="collection-item center-align white-text padding20 blue" style="border-top-left-radius: 10px; border-top-right-radius: 10px;">
            <img v-if="userInfo.avatar_url" width="30%" :src="userInfo.avatar_url" class="show-on-medium-and-down hide-on-med-and-up circle" alt="user image" style="margin: 0 auto; border: 3px solid white;">
            <h5 v-if="userInfo.name" class="text_h3 white-text textShadow swing-in-top-fwd">Hello, {{ userInfo.name.split(" ")[0] }}!</h5>
            <h5 v-else class="text_h3 white-text textShadow swing-in-top-fwd">Hello, {{ userInfo.login }}!</h5>
            <p><a target="_blank" class="white-text" :href="'https://github.com/'+userInfo.login"><i class="tiny fa fa-github-alt white-text"></i> {{userInfo.login}}</a></p>
          </li>
          <!--  -->
          <li class="collection-item center-align blue-grey darken-4 white-text show-on-small hide-on-med-and-up">
            <span class="logoFont blue-grey-text">SmartAPI</span><br />CONTRIBUTIONS <span class="l-blue-text">({{ total+") API's" }}</span>
          </li>
          <li class="collection-item blue-grey-text hide-on-small-only">
            <h5 class="center">APIs</h5>
            <h5 class="center blue-text"> {{ total}}</h5>
            <div class="center">
              <a href="/logout" class="btn red smallFont">Log Out</a>
            </div>
          </li>
        </ul>
      </div>
    <div class="col s12 m8 l9 xl9 center-align">
        <div class="row">
          <div class="p-1 col s12">
            <input v-model='searchQuery' placeholder="Search by API name" type="text" class="browser-default margin20 blue-grey darken-3 l-blue-text lighter" style="width: 40%; outline: none; padding: 10px; border-radius: 20px; border:var(--blue-light) 2px solid;"/>
          </div>
          
          <div class="col s12">
            <ul class="tabs transparent">
              <li class="tab col s3 transparent">
                <a class="white-text textShadow " href="#contributions">
                  APIs <span class="l-blue-text">({{total}})</span>
                </a>
              </li>
            </ul>
          </div>

          <div id="contributions" class="col s12 card-panel" style="padding:0;">
              <div class="s12">
                <ul class="collection resultsContainer">
                  <li class="collection-item" v-for="(api,index) in results" style="margin-bottom:0px;padding: 0px;">
                    <div class="row" style="padding: 0px; margin-bottom:0px;">
                      <div class="col s12 row" style="padding: 0px; 
                      margin-bottom:0px;
                      display: flex;
                      align-items: center;
                      flex-wrap: wrap;">
                        <div class="col s6 m3 p-1">
                          <a href="#modal2" class="modal-trigger" @click="getDetails(index)">
                            <h6><b>{{ api.info.title }}</b></h6>
                          </a>
                          <small>
                            <span class="grey-text smallFont">V.{{api.info.version}}</span>
                          </small>
                        </div>
                        <div class="col s6 m3 p-1">
                          <h6>
                            <small class="grey-text"><i class="fa fa-clock-o" aria-hidden="true"></i> Last Updated </small>
                          </h6>
                          <small>
                            <span class="green-text"> {{ convertDate(api._meta.last_updated) }}</span>
                          </small>
                        </div>
                        <div class="col s4 m2 p-1">
                          <refresh :refresh='refreshingThis' :title='api.info.title' :id="api._id" 
                          data-tippy-content="<b class='green-text'>Refresh</b> <br/>(Manually update API metadata when a valid change is detected)"></refresh>
                        </div>
                        <div class="col s4 m2 p-1">
                          <button type="button" @click="validate(api._meta.url)" class="btn btn-small scale-in-center indigo white-text" 
                          data-tippy-content="<b class='indigo-text'>Validate Only</b> <br/>(Validate latest API metadata from the source URL)">
                            <i class="material-icons white-text">check</i>
                        </button>
                        </div>
                        <div class="col s4 m2 p-1">
                          <a href="#modal1" @click="deleteAPI(api.info.title, api._id)" class="btn btn-small scale-in-center red white-text modal-trigger" 
                          data-tippy-content="<b class='red-text'>Delete</b> <br/>(Delete API metadata from SmartAPI registry permanently - cannot be undone)">
                            <i class="material-icons white-text">delete_forever</i>
                          </a>
                        </div>
                      </div>
                      <div class="col s12 row" style="padding: 0px; margin-bottom:0px;background-color: rgba(0, 0, 0, .05);">
                        <div class="col s6 m3">
                          <a href="#" class='popularity pointer blue-text' :data-tippy-name='api.info.title' :data-tippy-id='api._id'>
                            <small><i class="fa fa-bar-chart"></i> User Interactions</small>
                          </a>
                        </div>
                        <div class="col s6 m3">
                          <small>Specification </small>
                          <span v-if=" api.hasOwnProperty('openapi')" style="font-size:75%" class="smallFont badge green white-text" data-tippy-content="<b class='green-text'>OpenAPI 3</b> Specification">
                            OAS3
                          </span>
                          <span v-else-if=" api.hasOwnProperty('swagger')" style="font-size:75%" class="smallFont badge blue white-text" data-tippy-content="<b class='blue-text'>Swagger 2</b> Specification">
                            Swagger2
                          </span>
                        </div>
                        <div class="col s6 m3">
                          <small>API Status </small> <status :api='api'></status>
                        </div>
                        <div class="col s6 m3">
                          <small>Source Status </small>
                          <source-status :api='api'></source-status>
                        </div>
                      </div>
                    </div>
                  </li>
                  <div v-if="apis.length === 0">
                    <small class="center-align grey lighten-3">
                      <span class="grey-text smallFont">No Contributions Yet</span><br>
                    </small>
                  </div>
                </ul>
              </div>
          </div>

        </div>
    </div>
  </div>
  <div class="grey lighten-5 padding20 blue-text center">
      <small>
        <i class="material-icons">error_outline</i> Did you know you can set a custom slug for your API's documentation? It's easy! Just click on any API on your dashboard and go to the <em>Settings</em> tab.<br />
        Use the <em>Custom Slug Registration Wizard</em> and get a custom URL for your API's documentation. E.g. <b>&lt;slug&gt;.smart-api.info</b>
      </small>
  </div>
  <!-- Modal for Deletion Confirmation -->
  <div id="modal1" class="modal center-align">
    <div class="modal-content">
      <h5 class="blue-text">Delete <b>{{ confirmModal.title }}</b>?</h5>
      <div class="white padding20">
        <i class="material-icons small amber-text">warning</i>
        <p class="red-text">This action cannot be undone. Please type in the exact name of the API to confirm.</p>
        <input v-model="inputApiName" :placeholder="confirmModal.title" type="text" class="validate browser-default" style="outline: none; padding: 10px; width: 70%;">
        <hr/>
        <a href='#!' :disabled="confirmDelete" @click="deleteForever(confirmModal.title, confirmModal.id)" class=" deep-orange darken-2 btn modal-action modal-close">Delete API</a>
      </div>
      <hr>
      <a href="#!" class="btn blue modal-action modal-close">Cancel</a>
    </div>
  </div>
  <!-- delete Modal end -->


  <!-- Details Modal -->

  <div id="modal2" class="modal center-align">
    <div  class="modal-content" style="padding-top:45px;">
      <div class="row">
        <div class="col s12">
          <ul class="tabs transparent">
            <li class="tab col s3"><a href="#test1" class="active blue-text">About</a></li>
            <li class="tab col s3"><a class="blue-text" href="#test2"><i class="tiny material-icons">settings</i> Settings</a></li>
          </ul>
        </div>

        <div id="test1" class="col s12">
          <ul v-if="selectedAPIIndex || selectedAPIIndex === 0" class="collection with-header" style="border: none;">

            <li class="collection-header padding20">
              <object width="100px"  alt="SmartAPI" data="/static/img/logo-medium.svg" class="hide-on-small-only"></object>
              <h2 class="blue-text flow-text">
                {{apis[selectedAPIIndex].info.title}}
                <span class="versionBadge grey hide-on-small-only">Version {{apis[selectedAPIIndex].info.version}}</span>
                <span v-if=" apis[selectedAPIIndex].hasOwnProperty('openapi') " class="versionBadge green hide-on-small-only">
                  OAS3
                </span>
                <span v-else-if=" apis[selectedAPIIndex].hasOwnProperty('swagger') " class="versionBadge blue hide-on-small-only">
                  Swagger2
                </span>
                <template class="show-on-small hide-on-med-and-up">
                  <span v-if=" apis[selectedAPIIndex].hasOwnProperty('openapi') " class="versionBadge green hide-on-med-and-up">
                    V3
                  </span>
                  <span v-else-if=" apis[selectedAPIIndex].hasOwnProperty('swagger') " class="versionBadge blue hide-on-med-and-up">
                    V2
                  </span>
                </template>
              </h2>
              <hr />
              <template v-if=" apis[selectedAPIIndex].hasOwnProperty('swagger') ">
                <div class="yellow lighten-5 smallFont padding20">
                  APIs in Swagger V2 specification will experience limited functionality. <br />We recommend you update your metadata to OpenAPI V3 specification.
                  <br />
                  <a target="_blank" class="underlined" href="https://github.com/SmartAPI/smartAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md">Learn More about OpenAPI V3 Specification <i class="fa fa-external-link-square" aria-hidden="true"></i></a>
                  <br />
                  <a href="/guide" class="green-text underlined">Use our guide to help you convert your API to OpenAPI V3 specification.</a>
                </div>
                <hr />
              </template>
              <a :href="'/ui/'+apis[selectedAPIIndex]._id" class="btn blue">View API Doc</a>
            </li>
            <template v-for='link in checkForAPIInfoLink(apis[selectedAPIIndex])'>
              <li  class="collection-item blue-grey lighten-4">
                <a class="link blue-grey-text underlined" :href="link" target="_blank">
                 More Info
                </a>
              </li>
            </template>
            <li class="collection-item padding20 blue-grey lighten-5">
              <p style="line-height: 1.2em;" class="blue-grey-text flow-text" v-html="compiledMarkdown(apis[selectedAPIIndex].info.description || '')"></p>
            </li>
            <li class="collection-item blue-grey lighten-5">
              <i v-if="apis[selectedAPIIndex].info.termsOfService || apis[selectedAPIIndex].termsOfService" class="material-icons tiny blue-text">info_outline</i>
              <a v-if="apis[selectedAPIIndex].info.termsOfService" :href="apis[selectedAPIIndex].info.termsOfService" target="_blank" class="blue-text">Terms of Service</a>
              <a v-if="apis[selectedAPIIndex].termsOfService" :href="apis[selectedAPIIndex].termsOfService" target="_blank" class="blue-text">Terms of Service</a>

            </li>
          </ul>
        </div>

        <div id="test2" class="col s12 white">
          <div v-if="selectedAPIIndex || selectedAPIIndex === 0" class="row">
            <div class="col s12 m12 l12 center-align">
              <h3 class="flow-text blue-grey-text padding20">Slug Registration Wizard</h3>
            </div>
            <div v-if='!hasShortName' class="col s12 m12 l12 center-align">
              <object class="hide-on-small-only" width="250px" data="/static/img/wand.svg" alt='custom slug' style='border-radius: 10px;'></object>
              <p class="grey-text left-align">
                Every project has a subdomain that is available to serve its documentation.<br />
                By default we use your <i>API ID</i>. If you go to <span class="blue-text"><b>your-api-id</b>.smart-api.info</span> it should allow users to view your API documentation.
              </p>
              <p class="grey-text left-align">
                You can also register a unique slug to make sharing your API easier.
                <br />
                If you go to <span class="blue-text"><b>your-slug</b>.smart-api.info</span>, it will take users to your API documentation.
              </p>
              <a v-if='!createOrEditMode' @click.prevent='createOrEditMode = !createOrEditMode' class="blue btn">Create a new slug</a>
              <a v-if='createOrEditMode' @click.prevent='createOrEditMode = !createOrEditMode' class="red btn">Cancel</a>
            </div>
            <div v-if='hasShortName' class="col s12 m12 l12">
              <p>
                <i class="fa fa-check-circle-o green-text fa-5x" aria-hidden="true"></i>
              </p>
              <p class="grey-text">
                You have registered your custom slug!
                <br />
                If you visit to link below, it will take users to your API documentation.
              </p>
              <p class="green-text flow-text">
                 <a :href=" 'http://'+apis[selectedAPIIndex]._meta.slug+'.smart-api.info'" target="_blank" class="green-text link">http://<b>{{apis[selectedAPIIndex]._meta.slug}}</b>.smart-api.info <i class="fa fa-external-link-square" aria-hidden="true"></i></a>
                 <br />
                 <hr />
                 <a class="btn green smallFont margin20" @click.prevent='createOrEditMode = !createOrEditMode'>Edit Slug</a>
                 <a v-if="hasShortName" class="btn red smallFont margin20" @click.prevent='deleteSlug'>Delete Slug</a>
              </p>
            </div>
            <div v-if="createOrEditMode" style="width: 100%; display: flex; align-items: center;justify-content: center; flex-wrap: wrap;">
              <div class="left-align padding20 grey-text" style="flex: 1; min-width: 100%;">
                Slug length must be 4-50 characters (a-z) and/or numbers (0-9). Slugs will be converted to lower case. URL protected characters not allowed.
              </div>
              <div style="flex: 1; min-width: 200px;">
                <input autocomplete="false" v-model='myShortName' placeholder="Enter your slug here" id="first_name" type="text" class="disabled browser-default margin20 grey lighten-5 blue-grey-text lighter" style="width: 85%; outline: none; padding: 10px; border-radius: 20px; border:var(--blue-medium) 2px solid;">
              </div>
              <div style="flex: 1; min-width: 200px;">
                <p id="availabilityResults" v-bind:class="{'green-text': availableShortName, 'red-text': !availableShortName }">
                  <span v-if="myShortName" class="grey-text">http://</span>
                  <span v-if="myShortName">{{myShortName}}</span>
                  <span v-if="myShortName" class="grey-text">.smart-api.info</span>
                  <span v-if="!myShortName" class="grey-text">Check Slug Availability</span>
                  <i v-if='availableShortName && myShortName' class="fa fa-thumbs-up green-text" aria-hidden="true"></i>
                  <i v-if='!availableShortName && myShortName' class="fa fa-thumbs-down red-text" aria-hidden="true"></i>
                  <br />
                  <span v-if="myShortName.length <= 3 && myShortName.length > 0" class="amber-text"><i class="tiny material-icons">warning</i> Too Short</span>
                  <span v-if="myShortName.length >50" class="orange-text"><i class="tiny material-icons">warning</i> Too Long</span><br v-if="myShortName.length <= 3 && invalidChars"/>
                  <span v-if="invalidChars" class="red-text"><i class="tiny material-icons">warning</i> Invalid Characters</span>
                  <span v-if="takenSlug" class="orange-text"><i class="tiny material-icons">warning</i> Taken Slug</span>
                </p>
              </div>
              <div style="flex: 1; min-width: 200px;">
                <a @click.prevent="setShortname" :disabled='!availableShortName && !hasShortName' :class="!availableShortName ? 'btn grey' : 'green btn pulse' " >Set Slug</a>
              </div>

              <div id="shortNameSuccess" class="center-align padding20 green smallFont" style="flex: 1; min-width: 100%; display: none;">
                <h5 class="white-text"><i class="fa fa-check white-text" aria-hidden="true"></i> Slug Registered</h5>
                <a href="#!" class="btn green modal-action modal-close">Close</a>
              </div>
            </div>
          </div>
        </div>
      </div>
      <a href="#!" style="position: absolute; top:1%; right: 5%; font-size: 2em;" class="red-text modal-action modal-close">&times;</a>
    </div>
  </div>


</main>


{% endraw %}
{% include "footer.html" %}
{% endblock %}

{% block extra_scripts %}
<script src="https://unpkg.com/vuex"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.6/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://unpkg.com/tippy.js@3/dist/tippy.all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<script src="/static/js/moment.js"></script>


<script>

const store = new Vuex.Store({
    state: {
      'analytics':Object,
      'tags':Array
    },
    strict: true,
    mutations: {
      saveAnalytics(state,payload){
        state.analytics = payload['analytics'];
      },
    },
    getters:{
      // exposed as store.getters.nameOfGetter
      getHitsFor: (state) => (apiname) => {
        let data={'labels':[],'datasets':[]};
        let label = '';
        let dataArray=[];

        for (var i = 0; i < state.analytics.length; i++) {
          if (state.analytics[i][1].toLowerCase() === apiname.toLowerCase()) {
            label = state.analytics[i][0].toUpperCase();
            if (label == "EXPANDED") {
              label = "VIEWS"
            }
            data.labels.push(label);
            let number = state.analytics[i][2];
            dataArray.push(number)
          }

        }
        data.datasets.push({'label':"Users",'data':dataArray,'backgroundColor': ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],})
        // console.log('user interactions...',data)
        return data
      },
      getTags:(state)=>{
        let pop = []
        for (var i = 0; i < state.analytics.length; i++) {
          if (state.analytics[i][0] ==='tag') {
            pop.push({'name':state.analytics[i][1],'active':false,'count':state.analytics[i][2]})
          }
        }
        return pop;
      }

    }
  });

Vue.component('status', {
  data: function(){
    return{
      status:'',
      clss:'',
    }
  },
  props: ['api'],
  methods:{
    getStatus(api){
      let self = this;
      if (api.hasOwnProperty('_status') && api['_status'].hasOwnProperty('uptime_status')) {
        let stat = api['_status']['uptime_status'];
        switch (stat) {
          case 'unknown':
            self.status = 'UNKNOWN';
            self.clss = 'orange';
            break;
          case 'good':
            self.status = 'PASS';
            self.clss = 'green';
            break;
          case 'bad':
            self.status = 'BAD';
            self.clss = 'red';
            break;
          case 'incompatible':
            self.status = 'INCOMPATIBLE';
            self.clss = 'blue';
            break;
          default:
          self.status = 'N/A';
          self.clss = 'grey';
        }
      }else{
        self.status = 'N/A';
        self.clss = 'grey';
      }
    },
  },
  mounted: function(){
    this.getStatus(this.api);
  },
  template: `<span class="badge apiStatus white-text" style="font-size:75%" :class='clss' v-text="status"></span>`
});

Vue.component('source-status', {
  data: function(){
    return{
      status:'',
      clss:'',
    }
  },
  props: ['api'],
  methods:{
    getStatus(api){
      let self = this;
      if (api.hasOwnProperty('_status') && api['_status'].hasOwnProperty('refresh_status')) {
        let stat = api['_status']['refresh_status'];
        switch (stat) {
          case 200:
            self.status = "OK";
            self.clss = 'green';
            break;
          case 299:
            self.status = "OK";
            self.clss = 'green';
            break;
          case 499:
            self.status = "INVALID";
            self.clss = 'red';
            break;
          case 599:
            self.status = "BROKEN";
            self.clss = 'purple';
            break;
          case 404:
            self.status = "NOT FOUND";
            self.clss = 'orange';
            break;
          default:
          self.status = stat;
          self.clss = 'black';
        }
      }else{
        self.status = 'N/A';
        self.clss = 'grey darken-1';
      }
    },
  },
  mounted: function(){
    this.getStatus(this.api);
  },
  template: `<span class="badge urlStatus white-text" style="font-size:75%" :class='clss' v-text="status"></span>`
});


  // Refresh Button Component
  Vue.component('refresh', {
    data: function(){
      return{
        //timeout before being able to refresh again
        counter:30,
        //bind to disable attr while waiting
        currentlyRefreshing: false,
        text: 'refresh'
      }
    },
    // declare the props
    props: ['refresh', 'title', 'id'],
    // like data, the prop can be used inside templates and
    // is also made available in the vm as this.message
    methods:{
      countDown: function(){
        this.counter --;
        if( this.counter > 0 ){
          setTimeout(this.countDown,1000);
          this.currentlyRefreshing = true;
          this.text =this.counter+'...';
          var thisElement =$(this.$el);
          thisElement[0].text=this.text;
        }
        else if ( this.counter === 0){
          this.currentlyRefreshing = false;
          this.counter = 30;
          this.text = `<i class=" material-icons white-text"  @mouseenter="$event.target.classList.add('rotate')" @mouseleave="$event.target.classList.remove('rotate')">refresh</i>`;
          var thing =$(this.$el);
          thing[0].innerHTML=this.text;
        }
      },
      getText: function(){
        return this.text;
        //console.log(this.text);
      }
    },
    mounted: function(){
      // mounted logic
      tippy('[data-tippy-content]',{
        placement: 'top',
        theme:'light',
        onShow(instance) {
          let msg = instance.reference.dataset.tippyContent;
          instance.setContent('<div style="padding:5px;"><h6 class="blue-text">'+msg+'</h6></div>')
        },
      });
    },
    template: `<a class="btn btn-small" :disabled='currentlyRefreshing' @click="refresh(title,id); countDown()" :class="currentlyRefreshing ? 'grey' : 'green scale-in-center' ">
                <i class=" material-icons white-text">refresh</i>
              </a>`
  });

  // Main Dashboard Component
    var app = new Vue({
        el: '#dashApp',
        data: function(){
          return {
            userInfo:{},
            confirmModal:{
              title:'',
              id:''
            },
            selectedAPI:{},
            inputApiName:'',
            apis:[],
            total: 0,
            confirmDelete: true,
            searchQuery:'',
            searchResults:[],
            sortASC: true,
            myShortName:'',
            availableShortName: false,
            hasShortName: false,
            createOrEditMode: false,
            invalidChars: false,
            takenSlug: false,
            selectedAPIIndex:''
          }
        },
        computed:{
          results: function(){
            return this.searchResults.length ? this.searchResults : this.apis;
          }
        },
        methods:{
          validate(url){
            let self = this;
            if (url) {
              axios.post('/api/validate',{'url':url}).then(res=>{
                console.log(res.data)
                swal({
                    imageUrl: '/static/img/api-sucess.svg',
                    imageWidth: 300,
                    title: 'Great! Everything looks good!',
                  })
              }).catch(err=>{
                if(err.hasOwnProperty('response') && err.response.hasOwnProperty('data')){
                // console.log('[Error]:', err.response)
                if(err.response.data.hasOwnProperty('error') && err.response.data.error == "Conflict"){
                swal({
                  title: "Wait a second...",
                  html:'<h3>Looks like this API already exists</h3><p>If you are the owner of this API you can refresh it via the <a href="/dashboard">user dashboard</a></p>',
                  imageUrl: '/static/img/api-overwrite.svg',
                  imageWidth: 300,
                  confirmButtonText: 'OK',
                });
              }
              else if(err.response.data.hasOwnProperty('details') && err.response.data.details == "API exists"){
                swal({
                  title: "Wait a second...",
                  html:'<h3>Looks like this API already exists</h3><p>If you are the owner of this API you can refresh it via the <a href="/dashboard">user dashboard</a></p>',
                  imageUrl: '/static/img/api-fail.svg',
                  imageWidth: 300,
                  confirmButtonText: 'OK',<commit_msg>use formdata for validation<commit_after>{% extends "main.html" %}
{% include "smartapi-head.html" %}
{% block content %}
{% include "header.html" %}
{% raw %}
<main id="dashApp" style="padding-top:20px;min-height:90vh;" class="blue-grey darken-3" v-cloak>
  <!-- IF NO USER INFO DISPLAY LOGIN-->
  <div v-if="!userInfo.login" class="padding20 card-panel white center-align">
    <h5 class="text_h3 blue-grey-text-text">
      You Must Be Signed In To Use Your Dashboard
    </h5>
    <a href="/oauth" class="btn green">
      Login
    </a>
  </div>
  <!-- LOADING -->
  <div id="loading-overlay" class="center-align" style="background-color: rgba(18, 52, 84, 0.5); cursor: default;">
    <div class="center-align" style="padding-top: 300px;">
      <object width="100px"  alt="Loading" data="/static/img/fly.gif" class=""></object>
      <h3 class="white-text logoFont">Loading...</h3>
    </div>
  </div>
  <!-- Loading END -->
  <!-- IF USER INFO DISPLAY DASHBOARD -->
  <div id="tippyParent" v-if="userInfo.login" class="row" style="margin-bottom: 0; width: 100%;min-height:70vh;">
      <div class="col s12 m4 l3 xl3 transparent">
        <ul class="collection" style="border: none;">
          <li class="collection-item center-align transparent" style="border-bottom: none;">
            <img v-if="userInfo.avatar_url" id="dashboardPhoto" width="70%" :src="userInfo.avatar_url" class="responsive-img hideOnSmall hide-on-med-and-down" alt="user image" style="box-shadow: 5px 5px 5px #273238; margin-bottom: -25px; border-radius: 10px; border: 2px white solid; max-width:250px;">
            <img v-else id="dashboardPhoto" width="70%" src="/static/img/user-default.png" class="responsive-img hideOnSmall" alt="user image" style="box-shadow: 5px 5px 5px #273238; margin-bottom: -25px; border-radius: 10px; border: 2px white solid; max-width:250px;">
          </li>
          <li class="collection-item center-align white-text padding20 blue" style="border-top-left-radius: 10px; border-top-right-radius: 10px;">
            <img v-if="userInfo.avatar_url" width="30%" :src="userInfo.avatar_url" class="show-on-medium-and-down hide-on-med-and-up circle" alt="user image" style="margin: 0 auto; border: 3px solid white;">
            <h5 v-if="userInfo.name" class="text_h3 white-text textShadow swing-in-top-fwd">Hello, {{ userInfo.name.split(" ")[0] }}!</h5>
            <h5 v-else class="text_h3 white-text textShadow swing-in-top-fwd">Hello, {{ userInfo.login }}!</h5>
            <p><a target="_blank" class="white-text" :href="'https://github.com/'+userInfo.login"><i class="tiny fa fa-github-alt white-text"></i> {{userInfo.login}}</a></p>
          </li>
          <!--  -->
          <li class="collection-item center-align blue-grey darken-4 white-text show-on-small hide-on-med-and-up">
            <span class="logoFont blue-grey-text">SmartAPI</span><br />CONTRIBUTIONS <span class="l-blue-text">({{ total+") API's" }}</span>
          </li>
          <li class="collection-item blue-grey-text hide-on-small-only">
            <h5 class="center">APIs</h5>
            <h5 class="center blue-text"> {{ total}}</h5>
            <div class="center">
              <a href="/logout" class="btn red smallFont">Log Out</a>
            </div>
          </li>
        </ul>
      </div>
    <div class="col s12 m8 l9 xl9 center-align">
        <div class="row">
          <div class="p-1 col s12">
            <input v-model='searchQuery' placeholder="Search by API name" type="text" class="browser-default margin20 blue-grey darken-3 l-blue-text lighter" style="width: 40%; outline: none; padding: 10px; border-radius: 20px; border:var(--blue-light) 2px solid;"/>
          </div>
          
          <div class="col s12">
            <ul class="tabs transparent">
              <li class="tab col s3 transparent">
                <a class="white-text textShadow " href="#contributions">
                  APIs <span class="l-blue-text">({{total}})</span>
                </a>
              </li>
            </ul>
          </div>

          <div id="contributions" class="col s12 card-panel" style="padding:0;">
              <div class="s12">
                <ul class="collection resultsContainer">
                  <li class="collection-item" v-for="(api,index) in results" style="margin-bottom:0px;padding: 0px;">
                    <div class="row" style="padding: 0px; margin-bottom:0px;">
                      <div class="col s12 row" style="padding: 0px; 
                      margin-bottom:0px;
                      display: flex;
                      align-items: center;
                      flex-wrap: wrap;">
                        <div class="col s6 m3 p-1">
                          <a href="#modal2" class="modal-trigger" @click="getDetails(index)">
                            <h6><b>{{ api.info.title }}</b></h6>
                          </a>
                          <small>
                            <span class="grey-text smallFont">V.{{api.info.version}}</span>
                          </small>
                        </div>
                        <div class="col s6 m3 p-1">
                          <h6>
                            <small class="grey-text"><i class="fa fa-clock-o" aria-hidden="true"></i> Last Updated </small>
                          </h6>
                          <small>
                            <span class="green-text"> {{ convertDate(api._meta.last_updated) }}</span>
                          </small>
                        </div>
                        <div class="col s4 m2 p-1">
                          <refresh :refresh='refreshingThis' :title='api.info.title' :id="api._id" 
                          data-tippy-content="<b class='green-text'>Refresh</b> <br/>(Manually update API metadata when a valid change is detected)"></refresh>
                        </div>
                        <div class="col s4 m2 p-1">
                          <button type="button" @click="validate(api._meta.url)" class="btn btn-small scale-in-center indigo white-text" 
                          data-tippy-content="<b class='indigo-text'>Validate Only</b> <br/>(Validate latest API metadata from the source URL)">
                            <i class="material-icons white-text">check</i>
                        </button>
                        </div>
                        <div class="col s4 m2 p-1">
                          <a href="#modal1" @click="deleteAPI(api.info.title, api._id)" class="btn btn-small scale-in-center red white-text modal-trigger" 
                          data-tippy-content="<b class='red-text'>Delete</b> <br/>(Delete API metadata from SmartAPI registry permanently - cannot be undone)">
                            <i class="material-icons white-text">delete_forever</i>
                          </a>
                        </div>
                      </div>
                      <div class="col s12 row" style="padding: 0px; margin-bottom:0px;background-color: rgba(0, 0, 0, .05);">
                        <div class="col s6 m3">
                          <a href="#" class='popularity pointer blue-text' :data-tippy-name='api.info.title' :data-tippy-id='api._id'>
                            <small><i class="fa fa-bar-chart"></i> User Interactions</small>
                          </a>
                        </div>
                        <div class="col s6 m3">
                          <small>Specification </small>
                          <span v-if=" api.hasOwnProperty('openapi')" style="font-size:75%" class="smallFont badge green white-text" data-tippy-content="<b class='green-text'>OpenAPI 3</b> Specification">
                            OAS3
                          </span>
                          <span v-else-if=" api.hasOwnProperty('swagger')" style="font-size:75%" class="smallFont badge blue white-text" data-tippy-content="<b class='blue-text'>Swagger 2</b> Specification">
                            Swagger2
                          </span>
                        </div>
                        <div class="col s6 m3">
                          <small>API Status </small> <status :api='api'></status>
                        </div>
                        <div class="col s6 m3">
                          <small>Source Status </small>
                          <source-status :api='api'></source-status>
                        </div>
                      </div>
                    </div>
                  </li>
                  <div v-if="apis.length === 0">
                    <small class="center-align grey lighten-3">
                      <span class="grey-text smallFont">No Contributions Yet</span><br>
                    </small>
                  </div>
                </ul>
              </div>
          </div>

        </div>
    </div>
  </div>
  <div class="grey lighten-5 padding20 blue-text center">
      <small>
        <i class="material-icons">error_outline</i> Did you know you can set a custom slug for your API's documentation? It's easy! Just click on any API on your dashboard and go to the <em>Settings</em> tab.<br />
        Use the <em>Custom Slug Registration Wizard</em> and get a custom URL for your API's documentation. E.g. <b>&lt;slug&gt;.smart-api.info</b>
      </small>
  </div>
  <!-- Modal for Deletion Confirmation -->
  <div id="modal1" class="modal center-align">
    <div class="modal-content">
      <h5 class="blue-text">Delete <b>{{ confirmModal.title }}</b>?</h5>
      <div class="white padding20">
        <i class="material-icons small amber-text">warning</i>
        <p class="red-text">This action cannot be undone. Please type in the exact name of the API to confirm.</p>
        <input v-model="inputApiName" :placeholder="confirmModal.title" type="text" class="validate browser-default" style="outline: none; padding: 10px; width: 70%;">
        <hr/>
        <a href='#!' :disabled="confirmDelete" @click="deleteForever(confirmModal.title, confirmModal.id)" class=" deep-orange darken-2 btn modal-action modal-close">Delete API</a>
      </div>
      <hr>
      <a href="#!" class="btn blue modal-action modal-close">Cancel</a>
    </div>
  </div>
  <!-- delete Modal end -->


  <!-- Details Modal -->

  <div id="modal2" class="modal center-align">
    <div  class="modal-content" style="padding-top:45px;">
      <div class="row">
        <div class="col s12">
          <ul class="tabs transparent">
            <li class="tab col s3"><a href="#test1" class="active blue-text">About</a></li>
            <li class="tab col s3"><a class="blue-text" href="#test2"><i class="tiny material-icons">settings</i> Settings</a></li>
          </ul>
        </div>

        <div id="test1" class="col s12">
          <ul v-if="selectedAPIIndex || selectedAPIIndex === 0" class="collection with-header" style="border: none;">

            <li class="collection-header padding20">
              <object width="100px"  alt="SmartAPI" data="/static/img/logo-medium.svg" class="hide-on-small-only"></object>
              <h2 class="blue-text flow-text">
                {{apis[selectedAPIIndex].info.title}}
                <span class="versionBadge grey hide-on-small-only">Version {{apis[selectedAPIIndex].info.version}}</span>
                <span v-if=" apis[selectedAPIIndex].hasOwnProperty('openapi') " class="versionBadge green hide-on-small-only">
                  OAS3
                </span>
                <span v-else-if=" apis[selectedAPIIndex].hasOwnProperty('swagger') " class="versionBadge blue hide-on-small-only">
                  Swagger2
                </span>
                <template class="show-on-small hide-on-med-and-up">
                  <span v-if=" apis[selectedAPIIndex].hasOwnProperty('openapi') " class="versionBadge green hide-on-med-and-up">
                    V3
                  </span>
                  <span v-else-if=" apis[selectedAPIIndex].hasOwnProperty('swagger') " class="versionBadge blue hide-on-med-and-up">
                    V2
                  </span>
                </template>
              </h2>
              <hr />
              <template v-if=" apis[selectedAPIIndex].hasOwnProperty('swagger') ">
                <div class="yellow lighten-5 smallFont padding20">
                  APIs in Swagger V2 specification will experience limited functionality. <br />We recommend you update your metadata to OpenAPI V3 specification.
                  <br />
                  <a target="_blank" class="underlined" href="https://github.com/SmartAPI/smartAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md">Learn More about OpenAPI V3 Specification <i class="fa fa-external-link-square" aria-hidden="true"></i></a>
                  <br />
                  <a href="/guide" class="green-text underlined">Use our guide to help you convert your API to OpenAPI V3 specification.</a>
                </div>
                <hr />
              </template>
              <a :href="'/ui/'+apis[selectedAPIIndex]._id" class="btn blue">View API Doc</a>
            </li>
            <template v-for='link in checkForAPIInfoLink(apis[selectedAPIIndex])'>
              <li  class="collection-item blue-grey lighten-4">
                <a class="link blue-grey-text underlined" :href="link" target="_blank">
                 More Info
                </a>
              </li>
            </template>
            <li class="collection-item padding20 blue-grey lighten-5">
              <p style="line-height: 1.2em;" class="blue-grey-text flow-text" v-html="compiledMarkdown(apis[selectedAPIIndex].info.description || '')"></p>
            </li>
            <li class="collection-item blue-grey lighten-5">
              <i v-if="apis[selectedAPIIndex].info.termsOfService || apis[selectedAPIIndex].termsOfService" class="material-icons tiny blue-text">info_outline</i>
              <a v-if="apis[selectedAPIIndex].info.termsOfService" :href="apis[selectedAPIIndex].info.termsOfService" target="_blank" class="blue-text">Terms of Service</a>
              <a v-if="apis[selectedAPIIndex].termsOfService" :href="apis[selectedAPIIndex].termsOfService" target="_blank" class="blue-text">Terms of Service</a>

            </li>
          </ul>
        </div>

        <div id="test2" class="col s12 white">
          <div v-if="selectedAPIIndex || selectedAPIIndex === 0" class="row">
            <div class="col s12 m12 l12 center-align">
              <h3 class="flow-text blue-grey-text padding20">Slug Registration Wizard</h3>
            </div>
            <div v-if='!hasShortName' class="col s12 m12 l12 center-align">
              <object class="hide-on-small-only" width="250px" data="/static/img/wand.svg" alt='custom slug' style='border-radius: 10px;'></object>
              <p class="grey-text left-align">
                Every project has a subdomain that is available to serve its documentation.<br />
                By default we use your <i>API ID</i>. If you go to <span class="blue-text"><b>your-api-id</b>.smart-api.info</span> it should allow users to view your API documentation.
              </p>
              <p class="grey-text left-align">
                You can also register a unique slug to make sharing your API easier.
                <br />
                If you go to <span class="blue-text"><b>your-slug</b>.smart-api.info</span>, it will take users to your API documentation.
              </p>
              <a v-if='!createOrEditMode' @click.prevent='createOrEditMode = !createOrEditMode' class="blue btn">Create a new slug</a>
              <a v-if='createOrEditMode' @click.prevent='createOrEditMode = !createOrEditMode' class="red btn">Cancel</a>
            </div>
            <div v-if='hasShortName' class="col s12 m12 l12">
              <p>
                <i class="fa fa-check-circle-o green-text fa-5x" aria-hidden="true"></i>
              </p>
              <p class="grey-text">
                You have registered your custom slug!
                <br />
                If you visit to link below, it will take users to your API documentation.
              </p>
              <p class="green-text flow-text">
                 <a :href=" 'http://'+apis[selectedAPIIndex]._meta.slug+'.smart-api.info'" target="_blank" class="green-text link">http://<b>{{apis[selectedAPIIndex]._meta.slug}}</b>.smart-api.info <i class="fa fa-external-link-square" aria-hidden="true"></i></a>
                 <br />
                 <hr />
                 <a class="btn green smallFont margin20" @click.prevent='createOrEditMode = !createOrEditMode'>Edit Slug</a>
                 <a v-if="hasShortName" class="btn red smallFont margin20" @click.prevent='deleteSlug'>Delete Slug</a>
              </p>
            </div>
            <div v-if="createOrEditMode" style="width: 100%; display: flex; align-items: center;justify-content: center; flex-wrap: wrap;">
              <div class="left-align padding20 grey-text" style="flex: 1; min-width: 100%;">
                Slug length must be 4-50 characters (a-z) and/or numbers (0-9). Slugs will be converted to lower case. URL protected characters not allowed.
              </div>
              <div style="flex: 1; min-width: 200px;">
                <input autocomplete="false" v-model='myShortName' placeholder="Enter your slug here" id="first_name" type="text" class="disabled browser-default margin20 grey lighten-5 blue-grey-text lighter" style="width: 85%; outline: none; padding: 10px; border-radius: 20px; border:var(--blue-medium) 2px solid;">
              </div>
              <div style="flex: 1; min-width: 200px;">
                <p id="availabilityResults" v-bind:class="{'green-text': availableShortName, 'red-text': !availableShortName }">
                  <span v-if="myShortName" class="grey-text">http://</span>
                  <span v-if="myShortName">{{myShortName}}</span>
                  <span v-if="myShortName" class="grey-text">.smart-api.info</span>
                  <span v-if="!myShortName" class="grey-text">Check Slug Availability</span>
                  <i v-if='availableShortName && myShortName' class="fa fa-thumbs-up green-text" aria-hidden="true"></i>
                  <i v-if='!availableShortName && myShortName' class="fa fa-thumbs-down red-text" aria-hidden="true"></i>
                  <br />
                  <span v-if="myShortName.length <= 3 && myShortName.length > 0" class="amber-text"><i class="tiny material-icons">warning</i> Too Short</span>
                  <span v-if="myShortName.length >50" class="orange-text"><i class="tiny material-icons">warning</i> Too Long</span><br v-if="myShortName.length <= 3 && invalidChars"/>
                  <span v-if="invalidChars" class="red-text"><i class="tiny material-icons">warning</i> Invalid Characters</span>
                  <span v-if="takenSlug" class="orange-text"><i class="tiny material-icons">warning</i> Taken Slug</span>
                </p>
              </div>
              <div style="flex: 1; min-width: 200px;">
                <a @click.prevent="setShortname" :disabled='!availableShortName && !hasShortName' :class="!availableShortName ? 'btn grey' : 'green btn pulse' " >Set Slug</a>
              </div>

              <div id="shortNameSuccess" class="center-align padding20 green smallFont" style="flex: 1; min-width: 100%; display: none;">
                <h5 class="white-text"><i class="fa fa-check white-text" aria-hidden="true"></i> Slug Registered</h5>
                <a href="#!" class="btn green modal-action modal-close">Close</a>
              </div>
            </div>
          </div>
        </div>
      </div>
      <a href="#!" style="position: absolute; top:1%; right: 5%; font-size: 2em;" class="red-text modal-action modal-close">&times;</a>
    </div>
  </div>


</main>


{% endraw %}
{% include "footer.html" %}
{% endblock %}

{% block extra_scripts %}
<script src="https://unpkg.com/vuex"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.6/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://unpkg.com/tippy.js@3/dist/tippy.all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<script src="/static/js/moment.js"></script>


<script>

const store = new Vuex.Store({
    state: {
      'analytics':Object,
      'tags':Array
    },
    strict: true,
    mutations: {
      saveAnalytics(state,payload){
        state.analytics = payload['analytics'];
      },
    },
    getters:{
      // exposed as store.getters.nameOfGetter
      getHitsFor: (state) => (apiname) => {
        let data={'labels':[],'datasets':[]};
        let label = '';
        let dataArray=[];

        for (var i = 0; i < state.analytics.length; i++) {
          if (state.analytics[i][1].toLowerCase() === apiname.toLowerCase()) {
            label = state.analytics[i][0].toUpperCase();
            if (label == "EXPANDED") {
              label = "VIEWS"
            }
            data.labels.push(label);
            let number = state.analytics[i][2];
            dataArray.push(number)
          }

        }
        data.datasets.push({'label':"Users",'data':dataArray,'backgroundColor': ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],})
        // console.log('user interactions...',data)
        return data
      },
      getTags:(state)=>{
        let pop = []
        for (var i = 0; i < state.analytics.length; i++) {
          if (state.analytics[i][0] ==='tag') {
            pop.push({'name':state.analytics[i][1],'active':false,'count':state.analytics[i][2]})
          }
        }
        return pop;
      }

    }
  });

Vue.component('status', {
  data: function(){
    return{
      status:'',
      clss:'',
    }
  },
  props: ['api'],
  methods:{
    getStatus(api){
      let self = this;
      if (api.hasOwnProperty('_status') && api['_status'].hasOwnProperty('uptime_status')) {
        let stat = api['_status']['uptime_status'];
        switch (stat) {
          case 'unknown':
            self.status = 'UNKNOWN';
            self.clss = 'orange';
            break;
          case 'good':
            self.status = 'PASS';
            self.clss = 'green';
            break;
          case 'bad':
            self.status = 'BAD';
            self.clss = 'red';
            break;
          case 'incompatible':
            self.status = 'INCOMPATIBLE';
            self.clss = 'blue';
            break;
          default:
          self.status = 'N/A';
          self.clss = 'grey';
        }
      }else{
        self.status = 'N/A';
        self.clss = 'grey';
      }
    },
  },
  mounted: function(){
    this.getStatus(this.api);
  },
  template: `<span class="badge apiStatus white-text" style="font-size:75%" :class='clss' v-text="status"></span>`
});

Vue.component('source-status', {
  data: function(){
    return{
      status:'',
      clss:'',
    }
  },
  props: ['api'],
  methods:{
    getStatus(api){
      let self = this;
      if (api.hasOwnProperty('_status') && api['_status'].hasOwnProperty('refresh_status')) {
        let stat = api['_status']['refresh_status'];
        switch (stat) {
          case 200:
            self.status = "OK";
            self.clss = 'green';
            break;
          case 299:
            self.status = "OK";
            self.clss = 'green';
            break;
          case 499:
            self.status = "INVALID";
            self.clss = 'red';
            break;
          case 599:
            self.status = "BROKEN";
            self.clss = 'purple';
            break;
          case 404:
            self.status = "NOT FOUND";
            self.clss = 'orange';
            break;
          default:
          self.status = stat;
          self.clss = 'black';
        }
      }else{
        self.status = 'N/A';
        self.clss = 'grey darken-1';
      }
    },
  },
  mounted: function(){
    this.getStatus(this.api);
  },
  template: `<span class="badge urlStatus white-text" style="font-size:75%" :class='clss' v-text="status"></span>`
});


  // Refresh Button Component
  Vue.component('refresh', {
    data: function(){
      return{
        //timeout before being able to refresh again
        counter:30,
        //bind to disable attr while waiting
        currentlyRefreshing: false,
        text: 'refresh'
      }
    },
    // declare the props
    props: ['refresh', 'title', 'id'],
    // like data, the prop can be used inside templates and
    // is also made available in the vm as this.message
    methods:{
      countDown: function(){
        this.counter --;
        if( this.counter > 0 ){
          setTimeout(this.countDown,1000);
          this.currentlyRefreshing = true;
          this.text =this.counter+'...';
          var thisElement =$(this.$el);
          thisElement[0].text=this.text;
        }
        else if ( this.counter === 0){
          this.currentlyRefreshing = false;
          this.counter = 30;
          this.text = `<i class=" material-icons white-text"  @mouseenter="$event.target.classList.add('rotate')" @mouseleave="$event.target.classList.remove('rotate')">refresh</i>`;
          var thing =$(this.$el);
          thing[0].innerHTML=this.text;
        }
      },
      getText: function(){
        return this.text;
        //console.log(this.text);
      }
    },
    mounted: function(){
      // mounted logic
      tippy('[data-tippy-content]',{
        placement: 'top',
        theme:'light',
        onShow(instance) {
          let msg = instance.reference.dataset.tippyContent;
          instance.setContent('<div style="padding:5px;"><h6 class="blue-text">'+msg+'</h6></div>')
        },
      });
    },
    template: `<a class="btn btn-small" :disabled='currentlyRefreshing' @click="refresh(title,id); countDown()" :class="currentlyRefreshing ? 'grey' : 'green scale-in-center' ">
                <i class=" material-icons white-text">refresh</i>
              </a>`
  });

  // Main Dashboard Component
    var app = new Vue({
        el: '#dashApp',
        data: function(){
          return {
            userInfo:{},
            confirmModal:{
              title:'',
              id:''
            },
            selectedAPI:{},
            inputApiName:'',
            apis:[],
            total: 0,
            confirmDelete: true,
            searchQuery:'',
            searchResults:[],
            sortASC: true,
            myShortName:'',
            availableShortName: false,
            hasShortName: false,
            createOrEditMode: false,
            invalidChars: false,
            takenSlug: false,
            selectedAPIIndex:''
          }
        },
        computed:{
          results: function(){
            return this.searchResults.length ? this.searchResults : this.apis;
          }
        },
        methods:{
          validate(url){
            let self = this;
            if (url) {
              var bodyFormData = new FormData();
              bodyFormData.append('url', url);
              axios({
                  method: "post",
                  url: '/api/validate',
                  data: bodyFormData,
                  headers: { "Content-Type": "multipart/form-data" },
                }).then(res=>{
                console.log(res.data)
                swal({
                    imageUrl: '/static/img/api-sucess.svg',
                    imageWidth: 300,
                    title: 'Great! Everything looks good!',
                    footer: "<h5 class='green-text'>" + res.data.details + "</h5>"
                  })
              }).catch(err=>{
                if(err.hasOwnProperty('response') && err.response.hasOwnProperty('data')){
                // console.log('[Error]:', err.response)
                if(err.response.data.hasOwnProperty('error') && err.response.data.error == "Conflict"){
                swal({
                  title: "Wait a second...",
                  html:'<h3>Looks like this API already exists</h3><p>If you are the owner of this API you can refresh it via the <a href="/dashboard">user dashboard</a></p>',
                  imageUrl: '/static/img/api-overwrite.svg',
                  imageWidth: 300,
                  confirmButtonText: 'OK',
                });
              }
              else if(err.response.data.hasOwnProperty('details') && err.response.data.details == "API exists"){
                swal({
                  title: "Wait a second...",
                  html:'<h3>Looks like this API already exists</h3><p>If you are the owner of this API you can refresh it via the <a href="/dashboard">user dashboard</a></p>',
                  imageUrl: '/static/img/api-fail.svg',
                  imageWidth: 300,
                  confirmButtonText: 'OK',
{'fraction_non_alphanumeric': 0.157755499860763, 'fraction_numerical': 0.0142369813422445, 'mean_word_length': 1.9316291647533037, 'pattern_counts': {'":': 1, '<': 903, '<?xml version=': 0, '>': 911, 'https://': 16, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5297607', 'n_tokens_mistral': 17569, 'n_tokens_neox': 16595, 'n_words': 3737}