New admin dashboard layout

This commit is contained in:
Daniel Supernault 2021-05-24 23:24:42 -06:00
parent 53730e493f
commit eb7d5a4e36
No known key found for this signature in database
GPG key ID: 0DEF1C662C9033F7
17 changed files with 32165 additions and 171 deletions

View file

@ -3,6 +3,7 @@
namespace App\Services; namespace App\Services;
use Cache; use Cache;
use DB;
use App\Util\Lexer\PrettyNumber; use App\Util\Lexer\PrettyNumber;
use App\{ use App\{
Contact, Contact,
@ -16,21 +17,30 @@ use App\{
Status, Status,
User User
}; };
use \DateInterval;
use \DatePeriod;
class AdminStatsService class AdminStatsService
{ {
public static function get() public static function get()
{ {
return array_merge(self::recentData(), self::additionalData()); return array_merge(
self::recentData(),
self::additionalData(),
self::postsGraph()
);
} }
protected static function recentData() protected static function recentData()
{ {
$day = config('database.default') == 'pgsql' ? 'DATE_PART(\'day\',' : 'day('; $day = config('database.default') == 'pgsql' ? 'DATE_PART(\'day\',' : 'day(';
return Cache::remember('admin:dashboard:home:data:v0:15min', now()->addMinutes(15), function() use ($day) { $ttl = now()->addMinutes(15);
return Cache::remember('admin:dashboard:home:data:v0:15min', $ttl, function() use ($day) {
return [ return [
'contact' => PrettyNumber::convert(Contact::whereNull('read_at')->count()), 'contact' => PrettyNumber::convert(Contact::whereNull('read_at')->count()),
'contact_monthly' => PrettyNumber::convert(Contact::whereNull('read_at')->where('created_at', '>', now()->subMonth())->count()),
'reports' => PrettyNumber::convert(Report::whereNull('admin_seen')->count()), 'reports' => PrettyNumber::convert(Report::whereNull('admin_seen')->count()),
'reports_monthly' => PrettyNumber::convert(Report::whereNull('admin_seen')->where('created_at', '>', now()->subMonth())->count()),
]; ];
}); });
} }
@ -38,12 +48,15 @@ class AdminStatsService
protected static function additionalData() protected static function additionalData()
{ {
$day = config('database.default') == 'pgsql' ? 'DATE_PART(\'day\',' : 'day('; $day = config('database.default') == 'pgsql' ? 'DATE_PART(\'day\',' : 'day(';
return Cache::remember('admin:dashboard:home:data:v0:24hr', now()->addHours(24), function() use ($day) { $ttl = now()->addHours(24);
return Cache::remember('admin:dashboard:home:data:v0:24hr', $ttl, function() use ($day) {
return [ return [
'failedjobs' => PrettyNumber::convert(FailedJob::where('failed_at', '>=', \Carbon\Carbon::now()->subDay())->count()), 'failedjobs' => PrettyNumber::convert(FailedJob::where('failed_at', '>=', \Carbon\Carbon::now()->subDay())->count()),
'statuses' => PrettyNumber::convert(Status::count()), 'statuses' => PrettyNumber::convert(Status::count()),
'statuses_monthly' => PrettyNumber::convert(Status::where('created_at', '>', now()->subMonth())->count()),
'profiles' => PrettyNumber::convert(Profile::count()), 'profiles' => PrettyNumber::convert(Profile::count()),
'users' => PrettyNumber::convert(User::count()), 'users' => PrettyNumber::convert(User::count()),
'users_monthly' => PrettyNumber::convert(User::where('created_at', '>', now()->subMonth())->count()),
'instances' => PrettyNumber::convert(Instance::count()), 'instances' => PrettyNumber::convert(Instance::count()),
'media' => PrettyNumber::convert(Media::count()), 'media' => PrettyNumber::convert(Media::count()),
'storage' => Media::sum('size'), 'storage' => Media::sum('size'),
@ -51,4 +64,50 @@ class AdminStatsService
}); });
} }
protected static function postsGraph()
{
$ttl = now()->addHours(12);
return Cache::remember('admin:dashboard:home:data-postsGraph:v0:24hr', $ttl, function() {
$s = Status::selectRaw('Date(created_at) as date, count(statuses.id) as count, statuses.*')
->where('created_at', '>=', now()->subWeek())
->groupBy(DB::raw('Date(created_at)'))
->orderBy('created_at', 'DESC')
->pluck('count', 'date');
$begin = now()->subWeek();
$end = now();
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);
$dates = [];
foreach($daterange as $date){
$dates[$date->format("Y-m-d")] = 0;
}
$dates = collect($dates)->merge($s);
$s = Status::selectRaw('Date(created_at) as date, count(statuses.id) as count, statuses.*')
->where('created_at', '>=', now()->subWeeks(2))
->where('created_at', '<=', now()->subWeeks(1))
->groupBy(DB::raw('Date(created_at)'))
->orderBy('created_at', 'DESC')
->pluck('count', 'date');
$begin = now()->subWeeks(2);
$end = now()->subWeeks(1);
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);
$lw = [];
foreach($daterange as $date){
$lw[$date->format("Y-m-d")] = 0;
}
$lw = collect($lw)->merge($s);
return [
'posts_this_week' => $dates->values(),
'posts_last_week' => $lw->values(),
];
});
}
} }

127
package-lock.json generated
View file

@ -9,9 +9,13 @@
"animate.css": "^4.1.0", "animate.css": "^4.1.0",
"blurhash": "^1.1.3", "blurhash": "^1.1.3",
"bootstrap-vue": "^2.16.0", "bootstrap-vue": "^2.16.0",
"chart.js": "^2.7.2",
"filesize": "^3.6.1", "filesize": "^3.6.1",
"howler": "^2.2.0", "howler": "^2.2.0",
"infinite-scroll": "^3.0.6", "infinite-scroll": "^3.0.6",
"jquery-scroll-lock": "^3.1.3",
"jquery.scrollbar": "^0.2.11",
"js-cookie": "^2.2.0",
"laravel-echo": "^1.8.1", "laravel-echo": "^1.8.1",
"laravel-mix": "^4.1.4", "laravel-mix": "^4.1.4",
"node-sass": "^4.14.1", "node-sass": "^4.14.1",
@ -2732,6 +2736,45 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/chart.js": {
"version": "2.9.4",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz",
"integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==",
"dependencies": {
"chartjs-color": "^2.1.0",
"moment": "^2.10.2"
}
},
"node_modules/chartjs-color": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
"integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
"dependencies": {
"chartjs-color-string": "^0.6.0",
"color-convert": "^1.9.3"
}
},
"node_modules/chartjs-color-string": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
"integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
"dependencies": {
"color-name": "^1.0.0"
}
},
"node_modules/chartjs-color/node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dependencies": {
"color-name": "1.1.3"
}
},
"node_modules/chartjs-color/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"node_modules/chokidar": { "node_modules/chokidar": {
"version": "2.1.8", "version": "2.1.8",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
@ -6513,11 +6556,26 @@
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
"integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
}, },
"node_modules/jquery-scroll-lock": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/jquery-scroll-lock/-/jquery-scroll-lock-3.1.3.tgz",
"integrity": "sha1-GcWukMUUEdF6TEa+eUoGyoWZZkU="
},
"node_modules/jquery.scrollbar": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/jquery.scrollbar/-/jquery.scrollbar-0.2.11.tgz",
"integrity": "sha1-6RvUqX2DhZRjAk0m5zDcNmdqtZ0="
},
"node_modules/js-base64": { "node_modules/js-base64": {
"version": "2.6.4", "version": "2.6.4",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
"integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ=="
}, },
"node_modules/js-cookie": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz",
"integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ=="
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -7296,6 +7354,14 @@
"mkdirp": "bin/cmd.js" "mkdirp": "bin/cmd.js"
} }
}, },
"node_modules/moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
"engines": {
"node": "*"
}
},
"node_modules/move-concurrently": { "node_modules/move-concurrently": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@ -15734,6 +15800,47 @@
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
}, },
"chart.js": {
"version": "2.9.4",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz",
"integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==",
"requires": {
"chartjs-color": "^2.1.0",
"moment": "^2.10.2"
}
},
"chartjs-color": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
"integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
"requires": {
"chartjs-color-string": "^0.6.0",
"color-convert": "^1.9.3"
},
"dependencies": {
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
}
}
},
"chartjs-color-string": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
"integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
"requires": {
"color-name": "^1.0.0"
}
},
"chokidar": { "chokidar": {
"version": "2.1.8", "version": "2.1.8",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
@ -18731,11 +18838,26 @@
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
"integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
}, },
"jquery-scroll-lock": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/jquery-scroll-lock/-/jquery-scroll-lock-3.1.3.tgz",
"integrity": "sha1-GcWukMUUEdF6TEa+eUoGyoWZZkU="
},
"jquery.scrollbar": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/jquery.scrollbar/-/jquery.scrollbar-0.2.11.tgz",
"integrity": "sha1-6RvUqX2DhZRjAk0m5zDcNmdqtZ0="
},
"js-base64": { "js-base64": {
"version": "2.6.4", "version": "2.6.4",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
"integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ=="
}, },
"js-cookie": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz",
"integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ=="
},
"js-tokens": { "js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -19380,6 +19502,11 @@
"minimist": "^1.2.5" "minimist": "^1.2.5"
} }
}, },
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"move-concurrently": { "move-concurrently": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",

View file

@ -29,9 +29,13 @@
"animate.css": "^4.1.0", "animate.css": "^4.1.0",
"blurhash": "^1.1.3", "blurhash": "^1.1.3",
"bootstrap-vue": "^2.16.0", "bootstrap-vue": "^2.16.0",
"chart.js": "^2.7.2",
"filesize": "^3.6.1", "filesize": "^3.6.1",
"howler": "^2.2.0", "howler": "^2.2.0",
"infinite-scroll": "^3.0.6", "infinite-scroll": "^3.0.6",
"jquery-scroll-lock": "^3.1.3",
"jquery.scrollbar": "^0.2.11",
"js-cookie": "^2.2.0",
"laravel-echo": "^1.8.1", "laravel-echo": "^1.8.1",
"laravel-mix": "^4.1.4", "laravel-mix": "^4.1.4",
"node-sass": "^4.14.1", "node-sass": "^4.14.1",

1040
resources/assets/js/lib/argon.js vendored Normal file

File diff suppressed because it is too large Load diff

15
resources/assets/sass/admin.scss vendored Normal file
View file

@ -0,0 +1,15 @@
@import "lib/nucleo";
@import "lib/nucleo-svg";
@import "lib/argon";
body, button, input, textarea {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",
Roboto,Helvetica,Arial,sans-serif;
}
.title {
p.h3,
h3 {
font-size: 30px;
}
}

29776
resources/assets/sass/lib/argon.css vendored Normal file

File diff suppressed because it is too large Load diff

135
resources/assets/sass/lib/nucleo-svg.css vendored Normal file
View file

@ -0,0 +1,135 @@
/* Generated using nucleoapp.com */
/* --------------------------------
Icon colors
-------------------------------- */
.icon {
display: inline-block;
/* icon primary color */
color: #111111;
height: 1em;
width: 1em;
}
.icon use {
/* icon secondary color - fill */
fill: #7ea6f6;
}
.icon.icon-outline use {
/* icon secondary color - stroke */
stroke: #7ea6f6;
}
/* --------------------------------
Change icon size
-------------------------------- */
.icon-xs {
height: 0.5em;
width: 0.5em;
}
.icon-sm {
height: 0.8em;
width: 0.8em;
}
.icon-lg {
height: 1.6em;
width: 1.6em;
}
.icon-xl {
height: 2em;
width: 2em;
}
/* --------------------------------
Align icon and text
-------------------------------- */
.icon-text-aligner {
/* add this class to parent element that contains icon + text */
display: flex;
align-items: center;
}
.icon-text-aligner .icon {
color: inherit;
margin-right: 0.4em;
}
.icon-text-aligner .icon use {
color: inherit;
fill: currentColor;
}
.icon-text-aligner .icon.icon-outline use {
stroke: currentColor;
}
/* --------------------------------
Icon reset values - used to enable color customizations
-------------------------------- */
.icon {
fill: currentColor;
stroke: none;
}
.icon.icon-outline {
fill: none;
stroke: currentColor;
}
.icon use {
stroke: none;
}
.icon.icon-outline use {
fill: none;
}
/* --------------------------------
Stroke effects - Nucleo outline icons
- 16px icons -> up to 1px stroke (16px outline icons do not support stroke changes)
- 24px, 32px icons -> up to 2px stroke
- 48px, 64px icons -> up to 4px stroke
-------------------------------- */
.icon-outline.icon-stroke-1 {
stroke-width: 1px;
}
.icon-outline.icon-stroke-2 {
stroke-width: 2px;
}
.icon-outline.icon-stroke-3 {
stroke-width: 3px;
}
.icon-outline.icon-stroke-4 {
stroke-width: 4px;
}
.icon-outline.icon-stroke-1 use,
.icon-outline.icon-stroke-3 use {
-webkit-transform: translateX(0.5px) translateY(0.5px);
-moz-transform: translateX(0.5px) translateY(0.5px);
-ms-transform: translateX(0.5px) translateY(0.5px);
-o-transform: translateX(0.5px) translateY(0.5px);
transform: translateX(0.5px) translateY(0.5px);
}

572
resources/assets/sass/lib/nucleo.css vendored Normal file
View file

@ -0,0 +1,572 @@
/*--------------------------------
hermes-dashboard-icons Web Font - built using nucleoapp.com
License - nucleoapp.com/license/
-------------------------------- */
@font-face {
font-family: 'NucleoIcons';
src: url('/fonts/nucleo-icons.eot');
src: url('/fonts/nucleo-icons.eot') format('embedded-opentype'), url('/fonts/nucleo-icons.woff2') format('woff2'), url('/fonts/nucleo-icons.woff') format('woff'), url('/fonts/nucleo-icons.ttf') format('truetype'), url('/fonts/nucleo-icons.svg') format('svg');
font-weight: normal;
font-style: normal;
}
/*------------------------
base class definition
-------------------------*/
.ni {
display: inline-block;
font: normal normal normal 14px/1 NucleoIcons;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/*------------------------
change icon size
-------------------------*/
.ni-lg {
font-size: 1.33333333em;
line-height: 0.75em;
vertical-align: -15%;
}
.ni-2x {
font-size: 2em;
}
.ni-3x {
font-size: 3em;
}
.ni-4x {
font-size: 4em;
}
.ni-5x {
font-size: 5em;
}
/*----------------------------------
add a square/circle background
-----------------------------------*/
.ni.square,
.ni.circle {
padding: 0.33333333em;
vertical-align: -16%;
background-color: #eee;
}
.ni.circle {
border-radius: 50%;
}
/*------------------------
list icons
-------------------------*/
.ni-ul {
padding-left: 0;
margin-left: 2.14285714em;
list-style-type: none;
}
.ni-ul > li {
position: relative;
}
.ni-ul > li > .ni {
position: absolute;
left: -1.57142857em;
top: 0.14285714em;
text-align: center;
}
.ni-ul > li > .ni.lg {
top: 0;
left: -1.35714286em;
}
.ni-ul > li > .ni.circle,
.ni-ul > li > .ni.square {
top: -0.19047619em;
left: -1.9047619em;
}
/*------------------------
spinning icons
-------------------------*/
.ni.spin {
-webkit-animation: nc-spin 2s infinite linear;
-moz-animation: nc-spin 2s infinite linear;
animation: nc-spin 2s infinite linear;
}
@-webkit-keyframes nc-spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@-moz-keyframes nc-spin {
0% {
-moz-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(360deg);
}
}
@keyframes nc-spin {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
/*------------------------
rotated/flipped icons
-------------------------*/
.ni.rotate-90 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-o-transform: rotate(90deg);
transform: rotate(90deg);
}
.ni.rotate-180 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform: rotate(180deg);
}
.ni.rotate-270 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
-webkit-transform: rotate(270deg);
-moz-transform: rotate(270deg);
-ms-transform: rotate(270deg);
-o-transform: rotate(270deg);
transform: rotate(270deg);
}
.ni.flip-y {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0);
-webkit-transform: scale(-1, 1);
-moz-transform: scale(-1, 1);
-ms-transform: scale(-1, 1);
-o-transform: scale(-1, 1);
transform: scale(-1, 1);
}
.ni.flip-x {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
-webkit-transform: scale(1, -1);
-moz-transform: scale(1, -1);
-ms-transform: scale(1, -1);
-o-transform: scale(1, -1);
transform: scale(1, -1);
}
/*------------------------
font icons
-------------------------*/
.ni-active-40::before {
content: "\ea02";
}
.ni-air-baloon::before {
content: "\ea03";
}
.ni-album-2::before {
content: "\ea04";
}
.ni-align-center::before {
content: "\ea05";
}
.ni-align-left-2::before {
content: "\ea06";
}
.ni-ambulance::before {
content: "\ea07";
}
.ni-app::before {
content: "\ea08";
}
.ni-archive-2::before {
content: "\ea09";
}
.ni-atom::before {
content: "\ea0a";
}
.ni-badge::before {
content: "\ea0b";
}
.ni-bag-17::before {
content: "\ea0c";
}
.ni-basket::before {
content: "\ea0d";
}
.ni-bell-55::before {
content: "\ea0e";
}
.ni-bold-down::before {
content: "\ea0f";
}
.ni-bold-left::before {
content: "\ea10";
}
.ni-bold-right::before {
content: "\ea11";
}
.ni-bold-up::before {
content: "\ea12";
}
.ni-bold::before {
content: "\ea13";
}
.ni-book-bookmark::before {
content: "\ea14";
}
.ni-books::before {
content: "\ea15";
}
.ni-box-2::before {
content: "\ea16";
}
.ni-briefcase-24::before {
content: "\ea17";
}
.ni-building::before {
content: "\ea18";
}
.ni-bulb-61::before {
content: "\ea19";
}
.ni-bullet-list-67::before {
content: "\ea1a";
}
.ni-bus-front-12::before {
content: "\ea1b";
}
.ni-button-pause::before {
content: "\ea1c";
}
.ni-button-play::before {
content: "\ea1d";
}
.ni-button-power::before {
content: "\ea1e";
}
.ni-calendar-grid-58::before {
content: "\ea1f";
}
.ni-camera-compact::before {
content: "\ea20";
}
.ni-caps-small::before {
content: "\ea21";
}
.ni-cart::before {
content: "\ea22";
}
.ni-chart-bar-32::before {
content: "\ea23";
}
.ni-chart-pie-35::before {
content: "\ea24";
}
.ni-chat-round::before {
content: "\ea25";
}
.ni-check-bold::before {
content: "\ea26";
}
.ni-circle-08::before {
content: "\ea27";
}
.ni-cloud-download-95::before {
content: "\ea28";
}
.ni-cloud-upload-96::before {
content: "\ea29";
}
.ni-compass-04::before {
content: "\ea2a";
}
.ni-controller::before {
content: "\ea2b";
}
.ni-credit-card::before {
content: "\ea2c";
}
.ni-curved-next::before {
content: "\ea2d";
}
.ni-delivery-fast::before {
content: "\ea2e";
}
.ni-diamond::before {
content: "\ea2f";
}
.ni-email-83::before {
content: "\ea30";
}
.ni-fat-add::before {
content: "\ea31";
}
.ni-fat-delete::before {
content: "\ea32";
}
.ni-fat-remove::before {
content: "\ea33";
}
.ni-favourite-28::before {
content: "\ea34";
}
.ni-folder-17::before {
content: "\ea35";
}
.ni-glasses-2::before {
content: "\ea36";
}
.ni-hat-3::before {
content: "\ea37";
}
.ni-headphones::before {
content: "\ea38";
}
.ni-html5::before {
content: "\ea39";
}
.ni-istanbul::before {
content: "\ea3a";
}
.ni-key-25::before {
content: "\ea3b";
}
.ni-laptop::before {
content: "\ea3c";
}
.ni-like-2::before {
content: "\ea3d";
}
.ni-lock-circle-open::before {
content: "\ea3e";
}
.ni-map-big::before {
content: "\ea3f";
}
.ni-mobile-button::before {
content: "\ea40";
}
.ni-money-coins::before {
content: "\ea41";
}
.ni-note-03::before {
content: "\ea42";
}
.ni-notification-70::before {
content: "\ea43";
}
.ni-palette::before {
content: "\ea44";
}
.ni-paper-diploma::before {
content: "\ea45";
}
.ni-pin-3::before {
content: "\ea46";
}
.ni-planet::before {
content: "\ea47";
}
.ni-ruler-pencil::before {
content: "\ea48";
}
.ni-satisfied::before {
content: "\ea49";
}
.ni-scissors::before {
content: "\ea4a";
}
.ni-send::before {
content: "\ea4b";
}
.ni-settings-gear-65::before {
content: "\ea4c";
}
.ni-settings::before {
content: "\ea4d";
}
.ni-single-02::before {
content: "\ea4e";
}
.ni-single-copy-04::before {
content: "\ea4f";
}
.ni-sound-wave::before {
content: "\ea50";
}
.ni-spaceship::before {
content: "\ea51";
}
.ni-square-pin::before {
content: "\ea52";
}
.ni-support-16::before {
content: "\ea53";
}
.ni-tablet-button::before {
content: "\ea54";
}
.ni-tag::before {
content: "\ea55";
}
.ni-tie-bow::before {
content: "\ea56";
}
.ni-time-alarm::before {
content: "\ea57";
}
.ni-trophy::before {
content: "\ea58";
}
.ni-tv-2::before {
content: "\ea59";
}
.ni-umbrella-13::before {
content: "\ea5a";
}
.ni-user-run::before {
content: "\ea5b";
}
.ni-vector::before {
content: "\ea5c";
}
.ni-watch-time::before {
content: "\ea5d";
}
.ni-world::before {
content: "\ea5e";
}
.ni-zoom-split-in::before {
content: "\ea5f";
}
.ni-collection::before {
content: "\ea60";
}
.ni-image::before {
content: "\ea61";
}
.ni-shop::before {
content: "\ea62";
}
.ni-ungroup::before {
content: "\ea63";
}
.ni-world-2::before {
content: "\ea64";
}
.ni-ui-04::before {
content: "\ea65";
}
/* all icon font classes list here */

View file

@ -1,89 +1,161 @@
@extends('admin.partial.template-full') @extends('admin.partial.template-full')
@section('section') @section('section')
<div class="title">
<h3 class="font-weight-bold">Dashboard</h3>
</div> </div>
<div class="header bg-primary pb-6 mt-n4">
<hr> <div class="container-fluid">
<div class="header-body">
<div class="row align-items-center py-4">
<div class="col-lg-6 col-7">
<p class="display-1 text-white d-inline-block mb-0">Dashboard</p>
</div>
</div>
<div class="row">
<div class="col-xl-3 col-md-6">
<div class="card card-stats">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">Total posts</h5>
<span class="h2 font-weight-bold mb-0">{{$data['statuses']}}</span>
</div>
<div class="col-auto">
<div class="icon icon-shape bg-gradient-primary text-white rounded-circle shadow">
<i class="ni ni-image"></i>
</div>
</div>
</div>
<p class="mt-3 mb-0 text-sm">
<span class="text-success mr-2"><i class="fa fa-arrow-up"></i> {{$data['statuses_monthly']}}</span>
<span class="text-nowrap">in last 30 days</span>
</p>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card card-stats">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">Total users</h5>
<span class="h2 font-weight-bold mb-0">{{$data['users']}}</span>
</div>
<div class="col-auto">
<div class="icon icon-shape bg-gradient-primary text-white rounded-circle shadow">
<i class="ni ni-circle-08"></i>
</div>
</div>
</div>
<p class="mt-3 mb-0 text-sm">
<span class="text-success mr-2"><i class="fa fa-arrow-up"></i> {{$data['users_monthly']}}</span>
<span class="text-nowrap">in last 30 days</span>
</p>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card card-stats">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">Reports</h5>
<span class="h2 font-weight-bold mb-0">{{$data['reports']}}</span>
</div>
<div class="col-auto">
<div class="icon icon-shape bg-gradient-primary text-white rounded-circle shadow">
<i class="ni ni-bell-55"></i>
</div>
</div>
</div>
<p class="mt-3 mb-0 text-sm">
<span class="text-success mr-2"><i class="fa fa-arrow-up"></i> {{$data['reports_monthly']}}</span>
<span class="text-nowrap">in last 30 days</span>
</p>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card card-stats">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">Messages</h5>
<span class="h2 font-weight-bold mb-0">{{$data['contact']}}</span>
</div>
<div class="col-auto">
<div class="icon icon-shape bg-gradient-info text-white rounded-circle shadow">
<i class="ni ni-chat-round"></i>
</div>
</div>
</div>
<p class="mt-3 mb-0 text-sm">
<span class="text-success mr-2"><i class="fa fa-arrow-up"></i> {{$data['contact_monthly']}}</span>
<span class="text-nowrap">in last 30 days</span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container-fluid mt-4">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-8">
<div class="card shadow-none border" style="min-height:125px"> <div class="card bg-default">
<div class="card-header bg-transparent">
<div class="row align-items-center">
<div class="col">
<h6 class="text-light text-uppercase ls-1 mb-1">Overview</h6>
<h5 class="h3 text-white mb-0">Daily Posts</h5>
</div>
<div class="col">
<ul class="nav nav-pills justify-content-end">
<li class="nav-item mr-2 mr-md-0 posts-this-week" data-toggle="chart" data-target="#c1-dark" data-update='{"data":{"datasets":[{"data":{{$data['posts_this_week']}}}]}}'>
<a href="#" class="nav-link py-2 px-3 active" data-toggle="tab">
<span class="d-none d-md-block">This Week</span>
<span class="d-md-none">W</span>
</a>
</li>
<li class="nav-item" data-toggle="chart" data-target="#c1-dark" data-update='{"data":{"datasets":[{"data":{{$data['posts_last_week']}}}]}}'>
<a href="#" class="nav-link py-2 px-3" data-toggle="tab">
<span class="d-none d-md-block">Last Week</span>
<span class="d-md-none">W</span>
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="card-body"> <div class="card-body">
<p class="small text-uppercase font-weight-bold text-muted">New Messages</p> <!-- Chart -->
<p class="h2 mb-0">{{$data['contact']}}</p> <div class="chart">
<!-- Chart wrapper -->
<canvas id="c1-dark" class="chart-canvas"></canvas>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<div class="card shadow-none border" style="min-height:125px"> <div class="card shadow-none border mb-2" style="min-height:125px">
<div class="card-body"> <div class="card-body">
<p class="small text-uppercase font-weight-bold text-muted">Failed Jobs (24h)</p> <p class="small text-uppercase font-weight-bold text-muted">Failed Jobs (24h)</p>
<p class="h2 mb-0">{{$data['failedjobs']}}</p> <p class="h2 mb-0">{{$data['failedjobs']}}</p>
</div> </div>
</div> </div>
</div> <div class="card shadow-none border mb-2" style="min-height:125px">
<div class="col-md-4">
<div class="card shadow-none border" style="min-height:125px">
<div class="card-body">
<p class="small text-uppercase font-weight-bold text-muted">Reports</p>
<p class="h2 mb-0" title="{{$data['reports']}}" data-toggle="tooltip">{{$data['reports']}}</p>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-4">
<div class="card shadow-none border" style="min-height:125px">
<div class="card-body">
<p class="small text-uppercase font-weight-bold text-muted">Statuses</p>
<p class="h2 mb-0" title="{{$data['statuses']}}" data-toggle="tooltip">{{$data['statuses']}}</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card shadow-none border" style="min-height:125px">
<div class="card-body">
<p class="small text-uppercase font-weight-bold text-muted">Profiles</p>
<p class="h2 mb-0">{{$data['profiles']}}</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card shadow-none border" style="min-height:125px">
<div class="card-body">
<p class="small text-uppercase font-weight-bold text-muted">Users</p>
<p class="h2 mb-0">{{$data['users']}}</p>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-4">
<div class="card shadow-none border" style="min-height:125px">
<div class="card-body"> <div class="card-body">
<p class="small text-uppercase font-weight-bold text-muted">Remote Instances</p> <p class="small text-uppercase font-weight-bold text-muted">Remote Instances</p>
<p class="h2 mb-0">{{$data['instances']}}</p> <p class="h2 mb-0">{{$data['instances']}}</p>
</div> </div>
</div> </div>
</div> <div class="card shadow-none border mb-2" style="min-height:125px">
<div class="col-md-4">
<div class="card shadow-none border" style="min-height:125px">
<div class="card-body"> <div class="card-body">
<p class="small text-uppercase font-weight-bold text-muted">Photos Uploaded</p> <p class="small text-uppercase font-weight-bold text-muted">Photos Uploaded</p>
<p class="h2 mb-0">{{$data['media']}}</p> <p class="h2 mb-0">{{$data['media']}}</p>
</div> </div>
</div> </div>
</div>
<div class="col-md-4">
<div class="card shadow-none border" style="min-height:125px"> <div class="card shadow-none border" style="min-height:125px">
<div class="card-body"> <div class="card-body">
<p class="small text-uppercase font-weight-bold text-muted">Storage Used</p> <p class="small text-uppercase font-weight-bold text-muted">Storage Used</p>

View file

@ -0,0 +1,62 @@
<nav class="navbar navbar-top navbar-expand navbar-dark bg-primary border-bottom">
<div class="container-fluid">
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<form class="navbar-search navbar-search-light form-inline mr-sm-3" id="navbar-search-main" method="get" action="/i/results">
<div class="form-group mb-0">
<div class="input-group input-group-alternative input-group-merge">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" placeholder="{{__('navmenu.search')}}">
</div>
</div>
<button type="button" class="close" data-action="search-close" data-target="#navbar-search-main" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</form>
<ul class="navbar-nav align-items-center ml-md-auto ">
<li class="nav-item d-xl-none">
<div class="pr-3 sidenav-toggler sidenav-toggler-dark" data-action="sidenav-pin" data-target="#sidenav-main">
<div class="sidenav-toggler-inner">
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
</div>
</div>
</li>
<li class="nav-item d-sm-none">
<a class="nav-link" href="#" data-action="search-show" data-target="#navbar-search-main">
<i class="ni ni-zoom-split-in"></i>
</a>
</li>
</ul>
<ul class="navbar-nav align-items-center ml-auto ml-md-0 ">
<li class="nav-item dropdown">
<a class="nav-link pr-0" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div class="media align-items-center">
<span class="avatar avatar-sm rounded-circle">
<img alt="avatar" src="{{request()->user()->profile->avatarUrl()}}">
</span>
<div class="media-body ml-2 d-none d-lg-block">
<span class="mb-0 text-sm font-weight-bold">{{request()->user()->username}}</span>
</div>
</div>
</a>
<div class="dropdown-menu dropdown-menu-right ">
<div class="dropdown-header noti-title">
<h6 class="text-overflow m-0">Welcome!</h6>
</div>
<a href="/i/me" class="dropdown-item">
<i class="ni ni-single-02"></i>
<span>Profile</span>
</a>
<a href="/settings/home" class="dropdown-item">
<i class="ni ni-settings-gear-65"></i>
<span>Settings</span>
</a>
</div>
</li>
</ul>
</div>
</div>
</nav>

View file

@ -0,0 +1,120 @@
<nav class="sidenav navbar navbar-vertical fixed-left navbar-expand-xs navbar-light bg-white" id="sidenav-main">
<div class="scrollbar-inner">
<div class="sidenav-header align-items-center">
<a class="navbar-brand" href="/">
<img src="/img/pixelfed-icon-color.svg" class="navbar-brand-img">
</a>
</div>
<div class="navbar-inner">
<div class="collapse navbar-collapse" id="sidenav-collapse-main">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link {{request()->is('i/admin/dashboard')?'active':''}} " href="/i/admin/dashboard">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Dashboard</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*messages*')?'active':''}}" href="{{route('admin.messages')}}">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Messages</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*reports*')?'active':''}}" href="{{route('admin.reports')}}">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Moderation</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*statuses*')?'active':''}}" href="{{route('admin.statuses')}}">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Statuses</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*users*')?'active':''}}" href="{{route('admin.users')}}">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Users</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*admin/settings')?'active':''}}" href="{{route('admin.settings')}}">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Settings</span>
</a>
</li>
</ul>
<hr class="my-3">
<ul class="navbar-nav mb-md-3">
<li class="nav-item">
<a class="nav-link {{request()->is('*apps*')?'active':''}}" href="{{route('admin.apps')}}">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Apps</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*hashtags*')?'active':''}}" href="{{route('admin.hashtags')}}">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Hashtags</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*instances*')?'active':''}}" href="{{route('admin.instances')}}">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Instances</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*media*')?'active':''}}" href="{{route('admin.media')}}">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Media</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*site-news*')?'active':''}}" href="/i/admin/site-news">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Newsroom</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*profiles*')?'active':''}}" href="/i/admin/profiles">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Profiles</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*settings/pages')?'active':''}}" href="/i/admin/settings/pages">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">Pages</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{request()->is('*settings/system')?'active':''}}" href="/i/admin/settings/system">
<i class="ni ni-bold-right text-primary"></i>
<span class="nav-link-text">System</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</nav>

View file

@ -1,26 +1,12 @@
@extends('layouts.app') @extends('layouts.admin')
@section('content') @section('content')
@include('admin.partial.topnav') @include('admin.partial.sidenav')
<div class="main-content" id="panel">
<div class="container"> @include('admin.partial.nav')
<div class="col-12 mt-4"> <div class="container-fluid mt-4">
<div class="card shadow-none bg-transparent">
<div class="card-body p-0">
<div class="row">
<div class="col-12">
@if (session('status'))
<div class="alert alert-success">
{{ session('status')}}
</div>
@endif
@yield('section') @yield('section')
</div> </div>
</div> </div>
</div>
</div>
</div>
</div>
@endsection @endsection

View file

@ -1,27 +1,12 @@
@extends('layouts.app') @extends('layouts.admin')
@section('content') @section('content')
@include('admin.partial.topnav') @include('admin.partial.sidenav')
<div class="main-content" id="panel">
<div class="container"> @include('admin.partial.nav')
<div class="col-12 mt-4"> <div class="container-fluid mt-4">
<div class="card shadow-none border">
<div class="card-body p-0">
<div class="row">
@include('admin.partial.sidebar')
<div class="col-12 col-md-9 p-4">
@if (session('status'))
<div class="alert alert-success">
{{ session('status')}}
</div>
@endif
@yield('section') @yield('section')
</div> </div>
</div> </div>
</div>
</div>
</div>
</div>
@endsection @endsection

View file

@ -36,7 +36,7 @@
<div class="tab-content" id="myTabContent"> <div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab"> <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
{{-- <div class="ml-n4 mr-n2 p-3 bg-light border-top border-bottom"> {{-- <div class="ml-n4 mr-n2 p-3 border-top border-bottom">
<label class="font-weight-bold text-muted">System Configuration</label> <label class="font-weight-bold text-muted">System Configuration</label>
<ul class="list-unstyled"> <ul class="list-unstyled">
<li> <li>
@ -74,7 +74,7 @@
</ul> </ul>
</div> --}} </div> --}}
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-top border-bottom"> <div class="ml-n4 mr-n2 p-3 border-top border-bottom">
<label class="font-weight-bold text-muted">Features</label> <label class="font-weight-bold text-muted">Features</label>
@if($cloud_ready) @if($cloud_ready)
<div class="custom-control custom-checkbox mt-2"> <div class="custom-control custom-checkbox mt-2">
@ -122,21 +122,21 @@
</div> </div>
</div> </div>
{{-- <div class="form-group mb-0"> {{-- <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-top border-bottom"> <div class="ml-n4 mr-n2 p-3 border-top border-bottom">
<label class="font-weight-bold text-muted">Name</label> <label class="font-weight-bold text-muted">Name</label>
<input class="form-control col-8" name="name" placeholder="Pixelfed" value="{{config_cache('app.name')}}"> <input class="form-control col-8" name="name" placeholder="Pixelfed" value="{{config_cache('app.name')}}">
<p class="help-text small text-muted mt-3 mb-0">The instance name used in titles, metadata and apis.</p> <p class="help-text small text-muted mt-3 mb-0">The instance name used in titles, metadata and apis.</p>
</div> </div>
</div> </div>
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-bottom"> <div class="ml-n4 mr-n2 p-3 border-bottom">
<label class="font-weight-bold text-muted">Short Description</label> <label class="font-weight-bold text-muted">Short Description</label>
<textarea class="form-control" rows="3" name="short_description">{{config_cache('app.short_description')}}</textarea> <textarea class="form-control" rows="3" name="short_description">{{config_cache('app.short_description')}}</textarea>
<p class="help-text small text-muted mt-3 mb-0">Short description of instance used on various pages and apis.</p> <p class="help-text small text-muted mt-3 mb-0">Short description of instance used on various pages and apis.</p>
</div> </div>
</div> </div>
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-bottom"> <div class="ml-n4 mr-n2 p-3 border-bottom">
<label class="font-weight-bold text-muted">Long Description</label> <label class="font-weight-bold text-muted">Long Description</label>
<textarea class="form-control" rows="3" name="long_description">{{config_cache('app.description')}}</textarea> <textarea class="form-control" rows="3" name="long_description">{{config_cache('app.description')}}</textarea>
<p class="help-text small text-muted mt-3 mb-0">Longer description of instance used on about page.</p> <p class="help-text small text-muted mt-3 mb-0">Longer description of instance used on about page.</p>
@ -146,28 +146,28 @@
<div class="tab-pane" id="brand" role="tabpanel" aria-labelledby="brand-tab"> <div class="tab-pane" id="brand" role="tabpanel" aria-labelledby="brand-tab">
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-top border-bottom"> <div class="ml-n4 mr-n2 p-3 border-top border-bottom">
<label class="font-weight-bold text-muted">Name</label> <label class="font-weight-bold text-muted">Name</label>
<input class="form-control col-8" name="name" placeholder="Pixelfed" value="{{config_cache('app.name')}}"> <input class="form-control col-8" name="name" placeholder="Pixelfed" value="{{config_cache('app.name')}}">
<p class="help-text small text-muted mt-3 mb-0">The instance name used in titles, metadata and apis.</p> <p class="help-text small text-muted mt-3 mb-0">The instance name used in titles, metadata and apis.</p>
</div> </div>
</div> </div>
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-bottom"> <div class="ml-n4 mr-n2 p-3 border-bottom">
<label class="font-weight-bold text-muted">Short Description</label> <label class="font-weight-bold text-muted">Short Description</label>
<textarea class="form-control" rows="3" name="short_description">{{config_cache('app.short_description')}}</textarea> <textarea class="form-control" rows="3" name="short_description">{{config_cache('app.short_description')}}</textarea>
<p class="help-text small text-muted mt-3 mb-0">Short description of instance used on various pages and apis.</p> <p class="help-text small text-muted mt-3 mb-0">Short description of instance used on various pages and apis.</p>
</div> </div>
</div> </div>
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-bottom"> <div class="ml-n4 mr-n2 p-3 border-bottom">
<label class="font-weight-bold text-muted">Long Description</label> <label class="font-weight-bold text-muted">Long Description</label>
<textarea class="form-control" rows="3" name="long_description">{{config_cache('app.description')}}</textarea> <textarea class="form-control" rows="3" name="long_description">{{config_cache('app.description')}}</textarea>
<p class="help-text small text-muted mt-3 mb-0">Longer description of instance used on about page.</p> <p class="help-text small text-muted mt-3 mb-0">Longer description of instance used on about page.</p>
</div> </div>
</div> </div>
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-top border-bottom"> <div class="ml-n4 mr-n2 p-3 border-top border-bottom">
<label class="font-weight-bold text-muted">About Title</label> <label class="font-weight-bold text-muted">About Title</label>
<input class="form-control col-8" name="about_title" placeholder="Photo Sharing. For Everyone" value="{{config_cache('about.title')}}"> <input class="form-control col-8" name="about_title" placeholder="Photo Sharing. For Everyone" value="{{config_cache('about.title')}}">
<p class="help-text small text-muted mt-3 mb-0">The header title used on the <a href="/site/about">about page</a>.</p> <p class="help-text small text-muted mt-3 mb-0">The header title used on the <a href="/site/about">about page</a>.</p>
@ -177,7 +177,7 @@
<div class="tab-pane" id="users" role="tabpanel" aria-labelledby="users-tab"> <div class="tab-pane" id="users" role="tabpanel" aria-labelledby="users-tab">
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-top"> <div class="ml-n4 mr-n2 p-3 border-top">
<div class="custom-control custom-checkbox mt-2"> <div class="custom-control custom-checkbox mt-2">
<input type="checkbox" name="require_email_verification" class="custom-control-input" id="mailVerification" {{config_cache('pixelfed.enforce_email_verification') ? 'checked' : ''}}> <input type="checkbox" name="require_email_verification" class="custom-control-input" id="mailVerification" {{config_cache('pixelfed.enforce_email_verification') ? 'checked' : ''}}>
<label class="custom-control-label font-weight-bold" for="mailVerification">Require Email Verification</label> <label class="custom-control-label font-weight-bold" for="mailVerification">Require Email Verification</label>
@ -185,7 +185,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="ml-n4 mr-n2 p-3 bg-light border-top border-bottom"> <div class="ml-n4 mr-n2 p-3 border-top border-bottom">
<div class="custom-control custom-checkbox my-2"> <div class="custom-control custom-checkbox my-2">
<input type="checkbox" name="enforce_account_limit" class="custom-control-input" id="userEnforceLimit" {{config_cache('pixelfed.enforce_account_limit') ? 'checked' : ''}}> <input type="checkbox" name="enforce_account_limit" class="custom-control-input" id="userEnforceLimit" {{config_cache('pixelfed.enforce_account_limit') ? 'checked' : ''}}>
<label class="custom-control-label font-weight-bold" for="userEnforceLimit">Enable account storage limit</label> <label class="custom-control-label font-weight-bold" for="userEnforceLimit">Enable account storage limit</label>
@ -201,7 +201,7 @@
<div class="tab-pane" id="media" role="tabpanel" aria-labelledby="media-tab"> <div class="tab-pane" id="media" role="tabpanel" aria-labelledby="media-tab">
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-top"> <div class="ml-n4 mr-n2 p-3 border-top">
<label class="font-weight-bold text-muted">Max Size</label> <label class="font-weight-bold text-muted">Max Size</label>
<input class="form-control" name="max_photo_size" value="{{config_cache('pixelfed.max_photo_size')}}"> <input class="form-control" name="max_photo_size" value="{{config_cache('pixelfed.max_photo_size')}}">
<p class="help-text small text-muted mt-3 mb-0">Maximum file upload size in KB</p> <p class="help-text small text-muted mt-3 mb-0">Maximum file upload size in KB</p>
@ -209,21 +209,21 @@
</div> </div>
</div> </div>
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-top"> <div class="ml-n4 mr-n2 p-3 border-top">
<label class="font-weight-bold text-muted">Photo Album Limit</label> <label class="font-weight-bold text-muted">Photo Album Limit</label>
<input class="form-control" name="max_album_length" value="{{config_cache('pixelfed.max_album_length')}}"> <input class="form-control" name="max_album_length" value="{{config_cache('pixelfed.max_album_length')}}">
<p class="help-text small text-muted mt-3 mb-0">The maximum number of photos or videos per album</p> <p class="help-text small text-muted mt-3 mb-0">The maximum number of photos or videos per album</p>
</div> </div>
</div> </div>
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-top"> <div class="ml-n4 mr-n2 p-3 border-top">
<label class="font-weight-bold text-muted">Image Quality</label> <label class="font-weight-bold text-muted">Image Quality</label>
<input class="form-control" name="image_quality" value="{{config_cache('pixelfed.image_quality')}}"> <input class="form-control" name="image_quality" value="{{config_cache('pixelfed.image_quality')}}">
<p class="help-text small text-muted mt-3 mb-0">Image optimization quality from 0-100%. Set to 0 to disable image optimization.</p> <p class="help-text small text-muted mt-3 mb-0">Image optimization quality from 0-100%. Set to 0 to disable image optimization.</p>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="ml-n4 mr-n2 p-3 bg-light border-top border-bottom"> <div class="ml-n4 mr-n2 p-3 border-top border-bottom">
<label class="font-weight-bold text-muted">Media Types</label> <label class="font-weight-bold text-muted">Media Types</label>
<div class="custom-control custom-checkbox mt-2"> <div class="custom-control custom-checkbox mt-2">
<input type="checkbox" name="type_jpeg" class="custom-control-input" id="mediaType1" {{$jpeg ? 'checked' : ''}}> <input type="checkbox" name="type_jpeg" class="custom-control-input" id="mediaType1" {{$jpeg ? 'checked' : ''}}>
@ -250,7 +250,7 @@
<div class="border-top"> <div class="border-top">
<p class="lead mt-3 py-3 text-center">Add rules that explain what is acceptable use.</p> <p class="lead mt-3 py-3 text-center">Add rules that explain what is acceptable use.</p>
</div> </div>
<div class="ml-n4 mr-n2 p-3 bg-light border-top border-bottom"> <div class="ml-n4 mr-n2 p-3 border-top border-bottom">
<p class="font-weight-bold text-muted">Active Rules</p> <p class="font-weight-bold text-muted">Active Rules</p>
<ol class="font-weight-bold"> <ol class="font-weight-bold">
@if($rules) @if($rules)
@ -268,7 +268,7 @@
</ol> </ol>
</div> </div>
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-top border-bottom"> <div class="ml-n4 mr-n2 p-3 border-top border-bottom">
<label class="font-weight-bold text-muted">Add Rule</label> <label class="font-weight-bold text-muted">Add Rule</label>
<input class="form-control" name="new_rule" placeholder="Add a new rule, we recommend being descriptive but keeping it short"/> <input class="form-control" name="new_rule" placeholder="Add a new rule, we recommend being descriptive but keeping it short"/>
</div> </div>
@ -277,7 +277,7 @@
<div class="tab-pane" id="advanced" role="tabpanel" aria-labelledby="advanced-tab"> <div class="tab-pane" id="advanced" role="tabpanel" aria-labelledby="advanced-tab">
<div class="form-group mb-0"> <div class="form-group mb-0">
<div class="ml-n4 mr-n2 p-3 bg-light border-top border-bottom"> <div class="ml-n4 mr-n2 p-3 border-top border-bottom">
<label class="font-weight-bold text-muted">Custom CSS</label> <label class="font-weight-bold text-muted">Custom CSS</label>
<div class="custom-control custom-checkbox my-2"> <div class="custom-control custom-checkbox my-2">
<input type="checkbox" name="show_custom_css" class="custom-control-input" id="showCustomCss" {{config_cache('uikit.show_custom.css') ? 'checked' : ''}}> <input type="checkbox" name="show_custom_css" class="custom-control-input" id="showCustomCss" {{config_cache('uikit.show_custom.css') ? 'checked' : ''}}>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="mobile-web-app-capable" content="yes">
<title>{{ $title ?? config_cache('app.name') }}</title>
<link rel="manifest" href="/manifest.json">
<meta property="og:site_name" content="{{ config_cache('app.name') }}">
<meta property="og:title" content="{{ $title ?? config_cache('app.name') }}">
<meta property="og:type" content="article">
<meta property="og:url" content="{{url(request()->url())}}">
@stack('meta')
<meta name="medium" content="image">
<meta name="theme-color" content="#10c5f8">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="shortcut icon" type="image/png" href="/img/favicon.png?v=2">
<link rel="apple-touch-icon" type="image/png" href="/img/favicon.png?v=2">
<link rel="canonical" href="{{url(request()->url())}}">
<link href="{{ mix('css/app.css') }}" rel="stylesheet" data-stylesheet="light">
<link href="{{ mix('css/admin.css') }}" rel="stylesheet" data-stylesheet="light">
@stack('styles')
</head>
<body class="loggedIn">
@yield('content')
@include('layouts.partial.footer')
<script type="text/javascript" src="{{ mix('js/manifest.js') }}"></script>
<script type="text/javascript" src="{{ mix('js/vendor.js') }}"></script>
<script type="text/javascript" src="{{ mix('js/admin.js') }}"></script>
@stack('scripts')
</body>
</html>

View file

@ -73,7 +73,7 @@ Route::group(['prefix' => 'api'], function() use($middleware) {
Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware($middleware); Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware($middleware);
Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic');
Route::get('timelines/tag/{hashtag}', 'Api\ApiV1Controller@timelineHashtag')->middleware($middleware); Route::get('timelines/tag/{hashtag}', 'Api\ApiV1Controller@timelineHashtag');
}); });
Route::group(['prefix' => 'stories'], function () use($middleware) { Route::group(['prefix' => 'stories'], function () use($middleware) {
Route::get('v1/me', 'StoryController@apiV1Me'); Route::get('v1/me', 'StoryController@apiV1Me');

3
webpack.mix.js vendored
View file

@ -2,6 +2,7 @@ let mix = require('laravel-mix');
mix.sass('resources/assets/sass/app.scss', 'public/css') mix.sass('resources/assets/sass/app.scss', 'public/css')
.sass('resources/assets/sass/appdark.scss', 'public/css') .sass('resources/assets/sass/appdark.scss', 'public/css')
.sass('resources/assets/sass/admin.scss', 'public/css')
.sass('resources/assets/sass/landing.scss', 'public/css') .sass('resources/assets/sass/landing.scss', 'public/css')
.sass('resources/assets/sass/quill.scss', 'public/css').version(); .sass('resources/assets/sass/quill.scss', 'public/css').version();
@ -28,7 +29,7 @@ mix.js('resources/assets/js/app.js', 'public/js')
.js('resources/assets/js/story-compose.js', 'public/js') .js('resources/assets/js/story-compose.js', 'public/js')
// .js('resources/assets/js/embed.js', 'public') // .js('resources/assets/js/embed.js', 'public')
.js('resources/assets/js/direct.js', 'public/js') .js('resources/assets/js/direct.js', 'public/js')
// .js('resources/assets/js/admin.js', 'public/js') .js('resources/assets/js/admin.js', 'public/js')
// .js('resources/assets/js/micro.js', 'public/js') // .js('resources/assets/js/micro.js', 'public/js')
.js('resources/assets/js/rempro.js', 'public/js') .js('resources/assets/js/rempro.js', 'public/js')
.js('resources/assets/js/rempos.js', 'public/js') .js('resources/assets/js/rempos.js', 'public/js')