feat: display teamers' average ratings in several locations
This commit is contained in:
@@ -496,6 +496,23 @@ class Teamer implements TimestampableEntityInterface
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAverageRating(): ?int
|
||||||
|
{
|
||||||
|
$feedbackCount = $this->getFeedback()->count();
|
||||||
|
|
||||||
|
if (0 === $feedbackCount) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sum = 0;
|
||||||
|
|
||||||
|
foreach ($this->getFeedback() as $feedback) {
|
||||||
|
$sum += $feedback->getAverageRating();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sum / $feedbackCount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection<int, TrainingAttendance>
|
* @return Collection<int, TrainingAttendance>
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -69,8 +69,9 @@ class ApplicationRepository extends ServiceEntityRepository
|
|||||||
$qb = $this->createQueryBuilder('application');
|
$qb = $this->createQueryBuilder('application');
|
||||||
|
|
||||||
return $qb
|
return $qb
|
||||||
->select('application', 'teamer')
|
->select('application', 'teamer', 'feedback')
|
||||||
->innerJoin('application.teamer', 'teamer')
|
->innerJoin('application.teamer', 'teamer')
|
||||||
|
->leftJoin('teamer.feedback', 'feedback')
|
||||||
->where($qb->expr()->andX(
|
->where($qb->expr()->andX(
|
||||||
$qb->expr()->eq('application.assignment', ':assignment'),
|
$qb->expr()->eq('application.assignment', ':assignment'),
|
||||||
$qb->expr()->neq('application.status', ':status')
|
$qb->expr()->neq('application.status', ':status')
|
||||||
|
|||||||
@@ -96,8 +96,9 @@ class DispositionRepository extends ServiceEntityRepository
|
|||||||
$qb = $this->createQueryBuilder('disposition');
|
$qb = $this->createQueryBuilder('disposition');
|
||||||
|
|
||||||
return $qb
|
return $qb
|
||||||
->select('disposition', 'teamer')
|
->select('disposition', 'teamer', 'feedback')
|
||||||
->innerJoin('disposition.teamer', 'teamer')
|
->innerJoin('disposition.teamer', 'teamer')
|
||||||
|
->leftJoin('teamer.feedback', 'feedback')
|
||||||
->where($qb->expr()->eq('disposition.assignment', ':assignment'))
|
->where($qb->expr()->eq('disposition.assignment', ':assignment'))
|
||||||
->setParameter('assignment', $assignment)
|
->setParameter('assignment', $assignment)
|
||||||
->getQuery()
|
->getQuery()
|
||||||
|
|||||||
@@ -32,10 +32,11 @@ class TeamerRepository extends ServiceEntityRepository
|
|||||||
$qb = $this->createQueryBuilder('teamer');
|
$qb = $this->createQueryBuilder('teamer');
|
||||||
|
|
||||||
$qb
|
$qb
|
||||||
->select('teamer', 'user')
|
->select('teamer', 'user', 'feedback')
|
||||||
->leftJoin('teamer.availabilities', 'availability')
|
->leftJoin('teamer.availabilities', 'availability')
|
||||||
->leftJoin('teamer.jobProfiles', 'job_profile')
|
->leftJoin('teamer.jobProfiles', 'job_profile')
|
||||||
->leftJoin('teamer.licenses', 'license')
|
->leftJoin('teamer.licenses', 'license')
|
||||||
|
->leftJoin('teamer.feedback', 'feedback')
|
||||||
->leftJoin('teamer.user', 'user')
|
->leftJoin('teamer.user', 'user')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -89,8 +89,12 @@ class AppRuntime implements RuntimeExtensionInterface
|
|||||||
return $this->intlExtension->formatCurrency($amount, 'EUR');
|
return $this->intlExtension->formatCurrency($amount, 'EUR');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function formatRating(int $rating): string
|
public function formatRating(?int $rating): string
|
||||||
{
|
{
|
||||||
|
if (null === $rating) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
|
||||||
// Ratings are stored as integers so divide by 100 first
|
// Ratings are stored as integers so divide by 100 first
|
||||||
$rating = $rating / 100;
|
$rating = $rating / 100;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{% set averageRating = teamer.averageRating %}
|
||||||
|
<div class="inline-flex items-center"{% if teamer.averageRating %}{{ stimulus_controller('tooltip', { content: averageRating|format_rating|raw, placement: 'top' }) }}{% endif %}>
|
||||||
|
{% for grade in range(1, 6) %}
|
||||||
|
{{ icon('star', html_classes('w-3 h-3', { 'text-gray-200': averageRating < grade * 100, 'text-primary': averageRating >= grade * 100 })) }}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
@@ -134,6 +134,7 @@
|
|||||||
<span>{{ disposition.teamer }}</span>
|
<span>{{ disposition.teamer }}</span>
|
||||||
{{ icon('info', 'w-4 h-4') }}
|
{{ icon('info', 'w-4 h-4') }}
|
||||||
</button>
|
</button>
|
||||||
|
{% include '_partials/_rating_stars.html.twig' with { 'teamer': disposition.teamer } %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ disposition.remarks|nl2br|default('-') }}
|
{{ disposition.remarks|nl2br|default('-') }}
|
||||||
|
|||||||
@@ -59,15 +59,18 @@
|
|||||||
{% for teamer in pagination %}
|
{% for teamer in pagination %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{% if teamer.photo %}
|
<div class="flex flex-col items-center space-y-2">
|
||||||
<img src="{{ asset(teamer.photo.filename | imagine_filter('profile')) }}"
|
{% if teamer.photo %}
|
||||||
class="w-12 h-auto rounded-full"
|
<img src="{{ asset(teamer.photo.filename | imagine_filter('profile')) }}"
|
||||||
alt="{{ teamer.firstName }}">
|
class="w-12 h-auto rounded-full"
|
||||||
{% else %}
|
alt="{{ teamer.firstName }}">
|
||||||
<div class="flex flex-col items-center justify-center w-12 h-12 border-2 border-gray-200 rounded-full">
|
{% else %}
|
||||||
{{ icon('user', 'w-10 h-10 text-gray-200') }}
|
<div class="flex flex-col items-center justify-center w-12 h-12 border-2 border-gray-200 rounded-full">
|
||||||
</div>
|
{{ icon('user', 'w-10 h-10 text-gray-200') }}
|
||||||
{% endif %}
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% include '_partials/_rating_stars.html.twig' with { 'teamer': teamer } %}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ path('app_admin_teamer_profile', { 'uuid': teamer.uuid }) }}">
|
<a href="{{ path('app_admin_teamer_profile', { 'uuid': teamer.uuid }) }}">
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="flex flex-col space-y-4">
|
||||||
{% if teamer.photo %}
|
{% if teamer.photo %}
|
||||||
<img src="{{ asset(teamer.photo.filename | imagine_filter('profile')) }}"
|
<img src="{{ asset(teamer.photo.filename | imagine_filter('profile')) }}"
|
||||||
class="w-32 h-auto border-2 border-primary"
|
class="w-32 h-auto border-2 border-primary"
|
||||||
@@ -39,5 +39,6 @@
|
|||||||
{{ icon('user', 'w-32 h-32 text-gray-200') }}
|
{{ icon('user', 'w-32 h-32 text-gray-200') }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% include '_partials/_rating_stars.html.twig' with { 'teamer': teamer } %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user