diff --git a/app/Authorization/FlatAuthorization.php b/app/Authorization/FlatAuthorization.php index a732a8cbfdbf0dce34f95eb8b996202f4eb06c4a..f96fb2aa7b77fdf7e6d0c483a11fcbf6ed0b3999 100644 --- a/app/Authorization/FlatAuthorization.php +++ b/app/Authorization/FlatAuthorization.php @@ -49,7 +49,7 @@ class FlatAuthorization extends \Myth\Auth\Authorization\FlatAuthorization } /** - * Makes a member a part of multiple groups. + * Makes user part of given groups. * * @param $userId * @param array|null $groups // Either collection of ID or names diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 84a96218aca70886e2e5c6cbf0066bfc986b9d55..e288b15e2e497157f97331aa3a90941de637b205 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -77,11 +77,11 @@ $routes->group( $routes->get('podcasts', 'Podcast::list', [ 'as' => 'podcast_list', ]); - $routes->get('new-podcast', 'Podcast::create', [ + $routes->get('podcasts/new', 'Podcast::create', [ 'as' => 'podcast_create', 'filter' => 'permission:podcasts-create', ]); - $routes->post('new-podcast', 'Podcast::attemptCreate', [ + $routes->post('podcasts/new', 'Podcast::attemptCreate', [ 'filter' => 'permission:podcasts-create', ]); @@ -108,19 +108,19 @@ $routes->group( 'as' => 'episode_list', 'filter' => 'permission:podcasts-view,podcast-view', ]); - $routes->get('new-episode', 'Episode::create/$1', [ + $routes->get('episodes/new', 'Episode::create/$1', [ 'as' => 'episode_create', 'filter' => 'permission:episodes-create,podcast_episodes-create', ]); - $routes->post('new-episode', 'Episode::attemptCreate/$1', [ + $routes->post('episodes/new', 'Episode::attemptCreate/$1', [ 'filter' => 'permission:episodes-create,podcast_episodes-create', ]); $routes->get('episodes/(:num)', 'Episode::view/$1/$2', [ 'as' => 'episode_view', - 'filter' => 'permission:episodes-list,podcast_episodes-list', + 'filter' => 'permission:episodes-view,podcast_episodes-view', ]); $routes->get('episodes/(:num)/edit', 'Episode::edit/$1/$2', [ 'as' => 'episode_edit', @@ -146,15 +146,18 @@ $routes->group( 'filter' => 'permission:podcasts-manage_contributors,podcast-manage_contributors', ]); - $routes->get('add-contributor', 'Contributor::add/$1', [ + $routes->get('contributors/add', 'Contributor::add/$1', [ 'as' => 'contributor_add', 'filter' => 'permission:podcasts-manage_contributors,podcast-manage_contributors', ]); - $routes->post('add-contributor', 'Contributor::attemptAdd/$1', [ + $routes->post('contributors/add', 'Contributor::attemptAdd/$1', [ 'filter' => 'permission:podcasts-manage_contributors,podcast-manage_contributors', ]); + $routes->get('contributors/(:num)', 'Contributor::view/$1/$2', [ + 'as' => 'contributor_view', + ]); $routes->get( 'contributors/(:num)/edit', 'Contributor::edit/$1/$2', @@ -188,11 +191,15 @@ $routes->group( 'as' => 'user_list', 'filter' => 'permission:users-list', ]); - $routes->get('new-user', 'User::create', [ + $routes->get('users/new', 'User::create', [ 'as' => 'user_create', 'filter' => 'permission:users-create', ]); - $routes->post('new-user', 'User::attemptCreate', [ + $routes->get('users/(:num)', 'User::view/$1', [ + 'as' => 'user_view', + 'filter' => 'permission:users-view', + ]); + $routes->post('users/new', 'User::attemptCreate', [ 'filter' => 'permission:users-create', ]); $routes->get('users/(:num)/edit', 'User::edit/$1', [ diff --git a/app/Config/Services.php b/app/Config/Services.php index 275caab2378c034309dc7a1ea9327ba241fa0bdb..27d601fae5d0d6ae1398dad31cf9b242946679f4 100644 --- a/app/Config/Services.php +++ b/app/Config/Services.php @@ -7,6 +7,7 @@ use CodeIgniter\Model; use App\Authorization\FlatAuthorization; use App\Authorization\PermissionModel; use App\Authorization\GroupModel; +use App\Libraries\Breadcrumb; use App\Models\UserModel; use Myth\Auth\Models\LoginModel; @@ -91,4 +92,13 @@ class Services extends CoreServices return $instance->setUserModel($userModel); } + + public static function breadcrumb(bool $getShared = true) + { + if ($getShared) { + return self::getSharedInstance('breadcrumb'); + } + + return new Breadcrumb(); + } } diff --git a/app/Controllers/Admin/BaseController.php b/app/Controllers/Admin/BaseController.php index a10692c9e765010a296e8461e748fcfa21ca2ffd..92f4849ab40c42b399f2264210c53558ad081147 100644 --- a/app/Controllers/Admin/BaseController.php +++ b/app/Controllers/Admin/BaseController.php @@ -26,7 +26,7 @@ class BaseController extends Controller * * @var array */ - protected $helpers = ['auth']; + protected $helpers = ['auth', 'breadcrumb', 'svg']; /** * Constructor. diff --git a/app/Controllers/Admin/Contributor.php b/app/Controllers/Admin/Contributor.php index 4f5a8ae8250513d9ec91be83a92c7922f85a6bdc..2f8ed6d5f46a3554193510a46f900326281240b1 100644 --- a/app/Controllers/Admin/Contributor.php +++ b/app/Controllers/Admin/Contributor.php @@ -41,7 +41,24 @@ class Contributor extends BaseController 'podcast' => $this->podcast, ]; - echo view('admin/contributor/list', $data); + replace_breadcrumb_params([0 => $this->podcast->title]); + return view('admin/contributor/list', $data); + } + + public function view() + { + $data = [ + 'contributor' => (new UserModel())->getPodcastContributor( + $this->user->id, + $this->podcast->id + ), + ]; + + replace_breadcrumb_params([ + 0 => $this->podcast->title, + 1 => $this->user->username, + ]); + return view('admin/contributor/view', $data); } public function add() @@ -52,7 +69,8 @@ class Contributor extends BaseController 'roles' => (new GroupModel())->getContributorRoles(), ]; - echo view('admin/contributor/add', $data); + replace_breadcrumb_params([0 => $this->podcast->title]); + return view('admin/contributor/add', $data); } public function attemptAdd() @@ -87,7 +105,11 @@ class Contributor extends BaseController 'roles' => (new GroupModel())->getContributorRoles(), ]; - echo view('admin/contributor/edit', $data); + replace_breadcrumb_params([ + 0 => $this->podcast->title, + 1 => $this->user->username, + ]); + return view('admin/contributor/edit', $data); } public function attemptEdit() diff --git a/app/Controllers/Admin/Episode.php b/app/Controllers/Admin/Episode.php index 0c5ce4c2736ff318d34bd274718fb3f0c9a014eb..b639512ef16e95b5eb07c2827aae69b0a60e020d 100644 --- a/app/Controllers/Admin/Episode.php +++ b/app/Controllers/Admin/Episode.php @@ -42,6 +42,9 @@ class Episode extends BaseController 'podcast' => $this->podcast, ]; + replace_breadcrumb_params([ + 0 => $this->podcast->title, + ]); return view('admin/episode/list', $data); } @@ -49,6 +52,10 @@ class Episode extends BaseController { $data = ['episode' => $this->episode]; + replace_breadcrumb_params([ + 0 => $this->podcast->title, + 1 => $this->episode->title, + ]); return view('admin/episode/view', $data); } @@ -60,7 +67,10 @@ class Episode extends BaseController 'podcast' => $this->podcast, ]; - echo view('admin/episode/create', $data); + replace_breadcrumb_params([ + 0 => $this->podcast->title, + ]); + return view('admin/episode/create', $data); } public function attemptCreate() @@ -115,7 +125,11 @@ class Episode extends BaseController 'episode' => $this->episode, ]; - echo view('admin/episode/edit', $data); + replace_breadcrumb_params([ + 0 => $this->podcast->title, + 1 => $this->episode->title, + ]); + return view('admin/episode/edit', $data); } public function attemptEdit() diff --git a/app/Controllers/Admin/Podcast.php b/app/Controllers/Admin/Podcast.php index 99209e0761201f49b2eb9de4661a7becd585aa3b..c0e5b2cb33adb0eb56e29c75ddc2e48a7ea770d7 100644 --- a/app/Controllers/Admin/Podcast.php +++ b/app/Controllers/Admin/Podcast.php @@ -52,6 +52,7 @@ class Podcast extends BaseController { $data = ['podcast' => $this->podcast]; + replace_breadcrumb_params([0 => $this->podcast->title]); return view('admin/podcast/view', $data); } @@ -69,7 +70,7 @@ class Podcast extends BaseController ), ]; - echo view('admin/podcast/create', $data); + return view('admin/podcast/create', $data); } public function attemptCreate() @@ -145,7 +146,8 @@ class Podcast extends BaseController 'categories' => (new CategoryModel())->findAll(), ]; - echo view('admin/podcast/edit', $data); + replace_breadcrumb_params([0 => $this->podcast->title]); + return view('admin/podcast/edit', $data); } public function attemptEdit() diff --git a/app/Controllers/Admin/User.php b/app/Controllers/Admin/User.php index 98470cf13f8a805f1559cdee48b92fb979ea3b19..872d973ff82707e03e4cb408720a235b9ca5099d 100644 --- a/app/Controllers/Admin/User.php +++ b/app/Controllers/Admin/User.php @@ -34,13 +34,21 @@ class User extends BaseController return view('admin/user/list', $data); } + public function view() + { + $data = ['user' => $this->user]; + + replace_breadcrumb_params([0 => $this->user->username]); + return view('admin/user/view', $data); + } + public function create() { $data = [ 'roles' => (new GroupModel())->getUserRoles(), ]; - echo view('admin/user/create', $data); + return view('admin/user/create', $data); } public function attemptCreate() @@ -99,7 +107,8 @@ class User extends BaseController 'roles' => (new GroupModel())->getUserRoles(), ]; - echo view('admin/user/edit', $data); + replace_breadcrumb_params([0 => $this->user->username]); + return view('admin/user/edit', $data); } public function attemptEdit() diff --git a/app/Database/Seeds/AuthSeeder.php b/app/Database/Seeds/AuthSeeder.php index 5ce7edcce68040bec8dcd350c54dadfdd94e340f..6ddfd950128b5fff43f9e08992afb6be8408ddcb 100644 --- a/app/Database/Seeds/AuthSeeder.php +++ b/app/Database/Seeds/AuthSeeder.php @@ -50,6 +50,11 @@ class AuthSeeder extends Seeder 'description' => 'List all users', 'has_permission' => ['superadmin'], ], + [ + 'name' => 'view', + 'description' => 'View any user info', + 'has_permission' => ['superadmin'], + ], [ 'name' => 'manage_authorizations', 'description' => 'Add or remove roles/permissions to a user', @@ -128,6 +133,11 @@ class AuthSeeder extends Seeder 'description' => 'List all episodes of any podcast', 'has_permission' => ['superadmin'], ], + [ + 'name' => 'view', + 'description' => 'View any episode of any podcast', + 'has_permission' => ['superadmin'], + ], [ 'name' => 'create', 'description' => 'Add a new episode to any podcast', @@ -195,6 +205,11 @@ class AuthSeeder extends Seeder 'description' => 'List all episodes of a podcast', 'has_permission' => ['podcast_admin'], ], + [ + 'name' => 'view', + 'description' => 'View any episode of a podcast', + 'has_permission' => ['podcast_admin'], + ], [ 'name' => 'create', 'description' => 'Add new episodes for a podcast', diff --git a/app/Entities/User.php b/app/Entities/User.php index f710fd069260536d58b2e25da50239996f314b86..88fe6ed9621c106d00650832b9a5b09e17e93706 100644 --- a/app/Entities/User.php +++ b/app/Entities/User.php @@ -12,6 +12,12 @@ class User extends \Myth\Auth\Entities\User */ protected $podcasts = []; + /** + * The podcast user is contributing to + * @var \App\Entities\Podcast + */ + protected $podcast; + /** * Array of field names and the type of value to cast them as * when they are accessed. @@ -20,6 +26,7 @@ class User extends \Myth\Auth\Entities\User 'active' => 'boolean', 'force_pass_reset' => 'boolean', 'podcast_role' => '?string', + 'podcast_id' => '?integer', ]; /** @@ -41,4 +48,19 @@ class User extends \Myth\Auth\Entities\User return $this->podcasts; } + + public function getPodcast() + { + if (empty($this->podcast_id)) { + throw new \RuntimeException( + 'Podcast_id must be set before getting podcast.' + ); + } + + if (empty($this->podcast)) { + $this->podcast = (new PodcastModel())->find($this->podcast_id); + } + + return $this->podcast; + } } diff --git a/app/Helpers/breadcrumb_helper.php b/app/Helpers/breadcrumb_helper.php new file mode 100644 index 0000000000000000000000000000000000000000..52022860be06c48f5371bfa881ccd867972a8ab9 --- /dev/null +++ b/app/Helpers/breadcrumb_helper.php @@ -0,0 +1,28 @@ +<?php + +/** + * @copyright 2020 Podlibre + * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 + * @link https://castopod.org/ + */ + +use Config\Services; + +/** + * Returns the inline svg icon + * + * @param string $name name of the icon file without the .svg extension + * @param string $class to be added to the svg string + * @return string html breadcrumb + */ +function render_breadcrumb() +{ + $breadcrumb = Services::breadcrumb(); + return $breadcrumb->render(); +} + +function replace_breadcrumb_params($newParams) +{ + $breadcrumb = Services::breadcrumb(); + $breadcrumb->replaceParams($newParams); +} diff --git a/app/Helpers/html_helper.php b/app/Helpers/svg_helper.php similarity index 100% rename from app/Helpers/html_helper.php rename to app/Helpers/svg_helper.php diff --git a/app/Language/en/Breadcrumb.php b/app/Language/en/Breadcrumb.php new file mode 100644 index 0000000000000000000000000000000000000000..6ef22d33d2b1a3e972595ad51cb0edc6be069d66 --- /dev/null +++ b/app/Language/en/Breadcrumb.php @@ -0,0 +1,22 @@ +<?php + +/** + * @copyright 2020 Podlibre + * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 + * @link https://castopod.org/ + */ + +return [ + 'label' => 'breadcrumb', + config('App')->adminGateway => 'Home', + 'my-podcasts' => 'my podcasts', + 'podcasts' => 'podcasts', + 'episodes' => 'episodes', + 'contributors' => 'contributors', + 'add' => 'add', + 'new' => 'new', + 'edit' => 'edit', + 'users' => 'users', + 'my-account' => 'my account', + 'change-password' => 'change password', +]; diff --git a/app/Language/en/Contributor.php b/app/Language/en/Contributor.php index a9bf108bc5320859c11a096c41fa083489995f63..25fed243667fe145cd0d15026906c0ccf67725e8 100644 --- a/app/Language/en/Contributor.php +++ b/app/Language/en/Contributor.php @@ -8,6 +8,7 @@ return [ 'podcast_contributors' => 'Podcast contributors', + 'view' => '{username}\'s contribution to {podcastName}', 'add' => 'Add contributor', 'add_contributor' => 'Add a contributor for {0}', 'edit_role' => 'Update role for {0}', diff --git a/app/Language/en/MyAccount.php b/app/Language/en/MyAccount.php index c65d934460b65139629a421417b8b090323f5d32..b675cc177005156f91041bb8e2fa59407929517d 100644 --- a/app/Language/en/MyAccount.php +++ b/app/Language/en/MyAccount.php @@ -8,8 +8,8 @@ return [ 'info' => 'My account info', + 'changePassword' => 'Change my password', 'messages' => [ 'passwordChangeSuccess' => 'Password has been successfully changed!', - 'changePassword' => 'Change my password', ], ]; diff --git a/app/Language/en/User.php b/app/Language/en/User.php index 2cdc1e332a766bed8c4a7d486b288362dd5a8ff3..0e742c2a3200b228dd476a1e75128ae02ab4618d 100644 --- a/app/Language/en/User.php +++ b/app/Language/en/User.php @@ -13,6 +13,7 @@ return [ 'unban' => 'Unban', 'delete' => 'Delete', 'create' => 'Create a user', + 'view' => '{username}\'s info', 'all_users' => 'All users', 'form' => [ 'email' => 'Email', diff --git a/app/Libraries/Breadcrumb.php b/app/Libraries/Breadcrumb.php new file mode 100644 index 0000000000000000000000000000000000000000..43cb2f951ac2db08ad8686004233d9effa29fa12 --- /dev/null +++ b/app/Libraries/Breadcrumb.php @@ -0,0 +1,104 @@ +<?php + +/** + * Generates and renders a breadcrumb based on the current url segments + * + * @copyright 2020 Podlibre + * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 + * @link https://castopod.org/ + */ + +namespace App\Libraries; + +class Breadcrumb +{ + /** + * List of breadcrumb links. + * + * @var array + * $links = [ + * 'text' => (string) the anchor text, + * 'href' => (string) the anchor href, + * ] + */ + protected $links = []; + + /** + * Initializes the Breadcrumb object using the segments from + * current_url by populating the $links property with text and href data + */ + public function __construct() + { + $uri = ''; + foreach (current_url(true)->getSegments() as $segment) { + $uri .= '/' . $segment; + array_push($this->links, [ + 'text' => is_numeric($segment) + ? $segment + : lang('Breadcrumb.' . $segment), + 'href' => base_url($uri), + ]); + } + } + + /** + * Replaces all numeric text in breadcrumb's $link property + * with new params at same position + * + * Given a breadcrumb with numeric params, this function + * replaces them with the values provided in $newParams + * + * Example with `Home / podcasts / 1 / episodes / 1` + * + * $newParams = [ + * 0 => 'foo', + * 1 => 'bar' + * ] + * replaceParams($newParams); + * + * The breadcrumb is now `Home / podcasts / foo / episodes / bar` + * + * @param array $newParams + */ + public function replaceParams($newParams) + { + foreach ($this->links as $key => $link) { + if (is_numeric($link['text'])) { + $this->links[$key]['text'] = $newParams[0]; + array_shift($newParams); + } + } + } + + /** + * Renders the breadcrumb object as an accessible html breadcrumb nav + * + * @return string + */ + public function render() + { + $listItems = ''; + $keys = array_keys($this->links); + foreach ($this->links as $key => $link) { + if (end($keys) == $key) { + $listItem = + '<li class="breadcrumb-item active" aria-current="page">' . + $link['text'] . + '</li>'; + } else { + $listItem = + '<li class="breadcrumb-item">' . + anchor($link['href'], $link['text']) . + '</li>'; + } + + $listItems .= $listItem; + } + + return '<nav aria-label="' . + lang('Breadcrumb.label') . + '"><ol class="breadcrumb">' . + $listItems . + '</ol></nav>'; + } +} diff --git a/app/Models/UserModel.php b/app/Models/UserModel.php index 420c002dae5a76cc68ca0ce46e9bae69c84905bb..4f9f7d033370db62677288fbb2b27928af724437 100644 --- a/app/Models/UserModel.php +++ b/app/Models/UserModel.php @@ -17,8 +17,11 @@ class UserModel extends \Myth\Auth\Models\UserModel public function getPodcastContributor($user_id, $podcast_id) { - return $this->select('users.*') + return $this->select( + 'users.*, users_podcasts.podcast_id as podcast_id, auth_groups.name as podcast_role' + ) ->join('users_podcasts', 'users_podcasts.user_id = users.id') + ->join('auth_groups', 'auth_groups.id = users_podcasts.group_id') ->where([ 'users.id' => $user_id, 'podcast_id' => $podcast_id, diff --git a/app/Views/_assets/styles/breadcrumb.css b/app/Views/_assets/styles/breadcrumb.css new file mode 100644 index 0000000000000000000000000000000000000000..f2cb91620f3d705ceb52a267340bca7250dd1e81 --- /dev/null +++ b/app/Views/_assets/styles/breadcrumb.css @@ -0,0 +1,20 @@ +.breadcrumb { + @apply inline-flex flex-wrap px-1 py-2 text-sm text-gray-800; +} + +.breadcrumb-item + .breadcrumb-item::before { + @apply inline-block px-1 text-gray-500; + content: "/"; +} + +.breadcrumb-item a { + @apply no-underline; + + &:hover { + @apply underline; + } +} + +.breadcrumb-item.active { + @apply font-semibold; +} diff --git a/app/Views/_assets/styles/index.css b/app/Views/_assets/styles/index.css index 5f4c3b7fdaec0ce2056abacf6e69a053408fd33b..f12f46bb993ef86487ccce073593a77c8abe5439 100644 --- a/app/Views/_assets/styles/index.css +++ b/app/Views/_assets/styles/index.css @@ -1,2 +1,3 @@ @import "./tailwind.css"; @import "./layout.css"; +@import "./breadcrumb.css"; diff --git a/app/Views/admin/_header.php b/app/Views/admin/_header.php index 3fc1d87718cadc62d28d5518eed3e24315a82457..b97236e3cf7829abf2332ae91be094cb7ce8d20a 100644 --- a/app/Views/admin/_header.php +++ b/app/Views/admin/_header.php @@ -1,10 +1,13 @@ <header class="<?= $class ?>"> - <a href="<?= route_to( - 'admin_home' - ) ?>" class="inline-flex items-center text-xl"> - <?= svg('logo-castopod', 'text-3xl mr-2 -ml-2') ?> - Admin - </a> + <div class="w-64"> + <a href="<?= route_to( + 'admin_home' + ) ?>" class="inline-flex items-center text-xl"> + <?= svg('logo-castopod', 'text-3xl mr-2') ?> + Admin + </a> + </div> + <?= render_breadcrumb() ?> <div class="relative ml-auto" data-toggle="dropdown"> <button type="button" class="inline-flex items-center px-2 py-1 outline-none focus:shadow-outline" id="myAccountDropdown" data-popper="button" aria-haspopup="true" aria-expanded="false"> Hey <?= user()->username ?> diff --git a/app/Views/admin/_layout.php b/app/Views/admin/_layout.php index 75b11ac5ed750872c6f289822207b36c9565e1d8..f87c44f151c22d3f91e16bb9ea922f2a7e0f8b54 100644 --- a/app/Views/admin/_layout.php +++ b/app/Views/admin/_layout.php @@ -1,7 +1,3 @@ -<?php - -helper('html'); ?> - <!DOCTYPE html> <html lang="en"> diff --git a/app/Views/admin/_partials/_episode-card.php b/app/Views/admin/_partials/_episode-card.php index baf0b5677fb02b6236c30d87277d17dd38b1a24d..af1b46de638f237cf9e7fa246414154edcfcba84 100644 --- a/app/Views/admin/_partials/_episode-card.php +++ b/app/Views/admin/_partials/_episode-card.php @@ -1,7 +1,3 @@ -<?php - -helper('html'); ?> - <article class="flex w-full max-w-lg mb-4 bg-white border rounded shadow"> <img src="<?= $episode->image_url ?>" alt="<?= $episode->title ?>" class="object-cover w-32 h-32 rounded-l" /> <div class="flex flex-col flex-1 px-4 py-2"> diff --git a/app/Views/admin/_partials/_user_info.php b/app/Views/admin/_partials/_user_info.php new file mode 100644 index 0000000000000000000000000000000000000000..576311f197a6651403d56b3e10f0c3f15c70b53d --- /dev/null +++ b/app/Views/admin/_partials/_user_info.php @@ -0,0 +1,32 @@ +<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> + <dt class="text-sm font-medium leading-5 text-gray-500"> + Email + </dt> + <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> + <?= $user->email ?> + </dd> +</div> +<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> + <dt class="text-sm font-medium leading-5 text-gray-500"> + Username + </dt> + <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> + <?= $user->username ?> + </dd> +</div> +<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> + <dt class="text-sm font-medium leading-5 text-gray-500"> + Roles + </dt> + <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> + [<?= implode(', ', $user->roles) ?>] + </dd> +</div> +<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> + <dt class="text-sm font-medium leading-5 text-gray-500"> + Permissions + </dt> + <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> + [<?= implode(', ', $user->permissions) ?>] + </dd> +</div> \ No newline at end of file diff --git a/app/Views/admin/_sidenav.php b/app/Views/admin/_sidenav.php index 8b51f3139707135965eaeacd974c656659ba366d..fa349177e1159796f9062149e296aa81a9d76a67 100644 --- a/app/Views/admin/_sidenav.php +++ b/app/Views/admin/_sidenav.php @@ -11,7 +11,7 @@ $navigation = [ <nav class="<?= $class ?>"> <?php foreach ($navigation as $section => $data): ?> <div class="mb-4"> - <button class="inline-flex items-center w-full px-4 py-1 outline-none focus:shadow-outline" type="button"> + <button class="inline-flex items-center w-full px-6 py-1 outline-none focus:shadow-outline" type="button"> <?= icon($data['icon'], 'text-gray-500') ?> <span class="ml-2"><?= lang('AdminNavigation.' . $section) ?></span> </button> diff --git a/app/Views/admin/contributor/list.php b/app/Views/admin/contributor/list.php index f80732a2cf36c5fb89588ff590f6f6fa1fb0b322..b0e7eb41a074f809d7c75e7073a3223f72f518be 100644 --- a/app/Views/admin/contributor/list.php +++ b/app/Views/admin/contributor/list.php @@ -1,5 +1,3 @@ -<?php helper('html'); ?> - <?= $this->extend('admin/_layout') ?> <?= $this->section('title') ?> diff --git a/app/Views/admin/contributor/view.php b/app/Views/admin/contributor/view.php new file mode 100644 index 0000000000000000000000000000000000000000..2aca7825701db03e64240e2e3d0daf3891c8ba93 --- /dev/null +++ b/app/Views/admin/contributor/view.php @@ -0,0 +1,28 @@ +<?= $this->extend('admin/_layout') ?> + +<?= $this->section('title') ?> +<?= lang('Contributor.view', [ + 'username' => $contributor->username, + 'podcastName' => $contributor->podcast->name, +]) ?> +<?= $this->endSection() ?> + + +<?= $this->section('content') ?> +<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> + <dt class="text-sm font-medium leading-5 text-gray-500"> + Username + </dt> + <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> + <?= $contributor->username ?> + </dd> +</div> +<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> + <dt class="text-sm font-medium leading-5 text-gray-500"> + Role + </dt> + <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> + <?= $contributor->podcast_role ?> + </dd> +</div> +<?= $this->endSection() ?> diff --git a/app/Views/admin/episode/list.php b/app/Views/admin/episode/list.php index 1b86523d64526d03e85478f5166650905eaccefa..59f457c40da05135c384f093fca3599634098ca1 100644 --- a/app/Views/admin/episode/list.php +++ b/app/Views/admin/episode/list.php @@ -3,17 +3,18 @@ <?= $this->section('title') ?> <?= lang('Episode.all_podcast_episodes') ?> (<?= count($podcast->episodes) ?>) +<a class="inline-flex items-center px-2 py-1 mb-2 ml-2 text-sm text-white bg-green-500 rounded shadow-xs outline-none hover:bg-green-600 focus:shadow-outline" href="<?= route_to( + 'episode_create', + $podcast->id +) ?>"> +<?= icon('add', 'mr-2') ?> +<?= lang('Episode.create') ?></a> <?= $this->endSection() ?> <?= $this->section('content') ?> -<a class="inline-block px-4 py-2 mb-2 border hover:bg-gray-100" href="<?= route_to( - 'episode_create', - $podcast->id -) ?>"><?= lang('Episode.create') ?></a> - <?= view('admin/_partials/_episode-list.php', [ 'episodes' => $podcast->episodes, ]) ?> diff --git a/app/Views/admin/episode/view.php b/app/Views/admin/episode/view.php index 5bea39c45aaef7e388e69a914c1b2bc6594680a5..90b9a343ae0a12d6a343fae359963f41d3844430 100644 --- a/app/Views/admin/episode/view.php +++ b/app/Views/admin/episode/view.php @@ -1,12 +1,11 @@ <?= $this->extend('admin/_layout') ?> +<?= $this->section('title') ?> +<?= $episode->title ?> +<?= $this->endSection() ?> + <?= $this->section('content') ?> -<a class="underline hover:no-underline" href="<?= route_to( - 'podcast_view', - $episode->podcast->id -) ?>">< <?= lang('Episode.back_to_podcast') ?></a> -<h1 class="text-2xl font-semibold"><?= $episode->title ?></h1> <img src="<?= $episode->image_url ?>" alt="Episode cover" class="object-cover w-40 h-40 mb-6" /> <audio controls preload="none" class="mb-12"> <source src="<?= $episode->enclosure_url ?>" type="<?= $episode->enclosure_type ?>"> diff --git a/app/Views/admin/my_account/view.php b/app/Views/admin/my_account/view.php index 92ce2ed5b330879f9a9c67e1b68ba56b76970bdf..556876d561d73b3cc7d4447f1973f841ce7410bc 100644 --- a/app/Views/admin/my_account/view.php +++ b/app/Views/admin/my_account/view.php @@ -7,30 +7,7 @@ <?= $this->section('content') ?> -<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> - <dt class="text-sm font-medium leading-5 text-gray-500"> - Email - </dt> - <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> - <?= user()->email ?> - </dd> -</div> -<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> - <dt class="text-sm font-medium leading-5 text-gray-500"> - Username - </dt> - <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> - <?= user()->username ?> - </dd> -</div> -<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> - <dt class="text-sm font-medium leading-5 text-gray-500"> - Permissions - </dt> - <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> - [<?= implode(', ', user()->permissions) ?>] - </dd> -</div> +<?= view('admin/_partials/_user_info.php', ['user' => user()]) ?> <?= $this->endSection() ?> diff --git a/app/Views/admin/podcast/list.php b/app/Views/admin/podcast/list.php index 9f18b1cfec73921a330bbab658bf0a6140200fca..2efbe4d931ec7a74c120636ebd79d2f1c16be014 100644 --- a/app/Views/admin/podcast/list.php +++ b/app/Views/admin/podcast/list.php @@ -1,5 +1,3 @@ -<?php helper('html'); ?> - <?= $this->extend('admin/_layout') ?> <?= $this->section('title') ?> diff --git a/app/Views/admin/podcast/view.php b/app/Views/admin/podcast/view.php index 9a781031c0ad784d2b7fce6d6d93f55879344b26..3f21185e41a7191bae3a312492f63102d246bb7a 100644 --- a/app/Views/admin/podcast/view.php +++ b/app/Views/admin/podcast/view.php @@ -1,7 +1,3 @@ -<?php - -helper('html'); ?> - <?= $this->extend('admin/_layout') ?> <?= $this->section('title') ?> diff --git a/app/Views/admin/user/list.php b/app/Views/admin/user/list.php index 078d14ea70758331802af5dce8b2cbb3e7193e67..a8d096358b4d1d83b1ab3f24b7acf5f9083d51df 100644 --- a/app/Views/admin/user/list.php +++ b/app/Views/admin/user/list.php @@ -1,5 +1,3 @@ -<?php helper('html'); ?> - <?= $this->extend('admin/_layout') ?> <?= $this->section('title') ?> diff --git a/app/Views/admin/user/view.php b/app/Views/admin/user/view.php new file mode 100644 index 0000000000000000000000000000000000000000..42aa6495f80ad76e5493c7f64fec78628120a4ca --- /dev/null +++ b/app/Views/admin/user/view.php @@ -0,0 +1,12 @@ +<?= $this->extend('admin/_layout') ?> + +<?= $this->section('title') ?> +<?= lang('User.view', ['username' => $user->username]) ?> +<?= $this->endSection() ?> + + +<?= $this->section('content') ?> + +<?= view('admin/_partials/_user_info.php', ['user' => $user]) ?> + +<?= $this->endSection() ?> diff --git a/tailwind.config.js b/tailwind.config.js index 52ddd9b497584b0ab739d546cf3536d5d2cdf2a7..2f7c33d367518e1d93726802f37a628f1cc95698 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,7 +1,7 @@ /* eslint-disable */ module.exports = { - purge: ["./app/Views/**/*.php", "./app/Views/**/*.js"], + purge: ["./app/Views/**/*.php", "./app/Views/**/*.ts"], theme: { extend: {}, },