mirror of https://github.com/wg-easy/wg-easy
committed by
Sergei Birukov
24 changed files with 401 additions and 301 deletions
@ -1,60 +1,62 @@ |
|||
<!-- EditableAddress.vue --> |
|||
<template> |
|||
<span class="group block md:inline-block pb-1 md:pb-0"> |
|||
<!-- Show --> |
|||
<input |
|||
v-show="editAddressId === client.id" |
|||
v-model="editAddress" |
|||
@keyup.enter="updateAddress" |
|||
@keyup.escape="cancelEdit" |
|||
:test="'client-' + client.id + '-address'" |
|||
:ref="'client-' + client.id + '-address'" |
|||
class="rounded border-2 dark:bg-neutral-700 border-gray-100 dark:border-neutral-600 focus:border-gray-200 dark:focus:border-neutral-500 outline-none w-20 text-black dark:text-neutral-300 dark:placeholder:text-neutral-500" |
|||
/> |
|||
<span v-show="editAddressId !== client.id" class="inline-block border-t-2 border-b-2 border-transparent">{{ |
|||
client.address |
|||
}}</span> |
|||
<span class="group block md:inline-block pb-1 md:pb-0"> |
|||
<!-- Show --> |
|||
<input |
|||
v-show="editAddressId === client.id" |
|||
v-model="editAddress" |
|||
@keyup.enter="updateAddress" |
|||
@keyup.escape="cancelEdit" |
|||
:test="'client-' + client.id + '-address'" |
|||
:ref="'client-' + client.id + '-address'" |
|||
class="rounded border-2 dark:bg-neutral-700 border-gray-100 dark:border-neutral-600 focus:border-gray-200 dark:focus:border-neutral-500 outline-none w-20 text-black dark:text-neutral-300 dark:placeholder:text-neutral-500" |
|||
/> |
|||
<span |
|||
v-show="editAddressId !== client.id" |
|||
class="inline-block border-t-2 border-b-2 border-transparent" |
|||
>{{ client.address }}</span |
|||
> |
|||
|
|||
<!-- Edit --> |
|||
<span |
|||
v-show="editAddressId !== client.id" |
|||
@click="edit" |
|||
class="cursor-pointer opacity-0 group-hover:opacity-100 transition-opacity" |
|||
> |
|||
<IconEdit /> |
|||
</span> |
|||
<!-- Edit --> |
|||
<span |
|||
v-show="editAddressId !== client.id" |
|||
@click="edit" |
|||
class="cursor-pointer opacity-0 group-hover:opacity-100 transition-opacity" |
|||
> |
|||
<IconEdit /> |
|||
</span> |
|||
</span> |
|||
</template> |
|||
|
|||
<script> |
|||
import IconEdit from './icons/IconEdit.vue'; |
|||
|
|||
export default { |
|||
props: ["client"], |
|||
data() { |
|||
return { |
|||
editAddress: null, |
|||
editAddressId: null, |
|||
}; |
|||
props: ['client'], |
|||
data() { |
|||
return { |
|||
editAddress: null, |
|||
editAddressId: null, |
|||
}; |
|||
}, |
|||
methods: { |
|||
updateAddress() { |
|||
this.$emit('update-address', this.client, this.editAddress); |
|||
this.editAddress = null; |
|||
this.editAddressId = null; |
|||
}, |
|||
methods: { |
|||
updateAddress() { |
|||
this.$emit("update-address", this.client, this.editAddress); |
|||
this.editAddress = null; |
|||
this.editAddressId = null; |
|||
}, |
|||
cancelEdit() { |
|||
this.editAddress = null; |
|||
this.editAddressId = null; |
|||
}, |
|||
edit() { |
|||
this.editAddress = this.client.address; |
|||
this.editAddressId = this.client.id; |
|||
this.$nextTick(() => { |
|||
this.$refs["client-" + this.client.id + "-address"].select(); |
|||
}); |
|||
}, |
|||
cancelEdit() { |
|||
this.editAddress = null; |
|||
this.editAddressId = null; |
|||
}, |
|||
components: { IconEdit } |
|||
edit() { |
|||
this.editAddress = this.client.address; |
|||
this.editAddressId = this.client.id; |
|||
this.$nextTick(() => { |
|||
this.$refs['client-' + this.client.id + '-address'].select(); |
|||
}); |
|||
}, |
|||
}, |
|||
components: { IconEdit }, |
|||
}; |
|||
</script> |
|||
|
|||
@ -1,22 +1,33 @@ |
|||
<script> |
|||
import IconAvatarDefault from "./icons/IconAvatarDefault.vue"; |
|||
import IconAvatarDefault from './icons/IconAvatarDefault.vue'; |
|||
|
|||
export default { |
|||
props: ["client"], |
|||
components: { IconAvatarDefault }, |
|||
props: ['client'], |
|||
components: { IconAvatarDefault }, |
|||
}; |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="h-10 w-10 mr-5 rounded-full bg-gray-50 relative"> |
|||
<IconAvatarDefault class="w-6 m-2 text-gray-300" /> |
|||
<img v-if="client.avatar" :src="client.avatar" class="w-10 rounded-full absolute top-0 left-0" /> |
|||
<div class="h-10 w-10 mr-5 rounded-full bg-gray-50 relative"> |
|||
<IconAvatarDefault class="w-6 m-2 text-gray-300" /> |
|||
<img |
|||
v-if="client.avatar" |
|||
:src="client.avatar" |
|||
class="w-10 rounded-full absolute top-0 left-0" |
|||
/> |
|||
|
|||
<div v-if="client.latestHandshakeAt && new Date() - new Date(client.latestHandshakeAt) < 1000 * 60 * 10"> |
|||
<div |
|||
class="animate-ping w-4 h-4 p-1 bg-red-100 dark:bg-red-100 rounded-full absolute -bottom-1 -right-1" |
|||
></div> |
|||
<div class="w-2 h-2 bg-red-800 dark:bg-red-600 rounded-full absolute bottom-0 right-0"></div> |
|||
</div> |
|||
<div |
|||
v-if=" |
|||
client.latestHandshakeAt && |
|||
new Date() - new Date(client.latestHandshakeAt) < 1000 * 60 * 10 |
|||
" |
|||
> |
|||
<div |
|||
class="animate-ping w-4 h-4 p-1 bg-red-100 dark:bg-red-100 rounded-full absolute -bottom-1 -right-1" |
|||
></div> |
|||
<div |
|||
class="w-2 h-2 bg-red-800 dark:bg-red-600 rounded-full absolute bottom-0 right-0" |
|||
></div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
@ -1,30 +1,32 @@ |
|||
<!-- ClientNewButton.vue --> |
|||
<template> |
|||
<div class="flex flex-row flex-auto items-center p-3 px-5 border-b-2 border-gray-100 dark:border-neutral-600"> |
|||
<div class="flex-grow"> |
|||
<p class="text-2xl font-medium dark:text-neutral-200">Clients</p> |
|||
</div> |
|||
<div class="flex-shrink-0"> |
|||
<button |
|||
@click="createNewClient" |
|||
class="hover:bg-red-800 hover:border-red-800 hover:text-white text-gray-700 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-600 py-2 px-4 rounded inline-flex items-center transition" |
|||
> |
|||
<IconNew class="w-4 mr-2" /> |
|||
<span class="text-sm">New</span> |
|||
</button> |
|||
</div> |
|||
<div |
|||
class="flex flex-row flex-auto items-center p-3 px-5 border-b-2 border-gray-100 dark:border-neutral-600" |
|||
> |
|||
<div class="flex-grow"> |
|||
<p class="text-2xl font-medium dark:text-neutral-200">Clients</p> |
|||
</div> |
|||
<div class="flex-shrink-0"> |
|||
<button |
|||
@click="createNewClient" |
|||
class="hover:bg-red-800 hover:border-red-800 hover:text-white text-gray-700 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-600 py-2 px-4 rounded inline-flex items-center transition" |
|||
> |
|||
<IconNew class="w-4 mr-2" /> |
|||
<span class="text-sm">New</span> |
|||
</button> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import IconNew from './icons/IconNew.vue'; |
|||
|
|||
export default { |
|||
methods: { |
|||
createNewClient() { |
|||
this.$emit("create-new-client"); |
|||
}, |
|||
methods: { |
|||
createNewClient() { |
|||
this.$emit('create-new-client'); |
|||
}, |
|||
components: { IconNew } |
|||
}, |
|||
components: { IconNew }, |
|||
}; |
|||
</script> |
|||
|
|||
@ -1,13 +1,13 @@ |
|||
<template> |
|||
<span v-if="transferData" :title="title"> |
|||
· |
|||
<slot></slot> |
|||
{{ transferDataCurrent }}/s |
|||
</span> |
|||
<span v-if="transferData" :title="title"> |
|||
· |
|||
<slot></slot> |
|||
{{ transferDataCurrent }}/s |
|||
</span> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: ["transferData", "transferDataCurrent", "title"], |
|||
props: ['transferData', 'transferDataCurrent', 'title'], |
|||
}; |
|||
</script> |
|||
|
|||
@ -1,11 +1,11 @@ |
|||
<script> |
|||
import IconSpinnerVue from "./icons/IconSpinner.vue"; |
|||
import IconSpinnerVue from './icons/IconSpinner.vue'; |
|||
|
|||
export default { |
|||
components: { IconSpinnerVue } |
|||
components: { IconSpinnerVue }, |
|||
}; |
|||
</script> |
|||
|
|||
<template> |
|||
<IconSpinnerVue class="w-5 animate-spin mx-auto" /> |
|||
<IconSpinnerVue class="w-5 animate-spin mx-auto" /> |
|||
</template> |
|||
|
|||
@ -1,5 +1,13 @@ |
|||
<template> |
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"> |
|||
<path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd" /> |
|||
</svg> |
|||
<svg |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
viewBox="0 0 20 20" |
|||
fill="currentColor" |
|||
> |
|||
<path |
|||
fill-rule="evenodd" |
|||
d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" |
|||
clip-rule="evenodd" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
|
|||
@ -1,5 +1,16 @@ |
|||
<template> |
|||
<svg class="w-8" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
|||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> |
|||
</svg> |
|||
<svg |
|||
class="w-8" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
fill="none" |
|||
viewBox="0 0 24 24" |
|||
stroke="currentColor" |
|||
> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M6 18L18 6M6 6l12 12" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
|
|||
@ -1,9 +1,14 @@ |
|||
<template> |
|||
<svg class="w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"> |
|||
<path |
|||
fill-rule="evenodd" |
|||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" |
|||
clip-rule="evenodd" |
|||
/> |
|||
</svg> |
|||
<svg |
|||
class="w-5" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
viewBox="0 0 20 20" |
|||
fill="currentColor" |
|||
> |
|||
<path |
|||
fill-rule="evenodd" |
|||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" |
|||
clip-rule="evenodd" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
|
|||
@ -1,9 +1,14 @@ |
|||
<template> |
|||
<svg class="align-middle h-3 inline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"> |
|||
<path |
|||
fill-rule="evenodd" |
|||
d="M16.707 10.293a1 1 0 010 1.414l-6 6a1 1 0 01-1.414 0l-6-6a1 1 0 111.414-1.414L9 14.586V3a1 1 0 012 0v11.586l4.293-4.293a1 1 0 011.414 0z" |
|||
clip-rule="evenodd" |
|||
/> |
|||
</svg> |
|||
<svg |
|||
class="align-middle h-3 inline" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
viewBox="0 0 20 20" |
|||
fill="currentColor" |
|||
> |
|||
<path |
|||
fill-rule="evenodd" |
|||
d="M16.707 10.293a1 1 0 010 1.414l-6 6a1 1 0 01-1.414 0l-6-6a1 1 0 111.414-1.414L9 14.586V3a1 1 0 012 0v11.586l4.293-4.293a1 1 0 011.414 0z" |
|||
clip-rule="evenodd" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
|
|||
@ -1,10 +1,16 @@ |
|||
<template> |
|||
<svg class="w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" |
|||
/> |
|||
</svg> |
|||
<svg |
|||
class="w-5" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
fill="none" |
|||
viewBox="0 0 24 24" |
|||
stroke="currentColor" |
|||
> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
|
|||
@ -1,16 +1,16 @@ |
|||
<template> |
|||
<svg |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
class="h-4 w-4 inline align-middle opacity-25 hover:opacity-100" |
|||
fill="none" |
|||
viewBox="0 0 24 24" |
|||
stroke="currentColor" |
|||
> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" |
|||
/> |
|||
</svg> |
|||
<svg |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
class="h-4 w-4 inline align-middle opacity-25 hover:opacity-100" |
|||
fill="none" |
|||
viewBox="0 0 24 24" |
|||
stroke="currentColor" |
|||
> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
|
|||
@ -1,10 +1,16 @@ |
|||
<template> |
|||
<svg class="h-3 inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" |
|||
/> |
|||
</svg> |
|||
<svg |
|||
class="h-3 inline" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
fill="none" |
|||
viewBox="0 0 24 24" |
|||
stroke="currentColor" |
|||
> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
|
|||
@ -1,11 +1,16 @@ |
|||
<template> |
|||
<svg |
|||
inline |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
fill="none" |
|||
viewBox="0 0 24 24" |
|||
stroke="currentColor" |
|||
> |
|||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" /> |
|||
</svg> |
|||
<svg |
|||
inline |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
fill="none" |
|||
viewBox="0 0 24 24" |
|||
stroke="currentColor" |
|||
> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M12 6v6m0 0v6m0-6h6m-6 0H6" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
@ -1,10 +1,16 @@ |
|||
<template> |
|||
<svg class="w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z" |
|||
/> |
|||
</svg> |
|||
<svg |
|||
class="w-5" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
fill="none" |
|||
viewBox="0 0 24 24" |
|||
stroke="currentColor" |
|||
> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
|
|||
@ -1,10 +1,21 @@ |
|||
<template> |
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> |
|||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> |
|||
<path |
|||
class="opacity-75" |
|||
fill="currentColor" |
|||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" |
|||
></path> |
|||
</svg> |
|||
<svg |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
viewBox="0 0 24 24" |
|||
fill="currentColor" |
|||
> |
|||
<circle |
|||
class="opacity-25" |
|||
cx="12" |
|||
cy="12" |
|||
r="10" |
|||
stroke="currentColor" |
|||
stroke-width="4" |
|||
></circle> |
|||
<path |
|||
class="opacity-75" |
|||
fill="currentColor" |
|||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" |
|||
></path> |
|||
</svg> |
|||
</template> |
|||
|
|||
@ -1,9 +1,14 @@ |
|||
<template> |
|||
<svg class="align-middle h-3 inline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"> |
|||
<path |
|||
fill-rule="evenodd" |
|||
d="M3.293 9.707a1 1 0 010-1.414l6-6a1 1 0 011.414 0l6 6a1 1 0 01-1.414 1.414L11 5.414V17a1 1 0 11-2 0V5.414L4.707 9.707a1 1 0 01-1.414 0z" |
|||
clip-rule="evenodd" |
|||
/> |
|||
</svg> |
|||
<svg |
|||
class="align-middle h-3 inline" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
viewBox="0 0 20 20" |
|||
fill="currentColor" |
|||
> |
|||
<path |
|||
fill-rule="evenodd" |
|||
d="M3.293 9.707a1 1 0 010-1.414l6-6a1 1 0 011.414 0l6 6a1 1 0 01-1.414 1.414L11 5.414V17a1 1 0 11-2 0V5.414L4.707 9.707a1 1 0 01-1.414 0z" |
|||
clip-rule="evenodd" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
@ -1,17 +1,17 @@ |
|||
<template> |
|||
<svg |
|||
class="h-6 w-6 text-red-600" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
fill="none" |
|||
viewBox="0 0 24 24" |
|||
stroke="currentColor" |
|||
aria-hidden="true" |
|||
> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" |
|||
/> |
|||
</svg> |
|||
<svg |
|||
class="h-6 w-6 text-red-600" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
fill="none" |
|||
viewBox="0 0 24 24" |
|||
stroke="currentColor" |
|||
aria-hidden="true" |
|||
> |
|||
<path |
|||
stroke-linecap="round" |
|||
stroke-linejoin="round" |
|||
stroke-width="2" |
|||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" |
|||
/> |
|||
</svg> |
|||
</template> |
|||
|
|||
@ -1,13 +1,13 @@ |
|||
export function useDateTime() { |
|||
const dateTime = (value) => { |
|||
return new Intl.DateTimeFormat(undefined, { |
|||
year: "numeric", |
|||
month: "short", |
|||
day: "numeric", |
|||
hour: "numeric", |
|||
minute: "numeric", |
|||
}).format(value); |
|||
}; |
|||
const dateTime = (value) => { |
|||
return new Intl.DateTimeFormat(undefined, { |
|||
year: 'numeric', |
|||
month: 'short', |
|||
day: 'numeric', |
|||
hour: 'numeric', |
|||
minute: 'numeric', |
|||
}).format(value); |
|||
}; |
|||
|
|||
return { dateTime }; |
|||
return { dateTime }; |
|||
} |
|||
|
|||
@ -1,29 +1,29 @@ |
|||
export function useTimeAgo() { |
|||
const timeago = (date) => { |
|||
const now = new Date(); |
|||
const diff = now - date; |
|||
const timeago = (date) => { |
|||
const now = new Date(); |
|||
const diff = now - date; |
|||
|
|||
if (diff < 1000) { |
|||
return "just now"; |
|||
} else if (diff < 60000) { |
|||
const seconds = Math.floor(diff / 1000); |
|||
return `${seconds} ${plural("second", seconds)} ago`; |
|||
} else if (diff < 3600000) { |
|||
const minutes = Math.floor(diff / 60000); |
|||
return `${minutes} ${plural("minute", minutes)} ago`; |
|||
} else if (diff < 86400000) { |
|||
const hours = Math.floor(diff / 3600000); |
|||
return `${hours} ${plural("hour", hours)} ago`; |
|||
} else { |
|||
const days = Math.floor(diff / 86400000); |
|||
return `${days} ${plural("day", days)} ago`; |
|||
} |
|||
}; |
|||
if (diff < 1000) { |
|||
return 'just now'; |
|||
} else if (diff < 60000) { |
|||
const seconds = Math.floor(diff / 1000); |
|||
return `${seconds} ${plural('second', seconds)} ago`; |
|||
} else if (diff < 3600000) { |
|||
const minutes = Math.floor(diff / 60000); |
|||
return `${minutes} ${plural('minute', minutes)} ago`; |
|||
} else if (diff < 86400000) { |
|||
const hours = Math.floor(diff / 3600000); |
|||
return `${hours} ${plural('hour', hours)} ago`; |
|||
} else { |
|||
const days = Math.floor(diff / 86400000); |
|||
return `${days} ${plural('day', days)} ago`; |
|||
} |
|||
}; |
|||
|
|||
// #278 -- this function might need to be rewritten to support l18n
|
|||
const plural = (word, count) => { |
|||
return count !== 1 ? `${word}s` : word; |
|||
}; |
|||
// #278 -- this function might need to be rewritten to support l18n
|
|||
const plural = (word, count) => { |
|||
return count !== 1 ? `${word}s` : word; |
|||
}; |
|||
|
|||
return { timeago }; |
|||
return { timeago }; |
|||
} |
|||
|
|||
@ -1,6 +1,6 @@ |
|||
import './assets/style.css' |
|||
import './assets/style.css'; |
|||
|
|||
import { createApp } from 'vue' |
|||
import App from './App.vue' |
|||
import App from './App.vue'; |
|||
import { createApp } from 'vue'; |
|||
|
|||
createApp(App).mount('#app') |
|||
createApp(App).mount('#app'); |
|||
|
|||
Loading…
Reference in new issue