diff --git a/app/Config/App.php b/app/Config/App.php index fe5c59a8..cf921c7c 100644 --- a/app/Config/App.php +++ b/app/Config/App.php @@ -451,4 +451,9 @@ class App extends BaseConfig ]; public string $theme = 'pine'; + + /** + * Storage limit in Gigabytes + */ + public ?int $storageLimit = null; } diff --git a/app/Helpers/components_helper.php b/app/Helpers/components_helper.php index 6bef7013..6989ee4e 100644 --- a/app/Helpers/components_helper.php +++ b/app/Helpers/components_helper.php @@ -179,9 +179,9 @@ if (! function_exists('publication_button')) { break; } - return <<{$label} - CODE_SAMPLE; + HTML; } } @@ -205,7 +205,7 @@ if (! function_exists('publication_status_banner')) { case 'scheduled': $bannerDisclaimer = lang('Podcast.publication_status_banner.draft_mode'); $bannerText = lang('Podcast.publication_status_banner.scheduled', [ - 'publication_date' => local_time($publicationDate), + 'publication_date' => local_datetime($publicationDate), ], null, false); $linkRoute = route_to('podcast-publish_edit', $podcastId); $linkLabel = lang('Podcast.publish_edit'); @@ -218,7 +218,7 @@ if (! function_exists('publication_status_banner')) { break; } - return <<

{$bannerDisclaimer} @@ -226,7 +226,7 @@ if (! function_exists('publication_status_banner')) {

{$linkLabel} - CODE_SAMPLE; + HTML; } } @@ -321,7 +321,7 @@ if (! function_exists('audio_player')) { $language = service('request') ->getLocale(); - return << - CODE_SAMPLE; + HTML; } } @@ -361,16 +361,60 @@ if (! function_exists('relative_time')) { $translatedDate = $time->toLocalizedString($formatter->getPattern()); $datetime = $time->format(DateTime::ISO8601); - return << - CODE_SAMPLE; + HTML; } } +// ------------------------------------------------------------------------ + +if (! function_exists('local_datetime')) { + function local_datetime(Time $time): string + { + $formatter = new IntlDateFormatter(service( + 'request' + )->getLocale(), IntlDateFormatter::MEDIUM, IntlDateFormatter::LONG); + $translatedDate = $time->toLocalizedString($formatter->getPattern()); + $datetime = $time->format(DateTime::ISO8601); + + return << + + + HTML; + } +} + +// ------------------------------------------------------------------------ + +if (! function_exists('local_date')) { + function local_date(Time $time): string + { + $formatter = new IntlDateFormatter(service( + 'request' + )->getLocale(), IntlDateFormatter::MEDIUM, IntlDateFormatter::NONE); + $translatedDate = $time->toLocalizedString($formatter->getPattern()); + + return <<{$translatedDate} + HTML; + } +} + + // ------------------------------------------------------------------------ if (! function_exists('explicit_badge')) { @@ -381,9 +425,9 @@ if (! function_exists('explicit_badge')) { } $explicitLabel = lang('Common.explicit'); - return <<{$explicitLabel} - CODE_SAMPLE; + HTML; } } diff --git a/app/Helpers/misc_helper.php b/app/Helpers/misc_helper.php index e69e9e87..7975bdc1 100644 --- a/app/Helpers/misc_helper.php +++ b/app/Helpers/misc_helper.php @@ -8,7 +8,6 @@ declare(strict_types=1); * @link https://castopod.org/ */ -use CodeIgniter\I18n\Time; if (! function_exists('get_browser_language')) { /** @@ -281,41 +280,16 @@ if (! function_exists('format_bytes')) { /** * Adapted from https://stackoverflow.com/a/2510459 */ - function formatBytes(float $bytes, int $precision = 2): string + function formatBytes(float $bytes, bool $is_binary = false, int $precision = 2): string { - $units = ['B', 'KiB', 'MiB', 'GiB', 'TiB']; + $units = $is_binary ? ['B', 'KiB', 'MiB', 'GiB', 'TiB'] : ['B', 'KB', 'MB', 'GB', 'TB']; $bytes = max($bytes, 0); - $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); + $pow = floor(($bytes ? log($bytes) : 0) / log($is_binary ? 1024 : 1000)); $pow = min($pow, count($units) - 1); - $bytes /= pow(1024, $pow); + $bytes /= pow($is_binary ? 1024 : 1000, $pow); return round($bytes, $precision) . $units[$pow]; } } - -if (! function_exists('local_time')) { - function local_time(Time $time): string - { - $formatter = new IntlDateFormatter(service( - 'request' - )->getLocale(), IntlDateFormatter::MEDIUM, IntlDateFormatter::LONG); - $translatedDate = $time->toLocalizedString($formatter->getPattern()); - $datetime = $time->format(DateTime::ISO8601); - - return << - - - CODE_SAMPLE; - } -} diff --git a/app/Resources/icons/database.svg b/app/Resources/icons/database.svg new file mode 100644 index 00000000..6dc449b4 --- /dev/null +++ b/app/Resources/icons/database.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/Resources/icons/play-circle.svg b/app/Resources/icons/play-circle.svg new file mode 100644 index 00000000..5d5f7039 --- /dev/null +++ b/app/Resources/icons/play-circle.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/Views/Components/DashboardCard.php b/app/Views/Components/DashboardCard.php new file mode 100644 index 00000000..47402237 --- /dev/null +++ b/app/Views/Components/DashboardCard.php @@ -0,0 +1,46 @@ +subtitle = html_entity_decode($value); + } + + public function render(): string + { + $glyph = icon($this->glyph, 'flex-shrink-0 bg-base rounded-full w-8 h-8 p-2 text-accent-base'); + + if ($this->href !== null && $this->href !== '') { + $chevronRight = icon('chevron-right'); + $viewLang = lang('Common.view'); + return << +
{$glyph}
{$this->title}
{$viewLang}{$chevronRight}

{$this->subtitle}

+
{$this->slot}
+ + HTML; + } + + return << +
{$glyph}
{$this->title}

{$this->subtitle}

+
{$this->slot}
+ + HTML; + } +} diff --git a/ecs.php b/ecs.php index 6abb2da5..8e2da3b1 100644 --- a/ecs.php +++ b/ecs.php @@ -26,6 +26,7 @@ return static function (ECSConfig $ecsConfig): void { __DIR__ . '/app/Views/Components/*', __DIR__ . '/modules/**/Views/Components/*', __DIR__ . '/themes/**/Views/Components/*', + __DIR__ . '/app/Helpers/components_helper.php' ], LineLengthFixer::class => [ diff --git a/modules/Admin/Config/Routes.php b/modules/Admin/Config/Routes.php index b3ffcd13..d6c58357 100644 --- a/modules/Admin/Config/Routes.php +++ b/modules/Admin/Config/Routes.php @@ -19,7 +19,7 @@ $routes->group( 'namespace' => 'Modules\Admin\Controllers', ], function ($routes): void { - $routes->get('/', 'HomeController', [ + $routes->get('/', 'DashboardController', [ 'as' => 'admin', ]); diff --git a/modules/Admin/Controllers/DashboardController.php b/modules/Admin/Controllers/DashboardController.php new file mode 100644 index 00000000..14057bcd --- /dev/null +++ b/modules/Admin/Controllers/DashboardController.php @@ -0,0 +1,82 @@ +builder() + ->countAll(); + $podcastsLastPublishedAt = (new PodcastModel())->builder() + ->select('MAX(published_at) as last_published_at') + ->where('`published_at` <= UTC_TIMESTAMP()', null, false) + ->get() + ->getResultArray()[0]['last_published_at']; + $podcastsData['number_of_podcasts'] = (int) $podcastsCount; + $podcastsData['last_published_at'] = $podcastsLastPublishedAt === null ? null : new Time( + $podcastsLastPublishedAt + ); + + $episodesData = []; + $episodesCount = (new EpisodeModel())->builder() + ->countAll(); + $episodesLastPublishedAt = (new EpisodeModel())->builder() + ->select('MAX(published_at) as last_published_at') + ->where('`published_at` <= UTC_TIMESTAMP()', null, false) + ->get() + ->getResultArray()[0]['last_published_at']; + $episodesData['number_of_episodes'] = (int) $episodesCount; + $episodesData['last_published_at'] = $episodesLastPublishedAt === null ? null : new Time( + $episodesLastPublishedAt + ); + + $totalUploaded = (new MediaModel())->builder() + ->selectSum('file_size') + ->get() + ->getResultArray()[0]; + + $appStorageLimit = config('App') + ->storageLimit; + if ($appStorageLimit === null || $appStorageLimit < 0) { + $storageLimitBytes = disk_free_space('./'); + } else { + $storageLimitBytes = $appStorageLimit * 1000000000; + } + + $storageData = [ + 'limit' => formatBytes((int) $storageLimitBytes), + 'percentage' => round((((int) $totalUploaded['file_size']) / $storageLimitBytes) * 100, 0), + 'total_uploaded' => formatBytes((int) $totalUploaded['file_size']), + ]; + + $onlyPodcastId = null; + if ($podcastsData['number_of_podcasts'] === 1) { + $onlyPodcastId = (new PodcastModel())->first() + ->id; + } + + $data = [ + 'podcastsData' => $podcastsData, + 'episodesData' => $episodesData, + 'storageData' => $storageData, + 'onlyPodcastId' => $onlyPodcastId, + ]; + + return view('dashboard', $data); + } +} diff --git a/modules/Admin/Controllers/HomeController.php b/modules/Admin/Controllers/HomeController.php deleted file mode 100644 index 9248cb4c..00000000 --- a/modules/Admin/Controllers/HomeController.php +++ /dev/null @@ -1,22 +0,0 @@ -keepFlashdata('message'); - return redirect()->route('podcast-list'); - } -} diff --git a/modules/Admin/Language/ar/Common.php b/modules/Admin/Language/ar/Common.php index 9021d57e..8df44186 100644 --- a/modules/Admin/Language/ar/Common.php +++ b/modules/Admin/Language/ar/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Playing', ], 'size_limit' => 'Size limit: {0}.', + 'choose_interact' => 'اختر أسلوب التفاعل', ]; diff --git a/modules/Admin/Language/ar/Admin.php b/modules/Admin/Language/ar/Dashboard.php similarity index 68% rename from modules/Admin/Language/ar/Admin.php rename to modules/Admin/Language/ar/Dashboard.php index 971ecb10..43d14963 100644 --- a/modules/Admin/Language/ar/Admin.php +++ b/modules/Admin/Language/ar/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'لوحة التحكم الإدارية', + 'home' => 'لوحة التحكم الإدارية', 'welcome_message' => 'أهلًا بك في المنطقة الإدارية!', - 'choose_interact' => 'اختر أسلوب التفاعل', ]; diff --git a/modules/Admin/Language/br/Common.php b/modules/Admin/Language/br/Common.php index 7a0ca7e0..93bb776d 100644 --- a/modules/Admin/Language/br/Common.php +++ b/modules/Admin/Language/br/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'O lenn', ], 'size_limit' => 'Bevenn ar vent: {0}.', + 'choose_interact' => 'Dibabit penaos interaktiñ', ]; diff --git a/modules/Admin/Language/br/Admin.php b/modules/Admin/Language/br/Dashboard.php similarity index 73% rename from modules/Admin/Language/br/Admin.php rename to modules/Admin/Language/br/Dashboard.php index 3773855d..dd55b106 100644 --- a/modules/Admin/Language/br/Admin.php +++ b/modules/Admin/Language/br/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Taolenn-stur', + 'home' => 'Taolenn-stur', 'welcome_message' => 'Degemer mat en daolenn-stur!', - 'choose_interact' => 'Dibabit penaos interaktiñ', ]; diff --git a/modules/Admin/Language/de/Common.php b/modules/Admin/Language/de/Common.php index 64ee6f3e..71549ddb 100644 --- a/modules/Admin/Language/de/Common.php +++ b/modules/Admin/Language/de/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Spielt', ], 'size_limit' => 'Größenlimit: {0}.', + 'choose_interact' => 'Mit welchem Podcast-Profil wollen Sie handeln', ]; diff --git a/modules/Admin/Language/de/Admin.php b/modules/Admin/Language/de/Dashboard.php similarity index 69% rename from modules/Admin/Language/de/Admin.php rename to modules/Admin/Language/de/Dashboard.php index ec6d5e79..b3e24a69 100644 --- a/modules/Admin/Language/de/Admin.php +++ b/modules/Admin/Language/de/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Adminübersicht', + 'home' => 'Adminübersicht', 'welcome_message' => 'Willkommen im Administrationsbereich!', - 'choose_interact' => 'Mit welchem Podcast-Profil wollen Sie handeln', ]; diff --git a/modules/Admin/Language/el/Common.php b/modules/Admin/Language/el/Common.php index e19b3e73..126fc83a 100644 --- a/modules/Admin/Language/el/Common.php +++ b/modules/Admin/Language/el/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Αναπαράγεται', ], 'size_limit' => 'Όριο μεγέθους: {0}.', + 'choose_interact' => 'Επιλέξτε τον τρόπο αλληλεπίδρασης', ]; diff --git a/modules/Admin/Language/el/Admin.php b/modules/Admin/Language/el/Dashboard.php similarity index 63% rename from modules/Admin/Language/el/Admin.php rename to modules/Admin/Language/el/Dashboard.php index 7b4a8544..516b5368 100644 --- a/modules/Admin/Language/el/Admin.php +++ b/modules/Admin/Language/el/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Πίνακας ελέγχου διαχειριστή', + 'home' => 'Πίνακας ελέγχου διαχειριστή', 'welcome_message' => 'Καλώς ήρθατε στην περιοχή διαχείρισης!', - 'choose_interact' => 'Επιλέξτε τον τρόπο αλληλεπίδρασης', ]; diff --git a/modules/Admin/Language/en/Charts.php b/modules/Admin/Language/en/Charts.php index d9a75a1d..4b33530e 100644 --- a/modules/Admin/Language/en/Charts.php +++ b/modules/Admin/Language/en/Charts.php @@ -35,4 +35,6 @@ return [ 'by_weekday' => 'By week day (for the past 60 days)', 'by_hour' => 'By time of day (for the past 60 days)', 'podcast_by_bandwidth' => 'Daily used bandwidth (in MB)', + 'total_storage_by_month' => 'Monthly storage (in MB)', + 'total_bandwidth_by_month' => 'Monthly used bandwidth (in MB)', ]; diff --git a/modules/Admin/Language/en/Common.php b/modules/Admin/Language/en/Common.php index d97bcf99..596c8bcd 100644 --- a/modules/Admin/Language/en/Common.php +++ b/modules/Admin/Language/en/Common.php @@ -46,4 +46,6 @@ return [ 'playing' => 'Playing', ], 'size_limit' => 'Size limit: {0}.', + 'choose_interact' => 'Choose how to interact', + 'view' => 'View', ]; diff --git a/modules/Admin/Language/en/Dashboard.php b/modules/Admin/Language/en/Dashboard.php new file mode 100644 index 00000000..881073fd --- /dev/null +++ b/modules/Admin/Language/en/Dashboard.php @@ -0,0 +1,28 @@ + 'Admin dashboard', + 'welcome_message' => 'Welcome to the admin area!', + 'podcasts' => [ + 'title' => 'Podcasts', + 'not_found' => 'No published podcast', + 'last_published' => 'Last published on {lastPublicationDate}', + ], + 'episodes' => [ + 'title' => 'Episodes', + 'not_found' => 'No published episode', + 'last_published' => 'Last published on {lastPublicationDate}', + ], + 'storage' => [ + 'title' => 'Storage', + 'subtitle' => '{totalUploaded} out of {totalStorage}', + ], +]; diff --git a/modules/Admin/Language/es/Common.php b/modules/Admin/Language/es/Common.php index 05648953..61a42889 100644 --- a/modules/Admin/Language/es/Common.php +++ b/modules/Admin/Language/es/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Reproduciendo', ], 'size_limit' => 'Límite de tamaño: {0}.', + 'choose_interact' => 'Elige cómo interactuar', ]; diff --git a/modules/Admin/Language/es/Admin.php b/modules/Admin/Language/es/Dashboard.php similarity index 72% rename from modules/Admin/Language/es/Admin.php rename to modules/Admin/Language/es/Dashboard.php index 83f9f8d5..05ea7955 100644 --- a/modules/Admin/Language/es/Admin.php +++ b/modules/Admin/Language/es/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Panel de administración', + 'home' => 'Panel de administración', 'welcome_message' => '¡Bienvenido al área de administración!', - 'choose_interact' => 'Elige cómo interactuar', ]; diff --git a/modules/Admin/Language/fr/Common.php b/modules/Admin/Language/fr/Common.php index 04725db6..4187008e 100644 --- a/modules/Admin/Language/fr/Common.php +++ b/modules/Admin/Language/fr/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'En cours', ], 'size_limit' => 'Taille maximale : {0}.', + 'choose_interact' => 'Choisissez comment interagir', ]; diff --git a/modules/Admin/Language/fr/Admin.php b/modules/Admin/Language/fr/Dashboard.php similarity index 72% rename from modules/Admin/Language/fr/Admin.php rename to modules/Admin/Language/fr/Dashboard.php index 3b37a2b2..358a486b 100644 --- a/modules/Admin/Language/fr/Admin.php +++ b/modules/Admin/Language/fr/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Tableau de bord', + 'home' => 'Tableau de bord', 'welcome_message' => 'Bienvenue dans l’administration !', - 'choose_interact' => 'Choisissez comment interagir', ]; diff --git a/modules/Admin/Language/id/Common.php b/modules/Admin/Language/id/Common.php index d97bcf99..be498dac 100644 --- a/modules/Admin/Language/id/Common.php +++ b/modules/Admin/Language/id/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Playing', ], 'size_limit' => 'Size limit: {0}.', + 'choose_interact' => 'Choose how to interact', ]; diff --git a/modules/Admin/Language/en/Admin.php b/modules/Admin/Language/id/Dashboard.php similarity index 73% rename from modules/Admin/Language/en/Admin.php rename to modules/Admin/Language/id/Dashboard.php index 5e394237..7f28d24d 100644 --- a/modules/Admin/Language/en/Admin.php +++ b/modules/Admin/Language/id/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Admin dashboard', + 'home' => 'Admin dashboard', 'welcome_message' => 'Welcome to the admin area!', - 'choose_interact' => 'Choose how to interact', ]; diff --git a/modules/Admin/Language/it/Common.php b/modules/Admin/Language/it/Common.php index d97bcf99..be498dac 100644 --- a/modules/Admin/Language/it/Common.php +++ b/modules/Admin/Language/it/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Playing', ], 'size_limit' => 'Size limit: {0}.', + 'choose_interact' => 'Choose how to interact', ]; diff --git a/modules/Admin/Language/id/Admin.php b/modules/Admin/Language/it/Dashboard.php similarity index 73% rename from modules/Admin/Language/id/Admin.php rename to modules/Admin/Language/it/Dashboard.php index 5e394237..7f28d24d 100644 --- a/modules/Admin/Language/id/Admin.php +++ b/modules/Admin/Language/it/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Admin dashboard', + 'home' => 'Admin dashboard', 'welcome_message' => 'Welcome to the admin area!', - 'choose_interact' => 'Choose how to interact', ]; diff --git a/modules/Admin/Language/nl/Common.php b/modules/Admin/Language/nl/Common.php index 9ef0b772..ac06748d 100644 --- a/modules/Admin/Language/nl/Common.php +++ b/modules/Admin/Language/nl/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Wordt afgespeeld', ], 'size_limit' => 'Maximale grootte: {0}.', + 'choose_interact' => 'Kies hoe de interactie moet worden', ]; diff --git a/modules/Admin/Language/nl/Admin.php b/modules/Admin/Language/nl/Dashboard.php similarity index 70% rename from modules/Admin/Language/nl/Admin.php rename to modules/Admin/Language/nl/Dashboard.php index 8e50419d..b5c5ef81 100644 --- a/modules/Admin/Language/nl/Admin.php +++ b/modules/Admin/Language/nl/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Beheerder overzicht', + 'home' => 'Beheerder overzicht', 'welcome_message' => 'Welkom bij de beheerder omgeving!', - 'choose_interact' => 'Kies hoe de interactie moet worden', ]; diff --git a/modules/Admin/Language/nn-NO/Common.php b/modules/Admin/Language/nn-NO/Common.php index 813bb910..14026246 100644 --- a/modules/Admin/Language/nn-NO/Common.php +++ b/modules/Admin/Language/nn-NO/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Spelar', ], 'size_limit' => 'Maks storleik: {0}.', + 'choose_interact' => 'Vel korleis du vil samhandla', ]; diff --git a/modules/Admin/Language/nn-NO/Admin.php b/modules/Admin/Language/nn-NO/Dashboard.php similarity index 72% rename from modules/Admin/Language/nn-NO/Admin.php rename to modules/Admin/Language/nn-NO/Dashboard.php index 2b69c697..776337ab 100644 --- a/modules/Admin/Language/nn-NO/Admin.php +++ b/modules/Admin/Language/nn-NO/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Styringspanel', + 'home' => 'Styringspanel', 'welcome_message' => 'Velkomen til styrarområdet!', - 'choose_interact' => 'Vel korleis du vil samhandla', ]; diff --git a/modules/Admin/Language/oc/Common.php b/modules/Admin/Language/oc/Common.php index d97bcf99..be498dac 100644 --- a/modules/Admin/Language/oc/Common.php +++ b/modules/Admin/Language/oc/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Playing', ], 'size_limit' => 'Size limit: {0}.', + 'choose_interact' => 'Choose how to interact', ]; diff --git a/modules/Admin/Language/oc/Admin.php b/modules/Admin/Language/oc/Dashboard.php similarity index 73% rename from modules/Admin/Language/oc/Admin.php rename to modules/Admin/Language/oc/Dashboard.php index 5e394237..7f28d24d 100644 --- a/modules/Admin/Language/oc/Admin.php +++ b/modules/Admin/Language/oc/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Admin dashboard', + 'home' => 'Admin dashboard', 'welcome_message' => 'Welcome to the admin area!', - 'choose_interact' => 'Choose how to interact', ]; diff --git a/modules/Admin/Language/pl/Common.php b/modules/Admin/Language/pl/Common.php index f015f1f8..00e9c9f2 100644 --- a/modules/Admin/Language/pl/Common.php +++ b/modules/Admin/Language/pl/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Odtwarzanie', ], 'size_limit' => 'Limit rozmiaru: {0}.', + 'choose_interact' => 'Wybierz sposób interakcji', ]; diff --git a/modules/Admin/Language/pl/Admin.php b/modules/Admin/Language/pl/Dashboard.php similarity index 71% rename from modules/Admin/Language/pl/Admin.php rename to modules/Admin/Language/pl/Dashboard.php index cb262679..9c9a1268 100644 --- a/modules/Admin/Language/pl/Admin.php +++ b/modules/Admin/Language/pl/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Pulpit administratora', + 'home' => 'Pulpit administratora', 'welcome_message' => 'Witamy w panelu administracyjnym!', - 'choose_interact' => 'Wybierz sposób interakcji', ]; diff --git a/modules/Admin/Language/pt-BR/Common.php b/modules/Admin/Language/pt-BR/Common.php index e57238eb..82cb6180 100644 --- a/modules/Admin/Language/pt-BR/Common.php +++ b/modules/Admin/Language/pt-BR/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Reproduzindo', ], 'size_limit' => 'Limite de tamanho: {0}.', + 'choose_interact' => 'Escolha como interagir', ]; diff --git a/modules/Admin/Language/pt-BR/Admin.php b/modules/Admin/Language/pt-BR/Dashboard.php similarity index 71% rename from modules/Admin/Language/pt-BR/Admin.php rename to modules/Admin/Language/pt-BR/Dashboard.php index 432b6a92..6625b47d 100644 --- a/modules/Admin/Language/pt-BR/Admin.php +++ b/modules/Admin/Language/pt-BR/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Painel de administração', + 'home' => 'Painel de administração', 'welcome_message' => 'Bem-vindo à área de administração!', - 'choose_interact' => 'Escolha como interagir', ]; diff --git a/modules/Admin/Language/pt/Admin.php b/modules/Admin/Language/pt/Admin.php deleted file mode 100644 index 5e394237..00000000 --- a/modules/Admin/Language/pt/Admin.php +++ /dev/null @@ -1,15 +0,0 @@ - 'Admin dashboard', - 'welcome_message' => 'Welcome to the admin area!', - 'choose_interact' => 'Choose how to interact', -]; diff --git a/modules/Admin/Language/pt/Common.php b/modules/Admin/Language/pt/Common.php index d97bcf99..be498dac 100644 --- a/modules/Admin/Language/pt/Common.php +++ b/modules/Admin/Language/pt/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Playing', ], 'size_limit' => 'Size limit: {0}.', + 'choose_interact' => 'Choose how to interact', ]; diff --git a/modules/Admin/Language/it/Admin.php b/modules/Admin/Language/pt/Dashboard.php similarity index 73% rename from modules/Admin/Language/it/Admin.php rename to modules/Admin/Language/pt/Dashboard.php index 5e394237..7f28d24d 100644 --- a/modules/Admin/Language/it/Admin.php +++ b/modules/Admin/Language/pt/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Admin dashboard', + 'home' => 'Admin dashboard', 'welcome_message' => 'Welcome to the admin area!', - 'choose_interact' => 'Choose how to interact', ]; diff --git a/modules/Admin/Language/ru/Common.php b/modules/Admin/Language/ru/Common.php index d97bcf99..a0202532 100644 --- a/modules/Admin/Language/ru/Common.php +++ b/modules/Admin/Language/ru/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Playing', ], 'size_limit' => 'Size limit: {0}.', + 'choose_interact' => 'Выберите как взаимодействовать', ]; diff --git a/modules/Admin/Language/ru/Admin.php b/modules/Admin/Language/ru/Dashboard.php similarity index 66% rename from modules/Admin/Language/ru/Admin.php rename to modules/Admin/Language/ru/Dashboard.php index 1babcd9f..102be71d 100644 --- a/modules/Admin/Language/ru/Admin.php +++ b/modules/Admin/Language/ru/Dashboard.php @@ -9,7 +9,6 @@ declare(strict_types=1); */ return [ - 'dashboard' => 'Панель Администратора', + 'home' => 'Панель Администратора', 'welcome_message' => 'Добро пожаловать в панель администрирования!', - 'choose_interact' => 'Выберите как взаимодействовать', ]; diff --git a/modules/Admin/Language/sv/Admin.php b/modules/Admin/Language/sv/Admin.php deleted file mode 100644 index 5e394237..00000000 --- a/modules/Admin/Language/sv/Admin.php +++ /dev/null @@ -1,15 +0,0 @@ - 'Admin dashboard', - 'welcome_message' => 'Welcome to the admin area!', - 'choose_interact' => 'Choose how to interact', -]; diff --git a/modules/Admin/Language/sv/Common.php b/modules/Admin/Language/sv/Common.php index d97bcf99..be498dac 100644 --- a/modules/Admin/Language/sv/Common.php +++ b/modules/Admin/Language/sv/Common.php @@ -46,4 +46,5 @@ return [ 'playing' => 'Playing', ], 'size_limit' => 'Size limit: {0}.', + 'choose_interact' => 'Choose how to interact', ]; diff --git a/modules/Admin/Language/sv/Dashboard.php b/modules/Admin/Language/sv/Dashboard.php new file mode 100644 index 00000000..7f28d24d --- /dev/null +++ b/modules/Admin/Language/sv/Dashboard.php @@ -0,0 +1,14 @@ + 'Admin dashboard', + 'welcome_message' => 'Welcome to the admin area!', +]; diff --git a/modules/Analytics/Config/Routes.php b/modules/Analytics/Config/Routes.php index 1261e9ab..352682eb 100644 --- a/modules/Analytics/Config/Routes.php +++ b/modules/Analytics/Config/Routes.php @@ -19,7 +19,7 @@ $routes->addPlaceholder( ); $routes->addPlaceholder( 'filter', - '\bWeekly|\bYearly|\bByDay|\bByWeekday|\bByMonth|\bByAppWeekly|\bByAppYearly|\bByOsWeekly|\bByDeviceWeekly|\bBots|\bByServiceWeekly|\bBandwidthByDay|\bUniqueListenersByDay|\bUniqueListenersByMonth|\bTotalListeningTimeByDay|\bTotalListeningTimeByMonth|\bByDomainWeekly|\bByDomainYearly', + '\bWeekly|\bYearly|\bByDay|\bByWeekday|\bByMonth|\bByAppWeekly|\bByAppYearly|\bByOsWeekly|\bByDeviceWeekly|\bBots|\bByServiceWeekly|\bBandwidthByDay|\bUniqueListenersByDay|\bUniqueListenersByMonth|\bTotalListeningTimeByDay|\bTotalListeningTimeByMonth|\bByDomainWeekly|\bByDomainYearly|\bTotalBandwidthByMonth|\bTotalStorageByMonth', ); $routes->group('', [ @@ -53,6 +53,10 @@ $routes->group('', [ ); }); + $routes->get(config('Analytics')->gateway . '/(:class)/(:filter)', 'AnalyticsController::getData/$1/$2', [ + 'as' => 'analytics-data-instance', + ]); + // Route for podcast audio file analytics (/audio/pack(podcast_id,episode_id,bytes_threshold,filesize,duration,date)/podcast_folder/filename.mp3) $routes->head( 'audio/(:base64)/(:any)', diff --git a/modules/Analytics/Controllers/AnalyticsController.php b/modules/Analytics/Controllers/AnalyticsController.php index 06dfd180..fb0a0315 100644 --- a/modules/Analytics/Controllers/AnalyticsController.php +++ b/modules/Analytics/Controllers/AnalyticsController.php @@ -10,6 +10,7 @@ declare(strict_types=1); namespace Modules\Analytics\Controllers; +use CodeIgniter\API\ResponseTrait; use CodeIgniter\Controller; use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\HTTP\ResponseInterface; @@ -17,6 +18,8 @@ use CodeIgniter\Model; class AnalyticsController extends Controller { + use ResponseTrait; + protected Model $analyticsModel; protected string $methodName = ''; @@ -27,6 +30,12 @@ class AnalyticsController extends Controller throw PageNotFoundException::forPageNotFound(); } + if (! is_numeric($params[0])) { + $this->analyticsModel = model('Analytics' . $params[0] . 'Model'); + $this->methodName = 'getData' . $params[1]; + return $this->{$method}(); + } + $this->analyticsModel = model('Analytics' . $params[1] . 'Model'); $this->methodName = 'getData' . (count($params) >= 3 ? $params[2] : ''); @@ -36,14 +45,18 @@ class AnalyticsController extends Controller ); } - public function getData(int $podcastId, ?int $episodeId = null): ResponseInterface + public function getData(?int $podcastId = null, ?int $episodeId = null): ResponseInterface { $methodName = $this->methodName; - if ($episodeId === null) { - return $this->response->setJSON($this->analyticsModel->{$methodName}($podcastId)); + if ($podcastId === null) { + return $this->respond($this->analyticsModel->{$methodName}()); } - return $this->response->setJSON($this->analyticsModel->{$methodName}($podcastId, $episodeId)); + if ($episodeId === null) { + return $this->respond($this->analyticsModel->{$methodName}($podcastId)); + } + + return $this->respond($this->analyticsModel->{$methodName}($podcastId, $episodeId)); } } diff --git a/modules/Analytics/Models/AnalyticsPodcastModel.php b/modules/Analytics/Models/AnalyticsPodcastModel.php index 493dd5da..fee1ae44 100644 --- a/modules/Analytics/Models/AnalyticsPodcastModel.php +++ b/modules/Analytics/Models/AnalyticsPodcastModel.php @@ -12,6 +12,8 @@ declare(strict_types=1); namespace Modules\Analytics\Models; +use App\Entities\Media\BaseMedia; +use App\Models\MediaModel; use CodeIgniter\Model; use Modules\Analytics\Entities\AnalyticsPodcasts; @@ -93,7 +95,7 @@ class AnalyticsPodcastModel extends Model public function getDataBandwidthByDay(int $podcastId): array { if (! ($found = cache("{$podcastId}_analytics_podcast_by_bandwidth"))) { - $found = $this->select('date as labels, round(bandwidth / 1048576, 1) as `values`') + $found = $this->select('date as labels, ROUND(bandwidth / 1000000, 2) as `values`') ->where([ 'podcast_id' => $podcastId, 'date >' => date('Y-m-d', strtotime('-60 days')), @@ -235,4 +237,48 @@ class AnalyticsPodcastModel extends Model return $found; } + + /** + * Gets total bandwidth data for instance + * + * @return AnalyticsPodcasts[] + */ + public function getDataTotalBandwidthByMonth(): array + { + if (! ($found = cache('analytics_total_bandwidth_by_month'))) { + $found = $this->select( + 'DATE_FORMAT(updated_at,"%Y-%m") as labels, ROUND(sum(bandwidth) / 1000000, 2) as `values`' + ) + ->groupBy('labels') + ->orderBy('labels', 'ASC') + ->findAll(); + + cache() + ->save('analytics_total_bandwidth_by_month', $found, 600); + } + + return $found; + } + + /** + * Get total storage + * + * @return BaseMedia[] + */ + public function getDataTotalStorageByMonth(): array + { + if (! ($found = cache('analytics_total_storage_by_month'))) { + $found = (new MediaModel())->select( + 'DATE_FORMAT(uploaded_at,"%Y-%m") as labels, ROUND(sum(file_size) / 1000000, 2) as `values`' + ) + ->groupBy('labels') + ->orderBy('labels', 'ASC') + ->findAll(); + + cache() + ->save('analytics_total_storage_by_month', $found, 600); + } + + return $found; + } } diff --git a/themes/cp_admin/_partials/_nav_header.php b/themes/cp_admin/_partials/_nav_header.php index 82808628..6b40fafc 100644 --- a/themes/cp_admin/_partials/_nav_header.php +++ b/themes/cp_admin/_partials/_nav_header.php @@ -42,7 +42,7 @@ CODE_SAMPLE; } - $interactAsText = lang('Admin.choose_interact'); + $interactAsText = lang('Common.choose_interact'); $route = route_to('interact-as-actor'); $csrfField = csrf_field(); diff --git a/themes/cp_admin/_sidebar.php b/themes/cp_admin/_sidebar.php index 8f53e815..f557e5e9 100644 --- a/themes/cp_admin/_sidebar.php +++ b/themes/cp_admin/_sidebar.php @@ -1,6 +1,10 @@ [ + 'icon' => 'dashboard', + 'items' => ['admin'], + ], 'podcasts' => [ 'icon' => 'mic', 'items' => ['podcast-list', 'podcast-create', 'podcast-import'], diff --git a/themes/cp_admin/dashboard.php b/themes/cp_admin/dashboard.php index 7dce6c0d..bebdc2d0 100644 --- a/themes/cp_admin/dashboard.php +++ b/themes/cp_admin/dashboard.php @@ -2,13 +2,42 @@ extend('_layout') ?> section('title') ?> - + endSection() ?> section('pageTitle') ?> - + endSection() ?> section('content') ?> - + +
+ + + % +
+ +
+ + +
+ + +asset('js/charts.ts', 'js') ?> endsection() ?> diff --git a/themes/cp_admin/episode/create.php b/themes/cp_admin/episode/create.php index 61f05073..a35ab5a8 100644 --- a/themes/cp_admin/episode/create.php +++ b/themes/cp_admin/episode/create.php @@ -21,12 +21,12 @@ name="audio_file" label="" hint="" - helper="" + helper="" type="file" accept=".mp3,.m4a" required="true" data-max-size="" - data-max-size-error="" /> + data-max-size-error="" /> + data-max-size-error="" /> ['podcast-view', 'podcast-edit', 'podcast-persons-manage'], ], 'episodes' => [ - 'icon' => 'mic', + 'icon' => 'play-circle', 'items' => ['episode-list', 'episode-create'], ], 'analytics' => [ diff --git a/themes/cp_app/_admin_navbar.php b/themes/cp_app/_admin_navbar.php index f2a41004..690ac590 100644 --- a/themes/cp_app/_admin_navbar.php +++ b/themes/cp_app/_admin_navbar.php @@ -37,7 +37,7 @@ CODE_SAMPLE; } - $interactAsText = lang('Admin.choose_interact'); + $interactAsText = lang('Common.choose_interact'); $route = route_to('interact-as-actor'); $csrfField = csrf_field();