refactor(web): унифицировать UI по паттернам ReUI на всех 12 страницах
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:
Denozordec
2026-06-28 13:16:00 +07:00
co-authored by Cursor
parent dc0650b61e
commit 0ea92746e4
31 changed files with 2002 additions and 1430 deletions
+6
View File
@@ -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 {
+30
View File
@@ -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,
)
}
+13
View File
@@ -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>