Skip to content

Instantly share code, notes, and snippets.

@IlyasDeckers
Created September 13, 2018 10:43
Show Gist options
  • Save IlyasDeckers/a64a7541d80da6782ab7b77376f28517 to your computer and use it in GitHub Desktop.
Save IlyasDeckers/a64a7541d80da6782ab7b77376f28517 to your computer and use it in GitHub Desktop.
<template>
<section class="outer-card card">
<div class="flex flex-wrap items-center pt-6 mb-2 px-6">
<div class="flex-1 pr-8 pb-4">
<h2 class="mb-0 font-normal uppercase tracking-wide text-grey-dark mr-2">
consultants
<cw-tween :value="collection.length" />
</h2>
</div>
<div class="padding-auto">
<div class="flex flex-wrap btn-align">
<div class="flex mr-8 w-24 pb-4">
<a href @click.prevent="show('freelancers')" class="hover:text-orange">
<h4 class="">{{counters.freelancers}}</h4>
<h6 class=" font-normal uppercase tracking-wide ">Freelancers</h6>
</a>
</div>
<div class="flex mr-8 w-24 pb-4">
<a href @click.prevent="show('thirdparty')" class="hover:text-orange">
<h4 class="">{{counters.thirdparty}}</h4>
<h6 class=" font-normal uppercase tracking-wide">thirdparty</h6>
</a>
</div>
<div class="flex w-24 pb-4">
<a href @click.prevent="show('employees')" class="hover:text-orange">
<h4 class="">{{counters.employees}}</h4>
<h6 class=" font-normal uppercase tracking-wide">employees</h6>
</a>
</div>
</div>
</div>
</div>
<tabs class="shadow-none m-0 -mx-6">
<tab class="overflowAuto" name="Overview" :suffix="` (${collection.length})`">
<div class="flex items-center">
<router-link to="consultants/create" class="btn bg-white text-grey w-8 h-8 shadow-sm mr-2 inline-flex items-center justify-center uppercase text-sm rounded border-grey-light hover:text-orange-light hover:border-orange-lighter">
<font-awesome-icon :icon="['fas', 'plus']" fixed-width/>
</router-link>
<a href class="btn bg-white text-grey mr-2 w-8 h-8 shadow-sm inline-flex items-center justify-center uppercase text-sm rounded border-grey-light hover:text-orange-light hover:border-orange-lighter">
<font-awesome-icon :icon="['fas', 'filter']" fixed-width/>
</a>
<a @click.prevent="toggle('search')" href class="btn bg-white text-grey mr-2 w-8 h-8 shadow-sm inline-flex items-center justify-center uppercase text-sm rounded border-grey-light hover:text-orange-light hover:border-orange-lighter"> <font-awesome-icon :icon="['fas', 'search']" flip="horizontal" fixed-width/>
</a>
<a @click.prevent="reset()" href class="btn bg-white text-grey mr-2 w-8 h-8 shadow-sm inline-flex items-center justify-center uppercase text-sm rounded border-grey-light hover:text-orange-light hover:border-orange-lighter"> <font-awesome-icon :icon="['fas', 'unlock']" flip="horizontal" fixed-width/>
</a>
</div>
<div class="pt-3" v-if="loaded">
<input class="searchbox w-full" placeholder="Search..." type="text" :value="getState($options.name).search" @input="$search">
</div>
<p class="font-normal uppercase text-xs tracking-narrow text-grey ml-2 my-4" v-if="loaded">
<a class="text-grey-darker">Filters: &nbsp;&nbsp; </a>
<a href @click.prevent="$scope('active')" class="mr-2" :class="{'text-orange': getState($options.name).scope === 'active'}">Active</a>
<a href @click.prevent="$scope('inactive')" class="" :class="{'text-orange': getState($options.name).scope === 'inactive'}">Archived</a>
</p>
<div v-if="!loaded" class="h-64 chart-container flex items-center justify-center">
<orbit-spinner :animation-duration="1200" :size="55" color="#ff874d" />
</div>
<table v-else class="table table-main">
<thead>
<tr>
<th>
<input @change="select" class="styled-checkbox" id="queue-all" type="checkbox">
<label for="queue-all" class="uppercase tracking-normal text-xs"/>
</th>
<th>
<a @click.prevent="$sort('type')" :class="{'text-primary': $sortField('type')}" href="">type
<font-awesome-icon v-if="$sortField('type')" :icon="['fas', $sortIcon]"/>
</a>
</th>
<th>
<a @click.prevent="$sort('name')" :class="{'text-primary': $sortField('name')}" href="">
name
<font-awesome-icon v-if="$sortField('name')" :icon="['fas', $sortIcon]"/>
</a>
</th>
<th>
<a @click.prevent="$sort('email')" :class="{'text-primary': $sortField('email')}" href="">email
<font-awesome-icon v-if="$sortField('email')" :icon="['fas', $sortIcon]"/>
</a>
</th>
<th>
<a @click.prevent="$sort('company')" :class="{'text-primary': $sortField('company')}" href="">company
<font-awesome-icon v-if="$sortField('company')" :icon="['fas', $sortIcon]"/>
</a>
</th>
<th>Contract</th>
<th/>
<th/>
</tr>
</thead>
<tbody>
<tr class="data-row" v-for="row in rows" :key="row.id">
<td>
<input @change="queue(row, $event.target.checked)"
v-model="row.queue"
class="styled-checkbox"
:id="'queue-' + row.id"
type="checkbox">
<label :for="'queue-' + row.id" class="uppercase tracking-normal text-xs"/>
</td>
<td @click.prevent="$router.push(`/consultants/${row.id}`)">
<div class="w-6 h-6 text-sm bg-white rounded-full inline-flex items-center justify-center border border-orange-lighter text-orange-light">
{{row.type | initials}}
</div>
</td>
<td @click.prevent="$router.push(`/consultants/${row.id}`)">{{ row.name }}</td>
<td @click.prevent="$router.push(`/consultants/${row.id}`)">{{ row.email }}</td>
<td @click.prevent="$router.push(`/consultants/${row.id}`)">{{ row.company }}</td>
<td @click.prevent="$router.push(`/consultants/${row.id}`)">
<font-awesome-icon :icon="['fal', 'file-alt']" v-if="row.documents.length > 0"/>
</td>
<td @click.prevent="$router.push(`/consultants/${row.id}`)">
<template v-if="row.starting">
<span class="badge badge-primary text-uppercase">{{ row.starting | moment('YYYY-MM-DD') }}</span>
</template>
</td>
<td class="text-right">
<cw-popper :options="{placement: 'bottom-end'}">
<div class="popper">
<div class="bg-white py-1 rounded-sm dropdown-menu">
<router-link class="uppercase px-4 font-light hover:bg-orange-light hover:text-white py-2 text-xs tracking-wide flex items-center justify-between"
:to="{ name: 'consultant.detail', params: { id: row.id } }">
details
<div class="pl-8 ml-6">
<font-awesome-icon :icon="['fal', 'window-maximize']" fixed-width/>
</div>
</router-link>
<router-link class="uppercase px-4 font-light hover:bg-orange-light hover:text-white py-2 text-xs tracking-wide flex items-center justify-between"
:to="{ name: 'consultant.update', params: { id: row.id } }">
edit
<div class="pl-8 ml-6">
<font-awesome-icon :icon="['fal', 'cog']" fixed-width/>
</div>
</router-link>
<a v-if="getState($options.name).scope === 'active'" class="uppercase px-4 font-light hover:bg-orange-light hover:text-white py-2 text-xs tracking-wide flex items-center justify-between"
href
@click.prevent="remove(row)">
disable
<div class="pl-8 ml-6">
<font-awesome-icon :icon="['fal', 'ban']" fixed-width/>
</div>
</a>
<a v-else class="uppercase px-4 font-light hover:bg-orange-light hover:text-white py-2 text-xs tracking-wide flex items-center justify-between"
href
@click.prevent="enable(row)">
enable
<div class="pl-8 ml-6">
<font-awesome-icon :icon="['fal', 'ban']" fixed-width/>
</div>
</a>
</div>
<div class="popper__arrow" x-arrow/>
</div>
<button slot="toggle" class="px-2">
<font-awesome-icon :icon="['far', 'ellipsis-v']" size="lg" fixed-width/>
</button>
</cw-popper>
</td>
</tr>
</tbody>
</table>
</tab>
</tabs>
</section>
</template>
<script>
import { collection2, queue } from 'clockwork/mixins'
import { OrbitSpinner } from 'epic-spinners'
export default {
components: { OrbitSpinner },
mixins: [collection2, queue],
data () {
return {
field: 'id',
reverse: true,
order: 'asc',
loaded: false
}
},
computed: {
counters () {
return {
freelancers: this.rows.filter(x => x.type === 'freelancer').length,
thirdparty: this.rows.filter(x => x.type === 'thirdparty').length,
employees: this.rows.filter(x => x.type === 'employee').length
}
}
},
watch: {
async scope (newVal) {
await this.fetch(newVal)
}
},
async created () {
await this.fetch()
},
destroyed () {
this.$sort('id')
},
methods: {
async show (show) {
let response
await this.fetch()
if (show === 'freelancers') {
response = this.rows.filter(x => x.type === 'freelancer')
} else if (show === 'employees') {
response = this.rows.filter(x => x.type === 'employee')
} else if (show === 'thirdparty') {
response = this.rows.filter(x => x.type === 'thirdparty')
}
this.collection = response
},
async fetch (scope) {
scope = scope || this.scope
const response = await this.$http.get('/api/users', {
params: {
scopes: 'consultant,' + scope,
with: 'documents'
}
})
this.collection = response.data
this.collection.forEach((user) => {
user.documents = user.documents.filter(x => x.visibility === 'public')
})
this.loaded = true
},
async remove (model) {
model.active = false
if (await this.$confirm('Please confirm.', 'disable', model.name)) {
await this.$http.put(`api/users/${model.id}`, model)
this.fetch()
}
},
async enable (model) {
model.active = true
if (await this.$confirm('Please confirm.', 'enable', model.name)) {
await this.$http.put(`api/users/${model.id}`, model)
this.fetch()
}
},
async reset () {
if (this.$store.state.queue.pending.length === 0) {
} else {
const data = this.$store.state.queue.pending.map(x => x.id)
await this.$http.post(
'/api/users/reset',
{
users: data
}
)
this.$success('', 'reset', 'The password')
this.$store.dispatch('queue/reset')
}
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment