From 2352ef03693bfda4bb8ad1002adecb3482ca2d42 Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Thu, 7 Jan 2021 10:21:09 -0700 Subject: [PATCH] admin(ui): display dynamic user information on sidebar --- .../Api/Application/VersionController.php | 6 ++-- app/Models/User.php | 28 +++++++++++++++++-- .../Api/Application/BaseTransformer.php | 4 +-- .../Api/Application/UserTransformer.php | 5 ++-- resources/scripts/components/App.tsx | 8 ++++++ .../components/admin/users/UsersContainer.tsx | 2 +- resources/scripts/routers/AdminRouter.tsx | 14 ++++++---- resources/scripts/state/user.ts | 5 ++++ resources/views/templates/wrapper.blade.php | 2 +- 9 files changed, 57 insertions(+), 17 deletions(-) diff --git a/app/Http/Controllers/Api/Application/VersionController.php b/app/Http/Controllers/Api/Application/VersionController.php index 6956226b3..ee64b16ca 100644 --- a/app/Http/Controllers/Api/Application/VersionController.php +++ b/app/Http/Controllers/Api/Application/VersionController.php @@ -25,9 +25,11 @@ class VersionController extends ApplicationApiController } /** - * ? + * Returns version information. + * + * @return \Illuminate\Http\JsonResponse */ - public function __invoke() + public function __invoke(): JsonResponse { return new JsonResponse($this->softwareVersionService->getVersionData()); } diff --git a/app/Models/User.php b/app/Models/User.php index 24ef981f4..109700f28 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -168,9 +168,13 @@ class User extends Model implements * * @return array */ - public function toVueObject(): array + public function toReactObject(): array { - return (new Collection($this->toArray()))->except(['id', 'external_id'])->toArray(); + $object = (new Collection($this->toArray()))->except(['id', 'external_id'])->toArray(); + $object['avatar_url'] = $this->avatarURL(); + $object['role_name'] = $this->roleName(); + + return $object; } /** @@ -203,6 +207,26 @@ class User extends Model implements return trim($this->name_first . ' ' . $this->name_last); } + /** + * Get's the avatar url for the user. + * + * @return string + */ + public function avatarURL(): string + { + return 'https://www.gravatar.com/avatar/' . md5($this->email) . '.jpg'; + } + + /** + * Get's the name of the role assigned to a user. + * + * @return string|null + */ + public function roleName():? string + { + return $this->root_admin ? 'Super Administrator' : null; + } + /** * Returns all servers that a user owns. * diff --git a/app/Transformers/Api/Application/BaseTransformer.php b/app/Transformers/Api/Application/BaseTransformer.php index 90618fb09..4e8d5f7ac 100644 --- a/app/Transformers/Api/Application/BaseTransformer.php +++ b/app/Transformers/Api/Application/BaseTransformer.php @@ -20,12 +20,12 @@ abstract class BaseTransformer extends TransformerAbstract /** * @var \Pterodactyl\Models\ApiKey */ - private $key; + private ApiKey $key; /** * @var bool */ - private $rootAdmin; + private bool $rootAdmin; /** * Return the resource name for the JSONAPI output. diff --git a/app/Transformers/Api/Application/UserTransformer.php b/app/Transformers/Api/Application/UserTransformer.php index e48c406cc..24fb6360a 100644 --- a/app/Transformers/Api/Application/UserTransformer.php +++ b/app/Transformers/Api/Application/UserTransformer.php @@ -43,11 +43,10 @@ class UserTransformer extends BaseTransformer 'language' => $model->language, 'root_admin' => (bool) $model->root_admin, '2fa' => (bool) $model->use_totp, - 'avatar_url' => 'https://www.gravatar.com/avatar/' . md5($model->email) . '.jpg?s=40', - 'role_name' => $model->root_admin ? 'Super Administrator' : null, + 'avatar_url' => $model->avatarURL(), + 'role_name' => $model->roleName(), 'created_at' => $this->formatTimestamp($model->created_at), 'updated_at' => $this->formatTimestamp($model->updated_at), - 'avatar' ]; } diff --git a/resources/scripts/components/App.tsx b/resources/scripts/components/App.tsx index 5f42d13cd..dad6ef137 100644 --- a/resources/scripts/components/App.tsx +++ b/resources/scripts/components/App.tsx @@ -24,9 +24,13 @@ interface ExtendedWindow extends Window { username: string; email: string; /* eslint-disable camelcase */ + name_first: string; + name_last: string; root_admin: boolean; use_totp: boolean; language: string; + avatar_url: string; + role_name: string; updated_at: string; created_at: string; /* eslint-enable camelcase */ @@ -52,9 +56,13 @@ const App = () => { uuid: PterodactylUser.uuid, username: PterodactylUser.username, email: PterodactylUser.email, + firstName: PterodactylUser.name_first, + lastName: PterodactylUser.name_last, language: PterodactylUser.language, rootAdmin: PterodactylUser.root_admin, useTotp: PterodactylUser.use_totp, + avatarURL: PterodactylUser.avatar_url, + roleName: PterodactylUser.role_name, createdAt: new Date(PterodactylUser.created_at), updatedAt: new Date(PterodactylUser.updated_at), }); diff --git a/resources/scripts/components/admin/users/UsersContainer.tsx b/resources/scripts/components/admin/users/UsersContainer.tsx index f677a28ac..83d5fbddb 100644 --- a/resources/scripts/components/admin/users/UsersContainer.tsx +++ b/resources/scripts/components/admin/users/UsersContainer.tsx @@ -117,7 +117,7 @@ const UsersContainer = () => {
- +
diff --git a/resources/scripts/routers/AdminRouter.tsx b/resources/scripts/routers/AdminRouter.tsx index 138d82f25..bd7e408a4 100644 --- a/resources/scripts/routers/AdminRouter.tsx +++ b/resources/scripts/routers/AdminRouter.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { NavLink, Route, RouteComponentProps, Switch } from 'react-router-dom'; -import { useStoreState } from 'easy-peasy'; +import { State, useStoreState } from 'easy-peasy'; import tw from 'twin.macro'; import styled from 'styled-components/macro'; import { ApplicationStore } from '@/state'; @@ -88,7 +88,9 @@ const Sidebar = styled.div<{ collapsed?: boolean }>` `; const AdminRouter = ({ location, match }: RouteComponentProps) => { - const name = useStoreState((state: ApplicationStore) => state.settings.data!.name); + const user = useStoreState((state: State) => state.user.data); + const applicationName = useStoreState((state: ApplicationStore) => state.settings.data!.name); + const [ collapsed, setCollapsed ] = useState(); return ( @@ -96,7 +98,7 @@ const AdminRouter = ({ location, match }: RouteComponentProps) => {
{ setCollapsed(!collapsed); } }> { !collapsed ? -

{name}

+

{applicationName}

: {'Pterodactyl } @@ -162,11 +164,11 @@ const AdminRouter = ({ location, match }: RouteComponentProps) => {
- Profile Picture + Profile Picture
- Matthew Penner - Super Administrator + {user?.firstName} {user?.lastName} + {user?.roleName}
diff --git a/resources/scripts/state/user.ts b/resources/scripts/state/user.ts index f04f878ae..a49329338 100644 --- a/resources/scripts/state/user.ts +++ b/resources/scripts/state/user.ts @@ -5,9 +5,13 @@ export interface UserData { uuid: string; username: string; email: string; + firstName: string; + lastName: string; language: string; rootAdmin: boolean; useTotp: boolean; + avatarURL: string; + roleName: string; createdAt: Date; updatedAt: Date; } @@ -21,6 +25,7 @@ export interface UserStore { const user: UserStore = { data: undefined, + setUserData: action((state, payload) => { state.data = payload; }), diff --git a/resources/views/templates/wrapper.blade.php b/resources/views/templates/wrapper.blade.php index 89bb7b566..5f4b90eee 100644 --- a/resources/views/templates/wrapper.blade.php +++ b/resources/views/templates/wrapper.blade.php @@ -21,7 +21,7 @@ @section('user-data') @if(!is_null(Auth::user())) @endif @if(!empty($siteConfiguration))