Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Console/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ protected function installInertiaComponents()

info("Detected Inertia framework: {$framework}");

// Controllers...
(new Filesystem)->ensureDirectoryExists(app_path('Http/Controllers/Teams'));
$this->copy($this->stubsPath('app/Http/Controllers/Teams/TeamController.php'), app_path('Http/Controllers/Teams/TeamController.php'));
$this->copy($this->stubsPath('app/Http/Controllers/Teams/TeamMemberController.php'), app_path('Http/Controllers/Teams/TeamMemberController.php'));

// Pages...
(new Filesystem)->ensureDirectoryExists(resource_path('js/pages/teams'));

$reactStubsPath = $this->stubsPath('inertia/react/resources/js/pages/teams');
Expand Down
173 changes: 173 additions & 0 deletions stubs/app/Http/Controllers/Teams/TeamController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php

namespace App\Http\Controllers\Teams;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Inertia\Inertia;
use Malico\Teams\Contracts\AddsTeamMembers;
use Malico\Teams\Contracts\CreatesTeams;
use Malico\Teams\Contracts\DeletesTeams;
use Malico\Teams\Contracts\UpdatesTeamNames;
use Malico\Teams\Teams;

class TeamController extends Controller
{
public function index()
{
$user = auth()->user();

return Inertia::render('teams/index', [
'teams' => $user->allTeams(),
'currentTeam' => $user->currentTeam,
]);
}

public function create()
{
return Inertia::render('teams/create');
}

public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
]);

$team = app(CreatesTeams::class)->create(
$request->user(),
$request->only('name')
);

return redirect()->route('teams.show', $team);
}

public function show()
{
$user = auth()->user();
$team = $user->currentTeam;

if (! $team) {
return redirect()->route('teams.create');
}

return Inertia::render('teams/show', [
'team' => $team->load('owner'),
'permissions' => [
'canUpdateTeam' => Gate::check('updateTeamName', $team),
'canDeleteTeam' => Gate::check('delete', $team),
],
]);
}

public function update(Request $request)
{
$team = $request->user()->currentTeam;

if (! $team) {
return redirect()->route('teams.create');
}

Gate::authorize('updateTeamName', $team);

$request->validate([
'name' => 'required|string|max:255',
]);

app(UpdatesTeamNames::class)->update(
$request->user(),
$team,
$request->only('name')
);

return back()->with('success', 'Team updated successfully.');
}

public function destroy(Request $request)
{
$team = $request->user()->currentTeam;

if (! $team) {
return redirect()->route('teams.create');
}

Gate::authorize('delete', $team);

app(DeletesTeams::class)->delete($request->user(), $team);

return redirect()->route('dashboard');
}

public function showAcceptInvitation($invitationId)
{
$model = Teams::teamInvitationModel();
$invitation = $model::whereKey($invitationId)->firstOrFail();

if ($invitation->expires_at && $invitation->expires_at->isPast()) {
$invitation->delete();

return Inertia::render('teams/invitation-expired');
}

if (! auth()->check()) {
return Inertia::render('teams/accept-invitation', [
'invitation' => $invitation->load('team'),
]);
}

if (auth()->user()->email !== $invitation->email) {
return Inertia::render('teams/wrong-user', [
'invitation' => $invitation->load('team'),
'expectedEmail' => $invitation->email,
'currentEmail' => auth()->user()->email,
]);
}

return Inertia::render('teams/accept-invitation', [
'invitation' => $invitation->load('team'),
]);
}

public function acceptInvitation(Request $request, $invitationId)
{
$model = Teams::teamInvitationModel();
$invitation = $model::whereKey($invitationId)->firstOrFail();

if ($invitation->expires_at && $invitation->expires_at->isPast()) {
$invitation->delete();

return redirect('/')->with('error', __('This invitation has expired.'));
}

if (! auth()->check() || auth()->user()->email !== $invitation->email) {
return redirect()->back()->with('error', __('You are not authorized to accept this invitation.'));
}

app(AddsTeamMembers::class)->add(
$invitation->team->owner,
$invitation->team,
$invitation->email,
$invitation->role
);

$invitation->delete();

return redirect(config('teams.home', '/dashboard'))->with(
'success',
__('Great! You have accepted the invitation to join the :team team.', ['team' => $invitation->team->name])
);
}

public function declineInvitation(Request $request, $invitationId)
{
$model = Teams::teamInvitationModel();
$invitation = $model::whereKey($invitationId)->firstOrFail();

if (auth()->check() && auth()->user()->email === $invitation->email) {
$invitation->delete();
}

return redirect('/')->with('message', __('You have declined the team invitation.'));
}
}
140 changes: 140 additions & 0 deletions stubs/app/Http/Controllers/Teams/TeamMemberController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

namespace App\Http\Controllers\Teams;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Inertia\Inertia;
use Malico\Teams\Contracts\InvitesTeamMembers;
use Malico\Teams\Contracts\RemovesTeamMembers;
use Malico\Teams\Contracts\SendsTeamInvitations;
use Malico\Teams\Contracts\UpdatesTeamMemberRoles;
use Malico\Teams\Teams;

class TeamMemberController extends Controller
{
public function index()
{
$user = auth()->user();
$team = $user->currentTeam;

if (! $team) {
return redirect()->route('teams.create');
}

return Inertia::render('teams/members', [
'team' => $team->load(['owner', 'users', 'invitations']),
'roles' => Teams::getRoles(),
'permissions' => [
'canAddTeamMembers' => Gate::check('addTeamMember', $team),
'canRemoveTeamMembers' => Gate::check('removeTeamMember', $team),
'canUpdateTeamMembers' => Gate::check('updateTeamMember', $team),
],
]);
}

public function store(Request $request)
{
$team = $request->user()->currentTeam;

if (! $team) {
return redirect()->route('teams.create');
}

Gate::authorize('addTeamMember', $team);

$request->validate([
'email' => 'required|email',
'role' => 'nullable|string',
]);

app(InvitesTeamMembers::class)->invite(
$request->user(),
$team,
$request->email,
$request->role
);

return back()->with('success', 'Team member invited successfully.');
}

public function update(Request $request, $userId)
{
$team = $request->user()->currentTeam;
$user = Teams::userModel()::findOrFail($userId);

if (! $team) {
return redirect()->route('teams.create');
}

Gate::authorize('updateTeamMember', $team);

$request->validate([
'role' => 'required|string',
]);

app(UpdatesTeamMemberRoles::class)->update(
$request->user(),
$team,
$user,
$request->role
);

return back()->with('success', 'Team member role updated successfully.');
}

public function destroy(Request $request, $userId)
{
$team = $request->user()->currentTeam;
$user = Teams::userModel()::findOrFail($userId);

if (! $team) {
return redirect()->route('teams.create');
}

Gate::authorize('removeTeamMember', $team);

app(RemovesTeamMembers::class)->remove(
$request->user(),
$team,
$user
);

return back()->with('success', 'Team member removed successfully.');
}

public function resendInvitation(Request $request, $invitationId)
{
$team = $request->user()->currentTeam;

if (! $team) {
return redirect()->route('teams.create');
}

$invitation = $team->invitations()->findOrFail($invitationId);

Gate::authorize('addTeamMember', $team);

app(SendsTeamInvitations::class)->send($invitation);

return back()->with('success', 'Invitation resent successfully.');
}

public function cancelInvitation(Request $request, $invitationId)
{
$team = $request->user()->currentTeam;

if (! $team) {
return redirect()->route('teams.create');
}

$invitation = $team->invitations()->findOrFail($invitationId);

Gate::authorize('removeTeamMember', $team);

$invitation->delete();

return back()->with('success', 'Invitation cancelled successfully.');
}
}
Loading