From 1f40fcca6ab5ff47e7ad5e8dbb0e93aea86becd6 Mon Sep 17 00:00:00 2001 From: Paul Isaris Date: Wed, 23 Oct 2024 10:25:18 +0300 Subject: [PATCH] IP-97 As an "Active Citizen" user I want to see the Dashboard page, to see an overview of my contributions to the platform --- .../gamification/CommunicatorBadge.php | 4 +- .../gamification/ContributorBadge.php | 4 +- .../gamification/GamificationBadge.php | 6 +- .../GamificationPointsCalculator.php | 16 ---- .../gamification/InfluencerBadge.php | 8 +- ...PlatformWideGamificationBadgesProvider.php | 3 +- app/Http/Controllers/UserController.php | 2 +- app/ViewModels/GamificationBadgeVM.php | 12 +++ .../GamificationBadgesWithLevels.php | 33 ++++++-- resources/assets/sass/_variables.scss | 2 +- resources/assets/sass/common/button.scss | 1 + .../assets/sass/gamification/progress.scss | 22 +++++ .../assets/sass/project/landing-page.scss | 2 +- resources/lang/en/badges_messages.php | 3 + .../gamification/user-progress.blade.php | 55 +++++++++++- .../partials/header-controls.blade.php | 4 +- routes/web.php | 2 +- .../Controllers/UserControllerTest.php | 23 +++++ tests/Unit/Controllers/UserControllerTest.php | 83 +++++++++++++++++++ 19 files changed, 248 insertions(+), 37 deletions(-) delete mode 100644 app/BusinessLogicLayer/gamification/GamificationPointsCalculator.php create mode 100644 tests/Unit/Controllers/UserControllerTest.php diff --git a/app/BusinessLogicLayer/gamification/CommunicatorBadge.php b/app/BusinessLogicLayer/gamification/CommunicatorBadge.php index d8e47c08..723a2e63 100644 --- a/app/BusinessLogicLayer/gamification/CommunicatorBadge.php +++ b/app/BusinessLogicLayer/gamification/CommunicatorBadge.php @@ -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 { diff --git a/app/BusinessLogicLayer/gamification/ContributorBadge.php b/app/BusinessLogicLayer/gamification/ContributorBadge.php index a80d1eed..8f967f9b 100644 --- a/app/BusinessLogicLayer/gamification/ContributorBadge.php +++ b/app/BusinessLogicLayer/gamification/ContributorBadge.php @@ -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 ); } diff --git a/app/BusinessLogicLayer/gamification/GamificationBadge.php b/app/BusinessLogicLayer/gamification/GamificationBadge.php index caed66af..bd725b6b 100644 --- a/app/BusinessLogicLayer/gamification/GamificationBadge.php +++ b/app/BusinessLogicLayer/gamification/GamificationBadge.php @@ -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; @@ -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(); diff --git a/app/BusinessLogicLayer/gamification/GamificationPointsCalculator.php b/app/BusinessLogicLayer/gamification/GamificationPointsCalculator.php deleted file mode 100644 index 737a315a..00000000 --- a/app/BusinessLogicLayer/gamification/GamificationPointsCalculator.php +++ /dev/null @@ -1,16 +0,0 @@ -level; - } - - return $totalPoints; - } -} diff --git a/app/BusinessLogicLayer/gamification/InfluencerBadge.php b/app/BusinessLogicLayer/gamification/InfluencerBadge.php index 802ac0b9..c3252185 100644 --- a/app/BusinessLogicLayer/gamification/InfluencerBadge.php +++ b/app/BusinessLogicLayer/gamification/InfluencerBadge.php @@ -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 ); } @@ -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) { diff --git a/app/BusinessLogicLayer/gamification/PlatformWideGamificationBadgesProvider.php b/app/BusinessLogicLayer/gamification/PlatformWideGamificationBadgesProvider.php index 4b776c73..a54f3a2a 100644 --- a/app/BusinessLogicLayer/gamification/PlatformWideGamificationBadgesProvider.php +++ b/app/BusinessLogicLayer/gamification/PlatformWideGamificationBadgesProvider.php @@ -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 { diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 39f1d59c..c0afb923 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -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]); diff --git a/app/ViewModels/GamificationBadgeVM.php b/app/ViewModels/GamificationBadgeVM.php index d5a2763b..de3c0f3b 100644 --- a/app/ViewModels/GamificationBadgeVM.php +++ b/app/ViewModels/GamificationBadgeVM.php @@ -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; @@ -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); } } diff --git a/app/ViewModels/GamificationBadgesWithLevels.php b/app/ViewModels/GamificationBadgesWithLevels.php index a2c2bc13..e6d8e645 100644 --- a/app/ViewModels/GamificationBadgesWithLevels.php +++ b/app/ViewModels/GamificationBadgesWithLevels.php @@ -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) { @@ -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); + } } diff --git a/resources/assets/sass/_variables.scss b/resources/assets/sass/_variables.scss index 36e13460..ad015602 100644 --- a/resources/assets/sass/_variables.scss +++ b/resources/assets/sass/_variables.scss @@ -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; diff --git a/resources/assets/sass/common/button.scss b/resources/assets/sass/common/button.scss index 88f1bd47..f8e677e5 100644 --- a/resources/assets/sass/common/button.scss +++ b/resources/assets/sass/common/button.scss @@ -5,6 +5,7 @@ transition: all 0.2s; font-family: "Noto Sans Variable", sans-serif; border-radius: 21px; + font-weight: 600; } .btn-primary { diff --git a/resources/assets/sass/gamification/progress.scss b/resources/assets/sass/gamification/progress.scss index e69de29b..a80906e8 100644 --- a/resources/assets/sass/gamification/progress.scss +++ b/resources/assets/sass/gamification/progress.scss @@ -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); + } +} \ No newline at end of file diff --git a/resources/assets/sass/project/landing-page.scss b/resources/assets/sass/project/landing-page.scss index 533ac42f..781d4865 100644 --- a/resources/assets/sass/project/landing-page.scss +++ b/resources/assets/sass/project/landing-page.scss @@ -493,7 +493,7 @@ ol { i { font-size: 14px; font-weight: 300; - color: #4d5359; + color: var(--clr-secondary-grey); } .modal-body { diff --git a/resources/lang/en/badges_messages.php b/resources/lang/en/badges_messages.php index da609f64..30e7610c 100644 --- a/resources/lang/en/badges_messages.php +++ b/resources/lang/en/badges_messages.php @@ -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', ]; diff --git a/resources/views/gamification/user-progress.blade.php b/resources/views/gamification/user-progress.blade.php index ced73c2b..161f69d8 100644 --- a/resources/views/gamification/user-progress.blade.php +++ b/resources/views/gamification/user-progress.blade.php @@ -13,7 +13,60 @@ -
+
+
+
+
+
+
+ @foreach($badgesVM->badgesWithLevelsList as $badge) +
+
+
{{ $badge->badgeName }}
+

{{ $badge->badge->progressMessage }}

+
+
+

Your level progress: {{ $badge->level }} + /{{ $badge->badge->finalLevel }}

+
+
+
+
+
+
+
+ @endforeach +
+
+
Points
+
+
+

{{$badgesVM->getTotalPoints()}} + / {{$badgesVM->getMaxTotalPoints()}} to unlock a gift!

+
+
+
+
+
+
+
+
+
+
+
+ +
+
diff --git a/resources/views/loggedin-environment/partials/header-controls.blade.php b/resources/views/loggedin-environment/partials/header-controls.blade.php index 539e5887..0106a691 100644 --- a/resources/views/loggedin-environment/partials/header-controls.blade.php +++ b/resources/views/loggedin-environment/partials/header-controls.blade.php @@ -24,8 +24,8 @@ {{ __('menu.my_account') }} @if($userHasContributedToAProject) - @endif