Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public function update(Request $request, GeneralSettings $settings): \Illuminate
{
$request->validate([
'site_name' => 'required|string|max:50',
'copyright_name' => 'nullable|string|max:50',
'copyright_url' => 'nullable|url|max:255',
'enable_mcserver_onlineplayersbox' => 'required|boolean',
'enable_mcserver_statuspingbox' => 'required|boolean',
'enable_ingamechat' => 'required|boolean',
Expand Down Expand Up @@ -64,6 +66,8 @@ public function update(Request $request, GeneralSettings $settings): \Illuminate
'enable_topplayersbox' => 'required|boolean',
]);
$settings->site_name = $request->input('site_name');
$settings->copyright_name = $request->input('copyright_name') ?? null;
$settings->copyright_url = $request->input('copyright_url') ?? null;
$settings->enable_mcserver_onlineplayersbox = $request->input('enable_mcserver_onlineplayersbox');
$settings->enable_mcserver_statuspingbox = $request->input('enable_mcserver_statuspingbox');
$settings->enable_ingamechat = $request->input('enable_ingamechat');
Expand Down
2 changes: 2 additions & 0 deletions app/Settings/GeneralSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
class GeneralSettings extends Settings
{
public ?string $site_name;
public ?string $copyright_name;
public ?string $copyright_url;
public ?string $site_header_logo_path_light;
public ?string $site_header_logo_path_dark;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

use Spatie\LaravelSettings\Migrations\SettingsMigration;

return new class extends SettingsMigration
{
public function up(): void
{
$this->migrator->add('general.copyright_name', null);
$this->migrator->add('general.copyright_url', null);
}

public function down(): void
{
$this->migrator->deleteIfExists('general.copyright_name');
$this->migrator->deleteIfExists('general.copyright_url');
}
};
30 changes: 30 additions & 0 deletions resources/default/js/Pages/Admin/Setting/GeneralSetting.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const breadcrumbItems = [

const form = useForm({
site_name: props.settings.site_name,
copyright_name: props.settings.copyright_name,
copyright_url: props.settings.copyright_url,
enable_mcserver_onlineplayersbox: props.settings.enable_mcserver_onlineplayersbox,
enable_mcserver_statuspingbox: props.settings.enable_mcserver_statuspingbox,
enable_ingamechat: props.settings.enable_ingamechat,
Expand Down Expand Up @@ -170,6 +172,34 @@ function saveSetting() {
/>
</div>

<!-- Copyright Name -->
<div class="col-span-6 sm:col-span-3">
<XInput
id="copyright_name"
v-model="form.copyright_name"
:label="__('Copyright Name')"
:error="form.errors.copyright_name"
type="text"
name="copyright_name"
:help="__('Displayed in the footer. Falls back to Site Name if empty.')"
help-error-flex="flex-col"
/>
</div>

<!-- Copyright URL -->
<div class="col-span-6 sm:col-span-3">
<XInput
id="copyright_url"
v-model="form.copyright_url"
:label="__('Copyright URL')"
:error="form.errors.copyright_url"
type="text"
name="copyright_url"
:help="__('Optional. If set, the copyright name becomes a link.')"
help-error-flex="flex-col"
/>
</div>

<!-- Homepage Box Settings -->
<div class="col-span-6">
<fieldset>
Expand Down
13 changes: 12 additions & 1 deletion resources/default/js/Shared/MainFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const isAdminRoute = route().current("admin.*");
const canShowCustomFooter = !isAdminRoute && customFooterEnabled;

const generalSettings = usePage().props.generalSettings;
const displayCopyrightName = generalSettings.copyright_name || generalSettings.site_name;
const copyrightUrl = generalSettings.copyright_url;
Comment on lines 9 to +13
const discordUrl = generalSettings?.discord_invite_url;
const youtubeUrl = generalSettings?.youtube_url;
const facebookUrl = generalSettings?.facebook_url;
Expand Down Expand Up @@ -497,7 +499,16 @@ if(customFooterData?.style =="variant_1") {
class="flex flex-col items-center justify-center p-5"
>
<div class="text-sm text-foreground dark:text-foreground">
&copy; {{ $page.props.generalSettings.site_name }} {{ new Date().getFullYear() }}
&copy;
<a
v-if="copyrightUrl"
:href="copyrightUrl"
class="hover:underline hover:text-primary"
>
{{ displayCopyrightName }}
</a>
<template v-else>{{ displayCopyrightName }}</template>
{{ new Date().getFullYear() }}
</div>
<div
v-if="$page.props.showPoweredBy"
Expand Down
97 changes: 97 additions & 0 deletions tests/Feature/Admin/GeneralSettingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

use App\Models\User;
use App\Settings\GeneralSettings;

beforeEach(function () {
$this->superAdmin = User::whereId(1)->first(); // Super admin from seeder
});

function generalSettingPayload(array $overrides = []): array
{
return array_merge([
'site_name' => 'CrazyMC',
'copyright_name' => null,
'copyright_url' => null,
'enable_mcserver_onlineplayersbox' => false,
'enable_mcserver_statuspingbox' => false,
'enable_ingamechat' => false,
'enable_shoutbox' => false,
'enable_onlineuserbox' => false,
'enable_newuserbox' => false,
'enable_didyouknowbox' => false,
'enable_welcomebox' => false,
'welcomebox_content' => null,
'enable_socialbox' => false,
'youtube_url' => null,
'facebook_url' => null,
'twitter_url' => null,
'twitch_url' => null,
'tiktok_url' => null,
'linkedin_url' => null,
'instagram_url' => null,
'whatsapp_url' => null,
'telegram_url' => null,
'reddit_url' => null,
'threads_url' => null,
'github_url' => null,
'discord_invite_url' => null,
'enable_discordbox' => false,
'discord_server_id' => null,
'enable_voteforserverbox' => false,
'voteforserverbox_content' => null,
'enable_donation_box' => false,
'donation_box_url' => null,
'enable_status_feed' => false,
'header_broadcast_text' => null,
'header_broadcast_url' => null,
'enable_topplayersbox' => false,
], $overrides);
}

test('super admin can view general settings page', function () {
$this->actingAs($this->superAdmin)
->get(route('admin.setting.general.show'))
->assertSuccessful();
});

test('super admin can update copyright fields', function () {
$this->actingAs($this->superAdmin)
->post(route('admin.setting.general.update'), generalSettingPayload([
'copyright_name' => 'Minetrax',
'copyright_url' => 'https://Minetrax',
]))
->assertRedirect();

$settings = app(GeneralSettings::class);

expect($settings->copyright_name)->toBe('Minetrax')
->and($settings->copyright_url)->toBe('https://Minetrax');
});

test('copyright fields can be cleared', function () {
$settings = app(GeneralSettings::class);
$settings->copyright_name = 'Minetrax';
$settings->copyright_url = 'https://Minetrax';
$settings->save();

$this->actingAs($this->superAdmin)
->post(route('admin.setting.general.update'), generalSettingPayload([
'copyright_name' => null,
'copyright_url' => null,
]))
->assertRedirect();

$settings = app(GeneralSettings::class);

expect($settings->copyright_name)->toBeNull()
->and($settings->copyright_url)->toBeNull();
});

test('copyright_url must be a valid url when provided', function () {
$this->actingAs($this->superAdmin)
->post(route('admin.setting.general.update'), generalSettingPayload([
'copyright_url' => 'not-a-url',
]))
->assertSessionHasErrors('copyright_url');
});