Files
nimbus/resources/js/pages/Settings.vue
Mazen Touati 7b6e0f89f4 chore(base): release 0.4.1-alpha (#57)
* chore(base): release 0.4.1-alpha

* build: update production artifacts for v0.4.1-alpha
2026-02-02 02:34:48 +01:00

233 lines
10 KiB
Vue

<script setup lang="ts">
import { AppButton } from '@/components/base/button';
import { CheckCircleIcon, RefreshCwIcon, SettingsIcon } from 'lucide-vue-next';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import {
AppDialog,
AppDialogContent,
AppDialogDescription,
AppDialogFooter,
AppDialogHeader,
AppDialogTitle,
} from '@/components/base/dialog';
import {
AppPopover,
AppPopoverContent,
AppPopoverTrigger,
} from '@/components/base/popover';
import CopyButton from '@/components/common/CopyButton.vue';
import ConfigReadonlySection from '@/components/domain/Settings/ConfigReadonlySection.vue';
import UserPreferencesSection from '@/components/domain/Settings/UserPreferencesSection.vue';
import PageLayout from '@/components/layout/PageLayout.vue';
import { useSettingsStore } from '@/stores';
import { useClipboard } from '@vueuse/core';
defineOptions({
name: 'SettingsPage',
});
const VERSION = 'v0.4.1-alpha'; // x-release-please-version
/*
* Stores.
*/
const settingsStore = useSettingsStore();
/*
* State.
*/
const lastResetTime = ref<Date | null>(null);
const showResetDialog = ref(false);
/*
* Methods.
*/
const showResetConfirmation = () => {
showResetDialog.value = true;
};
const confirmReset = () => {
settingsStore.resetPreferences();
lastResetTime.value = new Date();
showResetDialog.value = false;
toast.success('Settings reset', {
description: 'All preferences have been restored to their default values.',
duration: 3000,
});
};
const cancelReset = () => {
showResetDialog.value = false;
};
const { copy, copied } = useClipboard();
const copyPublishCommand = async () => {
copy('php artisan vendor:publish --tag=nimbus-config');
};
</script>
<template>
<div>
<PageLayout title="Settings" :icon="SettingsIcon">
<!-- Header Actions -->
<template #header-actions>
<div v-if="lastResetTime" class="text-subtle-foreground mr-3 text-xs">
<CheckCircleIcon class="mr-1 inline h-3 w-3" />
Reset {{ lastResetTime.toLocaleTimeString() }}
</div>
</template>
<!-- Subheader Left -->
<template #subheader-left>
<div>
<span class="text-sm">Application Configuration</span>
</div>
</template>
<!-- Subheader Right -->
<template #subheader-right>
<AppButton variant="ghost" size="xs" @click="showResetConfirmation">
<RefreshCwIcon class="mr-1 h-3 w-3" />
Reset
</AppButton>
</template>
<!-- Content -->
<template #content>
<div class="h-full overflow-auto">
<div class="p-6">
<div class="max-w-6xl space-y-12">
<!-- Server Configuration Section -->
<div>
<div class="mb-6">
<h2 class="text-xl font-semibold">
Server Configuration
</h2>
<p class="text-subtle-foreground text-sm">
These values are read from your Laravel
application's
<code
class="rounded bg-zinc-100 px-1 dark:bg-zinc-900"
>
config/nimbus.php
</code>
file. They control how the API routes are
structured, what base URL is used, and which
headers are automatically included with requests.
</p>
<small class="text-subtle-foreground italic">
To customize these settings,
<AppPopover>
<AppPopoverTrigger
as="span"
class="inline-block cursor-pointer text-zinc-600 underline hover:text-blue-800 dark:text-zinc-400 dark:hover:text-blue-200"
>
publish the config file
</AppPopoverTrigger>
<AppPopoverContent class="w-[450px]">
<div class="space-y-3">
<div>
<h4 class="text-sm font-bold">
Publish Configuration
</h4>
<p class="text-xs">
Run this command to publish
the package configuration file
to your application's config
directory:
</p>
</div>
<div
class="relative flex items-center space-x-2 rounded bg-zinc-100 p-3 font-mono text-xs dark:bg-zinc-900"
>
<code class="flex-1">
php artisan vendor:publish
--tag=nimbus-config
</code>
<CopyButton
:on-click="copyPublishCommand"
:copied="copied"
/>
</div>
<p
class="text-subtle-foreground text-xs"
>
This will create
<code
class="rounded bg-zinc-100 px-1 dark:bg-zinc-900"
>
config/nimbus.php
</code>
in your project root.
</p>
</div>
</AppPopoverContent>
</AppPopover>
and edit the values directly.
</small>
<div class="my-2 text-xs">
<div
class="bg-subtle inline-flex items-center space-x-2 rounded px-1.5 py-0.5 font-mono"
>
<span>{{ VERSION }}</span>
<CopyButton
:on-click="() => copy(VERSION)"
:copied="copied"
/>
</div>
</div>
</div>
<ConfigReadonlySection />
</div>
<!-- Section Divider -->
<div
class="my-8 border-t border-zinc-200 dark:border-zinc-800"
/>
<!-- User Preferences Section -->
<div>
<div class="mb-6">
<h2 class="text-xl font-semibold">
User Preferences
</h2>
<p class="text-subtle-foreground text-sm">
Personal settings that are saved locally and
customize your experience with the application.
</p>
</div>
<UserPreferencesSection />
</div>
</div>
</div>
</div>
</template>
</PageLayout>
<!-- Reset Confirmation Dialog -->
<AppDialog v-model:open="showResetDialog">
<AppDialogContent>
<AppDialogHeader>
<AppDialogTitle>Reset Settings</AppDialogTitle>
<AppDialogDescription>
Are you sure you want to reset all your preferences to their
default values? This action cannot be undone.
</AppDialogDescription>
</AppDialogHeader>
<AppDialogFooter>
<AppButton size="xs" variant="outline" @click="cancelReset">
Cancel
</AppButton>
<AppButton size="xs" @click="confirmReset">Reset Settings</AppButton>
</AppDialogFooter>
</AppDialogContent>
</AppDialog>
</div>
</template>