Skip to content

Commit c469bbd

Browse files
committed
feat: engagements i've joined page
1 parent 657d022 commit c469bbd

16 files changed

+782
-39
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Enums\ProjectInvolvement;
6+
use App\Enums\UserContext;
7+
use App\Models\User;
8+
use Illuminate\Contracts\View\View;
9+
use Illuminate\Http\RedirectResponse;
10+
use Illuminate\Http\Response;
11+
use Illuminate\Support\Facades\Auth;
12+
13+
class UserEngagementsController extends Controller
14+
{
15+
public function show(): Response|View|RedirectResponse
16+
{
17+
$user = Auth::user();
18+
19+
if ($user->context === UserContext::Organization->value && ! $user->organization) {
20+
return redirect(localized_route('organizations.show-type-selection'));
21+
}
22+
23+
if ($this->isParticipant($user)) {
24+
$section = ProjectInvolvement::Participating->value;
25+
$activeEngagements = $user->{$user->context}->engagements()->active()->get();
26+
$completeEngagements = $user->{$user->context}->engagements()->complete()->get();
27+
} elseif ($this->isConnector($user)) {
28+
$section = ProjectInvolvement::Contracted->value;
29+
$activeEngagements = $user->{$user->context}->connectingEngagements()->active()->get();
30+
$completeEngagements = $user->{$user->context}->connectingEngagements()->complete()->get();
31+
} else {
32+
abort(404);
33+
}
34+
35+
return view('engagements.joined', [
36+
'section' => $section ?? '',
37+
'showParticipating' => $this->isParticipant($user),
38+
'showConnecting' => $this->isConnector($user),
39+
'activeEngagements' => $activeEngagements ?? [],
40+
'completeEngagements' => $completeEngagements ?? [],
41+
]);
42+
}
43+
44+
public function showContracted(): Response|View|RedirectResponse
45+
{
46+
$user = Auth::user();
47+
48+
if ($user->context === UserContext::Organization->value && ! $user->organization) {
49+
return redirect(localized_route('organizations.show-type-selection'));
50+
}
51+
52+
if ($this->isConnector($user)) {
53+
$activeEngagements = $user->{$user->context}->connectingEngagements()->active()->get();
54+
$completeEngagements = $user->{$user->context}->connectingEngagements()->complete()->get();
55+
56+
return view('engagements.joined', [
57+
'title' => __('Engagements I’ve joined as a Community Connector'),
58+
'section' => 'contracted',
59+
'showParticipating' => $this->isParticipant($user),
60+
'showConnecting' => true,
61+
'activeEngagements' => $activeEngagements,
62+
'completeEngagements' => $completeEngagements,
63+
]);
64+
}
65+
66+
abort(404);
67+
}
68+
69+
public function showParticipating(): Response|View|RedirectResponse
70+
{
71+
$user = Auth::user();
72+
73+
if ($user->context === UserContext::Organization->value && ! $user->organization) {
74+
return redirect(localized_route('organizations.show-type-selection'));
75+
}
76+
77+
if ($this->isParticipant($user)) {
78+
$activeEngagements = $user->{$user->context}->engagements()->active()->get();
79+
$completeEngagements = $user->{$user->context}->engagements()->complete()->get();
80+
81+
return view('engagements.joined', [
82+
'title' => __('Engagements I’ve joined as a Consultation Participant'),
83+
'section' => 'participating',
84+
'showParticipating' => true,
85+
'showConnecting' => $this->isConnector($user),
86+
'activeEngagements' => $activeEngagements,
87+
'completeEngagements' => $completeEngagements,
88+
]);
89+
}
90+
91+
abort(404);
92+
}
93+
94+
public function isParticipant(User $user): bool
95+
{
96+
$userContext = $user->{$user->context};
97+
98+
return $userContext && ($userContext->isParticipant() || $userContext->engagements()->count());
99+
}
100+
101+
public function isConnector(User $user): bool
102+
{
103+
$userContext = $user->{$user->context};
104+
105+
return $userContext && ($userContext->isConnector() || $userContext->connectingEngagements()->count());
106+
}
107+
}

app/Models/Engagement.php

+40
Original file line numberDiff line numberDiff line change
@@ -604,4 +604,44 @@ public function scopeLocations($query, $locations)
604604

605605
return $query;
606606
}
607+
608+
public function scopeActive($query)
609+
{
610+
$query->whereHas('project', function (Builder $projectQuery) {
611+
$projectQuery->where('end_date', '>', now());
612+
})
613+
->where(function (Builder $engagementQuery) {
614+
$engagementQuery->whereDoesntHave('meetings')
615+
->orWhereHas('meetings', function (Builder $meetingQuery) {
616+
$meetingQuery->where('date', '>', now());
617+
});
618+
})
619+
->where(function (Builder $engagementQuery) {
620+
$engagementQuery->whereNull('complete_by_date')
621+
->orWhere('complete_by_date', '>', now());
622+
})
623+
->where(function (Builder $engagementQuery) {
624+
$engagementQuery->whereNull('window_end_date')
625+
->orWhere('window_end_date', '>', now());
626+
});
627+
628+
return $query;
629+
}
630+
631+
public function scopeComplete($query)
632+
{
633+
$query->whereHas('project', function (Builder $projectQuery) {
634+
$projectQuery->where('end_date', '<', now());
635+
})
636+
->orWhere(function (Builder $engagementQuery) {
637+
$engagementQuery->whereHas('meetings')
638+
->whereDoesntHave('meetings', function (Builder $meetingQuery) {
639+
$meetingQuery->where('date', '>', now());
640+
});
641+
})
642+
->orWhere('complete_by_date', '<', now())
643+
->orWhere('window_end_date', '<', now());
644+
645+
return $query;
646+
}
607647
}

app/Models/Organization.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,15 @@ public function upcomingProjects(): MorphMany
245245
->orderBy('start_date');
246246
}
247247

248-
public function participatingEngagements(): HasMany
248+
public function engagements(): HasMany
249249
{
250250
return $this->hasMany(Engagement::class);
251251
}
252252

253253
public function participatingProjects(): HasManyDeep
254254
{
255255
return $this->hasManyDeepFromRelations(
256-
$this->participatingEngagements(),
256+
$this->engagements(),
257257
(new Engagement())->project()
258258
);
259259
}

app/Policies/EngagementPolicy.php

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Policies;
44

5+
use App\Enums\UserContext;
56
use App\Models\Engagement;
67
use App\Models\User;
78
use App\Traits\UserCanViewOwnedContent;
@@ -63,6 +64,13 @@ public function viewAny(User $user): bool
6364
return $this->canViewPublishedContent($user);
6465
}
6566

67+
public function viewJoined(User $user): Response
68+
{
69+
return ($user->context === UserContext::Individual->value || $user->context === UserContext::Organization->value)
70+
? Response::allow()
71+
: Response::denyAsNotFound();
72+
}
73+
6674
public function viewOwned(User $user): bool
6775
{
6876
return $this->canViewOwnedContent($user);

database/factories/IndividualFactory.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Database\Factories;
44

5+
use App\Enums\IndividualRole;
56
use App\Models\Individual;
67
use App\Models\User;
78
use Illuminate\Database\Eloquent\Factories\Factory;
@@ -26,7 +27,7 @@ public function definition(): array
2627
return User::find($attributes['user_id'])->name;
2728
},
2829
'region' => $this->faker->provinceAbbr(),
29-
'roles' => ['participant'],
30+
'roles' => [IndividualRole::ConsultationParticipant->value],
3031
'languages' => ['en', 'fr'],
3132
'first_language' => function (array $attributes) {
3233
return User::find($attributes['user_id'])->locale;

database/factories/UserFactory.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Database\Factories;
44

5+
use App\Enums\UserContext;
56
use App\Models\User;
67
use Illuminate\Database\Eloquent\Factories\Factory;
78
use Illuminate\Support\Str;
@@ -30,7 +31,7 @@ public function definition(): array
3031
'remember_token' => Str::random(10),
3132
'locale' => config('app.locale'),
3233
'theme' => 'system',
33-
'context' => 'individual',
34+
'context' => UserContext::Individual->value,
3435
'preferred_contact_person' => 'me',
3536
'preferred_contact_method' => 'email',
3637
'preferred_notification_method' => 'email',

database/seeders/data/Interpretations.json

+20
Original file line numberDiff line numberDiff line change
@@ -1587,6 +1587,26 @@
15871587
}
15881588
]
15891589
},
1590+
"engagements.joined": {
1591+
"interpretations": [
1592+
{
1593+
"name": "Engagements I’ve joined",
1594+
"namespace": "engagements-joined"
1595+
},
1596+
{
1597+
"name": "Joined as a Community Connector",
1598+
"namespace": "engagements-joined"
1599+
},
1600+
{
1601+
"name": "Joined as a Consultation Participant",
1602+
"namespace": "engagements-joined"
1603+
},
1604+
{
1605+
"name": "Completed engagements",
1606+
"namespace": "engagements-joined"
1607+
}
1608+
]
1609+
},
15901610
"engagements.add-connector": {
15911611
"interpretations": [
15921612
{

resources/lang/en.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@
369369
"Completed": "Completed",
370370
"completed": "completed",
371371
"Completed documents are due by:": "Completed documents are due by:",
372+
"Completed engagements": "Completed engagements",
372373
"Completed materials are due by": "Completed materials are due by",
373374
"Confirm": "Confirm",
374375
"Confirm and sign up": "Confirm and sign up",
@@ -577,6 +578,8 @@
577578
"Engagements": "Engagements",
578579
"Engagements by organizations that I have saved on my notification list": "Engagements by organizations that I have saved on my notification list",
579580
"Engagements I’ve joined": "Engagements I’ve joined",
581+
"Engagements I’ve joined as a Community Connector": "Engagements I’ve joined as a Community Connector",
582+
"Engagements I’ve joined as a Consultation Participant": "Engagements I’ve joined as a Consultation Participant",
580583
"Engagements that are looking for people that my organization represents or supports": "Engagements that are looking for people that my organization represents or supports",
581584
"Engagements that are looking for someone with my lived experience": "Engagements that are looking for someone with my lived experience",
582585
"Engagement translations": "Engagement translations",
@@ -813,6 +816,8 @@
813816
"I work for a private business, the federal government, or a public sector organization regulated under the Accessible Canada Act.": "I work for a private business, the federal government, or a public sector organization regulated under the Accessible Canada Act.",
814817
"I would like to speak to someone to discuss additional access needs or concerns": "I would like to speak to someone to discuss additional access needs or concerns",
815818
"I’ve gone to orientation, why isn’t this updated?": "I’ve gone to orientation, why isn’t this updated?",
819+
"Joined as a Community Connector": "Joined as a Community Connector",
820+
"Joined as a Consultation Participant": "Joined as a Consultation Participant",
816821
"Join our accessibility community": "Join our accessibility community",
817822
"Keeping my information up to date": "Keeping my information up to date",
818823
"Language": "Language",
@@ -1299,8 +1304,6 @@
12991304
"Projects I am contracted for": "Projects I am contracted for",
13001305
"Projects I am participating in": "Projects I am participating in",
13011306
"Projects I am running": "Projects I am running",
1302-
"Projects involved in as a Community Connector": "Projects involved in as a Community Connector",
1303-
"Projects involved in as a Consultation Participant": "Projects involved in as a Consultation Participant",
13041307
"Projects I’m running": "Projects I’m running",
13051308
"projects notification setting": "projects notification setting",
13061309
"Project start date": "Project start date",

resources/lang/fr.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@
369369
"Completed": "Terminé",
370370
"completed": "complété",
371371
"Completed documents are due by:": "Les documents dûment complétés doivent être remis au plus tard le : ",
372+
"Completed engagements": "",
372373
"Completed materials are due by": "Les documents dûment complétés doivent être remis au plus tard le",
373374
"Confirm": "Confirmer",
374375
"Confirm and sign up": "Confirmer et s’inscrire",
@@ -577,6 +578,8 @@
577578
"Engagements": "Consultations",
578579
"Engagements by organizations that I have saved on my notification list": "Consultations menées par les organisations que j’ai enregistrés dans ma liste de notifications",
579580
"Engagements I’ve joined": "",
581+
"Engagements I’ve joined as a Community Connector": "",
582+
"Engagements I’ve joined as a Consultation Participant": "",
580583
"Engagements that are looking for people that my organization represents or supports": "Consultations qui recherchent des personnes que mon organisation représente ou soutient",
581584
"Engagements that are looking for someone with my lived experience": "Consultations qui sont à la recherche de personnes avec mon expérience vécue",
582585
"Engagement translations": "Traductions de la consultation",
@@ -813,6 +816,8 @@
813816
"I work for a private business, the federal government, or a public sector organization regulated under the Accessible Canada Act.": "Je travaille pour une entreprise privée, le gouvernement fédéral ou une organisation du secteur public réglementée par la Loi canadienne sur l’accessibilité.",
814817
"I would like to speak to someone to discuss additional access needs or concerns": "Je voudrais parler à une personne afin de discuter de mes besoins ou préoccupations supplémentaires en matière d’accessibilité",
815818
"I’ve gone to orientation, why isn’t this updated?": "J’ai déjà participé à la séance d’information et d’orientation, pourquoi cela n’apparait-il pas?",
819+
"Joined as a Community Connector": "",
820+
"Joined as a Consultation Participant": "",
816821
"Join our accessibility community": "Rejoignez notre communauté en faveur de l’accessibilité",
817822
"Keeping my information up to date": "Maintenir mes informations à jour",
818823
"Language": "Langue",
@@ -1299,8 +1304,6 @@
12991304
"Projects I am contracted for": "Projets pour lesquels je suis sous contrat",
13001305
"Projects I am participating in": "Projets auxquels je participe",
13011306
"Projects I am running": "Projets que je dirige",
1302-
"Projects involved in as a Community Connector": "Mes projets à titre de personne facilitatrice communautaire",
1303-
"Projects involved in as a Consultation Participant": "Mes projets à titre de personne participant à des consultations",
13041307
"Projects I’m running": "Projets que je dirige",
13051308
"projects notification setting": "paramètres des notifications pour le projet",
13061309
"Project start date": "Date de début du projet",
@@ -2160,4 +2163,4 @@
21602163
"“About your organization” (English)": "« À propos de votre organisation » (en anglais)",
21612164
"“About your organization” (French)": "À propos de votre organisation",
21622165
"“About your organization” must be provided in either English or French.": "À propos de votre organisation doit être fournis en anglais ou en français."
2163-
}
2166+
}

resources/views/dashboard/individual.blade.php

+8-13
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,27 @@
1010
@endif
1111
</li>
1212
@endif
13-
@can('viewAny', App\Models\Project::class)
14-
@if ($user->individual->isConnector() || $user->individual->inProgressContractedProjects()->count())
15-
<li>
16-
<a
17-
href="{{ localized_route('projects.my-contracted-projects') }}">{{ __('Projects involved in as a Community Connector') }}</a>
18-
</li>
19-
@endif
20-
@endcan
2113
@if (!$user->oriented_at)
2214
<li>
2315
<a href="{{ orientation_link($user->context) }}">{{ __('Sign up for an orientation session') }}</a>
2416
</li>
2517
@endif
26-
@can('viewAny', App\Models\Project::class)
27-
@if ($user->individual->isParticipant() || $user->individual->inProgressParticipatingProjects()->count())
18+
@can('viewJoined', 'App\Models\Engagement')
19+
@if (
20+
$user->individual->isParticipant() ||
21+
$user->individual->isConnector() ||
22+
$user->individual->engagements()->count() ||
23+
$user->individual->connectingEngagements()->count())
2824
<li>
29-
<a
30-
href="{{ localized_route('projects.my-participating-projects') }}">{{ __('Projects involved in as a Consultation Participant') }}</a>
25+
<a href="{{ localized_route('engagements.joined') }}">{{ __('Engagements I’ve joined') }}</a>
3126
</li>
3227
@endif
3328
@endcan
3429
<li>
3530
<a href="{{ localized_route('dashboard.trainings') }}">{{ __('My trainings') }}</a>
3631
</li>
3732
</x-quick-links>
38-
<div class="border-divider mt-14 mb-12 border-x-0 border-t-3 border-b-0 border-solid pt-6">
33+
<div class="border-divider mb-12 mt-14 border-x-0 border-b-0 border-t-3 border-solid pt-6">
3934
@include('dashboard.partials.notifications', [
4035
'notifications' => $user->allUnreadNotifications(),
4136
])

0 commit comments

Comments
 (0)