+ Registered Users

+ UsersList Online
This commit is contained in:
Surya Paolo
2022-12-10 02:01:26 +01:00
parent aeeba5a6b9
commit cd31d2d020
18 changed files with 364 additions and 72 deletions

View File

@@ -0,0 +1,34 @@
.my-card-stat {
width: 100%;
max-width: 200px;
min-width: 120px;
padding: 1rem 1rem;
@media (max-width: 718px) {
// PER VERSIONE MOBILE
max-width: 150px;
padding: 0;
}
box-shadow: none;
}
.my-card-small-stat {
width: 100%;
max-width: 60px;
min-width: 40px;
@media (max-width: 718px) {
// PER VERSIONE MOBILE
max-width: 50px;
min-width: 40px;
}
box-shadow: none;
}
.text-h5-short {
line-height: 1.25rem !important;
@media (max-width: 718px) {
line-height: 1rem !important;
}
}

View File

@@ -0,0 +1,23 @@
import { defineComponent } from 'vue'
import { tools } from '@store/Modules/tools'
export default defineComponent({
name: 'CElemStat',
props: {
title: String,
icon: String,
value_today: Number,
mytextval: Number,
classColor: String,
colBack: String,
mystyle: String,
},
components: {},
setup(props) {
return {
tools
}
},
})

View File

@@ -0,0 +1,37 @@
<template>
<q-card :class="` text-center`" :style="mystyle">
<div
:class="`column q-pa-sm text-center align-center ` + classColor"
style="align-items: center"
>
<div class="elem text-h6">
{{ title }}
</div>
<q-icon :name="icon" size="xl" :class="classColor + ` elem `" />
<div>
<div>
</div>
</div>
<div
class="elem full-width elem-value text-h5 boldhigh"
>
{{ mytextval }}
<q-badge
v-if="value_today > 0"
align="top"
:label="`+` + value_today + ` oggi`"
:color="colBack"
>
</q-badge>
</div>
</div>
</q-card>
</template>
<script lang="ts" src="./CElemStat.ts">
</script>
<style lang="scss" scoped>
@import './CElemStat.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as CElemStat} from './CElemStat.vue'

View File

@@ -1165,6 +1165,7 @@ export default defineComponent({
username: 1,
name: 1,
surname: 1,
lasttimeonline: 1,
comune: 1,
mycities: 1,
'profile.img': 1,
@@ -1233,6 +1234,7 @@ export default defineComponent({
username: 1,
name: 1,
surname: 1,
lasttimeonline: 1,
comune: 1,
mycities: 1,
'profile.img': 1,
@@ -1303,6 +1305,7 @@ export default defineComponent({
username: 1,
name: 1,
surname: 1,
lasttimeonline: 1,
comune: 1,
mycities: 1,
'profile.img': 1,
@@ -1350,6 +1353,7 @@ export default defineComponent({
username: 1,
name: 1,
surname: 1,
lasttimeonline: 1,
comune: 1,
mycities: 1,
'profile.img': 1,

View File

@@ -28,6 +28,7 @@ import MixinBase from '@/mixins/mixin-base'
import MixinUsers from '@/mixins/mixin-users'
import { toolsext } from '@store/Modules/toolsext'
import { shared_consts } from '@/common/shared_vuejs'
import { useRouter } from 'vue-router'
export default defineComponent({
@@ -222,6 +223,8 @@ export default defineComponent({
const myImgGall = ref([{}] as IImgGallery[])
const $router = useRouter()
const col = ref(<IColGridTable>{
name: 'test',
fieldtype: 0,
@@ -770,6 +773,10 @@ export default defineComponent({
}
function gotoPage(link: string) {
$router.push(link)
}
function nameKeydown(e: any, col: any) {
if (col.allowchar === costanti.ALLOWCHAR_CODE) {
@@ -817,6 +824,7 @@ export default defineComponent({
myrow,
shared_consts,
nameKeydown,
gotoPage,
}
}
})

View File

@@ -80,17 +80,54 @@
</div>
</div>
<div v-else-if="col.fieldtype === costanti.FieldType.username_chip">
<div class="q-ma-xs">
<div class="q-ma-xs chip_shadow">
<span v-if="col.extrafield">
<span class="extrafield">{{ $t(col.extrafield) }}</span>
</span>
<div
v-if="
(col.tipovisu === costanti.TipoVisu.LINK ||
col.tipovisu === costanti.TipoVisu.NONE) &&
myvalue
"
class="q-pa-xs full-width justify-"
>
<q-item
clickable
v-ripple
@click="
gotoPage(
col.link
? col.link.replace(col.name, myvalue)
: `/my/username`.replace(col.name, myvalue)
)
"
>
<q-item-section avatar>
<q-avatar round size="48px">
<img :src="userStore.getImgUserByUsername(myvalue)" />
<q-badge v-if="tools.isUserOnline(row)" align="top" floating color="green">online</q-badge>
</q-avatar>
</q-item-section>
<q-item-section class="">
<q-item-label>{{ tools.getNameToShow(row) }}</q-item-label>
<q-item-label caption>{{
tools.getUserNameOnlyIfToShow(row)
}}</q-item-label>
</q-item-section>
<q-item-section side></q-item-section>
</q-item>
</div>
<!--
<q-btn
v-if="
(col.tipovisu === costanti.TipoVisu.LINK ||
col.tipovisu === costanti.TipoVisu.NONE) &&
myvalue
"
glossy
rounded
size="md"
:class="{ disabled: disable }"
@@ -102,9 +139,9 @@
? col.link.replace(col.name, myvalue)
: `/my/username`.replace(col.name, myvalue)
"
:label="myvalue"
:label="tools.getNameToShow(row)"
>
</q-btn>
</q-btn>-->
<q-avatar
v-else-if="
col.tipovisu === costanti.TipoVisu.LINKIMG && myvalue

View File

@@ -57,7 +57,7 @@ export default defineComponent({
const col_footer = ref('')
const col_tabfooter = ref('')
const extraparams = computed(() =>{
const extraparams = computed(() => {
if (props.table === 'goods')
return extraparams_Goods()
else
@@ -119,6 +119,7 @@ export default defineComponent({
username: 1,
name: 1,
surname: 1,
lasttimeonline: 1,
comune: 1,
mycities: 1,
'profile.img': 1,
@@ -155,8 +156,8 @@ export default defineComponent({
comune: 1,
userId: 1,
username: 1,
name: 1,
surname: 1,
lasttimeonline: 1,
mycities: 1,
'profile.img': 1,
'profile.mygroups': 1,
@@ -190,9 +191,9 @@ export default defineComponent({
date_created: 1,
date_updated: 1,
userId: 1,
username: 1,
name: 1,
surname: 1,
lasttimeonline: 1,
comune: 1,
mycities: 1,
'profile.img': 1,
@@ -251,10 +252,10 @@ export default defineComponent({
descr: 1,
date_created: 1,
date_updated: 1,
userId: 1,
surname: 1,
lasttimeonline: 1,
username: 1,
name: 1,
surname: 1,
comune: 1,
mycities: 1,
'profile.img': 1,
@@ -333,6 +334,7 @@ export default defineComponent({
username: 1,
name: 1,
surname: 1,
lasttimeonline: 1,
comune: 1,
mycities: 1,
'profile.img': 1,

View File

@@ -8,6 +8,7 @@ import MixinBase from '@src/mixins/mixin-base'
import { CTitleBanner } from '@/components/CTitleBanner'
import { CCardState } from '../CCardState'
import { CMyFieldRec } from '../CMyFieldRec'
import { CElemStat } from '../CElemStat'
import { CCardStat } from '../CCardStat'
import { CLineChart } from '@/components/CLineChart'
@@ -21,11 +22,13 @@ import { useGlobalStore } from '@store/globalStore'
import { useUserStore } from '@store/UserStore'
import { useI18n } from '@/boot/i18n'
import { useQuasar } from 'quasar'
import { useRouter } from 'vue-router'
export default defineComponent({
name: 'CStatusReg',
props: {},
components: { CTitleBanner, CCardState, CCardStat, CLineChart, CMyFieldRec },
components: { CTitleBanner, CElemStat,
CCardState, CCardStat, CLineChart, CMyFieldRec },
setup(props, { attrs, slots, emit }) {
const { t } = useI18n()
const $q = useQuasar()
@@ -40,8 +43,13 @@ export default defineComponent({
const polling = ref(<any>null)
const numpolled = ref(0)
const mytab = ref('reg')
const $router = useRouter()
const datastat = ref(<any>{
num_reg: 0,
num_reg_today: 0,
online_today: 0,
num_passeggeri: 0,
num_imbarcati: 0,
@@ -51,6 +59,7 @@ export default defineComponent({
email_non_verif: 0,
num_teleg_pending: 0,
lastsreg: [],
lastsonline: [],
checkuser: { verified_email: false }
})
@@ -69,6 +78,9 @@ export default defineComponent({
const lastsreg = computed(() => {
return datastat.value.lastsreg
})
const lastsonline = computed(() => {
return datastat.value.lastsonline
})
watch(() => $q.appVisible, (value: any, oldval: any) => {
// console.log('visible', value)
@@ -165,6 +177,14 @@ export default defineComponent({
return 0
}
function getImgUserByUsername(username: string) {
return userStore.getImgUserByUsername(username)
}
function gotoPage(link: string) {
$router.push(link)
}
created()
onBeforeUnmount(beforeDestroy)
@@ -176,9 +196,13 @@ export default defineComponent({
telegnonattivi,
emailnonverif,
lastsreg,
lastsonline,
datastat,
tools,
costanti,
mytab,
getImgUserByUsername,
gotoPage,
}
}

View File

@@ -1,25 +1,44 @@
<template>
<div>
<div v-if="visustat">
<CTitleBanner class="q-pa-xs" :title="$t('pages.status')" bgcolor="bg-primary" clcolor="text-white"
mystyle="" myclass="myshad" :canopen="true">
<CTitleBanner
class="q-pa-xs"
:title="$t('pages.status')"
bgcolor="bg-primary"
clcolor="text-white"
mystyle=""
myclass="myshad"
:canopen="true"
>
<div class="flex flex-center">
<CElemStat
:title="$t('pages.statusreg.reg')"
icon="fas fa-users"
:value_today="datastat.num_reg_today"
:mytextval="datastat.num_reg"
classColor="text-blue"
colBack="green"
>
</CElemStat>
<CCardState :mytext="$t('pages.statusreg.reg')" :myval="datastat.num_teleg_attivo"
mycolor="blue"
:myperc="(datastat.num_teleg_attivo / datastat.num_reg) * 100"></CCardState>
<CCardState :mytext="$t('pages.statusreg.online_today')" :myval="datastat.online_today"
mycolor="green" :myperc="(datastat.online_today / datastat.num_reg) * 100"></CCardState>
<CElemStat
:title="$t('pages.statusreg.online_today')"
icon="fas fa-wifi"
:mytextval="datastat.online_today"
classColor="text-green"
colBack="red"
>
</CElemStat>
<!--<CCardState :mytext="$t('pages.statusreg.autorizzare')" :myval="datastat.num_autorizzare"
mycolor="yellow" :myperc="(datastat.num_autorizzare / datastat.num_teleg_attivo) * 100"></CCardState>
-->
<div class="q-pa-xs" v-if="datastat.num_part_accepted > 1">
<CCardStat :mytext="$t('stat.accepted')" :myval="datastat.num_part_accepted"></CCardStat>
<CCardStat
:mytext="$t('stat.accepted')"
:myval="datastat.num_part_accepted"
></CCardStat>
<!--<CCardStat :mytext="$t('stat.modalita_pagamento')"
:myval="datastat.num_modalita_pagamento"></CCardStat>-->
<!--<CCardStat :mytext="$t('stat.requisiti')" :myval="datastat.num_requisiti"></CCardStat>-->
@@ -34,49 +53,96 @@
</div>
<div class="column animazione">
<div class="text-center">{{$t('pages.statusreg.newreg')}}</div>
<transition-group name="fade" mode="out-in"
appear
enter-active-class="animazione fadeIn"
leave-active-class="animazione fadeOut">
<q-tabs v-model="mytab" class="text-blue">
<q-tab name="reg" :label="$t('pages.statusreg.newreg')" />
<q-tab name="online" :label="$t('pages.statusreg.onlineusers')" />
</q-tabs>
<q-item v-for="(user, index) in lastsreg" :key="index" class="q-mb-xs animated"
v-ripple>
<q-tab-panels v-model="mytab" animated>
<q-tab-panel name="reg">
<transition-group
name="fade"
mode="out-in"
appear
enter-active-class="animazione fadeIn"
leave-active-class="animazione fadeOut"
>
<q-item
v-for="(user, index) in lastsreg"
:key="index"
class="animated"
v-ripple
>
<q-item-section>
<q-item-label lines="1">
<CMyFieldRec
table="users"
:id="user._id"
:rec="user"
field="username"
:canEdit="false"
:canModify="false"
:fieldtype="costanti.FieldType.username_chip"
>
</CMyFieldRec>
</q-item-label>
</q-item-section>
<!--
<q-item-section avatar>
<q-avatar v-if="tools.geticon(user.profile.nationality)"
:class="tools.geticon(user.profile.nationality)">
</q-avatar>
<q-avatar v-else color="primary" text-color="white" class="text-center">
{{ tools.capitalize(user.profile.nationality) }}
</q-avatar>
</q-item-section>-->
<q-item-section>
<q-item-label lines="1">
<CMyFieldRec
table="users"
:id="user._id"
:rec="user"
field="username"
:canEdit="false"
:canModify="false"
:fieldtype="costanti.FieldType.username_chip">
</CMyFieldRec>
</q-item-label>
</q-item-section>
<q-item-section side>
<q-item-label>{{ tools.getstrDateTimeShort(user.date_reg) }}</q-item-label>
<q-chip outline color="green" text-color="white" icon-right="fas fa-user-plus"
size="xs"></q-chip>
</q-item-section>
</q-item>
</transition-group>
<q-item-section side>
<q-item-label>{{
tools.getstrDateTimeShort(user.date_reg)
}}</q-item-label>
</q-item-section>
</q-item>
</transition-group>
</q-tab-panel>
<q-tab-panel name="online">
<div class="q-pa-md" style="max-width: 300px">
<q-list bordered>
<transition-group
name="fade"
mode="out-in"
appear
enter-active-class="animazione fadeIn"
leave-active-class="animazione fadeOut"
>
<q-item
v-for="(user, index) in lastsonline"
:key="index"
class="animated chip_shadow q-ma-sm"
clickable
v-ripple
@click="gotoPage(`/my/${user.username}`)"
>
<q-item-section avatar>
<q-avatar round size="48px">
<img :src="getImgUserByUsername(user.username)" />
<q-badge
v-if="tools.isUserOnline(user)"
align="top"
floating
color="green"
>online</q-badge
>
</q-avatar>
</q-item-section>
<q-item-section class="">
<q-item-label>{{
tools.getNameToShow(user)
}}</q-item-label>
<q-item-label caption>{{
tools.getUserNameOnlyIfToShow(user)
}}</q-item-label>
</q-item-section>
<q-item-section side>{{
tools.timeAgo(user.lasttimeonline)
}}</q-item-section>
</q-item>
</transition-group>
</q-list>
</div>
</q-tab-panel>
</q-tab-panels>
</div>
<!--<CGeoChart :mydata="datastat.arr_nations">
@@ -91,15 +157,19 @@
</CListNationality>
</div>-->
<div class="clBorderTutor">
<CLineChart :mydata="datastat.reg_daily" :title="$t('stat.reg_daily')" color="blue" bordercolor="blue" :sum="true">
<CLineChart
:mydata="datastat.reg_daily"
:title="$t('stat.reg_daily')"
color="blue"
bordercolor="blue"
:sum="true"
>
</CLineChart>
<!--<CLineChart :mydata="datastat.reg_weekly" :title="$t('stat.reg_weekly')" color="blue" bordercolor="green" :sum="true">
</CLineChart>-->
<!--<CLineChart :mydata="datastat.reg_daily" :title="$t('stat.reg_total')"
:offset="datastat.numreg_untilday" :sum="true"
:mycolors="['#0b0', '#666']">
@@ -117,5 +187,5 @@
</script>
<style lang="scss" scoped>
@import './CStatusReg.scss';
@import './CStatusReg.scss';
</style>

View File

@@ -52,7 +52,7 @@
<q-avatar @click="toHome" class="imglink">
<img :src="imglogo()" height="27" alt="Immagine Logo" />
</q-avatar>
<div class="q-mx-sm titlesite">{{ getappname() }}</div>
<div v-if="$q.screen.gt.xs" class="q-mx-sm titlesite">{{ getappname() }}</div>
</q-toolbar-title>
<!--

View File

@@ -1301,6 +1301,13 @@ h3 {
background: linear-gradient(45deg, #17ead9, #6078ea) !important;
}
.chip_shadow {
border-radius: 20px;
background: #1729ea;
background: -webkit-linear-gradient(45deg, #17ead9, #6078ea) !important;
background: linear-gradient(45deg, #17ead9, #6078ea) !important;
}
.duration-2s {
transition-duration: 5s !important;
}
@@ -1519,3 +1526,7 @@ h3 {
.semi-transparent {
opacity: 0.7;
}
.elem {
padding: 0;
}

View File

@@ -99,7 +99,8 @@ const msg_website_it = {
autorizzare: 'In attesa di Abilitazione',
passeggeri: 'Passeggeri Navi',
giainlista: 'Gia in Lista',
newreg: 'Ultime Registrazioni:',
newreg: 'Ultimi Registrati',
onlineusers: 'Utenti OnLine',
nationality: 'Nazionalità',
nationality_born: 'Nazione di Nascita',
verified: 'Verificata',

View File

@@ -18,6 +18,7 @@ export interface ICheckUser {
export interface INotData {
num_reg?: number
num_reg_today?: number
online_today?: number
num_passeggeri?: number
num_imbarcati?: number
@@ -31,6 +32,7 @@ export interface INotData {
num_modalita_pagamento?: number
arr_nations?: string
lastsreg?: IUserFields[]
lastsonline?: IUserFields[]
checkuser?: ICheckUser | any
numreg_untilday?: number
reg_daily?: string

View File

@@ -65,6 +65,7 @@ export const tools = {
FILTER_MYFOLLOW: 2,
COOK_SEARCH: 'SEARCH_',
COOK_TAB_CIRCUIT: 'TAB_CIRC',
FRIENDS_SEARCH: 'FR_SE',
GROUP_SEARCH: 'GR_SE',
@@ -2768,6 +2769,7 @@ export const tools = {
// Metti come default
userStore.setlang($q, $router, mylang)
}
}
if (!mylang) {
@@ -3612,6 +3614,11 @@ export const tools = {
return date.addToDate(mydate, { days })
},
isUserOnline(user: IUserFields) {
const dateonline = tools.addDays(tools.getDateNow(), -1)
return user.lasttimeonline && new Date(user.lasttimeonline).getTime() > dateonline.getTime()
},
addMinutes(mydate: Date, minutes: number) {
return date.addToDate(mydate, { minutes })
},
@@ -7337,6 +7344,23 @@ export const tools = {
return ''
},
getNameToShow(user: IUserFields): string {
const userStore = useUserStore()
let name = userStore.getNameToShow(user)
return name
},
getUserNameOnlyIfToShow(user: IUserFields): string {
const userStore = useUserStore()
let name = userStore.getUserNameOnlyIfToShow(user)
return name
},
getoptionsMainCards(only: boolean) {
let myarr = []
let obj = { label: '', value: '', icon: '' }

View File

@@ -273,7 +273,6 @@ export const useUserStore = defineStore('UserStore', {
return (trovato) || null
},
getImgByUsername(username: string): string {
if (username === '') return ''
// Check if is this User!
@@ -441,6 +440,15 @@ export const useUserStore = defineStore('UserStore', {
return name
},
getUserNameOnlyIfToShow(user: IUserFields): string {
if (user.name || user.surname) {
return user.username
}
return ''
},
getUserByUserId(userId: string): IUserFields | null {
// Check if is this User!
if (this.my._id === userId) return this.my

View File

@@ -63,7 +63,7 @@ export default defineComponent({
const loading = ref(false)
const requestToEnterCircuit = ref(false)
const tabgrp = ref('info')
const tabcircuit = ref('info')
const tabmembers = ref('all')
const showsaldi = ref(false)
const tab = ref('membri')
@@ -81,12 +81,18 @@ export default defineComponent({
loadCircuit()
})
watch(() => tabcircuit.value, (to: any, from: any) => {
tools.setCookie(tools.COOK_TAB_CIRCUIT + path.value, tabcircuit.value)
})
function profile() {
return userStore.my.profile
}
async function loadCircuit() {
tabcircuit.value = tools.getCookie(tools.COOK_TAB_CIRCUIT + path.value, 'info')
loading.value = true
// Carica il profilo di quest'utente
if (path.value) {
@@ -318,7 +324,7 @@ export default defineComponent({
extraparams_refused,
extraparams_movs,
tab,
tabgrp,
tabcircuit,
tabmembers,
numUsers,
numAdmins,

View File

@@ -194,7 +194,7 @@
v-if="circuit.name"
class="no-wrap justify-evenly items-center content-start"
>
<q-tabs v-model="tabgrp" class="text-blue">
<q-tabs v-model="tabcircuit" class="text-blue">
<q-tab
:label="t('shared.info1')"
name="info"
@@ -223,7 +223,7 @@
></q-tab>
</q-tabs>
<q-tab-panels v-model="tabgrp" animated>
<q-tab-panels v-model="tabcircuit" animated>
<q-tab-panel name="mov">
<q-toggle
v-model="showonlymine"