Files
stream.ui/src/composables/useSettingsPreferencesQuery.ts
claude b60f65e4d1 feat: add admin components for input, metrics, tables, and user forms
- Introduced AdminInput component for standardized input fields.
- Created AdminMetricCard for displaying metrics with customizable tones.
- Added AdminPlaceholderTable for loading states in tables.
- Developed AdminSectionCard for consistent section layouts.
- Implemented AdminSectionShell for organizing admin sections.
- Added AdminSelect for dropdown selections with v-model support.
- Created AdminTable for displaying tabular data with loading and empty states.
- Introduced AdminTextarea for multi-line text input.
- Developed AdminUserFormFields for user creation and editing forms.
- Added useAdminPageHeader composable for managing admin page header state.
2026-03-24 07:08:44 +00:00

77 lines
2.6 KiB
TypeScript

import { client as rpcClient } from '@/api/rpcclient';
import type { Preferences } from '@/server/gen/proto/app/v1/common';
import type { UpdatePreferencesRequest } from '@/server/gen/proto/app/v1/account';
import { useQuery } from '@pinia/colada';
export const SETTINGS_PREFERENCES_QUERY_KEY = ['settings', 'preferences'] as const;
export type SettingsPreferencesSnapshot = {
emailNotifications: boolean;
pushNotifications: boolean;
marketingNotifications: boolean;
telegramNotifications: boolean;
language: string;
locale: string;
};
export type NotificationSettingsDraft = {
email: boolean;
push: boolean;
marketing: boolean;
telegram: boolean;
};
type PreferencesResponse = {
preferences?: Preferences;
};
const DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT: SettingsPreferencesSnapshot = {
emailNotifications: true,
pushNotifications: true,
marketingNotifications: false,
telegramNotifications: false,
language: 'en',
locale: 'en',
};
const normalizePreferencesSnapshot = (responseData: unknown): SettingsPreferencesSnapshot => {
const preferences = (responseData as PreferencesResponse | undefined)?.preferences;
return {
emailNotifications: preferences?.emailNotifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.emailNotifications,
pushNotifications: preferences?.pushNotifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.pushNotifications,
marketingNotifications: preferences?.marketingNotifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.marketingNotifications,
telegramNotifications: preferences?.telegramNotifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.telegramNotifications,
language: preferences?.language ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.language,
locale: preferences?.locale ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.locale,
};
};
export const createNotificationSettingsDraft = (
snapshot: SettingsPreferencesSnapshot = DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT,
): NotificationSettingsDraft => ({
email: snapshot.emailNotifications,
push: snapshot.pushNotifications,
marketing: snapshot.marketingNotifications,
telegram: snapshot.telegramNotifications,
});
export const toNotificationPreferencesPayload = (
draft: NotificationSettingsDraft,
): UpdatePreferencesRequest => ({
emailNotifications: draft.email,
pushNotifications: draft.push,
marketingNotifications: draft.marketing,
telegramNotifications: draft.telegram,
});
export function useSettingsPreferencesQuery() {
return useQuery({
key: () => SETTINGS_PREFERENCES_QUERY_KEY,
query: async () => {
const response = await rpcClient.getPreferences();
return normalizePreferencesSnapshot(response);
},
});
}