diff --git a/app/Http/Controllers/Teams/MembersController.php b/app/Http/Controllers/Teams/MembersController.php new file mode 100644 index 00000000000..3c262ced4e1 --- /dev/null +++ b/app/Http/Controllers/Teams/MembersController.php @@ -0,0 +1,53 @@ +. Licensed under the GNU Affero General Public License v3.0. +// See the LICENCE file in the repository root for full licence text. + +declare(strict_types=1); + +namespace App\Http\Controllers\Teams; + +use App\Http\Controllers\Controller; +use App\Models\Team; +use App\Models\TeamMember; +use Symfony\Component\HttpFoundation\Response; + +class MembersController extends Controller +{ + public function __construct() + { + parent::__construct(); + + $this->middleware('auth'); + } + + public function destroy(string $teamId, string $userId): Response + { + $teamMember = TeamMember::where([ + 'team_id' => $teamId, + 'user_id' => $userId, + ])->firstOrFail(); + + if ($teamMember->user_id === \Auth::user()->getKey()) { + abort(422, 'can not remove self from team'); + } + + priv_check('TeamUpdate', $teamMember->team)->ensureCan(); + + $teamMember->delete(); + \Session::flash('popup', osu_trans('teams.members.destroy.success')); + + return response(null, 204); + } + + public function index(string $teamId): Response + { + $team = Team::findOrFail($teamId); + + priv_check('TeamUpdate', $team)->ensureCan(); + + $team->load('members.user'); + + return ext_view('teams.members.index', compact('team')); + } +} diff --git a/resources/css/bem-index.less b/resources/css/bem-index.less index 0228a0d00a2..20a241d8000 100644 --- a/resources/css/bem-index.less +++ b/resources/css/bem-index.less @@ -386,6 +386,7 @@ @import "bem/team-info-entries"; @import "bem/team-info-entry"; @import "bem/team-members"; +@import "bem/team-members-manage"; @import "bem/team-settings"; @import "bem/team-settings-description-preview"; @import "bem/team-summary"; diff --git a/resources/css/bem/profile-page-cover-editor-button.less b/resources/css/bem/profile-page-cover-editor-button.less index ac68ae3d4b9..a28abb0a1b0 100644 --- a/resources/css/bem/profile-page-cover-editor-button.less +++ b/resources/css/bem/profile-page-cover-editor-button.less @@ -4,7 +4,8 @@ .profile-page-cover-editor-button { position: absolute; bottom: 10px; - display: flex; + display: grid; + gap: 10px; justify-content: center; right: @gutter-v2; diff --git a/resources/css/bem/team-members-manage.less b/resources/css/bem/team-members-manage.less new file mode 100644 index 00000000000..9ddbb0f6544 --- /dev/null +++ b/resources/css/bem/team-members-manage.less @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the GNU Affero General Public License v3.0. +// See the LICENCE file in the repository root for full licence text. + +.team-members-manage { + list-style-type: none; + margin: 0; + padding: 0; + font-size: @font-size--title-small; + display: grid; + gap: 2px 10px; + grid-template-columns: auto 1fr auto auto auto; + + &__avatar { + .default-border-radius(); + overflow: hidden; + width: @user-list-icon-size; + height: $width; + } + + &__item { + --bg: hsl(var(--hsl-b3)); + --bg-hover: hsl(var(--hsl-b2)); + .default-border-radius(); + display: grid; + grid-template-columns: subgrid; + grid-column: 1 / -1; + align-items: center; + padding: 3px 10px; + background: var(--bg); + + &:hover { + background: var(--bg-hover); + } + + &--header { + --bg: none; + --bg-hover: var(--bg); + font-weight: 600; + } + } +} diff --git a/resources/lang/en/common.php b/resources/lang/en/common.php index 5bb26369a5a..4441277b1e0 100644 --- a/resources/lang/en/common.php +++ b/resources/lang/en/common.php @@ -22,6 +22,7 @@ 'admin' => 'Admin', 'authorise' => 'Authorise', 'authorising' => 'Authorising...', + 'back' => 'Back', 'back_to_previous' => 'Return to previous position', 'back_to_top' => 'Back to top', 'cancel' => 'Cancel', diff --git a/resources/lang/en/teams.php b/resources/lang/en/teams.php index b268cf78172..463c321fd04 100644 --- a/resources/lang/en/teams.php +++ b/resources/lang/en/teams.php @@ -6,6 +6,7 @@ return [ 'edit' => [ 'saved' => 'Settings saved successfully', + 'title' => 'Team Settings', 'description' => [ 'label' => 'Description', @@ -37,6 +38,27 @@ ], ], + 'members' => [ + 'destroy' => [ + 'success' => 'Team member removed', + ], + + 'index' => [ + 'title' => 'Manage Members', + + 'table' => [ + 'status' => 'Status', + 'joined_at' => 'Join Date', + 'remove' => 'Remove', + 'title' => 'Current Members', + ], + + 'status' => [ + 'status_0' => 'Inactive', + 'status_1' => 'Active', + ], + ], + ], 'show' => [ 'bar' => [ 'settings' => 'Settings', diff --git a/resources/views/teams/members/index.blade.php b/resources/views/teams/members/index.blade.php new file mode 100644 index 00000000000..b470ff76f9d --- /dev/null +++ b/resources/views/teams/members/index.blade.php @@ -0,0 +1,92 @@ +{{-- + Copyright (c) ppy Pty Ltd . Licensed under the GNU Affero General Public License v3.0. + See the LICENCE file in the repository root for full licence text. +--}} +@extends('master') + +@section('content') + @include('layout._page_header_v4', ['params' => [ + 'theme' => 'team', + 'backgroundImage' => $team->header()->url(), + ]]) + +
+ +
+@endsection diff --git a/resources/views/teams/show.blade.php b/resources/views/teams/show.blade.php index ac8638e0a3a..ba1153f329c 100644 --- a/resources/views/teams/show.blade.php +++ b/resources/views/teams/show.blade.php @@ -37,7 +37,18 @@ class="profile-info__bg profile-info__bg--team"
+ + + + diff --git a/routes/web.php b/routes/web.php index c65e4547bc1..a94e8853fa3 100644 --- a/routes/web.php +++ b/routes/web.php @@ -296,6 +296,9 @@ Route::post('user-cover-presets/batch-activate', 'UserCoverPresetsController@batchActivate')->name('user-cover-presets.batch-activate'); Route::resource('user-cover-presets', 'UserCoverPresetsController', ['only' => ['index', 'store', 'update']]); + Route::group(['as' => 'teams.', 'prefix' => 'teams/{team}', 'namespace' => 'Teams'], function () { + Route::resource('members', 'MembersController', ['only' => ['destroy', 'index']]); + }); Route::resource('teams', 'TeamsController', ['only' => ['edit', 'show', 'update']]); Route::post('users/check-username-availability', 'UsersController@checkUsernameAvailability')->name('users.check-username-availability');