stock-management-demo/src/pages/SettingsPage.vue

229 lines
5.1 KiB
Vue

<template>
<q-page padding>
<q-card
bordered
flat
>
<q-card-section class="row items-center justify-between">
<div class="text-h4">
Application Settings
</div>
</q-card-section>
<q-separator />
<q-card-section v-if="loading">
<q-spinner-dots size="2em" /> Loading settings...
</q-card-section>
<q-card-section v-else-if="loadError">
<q-banner
inline-actions
class="text-white bg-red"
>
<template #avatar>
<q-icon name="error" />
</template>
{{ loadError }}
<template #action>
<q-btn
flat
color="white"
label="Retry"
@click="loadSettings"
/>
</template>
</q-banner>
</q-card-section>
<q-card-section v-else>
<q-form @submit.prevent="saveSettings">
<div
v-for="(group, groupName) in settings"
:key="groupName"
class="q-mb-lg"
>
<div class="text-h6 q-mb-sm">
{{ groupName }}
</div>
<div
v-for="setting in group"
:key="setting.key"
class="q-mb-md"
>
<q-input
v-model="settingValues[setting.key]"
:label="setting.name"
:type="setting.type || 'text'"
outlined
dense
/>
</div>
<q-separator class="q-my-md" />
</div>
<div class="row justify-end">
<q-btn
label="Save Settings"
type="submit"
color="primary"
:loading="saving"
:disable="loading || saving"
/>
</div>
</q-form>
</q-card-section>
</q-card>
</q-page>
</template>
<script setup>
import { useQuasar } from 'quasar';
import { ref, onMounted } from 'vue';
import axios from 'boot/axios'; // Import axios
const $q = useQuasar();
// Define the structure of settings
const settings = ref({
General: [
{
name: 'Registration Token',
key: 'REGISTRATION_TOKEN',
}
],
Mantis: [
{
name: 'Mantis API Key',
key: 'MANTIS_API_KEY',
},
{
name: 'Mantis API Endpoint',
key: 'MANTIS_API_ENDPOINT'
},
{
name: 'Mantis Prompt',
key: 'MANTIS_PROMPT',
type: 'textarea'
}
],
Gemini: [
{
name: 'Gemini API Key',
key: 'GEMINI_API_KEY'
}
],
Database: [
{
name: 'MySQL Host',
key: 'MYSQL_HOST'
},
{
name: 'MySQL Port',
key: 'MYSQL_PORT'
},
{
name: 'MySQL User',
key: 'MYSQL_USER'
},
{
name: 'MySQL Password',
key: 'MYSQL_PASSWORD'
},
{
name: 'MySQL Database',
key: 'MYSQL_DATABASE'
}
]
});
// Reactive state for setting values, loading, saving, and errors
const settingValues = ref({});
const loading = ref(true);
const saving = ref(false);
const loadError = ref(null);
// Function to load settings from the server
async function loadSettings()
{
loading.value = true;
loadError.value = null;
settingValues.value = {}; // Reset values
const allSettingKeys = Object.values(settings.value).flat().map(s => s.key);
try
{
const responses = await Promise.all(allSettingKeys.map(key => axios.get(`/api/settings/${key}`, {
validateStatus: status => status === 200 || status === 404 // Accept 404 as a valid response
})));
responses.forEach((response, index) =>
{
const key = allSettingKeys[index];
//If the response status is 404, set the value to an empty string
if (response.status === 404)
{
settingValues.value[key] = '';
return;
}
settingValues.value[key] = response.data;
});
}
catch (err)
{
console.error('Error loading settings:', err);
loadError.value = err.response?.data?.error || 'Failed to load settings. Please check the console.';
$q.notify({
color: 'negative',
icon: 'error',
message: loadError.value,
});
}
finally
{
loading.value = false;
}
}
// Function to save settings to the server
async function saveSettings()
{
saving.value = true;
loadError.value = null; // Clear previous load errors
const allSettingKeys = Object.keys(settingValues.value);
const requests = allSettingKeys.map(key =>
axios.put(`/api/settings/${key}`, { value: settingValues.value[key] })
);
try
{
await Promise.all(requests);
$q.notify({
color: 'positive',
icon: 'check_circle',
message: 'Settings saved successfully!',
});
}
catch (err)
{
console.error('Error saving settings:', err);
const errorMessage = err.response?.data?.error || 'Failed to save settings. Please try again.';
$q.notify({
color: 'negative',
icon: 'error',
message: errorMessage,
});
}
finally
{
saving.value = false;
}
}
// Load settings when the component is mounted
onMounted(() =>
{
loadSettings();
});
</script>