Skip to content

Commit

Permalink
IP-97 As an "Active Citizen" user I want to see the Dashboard page, t…
Browse files Browse the repository at this point in the history
…o see an overview of my contributions to the platform
  • Loading branch information
PavlosIsaris committed Oct 23, 2024
1 parent 9b4ba4f commit 1f40fcc
Show file tree
Hide file tree
Showing 19 changed files with 248 additions and 37 deletions.
4 changes: 3 additions & 1 deletion app/BusinessLogicLayer/gamification/CommunicatorBadge.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ public function __construct(int $questionnairesSharedByUser, $userHasAchievedBad
parent::__construct(__('badges_messages.communicator_title'),
'communicator.png',
__('badges_messages.gain_badge_by_inviting'),
$numberOfActionsPerformed, $userHasAchievedBadgePlatformWide, 10);
$numberOfActionsPerformed, $userHasAchievedBadgePlatformWide, 10,
__('badges_messages.communicator_bade_progress', ['count' => $numberOfActionsPerformed]),
60);
}

protected function getBadgeMessageForLevel(): string {
Expand Down
4 changes: 3 additions & 1 deletion app/BusinessLogicLayer/gamification/ContributorBadge.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ public function __construct(int $allResponses, bool $userHasAchievedBadgePlatfor
__('badges_messages.contributor_badge_points_explanation'),
$allResponses,
$userHasAchievedBadgePlatformWide,
5
5,
__('badges_messages.contributor_bade_progress', ['count' => $allResponses]),
50
);
}

Expand Down
6 changes: 5 additions & 1 deletion app/BusinessLogicLayer/gamification/GamificationBadge.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ abstract class GamificationBadge {
public string $imageFileName;
public string $statusMessage;
public string $color;
public string $progressMessage;
public int $finalLevel;
protected bool $userHasAchievedBadgePlatformWide;

public function __construct($name, $imageFileName, $requiredActionMessage,
$numberOfActionsPerformed, $userHasAchievedBadgePlatformWide, $pointsPerAction = 1) {
$numberOfActionsPerformed, $userHasAchievedBadgePlatformWide, $pointsPerAction, $progressMessage = '', $finalLevel = 0) {
$this->name = $name;
$this->imageFileName = $imageFileName;
$this->numberOfActionsPerformed = $numberOfActionsPerformed;
Expand All @@ -24,6 +26,8 @@ public function __construct($name, $imageFileName, $requiredActionMessage,
$this->messageForLevel = $this->getBadgeMessageForLevel();
$this->statusMessage = $this->calculateStatusMessage($requiredActionMessage);
$this->userHasAchievedBadgePlatformWide = $userHasAchievedBadgePlatformWide;
$this->progressMessage = $progressMessage;
$this->finalLevel = $finalLevel;
}

abstract protected function getBadgeMessageForLevel();
Expand Down

This file was deleted.

8 changes: 5 additions & 3 deletions app/BusinessLogicLayer/gamification/InfluencerBadge.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ public function __construct(int $questionnaireReferralsNum, $userHasAchievedBadg
__('badges_messages.gain_influencer_badge'),
$questionnaireReferralsNum,
$userHasAchievedBadgePlatformWide,
15
15,
__('badges_messages.influencer_bade_progress', ['count' => $questionnaireReferralsNum]),
60
);
}

Expand All @@ -35,9 +37,9 @@ public function getNextStepMessage(): string {
if (!$this->questionnaireReferralsNum) {
$title = __('badges_messages.zero_people_responded_to_call');
} elseif ($this->questionnaireReferralsNum < 2) {
$title = __('badges_messages.good_job', $this->questionnaireReferralsNum, ['count' => $this->questionnaireReferralsNum]);
$title = __('badges_messages.good_job', $this->questionnaireReferralsNum, ['count' => $this->questionnaireReferralsNum]);
} else {
$title = __('badges_messages.true_influencer', $this->questionnaireReferralsNum, ['count' => $this->questionnaireReferralsNum]);
$title = __('badges_messages.true_influencer', $this->questionnaireReferralsNum, ['count' => $this->questionnaireReferralsNum]);
}

if ($this->userHasAchievedBadgePlatformWide) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ public function getPlatformWideGamificationBadgesListVM(int $userId, array $ques
foreach ($badges as $badge) {
$badgesVM->push(new GamificationBadgeVM($badge));
}
$gamificationPointsCalculator = new GamificationPointsCalculator;

return new GamificationBadgesWithLevels($badgesVM, $gamificationPointsCalculator->calculateTotalGamificationPoints($badges));
return new GamificationBadgesWithLevels($badgesVM);
}

public function getContributorBadge(array $questionnaireIdsUserHasAnsweredTo): ContributorBadge {
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function showUsersByCriteria(Request $request) {
}
}

public function showUserHistory() {
public function showUserContributions() {
$responses = $this->questionnaireResponseManager->getQuestionnaireResponsesForUser(Auth::user());

return view('loggedin-environment.my-history', ['responses' => $responses]);
Expand Down
12 changes: 12 additions & 0 deletions app/ViewModels/GamificationBadgeVM.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class GamificationBadgeVM {
public string $statusMessage;
public string $color;
public string $messageForLevel;
public GamificationBadge $badge;

public function __construct(GamificationBadge $badge) {
$this->badgeName = $badge->name;
Expand All @@ -21,5 +22,16 @@ public function __construct(GamificationBadge $badge) {
$this->statusMessage = $badge->statusMessage;
$this->color = $badge->color;
$this->messageForLevel = $badge->messageForLevel;
$this->badge = $badge;
}

public function computeLevelProgressPercentage(): int {
// return the percentage of the level progress
// if greater than 100, return 100
// if equal to 0, return 1 (as a default minimum)

$percentage = ($this->level / $this->badge->finalLevel) * 100;

return $percentage > 100 ? 100 : ($percentage == 0 ? 1 : $percentage);
}
}
33 changes: 27 additions & 6 deletions app/ViewModels/GamificationBadgesWithLevels.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@
use Illuminate\Support\Collection;

class GamificationBadgesWithLevels {
public $badgesWithLevelsList;
public $totalPoints;
public $numOfBadges;
public Collection $badgesWithLevelsList;
public int $numOfBadges;

public function __construct(Collection $badgesWithLevelsList, int $totalPoints) {
public function __construct(Collection $badgesWithLevelsList) {
$this->badgesWithLevelsList = $badgesWithLevelsList;
$this->totalPoints = $totalPoints;
$this->numOfBadges = $this->getNumOfBadges();
}

private function getNumOfBadges() {
private function getNumOfBadges(): int {
$i = 0;
foreach ($this->badgesWithLevelsList as $item) {
if ($item->level) {
Expand All @@ -25,4 +23,27 @@ private function getNumOfBadges() {

return $i;
}

public function getTotalPoints(): int {
$totalPoints = 0;
foreach ($this->badgesWithLevelsList as $badge) {
$totalPoints += $badge->level;
}

return $totalPoints;
}

public function getMaxTotalPoints(): int {
return 100;
}

public function computeTotalPointsProgressPercentage(): int {
// return the percentage of the points progress
// if greater than 100, return 100
// if equal to 0, return 1 (as a default minimum)

$percentage = ($this->getTotalPoints() / $this->getMaxTotalPoints()) * 100;

return $percentage > 100 ? 100 : ($percentage == 0 ? 1 : $percentage);
}
}
2 changes: 1 addition & 1 deletion resources/assets/sass/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ $panel-default-border: $laravel-border-color;
$panel-inner-border: $laravel-border-color;

// Brands
$brand-primary: #0069d9;
$brand-primary: #2B73FA;
$brand-success: $success;
$brand-warning: $success;
$brand-danger: $danger;
Expand Down
1 change: 1 addition & 0 deletions resources/assets/sass/common/button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
transition: all 0.2s;
font-family: "Noto Sans Variable", sans-serif;
border-radius: 21px;
font-weight: 600;
}

.btn-primary {
Expand Down
22 changes: 22 additions & 0 deletions resources/assets/sass/gamification/progress.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@import "../_variables.scss";

#progress-container {
background-color: $grey;

.progress-for-badge {
margin-bottom: 5rem;

// on mobile, the margin is smaller
@media (max-width: 768px) {
margin-bottom: 2rem;
}
}

.progress {
background-color: rgba(#4d5359, 0.6);
}

.progress-bar {
background-color: var(--clr-secondary-grey);
}
}
2 changes: 1 addition & 1 deletion resources/assets/sass/project/landing-page.scss
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ ol {
i {
font-size: 14px;
font-weight: 300;
color: #4d5359;
color: var(--clr-secondary-grey);
}

.modal-body {
Expand Down
3 changes: 3 additions & 0 deletions resources/lang/en/badges_messages.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@
'contribute_for' => 'Contribute for',
'you_do_not_own' => 'You don\'t own this badge',
'badges_title' => 'Badges Showcase',
'contributor_bade_progress' => 'You have contributed to :count projects',
'communicator_bade_progress' => 'You have shared :count times so far',
'influencer_bade_progress' => ':count users engaged with your shared content',
];
55 changes: 54 additions & 1 deletion resources/views/gamification/user-progress.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,60 @@
</div>
</div>
</div>
<div class="text-center badges-container row">
<div class="text-center row">
<div class="container-fluid">
<div class="row">
<div class="col">
<div class="px-2">
<div class="container-fluid px-lg-5 px-sm-2 py-lg-5 py-sm-3" id="progress-container">
@foreach($badgesVM->badgesWithLevelsList as $badge)
<div class="row progress-for-badge">
<div class="col-md-6 col-sm-12 text-left">
<h6>{{ $badge->badgeName }}</h6>
<p class="mb-1">{{ $badge->badge->progressMessage }}</p>
</div>
<div class="col-md-6 col-sm-12 text-right">
<p class="mb-1">Your level progress: {{ $badge->level }}
/{{ $badge->badge->finalLevel }}</p>
</div>
<div class="col-12">
<div class="progress">
<div class="progress-bar" role="progressbar"
style="width: {{ $badge->computeLevelProgressPercentage() }}%"
aria-valuenow="{{ $badge->computeLevelProgressPercentage() }}"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
@endforeach
<div class="row">
<div class="col-md-6 col-sm-12 text-left">
<h6>Points</h6>
</div>
<div class="col-md-6 col-sm-12 text-right">
<p class="mb-1">{{$badgesVM->getTotalPoints()}}
/ {{$badgesVM->getMaxTotalPoints()}} to unlock a gift!</p>
</div>
<div class="col-12">
<div class="progress">
<div class="progress-bar" role="progressbar"
style="width: {{ $badgesVM->computeTotalPointsProgressPercentage() }}%"
aria-valuenow="{{ $badgesVM->computeTotalPointsProgressPercentage() }}"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row my-5">
<div class="col mx-auto">
<a href="{{ route('my-contributions') }}" class="btn btn-primary btn-lg">{{ __('my-history.my_contributions') }}</a>
</div>
</div>
</div>

</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
<a class="nav-link" href="{{ route('my-account') }}"> {{ __('menu.my_account') }} </a>
</li>
@if($userHasContributedToAProject)
<li class="nav-item {{ UrlMatchesMenuItem('myHistory') }}">
<a class="nav-link" href="{{ route('myHistory') }}"> {{ __('menu.my_history') }} </a>
<li class="nav-item {{ UrlMatchesMenuItem('my-contributions') }}">
<a class="nav-link" href="{{ route('my-contributions') }}"> {{ __('my-history.my_contributions') }} </a>
</li>
@endif
<li class="nav-item dropdown user user-menu">
Expand Down
2 changes: 1 addition & 1 deletion routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
Route::group($localeInfo, function () {
Route::get('/my-dashboard', [UserController::class, 'myDashboard'])->name('my-dashboard');
Route::get('/my-account', [UserController::class, 'myAccount'])->name('my-account');
Route::get('/users/history', [UserController::class, 'showUserHistory'])->name('myHistory');
Route::get('/my-contributions', [UserController::class, 'showUserContributions'])->name('my-contributions');
});
});

Expand Down
23 changes: 23 additions & 0 deletions tests/Feature/Controllers/UserControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use App\BusinessLogicLayer\lkp\UserRolesLkp;
use App\Http\Middleware\VerifyCsrfToken;
use App\Models\CrowdSourcingProject\CrowdSourcingProject;
use App\Models\Questionnaire\Questionnaire;
use App\Models\User;
use App\Models\UserRole;
use Illuminate\Foundation\Testing\RefreshDatabase;
Expand Down Expand Up @@ -175,4 +177,25 @@ public function nonAdminUserCannotGetUsersByCriteria() {

$response->assertStatus(403);
}

/** @test */
public function myDashboardDisplaysCorrectlyForUserWithNoBadges() {
// for this test, we want to emulate that the platform does not have any questionnaires or projects
// delete all questionnaires and projects
Questionnaire::query()->delete();
CrowdSourcingProject::query()->delete();

$user = User::factory()->create();
$this->be($user);

$response = $this->get(route('my-dashboard', ['locale' => 'en']));

$response->assertStatus(200);
$response->assertViewIs('loggedin-environment.my-dashboard');
$response->assertViewHas('viewModel');
$viewModel = $response->original->getData()['viewModel'];
$this->assertCount(3, $viewModel->platformWideGamificationBadgesVM->badgesWithLevelsList);
$this->assertCount(0, $viewModel->questionnaires);
$this->assertCount(0, $viewModel->projectsWithActiveProblems);
}
}
Loading

0 comments on commit 1f40fcc

Please sign in to comment.