mirror of
https://github.com/Kovah/LinkAce.git
synced 2025-01-16 12:48:25 +01:00
- contact page with editable content - additional footer link - custom navbar title / logo text - small optimizations for guest mode
This commit is contained in:
parent
bba868deba
commit
0dccd1a7f8
@ -41,8 +41,11 @@ class SystemSettingsController extends Controller
|
||||
public function updateGuest(SystemSettingsUpdateRequest $request): RedirectResponse
|
||||
{
|
||||
$guestSettings = app(GuestSettings::class);
|
||||
$systemSettings = app(SystemSettings::class);
|
||||
|
||||
$settings = $request->except(['_token', 'guest_share']);
|
||||
$systemSettings->guest_access_enabled = $request->input('guest_access_enabled');
|
||||
|
||||
$settings = $request->except(['_token', 'guest_share', 'guest_access_enabled']);
|
||||
|
||||
foreach ($settings as $key => $value) {
|
||||
$guestSettings->$key = $value;
|
||||
@ -56,6 +59,7 @@ class SystemSettingsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
$systemSettings->save();
|
||||
$guestSettings->save();
|
||||
|
||||
flash(trans('settings.settings_saved'));
|
||||
|
20
app/Http/Controllers/ContactController.php
Normal file
20
app/Http/Controllers/ContactController.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Settings\SystemSettings;
|
||||
|
||||
class ContactController extends Controller
|
||||
{
|
||||
public function __invoke(SystemSettings $systemSettings)
|
||||
{
|
||||
if (!$systemSettings->contact_page_enabled) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return view('app.contact', [
|
||||
'title' => $systemSettings->contact_page_title,
|
||||
'content' => $systemSettings->contact_page_content,
|
||||
]);
|
||||
}
|
||||
}
|
@ -28,6 +28,8 @@ class SettingsMiddleware
|
||||
|
||||
if ($userLocale = usersettings('locale')) {
|
||||
app()->setLocale($userLocale);
|
||||
} else {
|
||||
app()->setLocale(guestsettings('locale'));
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
@ -11,14 +11,49 @@ class SystemSettingsUpdateRequest extends FormRequest
|
||||
return [
|
||||
'system_page_title' => [
|
||||
'max:256',
|
||||
'nullable',
|
||||
'string',
|
||||
],
|
||||
'system_guest_access' => [
|
||||
'system_logo_text' => [
|
||||
'max:20',
|
||||
'nullable',
|
||||
'string',
|
||||
],
|
||||
'additional_footer_link_url' => [
|
||||
'nullable',
|
||||
'string',
|
||||
'required_with:additional_footer_link_text'
|
||||
],
|
||||
'additional_footer_link_text' => [
|
||||
'max:20',
|
||||
'nullable',
|
||||
'string',
|
||||
'required_with:additional_footer_link_url'
|
||||
],
|
||||
'contact_page_enabled' => [
|
||||
'boolean',
|
||||
],
|
||||
'contact_page_title' => [
|
||||
'max:20',
|
||||
'nullable',
|
||||
'string',
|
||||
],
|
||||
'contact_page_content' => [
|
||||
'max:10000',
|
||||
'nullable',
|
||||
'string',
|
||||
],
|
||||
'system_custom_header_content' => [
|
||||
'nullable',
|
||||
'string',
|
||||
],
|
||||
// Guest settings
|
||||
'system_guest_access' => [
|
||||
'boolean',
|
||||
],
|
||||
'guest_locale' => [
|
||||
'string',
|
||||
],
|
||||
'guest_listitem_count' => [
|
||||
'integer',
|
||||
],
|
||||
|
@ -10,6 +10,8 @@ class GuestSettings extends Settings
|
||||
public bool $links_new_tab;
|
||||
public int $darkmode_setting;
|
||||
|
||||
public string $locale;
|
||||
|
||||
public bool $share_email;
|
||||
public bool $share_buffer;
|
||||
public bool $share_evernote;
|
||||
|
@ -7,9 +7,19 @@ use Spatie\LaravelSettings\Settings;
|
||||
class SystemSettings extends Settings
|
||||
{
|
||||
public ?string $page_title;
|
||||
public ?string $logo_text;
|
||||
|
||||
public ?string $cron_token;
|
||||
|
||||
public ?string $custom_header_content;
|
||||
|
||||
public ?string $additional_footer_link_url;
|
||||
public ?string $additional_footer_link_text;
|
||||
|
||||
public bool $contact_page_enabled;
|
||||
public ?string $contact_page_title;
|
||||
public ?string $contact_page_content;
|
||||
|
||||
public bool $guest_access_enabled;
|
||||
public bool $setup_completed;
|
||||
|
||||
|
@ -7,6 +7,7 @@ return [
|
||||
* put them (manually) here.
|
||||
*/
|
||||
'settings' => [
|
||||
\App\Settings\GuestSettings::class,
|
||||
\App\Settings\SystemSettings::class,
|
||||
\App\Settings\UserSettings::class,
|
||||
],
|
||||
|
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
|
||||
Class ExtendSystemSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$this->migrator->add('system.logo_text', null);
|
||||
|
||||
$this->migrator->add('system.additional_footer_link_url', null);
|
||||
$this->migrator->add('system.additional_footer_link_text', null);
|
||||
|
||||
$this->migrator->add('system.contact_page_enabled', false);
|
||||
$this->migrator->add('system.contact_page_title', null);
|
||||
$this->migrator->add('system.contact_page_content', null);
|
||||
|
||||
$this->migrator->add('guest.locale', config('app.fallback_locale'));
|
||||
}
|
||||
}
|
@ -47,6 +47,7 @@ return [
|
||||
'menu' => 'Menu',
|
||||
'entries' => 'Entries',
|
||||
'feed' => 'Feed',
|
||||
'contact' => 'Contact',
|
||||
|
||||
'continue_adding' => 'Continue Adding',
|
||||
|
||||
|
@ -74,11 +74,22 @@ return [
|
||||
'two_factor_regenerate_recovery_codes' => 'Generate new Recovery Codes',
|
||||
|
||||
'page_title' => 'Page Title',
|
||||
'logo_text' => 'Custom Logo Text',
|
||||
'guest_access' => 'Enable Guest Access',
|
||||
'guest_access_help' => 'If enabled, guest will be able to see all links that are not private.',
|
||||
'custom_header_content' => 'Custom Header Content',
|
||||
'custom_header_content_help' => 'Content entered here will be placed before the </head> tag on all LinkAce sites. Useful to place analytics or customization scripts. Caution: contents are not escaped and may break the site!',
|
||||
|
||||
'additional_footer_link' => 'Additional Link in the Footer',
|
||||
'additional_footer_link_url' => 'Link URL',
|
||||
'additional_footer_link_text' => 'Link Text',
|
||||
|
||||
'contact_page' => 'Contact/About Page',
|
||||
'contact_page_info' => 'The contact/about page can be used to display additional information about your bookmarks. The link is visible in the footer. Markdown is supported.',
|
||||
'contact_page_enabled' => 'Enable the contact/about page',
|
||||
'contact_page_title' => 'Custom title for the page',
|
||||
'contact_page_content' => 'Content of the page',
|
||||
|
||||
'cron_token' => 'Cron Token',
|
||||
'cron_token_generate' => 'Generate Token',
|
||||
'cron_token_generate_confirm' => 'Do you really want to generate a new token?',
|
||||
|
4
resources/assets/sass/custom/_app.scss
vendored
4
resources/assets/sass/custom/_app.scss
vendored
@ -50,6 +50,10 @@ body:not(.bookmarklet) {
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-family: $font-family-sans-condensed;
|
||||
}
|
||||
|
||||
.card-table {
|
||||
margin: -#{$card-border-width};
|
||||
|
||||
|
@ -27,17 +27,14 @@
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="guest_access_enabled">
|
||||
@lang('settings.guest_access')
|
||||
<label class="form-label" for="logo_text">
|
||||
@lang('settings.logo_text')
|
||||
</label>
|
||||
<select id="guest_access_enabled" name="guest_access_enabled"
|
||||
class="simple-select {{ $errors->has('guest_access_enabled') ? ' is-invalid' : '' }}">
|
||||
<x-forms.yes-no-options :setting="systemsettings('guest_access_enabled')"/>
|
||||
</select>
|
||||
<p class="small text-pale mt-1">@lang('settings.guest_access_help')</p>
|
||||
@if ($errors->has('guest_access_enabled'))
|
||||
<p class="invalid-feedback" role="alert">
|
||||
{{ $errors->first('guest_access_enabled') }}
|
||||
<input type="text" id="logo_text" name="logo_text" class="form-control" maxlength="20"
|
||||
value="{{ old('logo_text') ?: systemsettings('logo_text') }}">
|
||||
@if ($errors->has('logo_text'))
|
||||
<p class="invalid-feedback mt-1" role="alert">
|
||||
{{ $errors->first('logo_text') }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
@ -45,24 +42,122 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row my-4">
|
||||
<div class="col-12"><h5>@lang('settings.additional_footer_link')</h5></div>
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="additional_footer_link_url">
|
||||
@lang('settings.additional_footer_link_url')
|
||||
</label>
|
||||
<input type="url" id="additional_footer_link_url" name="additional_footer_link_url"
|
||||
class="form-control"
|
||||
value="{{ old('additional_footer_link_url') ?: systemsettings('additional_footer_link_url') }}">
|
||||
@if ($errors->has('additional_footer_link_url'))
|
||||
<p class="invalid-feedback mt-1" role="alert">
|
||||
{{ $errors->first('additional_footer_link_url') }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="additional_footer_link_text">
|
||||
@lang('settings.additional_footer_link_text')
|
||||
</label>
|
||||
<input type="text" id="additional_footer_link_text" name="additional_footer_link_text"
|
||||
class="form-control" maxlength="20"
|
||||
value="{{ old('additional_footer_link_text') ?: systemsettings('additional_footer_link_text') }}">
|
||||
@if ($errors->has('additional_footer_link_text'))
|
||||
<p class="invalid-feedback mt-1" role="alert">
|
||||
{{ $errors->first('additional_footer_link_text') }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row my-4">
|
||||
<div class="col-12">
|
||||
<h5>@lang('settings.contact_page')</h5>
|
||||
<p class="my-3 small">@lang('settings.contact_page_info')</p>
|
||||
</div>
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="contact_page_enabled">
|
||||
@lang('settings.contact_page_enabled')
|
||||
</label>
|
||||
<select id="contact_page_enabled" name="contact_page_enabled"
|
||||
class="simple-select {{ $errors->has('contact_page_enabled') ? ' is-invalid' : '' }}">
|
||||
<x-forms.yes-no-options :setting="systemsettings('contact_page_enabled')"/>
|
||||
</select>
|
||||
<p class="small text-pale mt-1">@lang('settings.guest_access_help')</p>
|
||||
@if ($errors->has('contact_page_enabled'))
|
||||
<p class="invalid-feedback" role="alert">
|
||||
{{ $errors->first('contact_page_enabled') }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="contact_page_title">
|
||||
@lang('settings.contact_page_title')
|
||||
</label>
|
||||
<input type="text" id="contact_page_title" name="contact_page_title"
|
||||
class="form-control" maxlength="20"
|
||||
value="{{ old('contact_page_title') ?: systemsettings('contact_page_title') }}">
|
||||
@if ($errors->has('contact_page_title'))
|
||||
<p class="invalid-feedback mt-1" role="alert">
|
||||
{{ $errors->first('contact_page_title') }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-12">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="contact_page_content">
|
||||
@lang('settings.contact_page_content')
|
||||
</label>
|
||||
<textarea name="contact_page_content" id="contact_page_content" rows="4"
|
||||
class="form-control{{ $errors->has('contact_page_content') ? ' is-invalid' : '' }}"
|
||||
>{{ old('contact_page_content', systemsettings('contact_page_content')) }}</textarea>
|
||||
@error('contact_page_content')
|
||||
<p class="invalid-feedback" role="alert">
|
||||
{{ $errors->first('contact_page_content') }}
|
||||
</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="custom_header_content">
|
||||
@lang('settings.custom_header_content')
|
||||
</label>
|
||||
|
||||
<textarea name="custom_header_content" id="custom_header_content" rows="4"
|
||||
class="form-control{{ $errors->has('custom_header_content') ? ' is-invalid' : '' }}"
|
||||
>{{ old('custom_header_content', systemsettings('custom_header_content')) }}</textarea>
|
||||
<p class="small text-pale mt-1">@lang('settings.custom_header_content_help')</p>
|
||||
|
||||
@error('custom_header_content')
|
||||
<p class="invalid-feedback" role="alert">
|
||||
{{ $errors->first('custom_header_content') }}
|
||||
</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -10,6 +10,52 @@
|
||||
@csrf
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="guest_access_enabled">
|
||||
@lang('settings.guest_access')
|
||||
</label>
|
||||
<select id="guest_access_enabled" name="guest_access_enabled"
|
||||
class="simple-select {{ $errors->has('guest_access_enabled') ? ' is-invalid' : '' }}">
|
||||
<x-forms.yes-no-options :setting="systemsettings('guest_access_enabled')"/>
|
||||
</select>
|
||||
<p class="small text-pale mt-1">@lang('settings.guest_access_help')</p>
|
||||
@if ($errors->has('guest_access_enabled'))
|
||||
<p class="invalid-feedback" role="alert">
|
||||
{{ $errors->first('guest_access_enabled') }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4">
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="locale">
|
||||
@lang('settings.locale')
|
||||
</label>
|
||||
<select id="locale" name="locale"
|
||||
class="simple-select {{ $errors->has('locale') ? ' is-invalid' : '' }}">
|
||||
@foreach(config('app.available_locales') as $key => $locale)
|
||||
<option value="{{ $key }}"
|
||||
@if(guestsettings('locale') === $key) selected @endif>
|
||||
{{ $locale }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@if($errors->has('locale'))
|
||||
<p class="invalid-feedback" role="alert">
|
||||
{{ $errors->first('locale') }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
|
||||
<div class="mb-4">
|
||||
|
13
resources/views/app/contact.blade.php
Normal file
13
resources/views/app/contact.blade.php
Normal file
@ -0,0 +1,13 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="contact-page">
|
||||
<h3 class="mb-4">{{ $title ?? trans('linkace.contact') }}</h3>
|
||||
|
||||
<div class="card mt-4">
|
||||
<div class="card-body contact-content">
|
||||
{!! \Illuminate\Support\Str::markdown($content) !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
@ -1,6 +1,16 @@
|
||||
<aside class="footer container text-center small pt-3 pb-5">
|
||||
<div>
|
||||
@lang('linkace.project_of') <a href="https://kovah.de/?utm_source=linkace" rel="noopener" target="_blank">Kovah.de</a>
|
||||
@if(systemsettings('additional_footer_link_url') && systemsettings('additional_footer_link_text'))
|
||||
| <a href="{{ systemsettings('additional_footer_link_url') }}" rel="noreferrer noopener" target="_blank">
|
||||
{{ systemsettings('additional_footer_link_text') }}
|
||||
</a>
|
||||
@endif
|
||||
@if(systemsettings('contact_page_enabled'))
|
||||
| <a href="{{ route('contact') }}">
|
||||
{{ systemsettings('contact_page_title') ?? trans('linkace.contact') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
@auth
|
||||
<div class="mt-1">
|
||||
|
@ -1,8 +1,6 @@
|
||||
@if(usersettings('darkmode_setting') === 1
|
||||
|| (request()->is('guest/*') && guestsettings('darkmode_setting') === 1))
|
||||
@if(usersettings('darkmode_setting') === 1 || (auth()->guest() && guestsettings('darkmode_setting') === 1))
|
||||
<link href="{{ mix('assets/dist/css/app-dark.css') }}" rel="stylesheet">
|
||||
@elseif(usersettings('darkmode_setting') === 2
|
||||
|| (request()->is('guest/*') && guestsettings('darkmode_setting') === 2))
|
||||
@elseif(usersettings('darkmode_setting') === 2 || (auth()->guest() && guestsettings('darkmode_setting') === 2))
|
||||
<link rel="stylesheet" media="(prefers-color-scheme: light)" href="{{ mix('assets/dist/css/app.css') }}">
|
||||
<link rel="stylesheet" media="(prefers-color-scheme: dark)" href="{{ mix('assets/dist/css/app-dark.css') }}">
|
||||
@else
|
||||
|
@ -1,7 +1,11 @@
|
||||
<nav class="navbar navbar-dark navbar-expand bg-primary shadow-sm d-none d-md-flex">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="{{ route('dashboard') }}">
|
||||
<x-icon.linkace/>
|
||||
@if(systemsettings('logo_text'))
|
||||
{{ systemsettings('logo_text') }}
|
||||
@else
|
||||
<x-icon.linkace/>
|
||||
@endif
|
||||
</a>
|
||||
@auth
|
||||
<ul class="navbar-nav">
|
||||
@ -62,7 +66,11 @@
|
||||
<div class="navbar navbar-dark navbar-expand brand-only bg-primary shadow-sm d-md-none">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="{{ route('dashboard') }}">
|
||||
<x-icon.linkace/>
|
||||
@if(systemsettings('logo_text'))
|
||||
{{ systemsettings('logo_text') }}
|
||||
@else
|
||||
<x-icon.linkace/>
|
||||
@endif
|
||||
</a>
|
||||
<ul class="navbar-nav ms-auto">
|
||||
@include('partials.nav-user')
|
||||
|
@ -13,6 +13,7 @@ use App\Http\Controllers\App\ImportController;
|
||||
use App\Http\Controllers\App\SearchController;
|
||||
use App\Http\Controllers\App\TrashController;
|
||||
use App\Http\Controllers\App\UserSettingsController;
|
||||
use App\Http\Controllers\ContactController;
|
||||
use App\Http\Controllers\CronController;
|
||||
use App\Http\Controllers\FetchController;
|
||||
use App\Http\Controllers\FrontController;
|
||||
@ -64,6 +65,8 @@ Route::prefix('bookmarklet')->group(function () {
|
||||
Route::get('login', [BookmarkletController::class, 'getLoginForm'])->name('bookmarklet-login');
|
||||
});
|
||||
|
||||
Route::get('contact', ContactController::class)->name('contact');
|
||||
|
||||
Route::get('cron/{token}', CronController::class)->name('cron');
|
||||
|
||||
Route::get('auth/accept-invite', [RegistrationController::class, 'acceptInvitation'])
|
||||
|
@ -1,9 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Controller\API;
|
||||
namespace Tests\Controller\API;
|
||||
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\Controller\API\ApiTestCase;
|
||||
|
||||
class GeneralApiTest extends ApiTestCase
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user