fix: resolve settings page icon and 404 errors

- Change icon from 'envelope' to 'mail' (envelope not in icons.js)
- Add default query param to GET /admin/settings/{key} endpoint
- Return AdminSettingDefaultResponse instead of 404 when default provided
- Update loadShippingSettings() to use default param for carrier settings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-05 22:46:27 +01:00
parent 84a523cd7b
commit e1c0c117c2
4 changed files with 33 additions and 16 deletions

View File

@@ -24,6 +24,7 @@ from app.services.admin_settings_service import admin_settings_service
from models.database.user import User from models.database.user import User
from models.schema.admin import ( from models.schema.admin import (
AdminSettingCreate, AdminSettingCreate,
AdminSettingDefaultResponse,
AdminSettingListResponse, AdminSettingListResponse,
AdminSettingResponse, AdminSettingResponse,
AdminSettingUpdate, AdminSettingUpdate,
@@ -75,16 +76,24 @@ def get_setting_categories(
} }
@router.get("/{key}", response_model=AdminSettingResponse) @router.get("/{key}", response_model=AdminSettingResponse | AdminSettingDefaultResponse)
def get_setting( def get_setting(
key: str, key: str,
default: str | None = Query(None, description="Default value if setting not found"),
db: Session = Depends(get_db), db: Session = Depends(get_db),
current_admin: User = Depends(get_current_admin_api), current_admin: User = Depends(get_current_admin_api),
): ) -> AdminSettingResponse | AdminSettingDefaultResponse:
"""Get specific setting by key.""" """Get specific setting by key.
If `default` is provided and the setting doesn't exist, returns a response
with the default value instead of 404.
"""
setting = admin_settings_service.get_setting_by_key(db, key) setting = admin_settings_service.get_setting_by_key(db, key)
if not setting: if not setting:
if default is not None:
# Return default value without creating the setting
return AdminSettingDefaultResponse(key=key, value=default, exists=False)
raise ResourceNotFoundException(resource_type="Setting", identifier=key) raise ResourceNotFoundException(resource_type="Setting", identifier=key)
return AdminSettingResponse.model_validate(setting) return AdminSettingResponse.model_validate(setting)

View File

@@ -20,7 +20,7 @@
{% call tabs_nav() %} {% call tabs_nav() %}
{{ tab_button('display', 'Display', icon='view-grid') }} {{ tab_button('display', 'Display', icon='view-grid') }}
{{ tab_button('logging', 'Logging', icon='document-text') }} {{ tab_button('logging', 'Logging', icon='document-text') }}
{{ tab_button('email', 'Email', icon='envelope') }} {{ tab_button('email', 'Email', icon='mail') }}
{{ tab_button('shipping', 'Shipping', icon='truck') }} {{ tab_button('shipping', 'Shipping', icon='truck') }}
{{ tab_button('system', 'System', icon='cog') }} {{ tab_button('system', 'System', icon='cog') }}
{{ tab_button('security', 'Security', icon='shield-check') }} {{ tab_button('security', 'Security', icon='shield-check') }}

View File

@@ -172,6 +172,14 @@ class AdminSettingResponse(BaseModel):
model_config = {"from_attributes": True} model_config = {"from_attributes": True}
class AdminSettingDefaultResponse(BaseModel):
"""Response when returning a default value for non-existent setting."""
key: str
value: str
exists: bool = False
class AdminSettingUpdate(BaseModel): class AdminSettingUpdate(BaseModel):
"""Update admin setting value.""" """Update admin setting value."""

View File

@@ -242,24 +242,24 @@ function adminSettings() {
async loadShippingSettings() { async loadShippingSettings() {
try { try {
// Load each carrier setting // Load each carrier setting with defaults to avoid 404 errors
const carriers = ['greco', 'colissimo', 'xpresslogistics']; const carriers = [
{ name: 'greco', default: 'https://dispatchweb.fr/Tracky/Home/' },
{ name: 'colissimo', default: '' },
{ name: 'xpresslogistics', default: '' }
];
for (const carrier of carriers) { for (const carrier of carriers) {
try { const key = `carrier_${carrier.name}_label_url`;
const key = `carrier_${carrier}_label_url`; // Use default query param to avoid 404 for non-existent settings
const data = await apiClient.get(`/admin/settings/${key}`); const data = await apiClient.get(`/admin/settings/${key}?default=${encodeURIComponent(carrier.default)}`);
if (data && data.value) { if (data && data.value !== undefined) {
this.shippingSettings[key] = data.value; this.shippingSettings[key] = data.value;
}
} catch (error) {
// Setting doesn't exist yet, use default
settingsLog.debug(`Setting carrier_${carrier}_label_url not found, using default`);
} }
} }
settingsLog.info('Shipping settings loaded:', this.shippingSettings); settingsLog.info('Shipping settings loaded:', this.shippingSettings);
} catch (error) { } catch (error) {
settingsLog.error('Failed to load shipping settings:', error); settingsLog.error('Failed to load shipping settings:', error);
// Don't show error for missing settings, just use defaults // On error, keep existing defaults
} }
}, },