display nb paid user on SIWSL app
This commit is contained in:
parent
8bafdfc879
commit
befec56a86
|
@ -53,54 +53,40 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row row-cards row-deck mt-4">
|
<div class="row row-cards row-deck mt-4">
|
||||||
{% for client in clients %}
|
{% for client in clients %}
|
||||||
<div class="col-md-6">
|
<div class="col-12 col-lg-6">
|
||||||
<div class="card">
|
<div class="card" style="">
|
||||||
<div class="card-header">
|
<div class="card-body">
|
||||||
<div class="card-title d-flex align-items-center">
|
<h5 class="card-title">
|
||||||
{% if client.icon_id %}
|
<a href="{{ url_for('developer.client_detail', client_id=client.id) }}">{{ client.name }}</a>
|
||||||
<span class="avatar mr-2" style="background-image: url({{ client.icon.get_url() }})"></span>
|
|
||||||
{% endif %}
|
|
||||||
<span class="">
|
|
||||||
<a href="{{ url_for('developer.client_detail', client_id=client.id) }}">
|
|
||||||
{{ client.name }}
|
|
||||||
</a>
|
|
||||||
{% if client.approved %}
|
{% if client.approved %}
|
||||||
<span class="cursor" data-toggle="tooltip" data-original-title="Approved">✅</span>
|
<span class="cursor" data-toggle="tooltip" data-original-title="Approved">✅</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="cursor" data-toggle="tooltip" data-original-title="In Dev mode">
|
<span class="cursor" data-toggle="tooltip"
|
||||||
|
data-original-title="In Dev mode. Please contact us to publish your app.">
|
||||||
<a href="{{ url_for('developer.client_detail', client_id=client.id) }}"
|
<a href="{{ url_for('developer.client_detail', client_id=client.id) }}"
|
||||||
class="text-decoration-none">🚫
|
class="text-decoration-none">🚫
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
</h5>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-options">
|
<h6 class="card-subtitle mb-4 text-muted">
|
||||||
<a href="{{ url_for('developer.client_detail', client_id=client.id) }}"
|
Created {{ client.created_at | dt }} <br>
|
||||||
class="btn btn-primary btn-sm">
|
<span class="font-weight-bold">{{ client.nb_user() }}</span> users.
|
||||||
Edit
|
<span class="font-weight-bold">{{ client.nb_paid_user() }}</span> paid users.
|
||||||
|
<br>
|
||||||
|
</h6>
|
||||||
|
|
||||||
|
<a href="{{ url_for('developer.client_detail', client_id=client.id) }}" class="mt-3">
|
||||||
|
Details ➡
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
<span class="h1 m-0">{{ client.nb_user() }}</span> Users <br>
|
|
||||||
Created {{ client.created_at |dt }} <br>
|
|
||||||
{% if client.last_user_login() %}
|
|
||||||
Last User Login: {{ client.last_user_login().get_user_name() }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ from sqlalchemy import orm
|
||||||
from sqlalchemy import text, desc, CheckConstraint, Index, Column
|
from sqlalchemy import text, desc, CheckConstraint, Index, Column
|
||||||
from sqlalchemy.dialects.postgresql import TSVECTOR
|
from sqlalchemy.dialects.postgresql import TSVECTOR
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.orm import deferred
|
from sqlalchemy.orm import deferred, joinedload
|
||||||
from sqlalchemy_utils import ArrowType
|
from sqlalchemy_utils import ArrowType
|
||||||
|
|
||||||
from app import s3
|
from app import s3
|
||||||
|
@ -991,6 +991,20 @@ class Client(Base, ModelMixin):
|
||||||
def nb_user(self):
|
def nb_user(self):
|
||||||
return ClientUser.filter_by(client_id=self.id).count()
|
return ClientUser.filter_by(client_id=self.id).count()
|
||||||
|
|
||||||
|
def nb_paid_user(self) -> int:
|
||||||
|
res = 0
|
||||||
|
for client_user in (
|
||||||
|
Session.query(ClientUser)
|
||||||
|
.options(joinedload(ClientUser.user))
|
||||||
|
.filter_by(client_id=self.id)
|
||||||
|
.all()
|
||||||
|
):
|
||||||
|
user = client_user.user
|
||||||
|
if user.is_paid():
|
||||||
|
res += 1
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
def get_scopes(self) -> [Scope]:
|
def get_scopes(self) -> [Scope]:
|
||||||
# todo: client can choose which scopes they want to have access
|
# todo: client can choose which scopes they want to have access
|
||||||
return [Scope.NAME, Scope.EMAIL, Scope.AVATAR_URL]
|
return [Scope.NAME, Scope.EMAIL, Scope.AVATAR_URL]
|
||||||
|
|
Loading…
Reference in a new issue