[Feature] Add useful links in top menubar (#662)
This commit is contained in:
commit
0cfa02b4ce
12 changed files with 133 additions and 6 deletions
19
app/Enums/UsefulLinkLocation.php
Normal file
19
app/Enums/UsefulLinkLocation.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum UsefulLinkLocation:String
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Top bar
|
||||||
|
* Only visible in the dashboard view
|
||||||
|
*/
|
||||||
|
case topbar = "topbar";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dashboard
|
||||||
|
* Only visible in the dashboard view
|
||||||
|
*/
|
||||||
|
case dashboard = "dashboard";
|
||||||
|
|
||||||
|
}
|
|
@ -22,7 +22,13 @@ class SettingsController extends Controller
|
||||||
|
|
||||||
//Get all tabs as laravel view paths
|
//Get all tabs as laravel view paths
|
||||||
$tabs = [];
|
$tabs = [];
|
||||||
foreach (glob(Theme::getViewPaths()[0] . '/admin/settings/tabs/*.blade.php') as $filename) {
|
if(file_exists(Theme::getViewPaths()[0] . '/admin/settings/tabs/')){
|
||||||
|
$tabspath = glob(Theme::getViewPaths()[0] . '/admin/settings/tabs/*.blade.php');
|
||||||
|
}else{
|
||||||
|
$tabspath = glob(Theme::path($path = 'views', $themeName = 'default').'/admin/settings/tabs/*.blade.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($tabspath as $filename) {
|
||||||
$tabs[] = 'admin.settings.tabs.'.basename($filename, '.blade.php');
|
$tabs[] = 'admin.settings.tabs.'.basename($filename, '.blade.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Enums\UsefulLinkLocation;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\UsefulLink;
|
use App\Models\UsefulLink;
|
||||||
use Illuminate\Contracts\Foundation\Application;
|
use Illuminate\Contracts\Foundation\Application;
|
||||||
|
@ -30,7 +31,8 @@ class UsefulLinkController extends Controller
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
return view('admin.usefullinks.create');
|
$positions = UsefulLinkLocation::cases();
|
||||||
|
return view('admin.usefullinks.create')->with('positions', $positions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +50,14 @@ class UsefulLinkController extends Controller
|
||||||
'description' => 'required|string|max:2000',
|
'description' => 'required|string|max:2000',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
UsefulLink::create($request->all());
|
|
||||||
|
UsefulLink::create([
|
||||||
|
'icon' => $request->icon,
|
||||||
|
'title' => $request->title,
|
||||||
|
'link' => $request->link,
|
||||||
|
'description' => $request->description,
|
||||||
|
'position' => implode(",",$request->position),
|
||||||
|
]);
|
||||||
|
|
||||||
return redirect()->route('admin.usefullinks.index')->with('success', __('link has been created!'));
|
return redirect()->route('admin.usefullinks.index')->with('success', __('link has been created!'));
|
||||||
}
|
}
|
||||||
|
@ -72,8 +81,10 @@ class UsefulLinkController extends Controller
|
||||||
*/
|
*/
|
||||||
public function edit(UsefulLink $usefullink)
|
public function edit(UsefulLink $usefullink)
|
||||||
{
|
{
|
||||||
|
$positions = UsefulLinkLocation::cases();
|
||||||
return view('admin.usefullinks.edit', [
|
return view('admin.usefullinks.edit', [
|
||||||
'link' => $usefullink,
|
'link' => $usefullink,
|
||||||
|
'positions' => $positions,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +104,13 @@ class UsefulLinkController extends Controller
|
||||||
'description' => 'required|string|max:2000',
|
'description' => 'required|string|max:2000',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$usefullink->update($request->all());
|
$usefullink->update([
|
||||||
|
'icon' => $request->icon,
|
||||||
|
'title' => $request->title,
|
||||||
|
'link' => $request->link,
|
||||||
|
'description' => $request->description,
|
||||||
|
'position' => implode(",",$request->position),
|
||||||
|
]);
|
||||||
|
|
||||||
return redirect()->route('admin.usefullinks.index')->with('success', __('link has been updated!'));
|
return redirect()->route('admin.usefullinks.index')->with('success', __('link has been updated!'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ class HomeController extends Controller
|
||||||
return view('home')->with([
|
return view('home')->with([
|
||||||
'usage' => $usage,
|
'usage' => $usage,
|
||||||
'credits' => $credits,
|
'credits' => $credits,
|
||||||
'useful_links' => UsefulLink::all()->sortBy('id'),
|
'useful_links' => UsefulLink::where("position","like","%dashboard%")->get()->sortby("id"),
|
||||||
'bg' => $bg,
|
'bg' => $bg,
|
||||||
'boxText' => $boxText,
|
'boxText' => $boxText,
|
||||||
'unit' => $unit,
|
'unit' => $unit,
|
||||||
|
|
|
@ -16,5 +16,6 @@ class UsefulLink extends Model
|
||||||
'title',
|
'title',
|
||||||
'link',
|
'link',
|
||||||
'description',
|
'description',
|
||||||
|
'position',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Models\Settings;
|
use App\Models\Settings;
|
||||||
|
use App\Models\UsefulLink;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Pagination\Paginator;
|
use Illuminate\Pagination\Paginator;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
@ -53,6 +54,12 @@ class AppServiceProvider extends ServiceProvider
|
||||||
return $ok;
|
return $ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (Schema::hasColumn('useful_links', 'position')) {
|
||||||
|
$useful_links = UsefulLink::where("position","like","%topbar%")->get()->sortby("id");
|
||||||
|
view()->share('useful_links', $useful_links);
|
||||||
|
}
|
||||||
|
|
||||||
//only run if the installer has been executed
|
//only run if the installer has been executed
|
||||||
try {
|
try {
|
||||||
$settings = Settings::all();
|
$settings = Settings::all();
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('useful_links', function (Blueprint $table) {
|
||||||
|
$table->string('position')->after("description")->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('useful_links', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('position');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -481,7 +481,7 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<script>tinymce.init({selector:'textarea',skin: "oxide-dark",
|
<script>tinymce.init({selector:'textarea',promotion: false,skin: "oxide-dark",
|
||||||
content_css: "dark",branding: false, height: 500,
|
content_css: "dark",branding: false, height: 500,
|
||||||
plugins: ['image','link'],});
|
plugins: ['image','link'],});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -94,6 +94,22 @@
|
||||||
@enderror
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<select id="position" style="width:100%" class="custom-select" name="position[]"
|
||||||
|
required multiple autocomplete="off" @error('position') is-invalid @enderror>
|
||||||
|
@foreach ($positions as $position)
|
||||||
|
<option id="{{$position->value}}" value="{{ $position->value }}">
|
||||||
|
{{ __($position->value) }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
@error('position')
|
||||||
|
<div class="text-danger">
|
||||||
|
{{$message}}
|
||||||
|
</div>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group text-right">
|
<div class="form-group text-right">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary">
|
||||||
|
@ -111,6 +127,7 @@
|
||||||
<!-- END CONTENT -->
|
<!-- END CONTENT -->
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', (event) => {
|
document.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
$('.custom-select').select2();
|
||||||
// Summernote
|
// Summernote
|
||||||
$('#description').summernote({
|
$('#description').summernote({
|
||||||
height: 100,
|
height: 100,
|
||||||
|
@ -127,6 +144,8 @@
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
@ -95,6 +95,22 @@
|
||||||
@enderror
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<select id="position" style="width:100%" class="custom-select" name="position[]"
|
||||||
|
required multiple autocomplete="off" @error('position') is-invalid @enderror>
|
||||||
|
@foreach ($positions as $position)
|
||||||
|
<option id="{{$position->value}}" value="{{ $position->value }}" @if (strpos($link->position, $position->value) !== false) selected @endif>
|
||||||
|
{{ __($position->value) }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
@error('position')
|
||||||
|
<div class="text-danger">
|
||||||
|
{{$message}}
|
||||||
|
</div>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group text-right">
|
<div class="form-group text-right">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary">
|
||||||
|
@ -113,6 +129,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', (event) => {
|
document.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
$('.custom-select').select2();
|
||||||
// Summernote
|
// Summernote
|
||||||
$('#description').summernote({
|
$('#description').summernote({
|
||||||
height: 100,
|
height: 100,
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
<th width="50">{{__('Icon')}}</th>
|
<th width="50">{{__('Icon')}}</th>
|
||||||
<th>{{__('Title')}}</th>
|
<th>{{__('Title')}}</th>
|
||||||
<th>{{__('Link')}}</th>
|
<th>{{__('Link')}}</th>
|
||||||
|
<th>{{__('Position')}}</th>
|
||||||
<th>{{__('Created at')}}</th>
|
<th>{{__('Created at')}}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -79,6 +80,7 @@
|
||||||
{data: 'icon'},
|
{data: 'icon'},
|
||||||
{data: 'title'},
|
{data: 'title'},
|
||||||
{data: 'link'},
|
{data: 'link'},
|
||||||
|
{data: 'position'},
|
||||||
{data: 'created_at'},
|
{data: 'created_at'},
|
||||||
{data: 'actions', sortable: false},
|
{data: 'actions', sortable: false},
|
||||||
],
|
],
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
|
class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<!-- Language Selection -->
|
<!-- Language Selection -->
|
||||||
@if (config('SETTINGS::LOCALE:CLIENTS_CAN_CHANGE') == 'true')
|
@if (config('SETTINGS::LOCALE:CLIENTS_CAN_CHANGE') == 'true')
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
|
@ -84,6 +85,12 @@
|
||||||
</li>
|
</li>
|
||||||
<!-- End Language Selection -->
|
<!-- End Language Selection -->
|
||||||
@endif
|
@endif
|
||||||
|
@foreach($useful_links as $link)
|
||||||
|
<li class="nav-item d-none d-sm-inline-block">
|
||||||
|
<a href="{{ $link->link }}" class="nav-link" target="__blank"><i
|
||||||
|
class="{{$link->icon}}"></i> {{ $link->title }}</a>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- Right navbar links -->
|
<!-- Right navbar links -->
|
||||||
|
|
Loading…
Reference in a new issue