refactor(web): унифицировать UI по паттернам ReUI на всех 12 страницах
Docker / build (push) Has been cancelled
Docker / build (push) Has been cancelled
Ввести CrudListPage, AnalyticsPage, RowActions и domain edit sheets с FormSheetRhf; убрать устаревшие TableCard/DataTableCard. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -144,6 +144,12 @@ export const api = {
|
||||
fetchApi<import('@/queries/dashboard').DashboardStats>('/api/dashboard/stats'),
|
||||
|
||||
fetchProjects: () => fetchApi<{ id: string; name: string }[]>('/api/projects'),
|
||||
|
||||
createProject: (name: string) =>
|
||||
fetchApi<{ id: string; name: string }>('/api/projects', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ name }),
|
||||
}),
|
||||
}
|
||||
|
||||
export type {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { toCsv, downloadTextFile } from '@/lib/format'
|
||||
|
||||
export function exportVpsCsv(
|
||||
rows: Record<string, unknown>[],
|
||||
fileName = 'vps-export.csv',
|
||||
): void {
|
||||
downloadTextFile(fileName, toCsv(rows))
|
||||
}
|
||||
|
||||
export function exportActiveVpsCsv(
|
||||
vps: Array<{
|
||||
ip: string
|
||||
status: string
|
||||
project?: string
|
||||
currency: string
|
||||
monthlyRate?: number | null
|
||||
}>,
|
||||
fileName = 'vps-export.csv',
|
||||
): void {
|
||||
exportVpsCsv(
|
||||
vps.map((v) => ({
|
||||
ip: v.ip,
|
||||
status: v.status,
|
||||
project: v.project ?? '',
|
||||
currency: v.currency,
|
||||
monthlyRate: v.monthlyRate ?? 0,
|
||||
})),
|
||||
fileName,
|
||||
)
|
||||
}
|
||||
@@ -33,6 +33,7 @@ export const providerAccountSchema = z.object({
|
||||
login: z.string().optional().default(''),
|
||||
apiCredentials: z.string().optional().default(''),
|
||||
billingMode: billingModeSchema.default('monthly'),
|
||||
balanceAlertBelow: z.union([z.coerce.number().min(0), z.literal('')]).optional(),
|
||||
notes: z.string().optional().default(''),
|
||||
})
|
||||
|
||||
@@ -83,10 +84,22 @@ export const settingsSchema = z.object({
|
||||
ratesUrl: z.string().url('Невалидный URL').or(z.literal('')).optional(),
|
||||
autoConvert: z.boolean().default(true),
|
||||
syncEnabled: z.boolean().optional().default(true),
|
||||
syncIntervalMinutes: z.coerce.number().min(15).optional().default(60),
|
||||
syncTariffsIntervalMinutes: z.coerce.number().min(60).optional().default(1440),
|
||||
telegramChatId: z.string().optional().default(''),
|
||||
telegramBotToken: z.string().optional().default(''),
|
||||
notifyPaymentExpiryEnabled: z.boolean().optional().default(true),
|
||||
notifyNewTariffsEnabled: z.boolean().optional().default(true),
|
||||
notifyLowBalanceEnabled: z.boolean().optional().default(true),
|
||||
notifySyncDigestEnabled: z.boolean().optional().default(true),
|
||||
})
|
||||
|
||||
export const projectSchema = z.object({
|
||||
name: z.string().min(1, 'Укажите название проекта').max(120),
|
||||
})
|
||||
|
||||
export type ProjectFormValues = z.infer<typeof projectSchema>
|
||||
|
||||
export type ProviderFormValues = z.infer<typeof providerSchema>
|
||||
export type ProviderAccountFormValues = z.infer<typeof providerAccountSchema>
|
||||
export type VpsFormValues = z.infer<typeof vpsSchema>
|
||||
|
||||
Reference in New Issue
Block a user