This commit is contained in:
Baobhan Sith
2025-04-25 21:54:13 +08:00
parent 5b3c6f325a
commit aa665d6609
3 changed files with 81 additions and 69 deletions
@@ -4,25 +4,28 @@
{{ $t('settings.notifications.title') }} {{ $t('settings.notifications.title') }}
</h2> </h2>
<!-- Loading state (Only show if loading AND no settings are displayed yet) --> <!-- Error state (Show first if error exists) -->
<div v-if="store.isLoading && settings.length === 0" class="p-4 text-center text-text-secondary italic"> <div v-if="store.error" class="p-4 mb-4 border-l-4 border-error bg-error/10 text-error rounded">
{{ $t('common.loading') }}
</div>
<div v-if="store.error" class="p-4 mb-4 border-l-4 border-error bg-error/10 text-error rounded"> <!-- Error state using error color -->
{{ store.error }} {{ store.error }}
</div> </div>
<div v-if="!store.isLoading && !store.error"> <!-- Add Button (Show if no error) -->
<button @click="showAddForm = true" class="px-4 py-2 bg-button text-button-text rounded hover:bg-button-hover mb-4 inline-flex items-center text-sm font-medium"> <!-- Add button --> <button v-if="!store.error" @click="showAddForm = true" class="px-4 py-2 bg-button text-button-text rounded hover:bg-button-hover mb-4 inline-flex items-center text-sm font-medium">
{{ $t('settings.notifications.addChannel') }} {{ $t('settings.notifications.addChannel') }}
</button> </button>
<div v-if="settings.length === 0" class="p-4 mb-4 border-l-4 border-blue-400 bg-blue-100 text-blue-700 rounded"> <!-- Info state (using blue for now) --> <!-- Loading state (Show only if loading AND settings empty AND no error) -->
<div v-if="store.isLoading && settings.length === 0 && !store.error" class="p-4 text-center text-text-secondary italic">
{{ $t('common.loading') }}
</div>
<!-- Empty state (Show only if not loading, no error, and settings empty) -->
<div v-else-if="!store.isLoading && !store.error && settings.length === 0" class="p-4 mb-4 border-l-4 border-blue-400 bg-blue-100 text-blue-700 rounded">
{{ $t('settings.notifications.noChannels') }} {{ $t('settings.notifications.noChannels') }}
</div> </div>
<!-- Notification List --> <!-- Notification List (Show if not loading, no error, and has settings) -->
<div v-else class="grid gap-4 mt-4"> <div v-else-if="!store.isLoading && !store.error && settings.length > 0" class="grid gap-4 mt-4">
<div v-for="setting in settings" :key="setting.id" class="bg-background border border-border rounded-lg p-4 flex justify-between items-start gap-4 shadow-sm hover:shadow-md transition-shadow duration-200"> <!-- List item card --> <div v-for="setting in settings" :key="setting.id" class="bg-background border border-border rounded-lg p-4 flex justify-between items-start gap-4 shadow-sm hover:shadow-md transition-shadow duration-200"> <!-- List item card -->
<div class="flex-grow"> <!-- Details section --> <div class="flex-grow"> <!-- Details section -->
<strong class="block font-semibold text-base mb-1 text-foreground">{{ setting.name }}</strong> <strong class="block font-semibold text-base mb-1 text-foreground">{{ setting.name }}</strong>
@@ -51,7 +54,6 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Add/Edit Form Section --> <!-- Add/Edit Form Section -->
<div v-if="showAddForm || editingSetting" class="mt-6 p-6 border border-border bg-background rounded-lg shadow-sm"> <!-- Form container --> <div v-if="showAddForm || editingSetting" class="mt-6 p-6 border border-border bg-background rounded-lg shadow-sm"> <!-- Form container -->
+12 -8
View File
@@ -29,19 +29,23 @@
</div> </div>
<!-- End Filtering Controls --> <!-- End Filtering Controls -->
<!-- Loading state (Only show if loading AND no logs are displayed yet) --> <!-- Error state -->
<div v-if="store.isLoading && logs.length === 0" class="p-4 text-center text-text-secondary italic"> <div v-if="store.error" class="p-4 mb-4 border-l-4 border-error bg-error/10 text-error rounded">
{{ $t('common.loading') }}
</div>
<div v-if="store.error" class="p-4 mb-4 border-l-4 border-error bg-error/10 text-error rounded"> <!-- Error state -->
{{ store.error }} {{ store.error }}
</div> </div>
<div v-if="!store.isLoading && !store.error"> <!-- Loading state (Only show if loading AND logs empty) -->
<div v-if="logs.length === 0" class="p-4 mb-4 border-l-4 border-blue-400 bg-blue-100 text-blue-700 rounded"> <!-- No logs state --> <div v-else-if="store.isLoading && logs.length === 0" class="p-4 text-center text-text-secondary italic">
{{ $t('common.loading') }}
</div>
<!-- No logs state (Show only if not loading, no error, and logs empty) -->
<div v-else-if="!store.isLoading && !store.error && logs.length === 0" class="p-4 mb-4 border-l-4 border-blue-400 bg-blue-100 text-blue-700 rounded">
{{ $t('auditLog.noLogs') }} {{ $t('auditLog.noLogs') }}
</div> </div>
<div v-else>
<!-- Table and Pagination (Show if not loading, no error, and logs exist) -->
<div v-else-if="!store.isLoading && !store.error && logs.length > 0">
<div class="border border-border rounded-lg overflow-hidden shadow-sm mt-4 bg-background"> <!-- Table container --> <div class="border border-border rounded-lg overflow-hidden shadow-sm mt-4 bg-background"> <!-- Table container -->
<div class="overflow-x-auto"> <!-- Allow horizontal scroll --> <div class="overflow-x-auto"> <!-- Allow horizontal scroll -->
<table class="min-w-full divide-y divide-border text-sm"> <!-- Table styling --> <table class="min-w-full divide-y divide-border text-sm"> <!-- Table styling -->
+19 -13
View File
@@ -6,17 +6,21 @@
{{ $t('settings.title') }} {{ $t('settings.title') }}
</h1> </h1>
<!-- General Settings Loading/Error --> <!-- Error state (Show first if error exists) -->
<div v-if="settingsLoading" class="p-4 text-center text-text-secondary italic"> <!-- Loading state --> <div v-if="settingsError" class="p-4 mb-4 border-l-4 border-error bg-error/10 text-error rounded">
{{ $t('common.loading') }}
</div>
<div v-if="settingsError" class="p-4 mb-4 border-l-4 border-error bg-error/10 text-error rounded"> <!-- Error state -->
{{ settingsError }} {{ settingsError }}
</div> </div>
<!-- Settings Sections Grid --> <!-- Settings Sections Grid (Render grid structure always if no error) -->
<div v-if="!settingsLoading && !settingsError" class="grid grid-cols-1 lg:grid-cols-3 gap-6"> <div v-else class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Loading state (Show inside grid area when loading) -->
<div v-if="settingsLoading" class="lg:col-span-3 p-8 text-center text-text-secondary italic">
{{ $t('common.loading') }}
</div>
<!-- Actual Settings Content (Show only when not loading) -->
<template v-else>
<!-- Column 1: Security --> <!-- Column 1: Security -->
<div class="lg:col-span-2 space-y-6"> <!-- Security takes 2 columns on large screens --> <div class="lg:col-span-2 space-y-6"> <!-- Security takes 2 columns on large screens -->
<div class="bg-background border border-border rounded-lg shadow-sm overflow-hidden"> <div class="bg-background border border-border rounded-lg shadow-sm overflow-hidden">
@@ -242,11 +246,14 @@
<hr class="border-border/50"> <hr class="border-border/50">
<!-- Blacklist table --> <!-- Blacklist table -->
<h3 class="text-base font-semibold text-foreground">{{ $t('settings.ipBlacklist.currentBannedTitle') }}</h3> <h3 class="text-base font-semibold text-foreground">{{ $t('settings.ipBlacklist.currentBannedTitle') }}</h3>
<!-- Loading state (Only show if loading AND no entries are displayed yet) --> <!-- Error state -->
<div v-if="ipBlacklist.loading && ipBlacklist.entries.length === 0" class="p-4 text-center text-text-secondary italic">{{ $t('settings.ipBlacklist.loadingList') }}</div>
<div v-if="ipBlacklist.error" class="p-3 border-l-4 border-error bg-error/10 text-error text-sm rounded">{{ ipBlacklist.error }}</div> <div v-if="ipBlacklist.error" class="p-3 border-l-4 border-error bg-error/10 text-error text-sm rounded">{{ ipBlacklist.error }}</div>
<div v-if="!ipBlacklist.loading && !ipBlacklist.error"> <!-- Loading state (Only show if loading AND no entries are displayed yet) -->
<div v-if="ipBlacklist.entries.length > 0" class="overflow-x-auto border border-border rounded-lg shadow-sm bg-background"> <div v-else-if="ipBlacklist.loading && ipBlacklist.entries.length === 0" class="p-4 text-center text-text-secondary italic">{{ $t('settings.ipBlacklist.loadingList') }}</div>
<!-- Empty state (Show only if not loading, no error, and entries empty) -->
<p v-else-if="!ipBlacklist.loading && !ipBlacklist.error && ipBlacklist.entries.length === 0" class="p-4 text-center text-text-secondary italic">{{ $t('settings.ipBlacklist.noBannedIps') }}</p>
<!-- Table (Show if not loading, no error, and has entries) -->
<div v-else-if="!ipBlacklist.loading && !ipBlacklist.error && ipBlacklist.entries.length > 0" class="overflow-x-auto border border-border rounded-lg shadow-sm bg-background">
<table class="min-w-full divide-y divide-border text-sm"> <table class="min-w-full divide-y divide-border text-sm">
<thead class="bg-header"> <thead class="bg-header">
<tr> <tr>
@@ -276,12 +283,11 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<p v-else class="p-4 text-center text-text-secondary italic">{{ $t('settings.ipBlacklist.noBannedIps') }}</p> <!-- Delete Error (Show regardless of loading state if present) -->
<p v-if="blacklistDeleteError" class="mt-3 text-sm text-error">{{ blacklistDeleteError }}</p> <p v-if="blacklistDeleteError" class="mt-3 text-sm text-error">{{ blacklistDeleteError }}</p>
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Column 2: Appearance, Workspace, System --> <!-- Column 2: Appearance, Workspace, System -->
<div class="lg:col-span-1 space-y-6"> <div class="lg:col-span-1 space-y-6">