8dad933ff1
- Fixed all Card components to use padding prop instead of className - Updated padding values: p-4 -> sm, p-6 -> md, p-8 -> lg - This resolves the React element type invalid error 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
111 lines
3.2 KiB
TypeScript
111 lines
3.2 KiB
TypeScript
import { api } from '../config/api';
|
|
|
|
export interface BrandingSettings {
|
|
company_name: string;
|
|
company_tagline: string;
|
|
support_email: string;
|
|
footer_text: string;
|
|
watermark_enabled: boolean;
|
|
logo_url?: string;
|
|
}
|
|
|
|
export interface ThemeSettings {
|
|
name?: string;
|
|
primaryColor?: string;
|
|
accentColor?: string;
|
|
backgroundColor?: string;
|
|
textColor?: string;
|
|
fontFamily?: string;
|
|
borderRadius?: 'none' | 'sm' | 'md' | 'lg';
|
|
customCss?: string;
|
|
}
|
|
|
|
export interface StorageInfo {
|
|
total_used: number;
|
|
archive_storage: number;
|
|
storage_by_event: Array<{
|
|
event_name: string;
|
|
id: number;
|
|
size: number;
|
|
}>;
|
|
storage_limit: number;
|
|
}
|
|
|
|
export const settingsService = {
|
|
// Get all settings
|
|
async getAllSettings(): Promise<Record<string, any>> {
|
|
const response = await api.get<Record<string, any>>('/api/admin/settings');
|
|
return response.data;
|
|
},
|
|
|
|
// Get settings by type
|
|
async getSettingsByType(type: 'branding' | 'theme' | 'general'): Promise<Record<string, any>> {
|
|
const response = await api.get<Record<string, any>>(`/api/admin/settings/${type}`);
|
|
return response.data;
|
|
},
|
|
|
|
// Update branding settings
|
|
async updateBranding(settings: BrandingSettings): Promise<void> {
|
|
await api.put('/api/admin/settings/branding', settings);
|
|
},
|
|
|
|
// Upload logo
|
|
async uploadLogo(file: File): Promise<{ logo_url: string }> {
|
|
const formData = new FormData();
|
|
formData.append('logo', file);
|
|
|
|
const response = await api.post<{ message: string; logo_url: string }>(
|
|
'/api/admin/settings/logo',
|
|
formData,
|
|
{
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data'
|
|
}
|
|
}
|
|
);
|
|
|
|
return { logo_url: response.data.logo_url };
|
|
},
|
|
|
|
// Update theme settings
|
|
async updateTheme(settings: ThemeSettings): Promise<void> {
|
|
await api.put('/api/admin/settings/theme', settings);
|
|
},
|
|
|
|
// Update multiple settings at once
|
|
async updateSettings(settings: Record<string, any>): Promise<void> {
|
|
await api.put('/api/admin/settings', settings);
|
|
},
|
|
|
|
// Get storage information
|
|
async getStorageInfo(): Promise<StorageInfo> {
|
|
const response = await api.get<StorageInfo>('/api/admin/settings/storage/info');
|
|
return response.data;
|
|
},
|
|
|
|
// Format branding settings from raw data
|
|
formatBrandingSettings(rawSettings: Record<string, any>): BrandingSettings {
|
|
return {
|
|
company_name: rawSettings.branding_company_name || '',
|
|
company_tagline: rawSettings.branding_company_tagline || '',
|
|
support_email: rawSettings.branding_support_email || '',
|
|
footer_text: rawSettings.branding_footer_text || '',
|
|
watermark_enabled: rawSettings.branding_watermark_enabled || false,
|
|
logo_url: rawSettings.branding_logo_url || undefined
|
|
};
|
|
},
|
|
|
|
// Format theme settings from raw data
|
|
formatThemeSettings(rawSettings: Record<string, any>): ThemeSettings {
|
|
return rawSettings.theme_config || {};
|
|
},
|
|
|
|
// Format bytes to human readable
|
|
formatBytes(bytes: number): string {
|
|
if (bytes === 0) return '0 Bytes';
|
|
const k = 1024;
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
}
|
|
}; |