Skip to content

Commit 9fa56ef

Browse files
committed
feat(GlobalSettings): enhance settings UI with card layout and improved input handling
1 parent 66e1f52 commit 9fa56ef

File tree

2 files changed

+80
-49
lines changed

2 files changed

+80
-49
lines changed

services/frontend/src/assets/index.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ body {
115115
color: var(--foreground);
116116
}
117117

118+
input {
119+
background-color: hsl(0 0% 100%); /* Corresponds to bg-white */
120+
}
121+
122+
.bg-card {
123+
background-color: var(--color-muted);
124+
}
125+
118126
/* Global cursor pointer for buttons and interactive elements */
119127
button,
120128
[role="button"],
@@ -124,6 +132,8 @@ button,
124132
cursor: pointer;
125133
}
126134

135+
136+
127137
/* Ensure disabled buttons don't show pointer cursor */
128138
button:disabled,
129139
[role="button"]:disabled,
@@ -137,3 +147,4 @@ button:disabled,
137147
a[role="button"] {
138148
cursor: pointer;
139149
}
150+

services/frontend/src/views/admin/GlobalSettings.vue

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ import DashboardLayout from '@/components/DashboardLayout.vue'
77
import { getEnv } from '@/utils/env'
88
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
99
import { CheckCircle2Icon, XIcon } from 'lucide-vue-next'
10+
import {
11+
Card,
12+
CardContent,
13+
CardDescription,
14+
CardHeader,
15+
CardTitle,
16+
} from '@/components/ui/card'
1017
1118
const { t } = useI18n()
1219
const route = useRoute()
@@ -221,59 +228,72 @@ async function handleSubmit(event: Event) {
221228

222229
<div v-if="isLoading" class="text-muted-foreground">Loading settings...</div>
223230
<div v-else-if="error" class="text-red-500">Error loading settings: {{ error }}</div>
231+
232+
224233
<div v-else-if="selectedGroup" class="space-y-6">
225-
<div>
226-
<h3 class="text-lg font-medium">
227-
{{ selectedGroup.name }}
228-
</h3>
229-
<p v-if="selectedGroup.description" class="text-sm text-muted-foreground">
230-
{{ selectedGroup.description }}
231-
</p>
232-
</div>
233-
<form v-if="selectedGroup.settings && selectedGroup.settings.length > 0" class="space-y-6" @submit="handleSubmit">
234-
<div v-for="setting in selectedGroup.settings" :key="setting.key" class="space-y-2">
235-
<Label :for="`setting-${setting.key}`">{{ setting.description || setting.key }}</Label>
236-
237-
<!-- String Input (text or password) -->
238-
<Input
239-
v-if="setting.type === 'string'"
240-
:id="`setting-${setting.key}`"
241-
:type="setting.is_encrypted ? 'password' : 'text'"
242-
v-model="formValues[setting.key] as string"
243-
class="w-full"
244-
/>
245-
246-
<!-- Number Input -->
247-
<Input
248-
v-else-if="setting.type === 'number'"
249-
:id="`setting-${setting.key}`"
250-
type="number"
251-
v-model.number="formValues[setting.key] as number"
252-
class="w-full"
253-
/>
254-
255-
<!-- Boolean Toggle Switch -->
256-
<div v-else-if="setting.type === 'boolean'">
257-
<Switch
258-
:id="`setting-${setting.key}`"
259-
v-model:checked="formValues[setting.key]"
260-
/>
234+
235+
<Card>
236+
<CardHeader>
237+
<CardTitle class="text-xl">
238+
{{ selectedGroup.name }}
239+
</CardTitle>
240+
<CardDescription v-if="selectedGroup.description">
241+
{{ selectedGroup.description }}
242+
</CardDescription>
243+
</CardHeader>
244+
<CardContent>
245+
246+
<form v-if="selectedGroup.settings && selectedGroup.settings.length > 0" class="space-y-6" @submit="handleSubmit">
247+
<div v-for="setting in selectedGroup.settings" :key="setting.key" class="space-y-2">
248+
<Label :for="`setting-${setting.key}`">{{ setting.description || setting.key }}</Label>
249+
250+
<!-- String Input (text or password) -->
251+
<Input
252+
v-if="setting.type === 'string'"
253+
:id="`setting-${setting.key}`"
254+
:type="setting.is_encrypted ? 'password' : 'text'"
255+
v-model="formValues[setting.key] as string"
256+
class="w-full"
257+
/>
258+
259+
<!-- Number Input -->
260+
<Input
261+
v-else-if="setting.type === 'number'"
262+
:id="`setting-${setting.key}`"
263+
type="number"
264+
v-model.number="formValues[setting.key] as number"
265+
class="w-full"
266+
/>
267+
268+
<!-- Boolean Toggle Switch -->
269+
<div v-else-if="setting.type === 'boolean'">
270+
<Switch
271+
:id="`setting-${setting.key}`"
272+
v-model:checked="formValues[setting.key]"
273+
/>
274+
</div>
275+
276+
<p v-if="setting.is_encrypted" class="text-xs text-muted-foreground">This value is encrypted.</p>
277+
</div>
278+
279+
<Button type="submit">
280+
Save Changes
281+
</Button>
282+
</form>
283+
<div v-else-if="selectedGroup && (!selectedGroup.settings || selectedGroup.settings.length === 0)">
284+
<p class="text-sm text-muted-foreground">No settings in this group.</p>
285+
</div>
286+
<div v-else>
287+
<p class="text-sm text-muted-foreground">Group not found or settings unavailable.</p>
261288
</div>
262289

263-
<p v-if="setting.is_encrypted" class="text-xs text-muted-foreground">This value is encrypted.</p>
264-
</div>
265-
266-
<Button type="submit">
267-
Save Changes
268-
</Button>
269-
</form>
270-
<div v-else-if="selectedGroup && (!selectedGroup.settings || selectedGroup.settings.length === 0)">
271-
<p class="text-sm text-muted-foreground">No settings in this group.</p>
272-
</div>
273-
<div v-else>
274-
<p class="text-sm text-muted-foreground">Group not found or settings unavailable.</p>
275-
</div>
290+
</CardContent>
291+
</Card>
292+
293+
276294
</div>
295+
296+
277297
<div v-else-if="!currentGroupId && settingGroups.length > 0">
278298
<p class="text-muted-foreground">Select a category from the sidebar to view its settings.</p>
279299
</div>

0 commit comments

Comments
 (0)