added preview and update some views
This commit is contained in:
1 parent
a11510d6fa
commit
2ceacb9c2b
22 files changed
+1267
-172
No files matched your search
@@ -38,3 +38,8 @@ struct ContentView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Главный экран") {
|
||||
ContentView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -56,3 +56,101 @@ enum BalanceModelContainer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Превью
|
||||
|
||||
extension BalanceModelContainer {
|
||||
/// Контейнер в памяти с демо-данными для #Preview.
|
||||
@MainActor
|
||||
static var previewContainer: ModelContainer {
|
||||
let configuration = ModelConfiguration(
|
||||
schema: schema,
|
||||
isStoredInMemoryOnly: true,
|
||||
cloudKitDatabase: .none
|
||||
)
|
||||
do {
|
||||
let container = try ModelContainer(for: schema, configurations: [configuration])
|
||||
PreviewSampleData.seed(into: container.mainContext)
|
||||
return container
|
||||
} catch {
|
||||
fatalError("Не удалось создать контейнер для превью: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Демо-данные, которыми наполняется контейнер превью.
|
||||
@MainActor
|
||||
private enum PreviewSampleData {
|
||||
static func seed(into context: ModelContext) {
|
||||
let calendar = Calendar.current
|
||||
let monthStart = FinanceCalculations.monthInterval(containing: .now, calendar: calendar).start
|
||||
|
||||
context.insert(CustomCategory(
|
||||
name: "Кофе",
|
||||
icon: "cup.and.saucer.fill",
|
||||
emoji: "☕️",
|
||||
colorName: "brown",
|
||||
kind: .expense
|
||||
))
|
||||
|
||||
let expenses: [(name: String, icon: String, emoji: String, colorName: String, amount: Double)] = [
|
||||
("Продукты", "cart.fill", "", "auto", 3_400),
|
||||
("Транспорт", "car.fill", "", "auto", 1_200),
|
||||
("Развлечения", "gamecontroller.fill", "", "auto", 2_600),
|
||||
("Подписки", "repeat", "", "auto", 649),
|
||||
("Кофе", "cup.and.saucer.fill", "☕️", "brown", 380),
|
||||
("Покупки", "bag.fill", "", "auto", 4_800)
|
||||
]
|
||||
|
||||
for monthOffset in 0..<6 {
|
||||
guard let anchor = calendar.date(byAdding: .month, value: -monthOffset, to: monthStart) else {
|
||||
continue
|
||||
}
|
||||
|
||||
if let salaryDate = calendar.date(byAdding: .day, value: 2, to: anchor) {
|
||||
context.insert(FinanceTransaction(
|
||||
amount: 150_000,
|
||||
date: salaryDate,
|
||||
note: "",
|
||||
categoryName: "Зарплата",
|
||||
categoryIcon: "banknote.fill",
|
||||
kind: .income
|
||||
))
|
||||
}
|
||||
|
||||
for (index, template) in expenses.enumerated() {
|
||||
guard let date = calendar.date(byAdding: .day, value: 4 + index * 3, to: anchor) else {
|
||||
continue
|
||||
}
|
||||
let variation = 1 + Double((monthOffset + index) % 4) * 0.08
|
||||
context.insert(FinanceTransaction(
|
||||
amount: (template.amount * variation).rounded(),
|
||||
date: date,
|
||||
note: "",
|
||||
categoryName: template.name,
|
||||
categoryIcon: template.icon,
|
||||
categoryEmoji: template.emoji,
|
||||
categoryColorName: template.colorName,
|
||||
kind: .expense
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
let budgets: [(name: String, icon: String, emoji: String, limit: Double)] = [
|
||||
("Продукты", "cart.fill", "", 30_000),
|
||||
("Транспорт", "car.fill", "", 8_000),
|
||||
("Развлечения", "gamecontroller.fill", "", 10_000),
|
||||
("Кофе", "cup.and.saucer.fill", "☕️", 5_000)
|
||||
]
|
||||
|
||||
for budget in budgets {
|
||||
context.insert(MonthlyBudget(
|
||||
categoryName: budget.name,
|
||||
categoryIcon: budget.icon,
|
||||
categoryEmoji: budget.emoji,
|
||||
limit: budget.limit,
|
||||
monthStart: monthStart
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -334,6 +334,11 @@ struct AnalyticsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Аналитика") {
|
||||
AnalyticsView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
private struct AnalyticsMetricCard: View {
|
||||
let title: String
|
||||
let value: String
|
||||
@@ -355,3 +360,21 @@ private struct AnalyticsMetricCard: View {
|
||||
.background(.background, in: RoundedRectangle(cornerRadius: 18, style: .continuous))
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Карточка метрики") {
|
||||
LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 12) {
|
||||
AnalyticsMetricCard(
|
||||
title: "Доходы",
|
||||
value: "150 000 ₽",
|
||||
icon: "arrow.down.left",
|
||||
tint: .green
|
||||
)
|
||||
AnalyticsMetricCard(
|
||||
title: "Расходы",
|
||||
value: "87 300 ₽",
|
||||
icon: "arrow.up.right",
|
||||
tint: .red
|
||||
)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
@@ -111,3 +111,24 @@ struct BudgetEditorView: View {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Лимиты") {
|
||||
BudgetEditorView(
|
||||
budgets: [
|
||||
MonthlyBudget(
|
||||
categoryName: "Продукты",
|
||||
categoryIcon: "cart.fill",
|
||||
limit: 30_000,
|
||||
monthStart: .now
|
||||
),
|
||||
MonthlyBudget(
|
||||
categoryName: "Транспорт",
|
||||
categoryIcon: "car.fill",
|
||||
limit: 8_000,
|
||||
monthStart: .now
|
||||
)
|
||||
],
|
||||
monthStart: FinanceCalculations.monthInterval(containing: .now).start
|
||||
)
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -116,3 +116,8 @@ struct BudgetsView: View {
|
||||
return .indigo
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Бюджеты") {
|
||||
BudgetsView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -33,3 +33,20 @@ struct CategoryIconView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Иконки") {
|
||||
HStack(spacing: 16) {
|
||||
CategoryIconView(systemName: "cart.fill", emoji: "", tint: .orange, containerSize: 40)
|
||||
CategoryIconView(systemName: "car.fill", emoji: "", tint: .blue)
|
||||
CategoryIconView(systemName: "banknote.fill", emoji: "", tint: .green, size: 24, containerSize: 52)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
|
||||
#Preview("Эмодзи") {
|
||||
HStack(spacing: 16) {
|
||||
CategoryIconView(systemName: "star.fill", emoji: "☕️", tint: .brown, size: 21, containerSize: 40)
|
||||
CategoryIconView(systemName: "star.fill", emoji: "🐶", tint: .purple, size: 21, containerSize: 40)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
@@ -22,3 +22,12 @@ struct EmptyStateCard: View {
|
||||
.background(.background, in: RoundedRectangle(cornerRadius: 20, style: .continuous))
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Пустое состояние") {
|
||||
EmptyStateCard(
|
||||
icon: "tray",
|
||||
title: "История пуста",
|
||||
message: "Доходы и расходы будут собраны здесь."
|
||||
)
|
||||
.padding()
|
||||
}
|
||||
@@ -31,3 +31,23 @@ struct SummaryCard: View {
|
||||
.shadow(color: .black.opacity(0.05), radius: 12, y: 5)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Карточки сводки") {
|
||||
HStack(spacing: 12) {
|
||||
SummaryCard(
|
||||
title: "Доходы",
|
||||
amount: 150_000,
|
||||
currencyCode: "RUB",
|
||||
icon: "arrow.down.left",
|
||||
tint: .green
|
||||
)
|
||||
SummaryCard(
|
||||
title: "Расходы",
|
||||
amount: 87_300,
|
||||
currencyCode: "RUB",
|
||||
icon: "arrow.up.right",
|
||||
tint: .red
|
||||
)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
@@ -105,3 +105,8 @@ struct BalanceAdjustmentView: View {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Корректировка баланса") {
|
||||
BalanceAdjustmentView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -211,3 +211,8 @@ struct DashboardView: View {
|
||||
return FinanceCategory.color(named: item.colorName)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Обзор") {
|
||||
DashboardView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -338,3 +338,28 @@ private struct CategoryEditorView: View {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Категории") {
|
||||
NavigationStack {
|
||||
CategoriesView()
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
#Preview("Новая категория") {
|
||||
CategoryEditorView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
#Preview("Редактирование категории") {
|
||||
CategoryEditorView(
|
||||
category: CustomCategory(
|
||||
name: "Кофе",
|
||||
icon: "cup.and.saucer.fill",
|
||||
emoji: "☕️",
|
||||
colorName: "brown",
|
||||
kind: .expense
|
||||
)
|
||||
)
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -84,3 +84,8 @@ struct SettingsView: View {
|
||||
return "Без входа данные остаются на устройстве. Собственный сервер можно подключить выше без iCloud и платной Apple Developer Team."
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Настройки") {
|
||||
SettingsView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -175,3 +175,22 @@ struct NewTransactionView: View {
|
||||
return kind == .expense ? "Новый расход" : "Новый доход"
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Новая операция") {
|
||||
NewTransactionView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
#Preview("Редактирование операции") {
|
||||
NewTransactionView(
|
||||
transaction: FinanceTransaction(
|
||||
amount: 2_450,
|
||||
date: .now,
|
||||
note: "Пятёрочка у дома",
|
||||
categoryName: "Продукты",
|
||||
categoryIcon: "cart.fill",
|
||||
kind: .expense
|
||||
)
|
||||
)
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -44,3 +44,37 @@ struct TransactionRow: View {
|
||||
return prefix + transaction.amount.formattedCurrency(code: currencyCode)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Расход") {
|
||||
List {
|
||||
TransactionRow(
|
||||
transaction: FinanceTransaction(
|
||||
amount: 2_450,
|
||||
date: .now,
|
||||
note: "Пятёрочка у дома",
|
||||
categoryName: "Продукты",
|
||||
categoryIcon: "cart.fill",
|
||||
kind: .expense
|
||||
),
|
||||
currencyCode: "RUB"
|
||||
)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
}
|
||||
|
||||
#Preview("Доход") {
|
||||
List {
|
||||
TransactionRow(
|
||||
transaction: FinanceTransaction(
|
||||
amount: 150_000,
|
||||
date: .now,
|
||||
note: "",
|
||||
categoryName: "Зарплата",
|
||||
categoryIcon: "banknote.fill",
|
||||
kind: .income
|
||||
),
|
||||
currencyCode: "RUB"
|
||||
)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
}
|
||||
@@ -102,3 +102,8 @@ struct TransactionsView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Операции") {
|
||||
TransactionsView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -434,3 +434,57 @@ private struct MacCategoriesView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Главное окно") {
|
||||
MacContentView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
#Preview("Обзор") {
|
||||
MacOverviewView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
.frame(width: 900, height: 620)
|
||||
}
|
||||
|
||||
#Preview("Карточки метрик") {
|
||||
HStack(spacing: 14) {
|
||||
MacMetricCard(
|
||||
title: "Общий баланс",
|
||||
value: "62 700 ₽",
|
||||
icon: "creditcard.fill",
|
||||
tint: .indigo
|
||||
)
|
||||
MacMetricCard(
|
||||
title: "Доходы за месяц",
|
||||
value: "150 000 ₽",
|
||||
icon: "arrow.down.left",
|
||||
tint: .green
|
||||
)
|
||||
MacMetricCard(
|
||||
title: "Расходы за месяц",
|
||||
value: "87 300 ₽",
|
||||
icon: "arrow.up.right",
|
||||
tint: .red
|
||||
)
|
||||
}
|
||||
.padding()
|
||||
.frame(width: 720)
|
||||
}
|
||||
|
||||
#Preview("Операции") {
|
||||
MacTransactionsView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
.frame(width: 900, height: 620)
|
||||
}
|
||||
|
||||
#Preview("Бюджеты") {
|
||||
MacBudgetsView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
.frame(width: 900, height: 620)
|
||||
}
|
||||
|
||||
#Preview("Категории") {
|
||||
MacCategoriesView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
.frame(width: 900, height: 620)
|
||||
}
|
||||
@@ -107,6 +107,25 @@ struct MacTransactionEditor: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Новая операция") {
|
||||
MacTransactionEditor()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
#Preview("Редактирование операции") {
|
||||
MacTransactionEditor(
|
||||
transaction: FinanceTransaction(
|
||||
amount: 2_450,
|
||||
date: .now,
|
||||
note: "Пятёрочка у дома",
|
||||
categoryName: "Продукты",
|
||||
categoryIcon: "cart.fill",
|
||||
kind: .expense
|
||||
)
|
||||
)
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
struct MacCategoryEditor: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Environment(\.modelContext) private var modelContext
|
||||
@@ -231,3 +250,21 @@ struct MacCategoryEditor: View {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Новая категория") {
|
||||
MacCategoryEditor()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
#Preview("Редактирование категории") {
|
||||
MacCategoryEditor(
|
||||
category: CustomCategory(
|
||||
name: "Кофе",
|
||||
icon: "cup.and.saucer.fill",
|
||||
emoji: "☕️",
|
||||
colorName: "brown",
|
||||
kind: .expense
|
||||
)
|
||||
)
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -174,6 +174,12 @@ struct MacAnalyticsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Аналитика") {
|
||||
MacAnalyticsView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
.frame(width: 1000, height: 700)
|
||||
}
|
||||
|
||||
struct MacBalanceAdjustmentView: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Environment(\.modelContext) private var modelContext
|
||||
@@ -229,6 +235,11 @@ struct MacBalanceAdjustmentView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Корректировка баланса") {
|
||||
MacBalanceAdjustmentView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
struct MacBudgetEditor: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Environment(\.modelContext) private var modelContext
|
||||
@@ -308,6 +319,27 @@ struct MacBudgetEditor: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Лимиты") {
|
||||
MacBudgetEditor(
|
||||
budgets: [
|
||||
MonthlyBudget(
|
||||
categoryName: "Продукты",
|
||||
categoryIcon: "cart.fill",
|
||||
limit: 30_000,
|
||||
monthStart: .now
|
||||
),
|
||||
MonthlyBudget(
|
||||
categoryName: "Транспорт",
|
||||
categoryIcon: "car.fill",
|
||||
limit: 8_000,
|
||||
monthStart: .now
|
||||
)
|
||||
],
|
||||
monthStart: FinanceCalculations.monthInterval(containing: .now).start
|
||||
)
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
struct MacSettingsView: View {
|
||||
@Query private var transactions: [FinanceTransaction]
|
||||
@AppStorage("currencyCode") private var currencyCode = SupportedCurrency.RUB.rawValue
|
||||
@@ -359,3 +391,11 @@ struct MacSettingsView: View {
|
||||
.padding(24)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Настройки") {
|
||||
NavigationStack {
|
||||
MacSettingsView()
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
.frame(width: 640, height: 640)
|
||||
}
|
||||
@@ -108,3 +108,22 @@ struct WatchAddTransactionView: View {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Новая операция") {
|
||||
WatchAddTransactionView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
#Preview("Редактирование операции") {
|
||||
WatchAddTransactionView(
|
||||
transaction: FinanceTransaction(
|
||||
amount: 2_450,
|
||||
date: .now,
|
||||
note: "Пятёрочка у дома",
|
||||
categoryName: "Продукты",
|
||||
categoryIcon: "cart.fill",
|
||||
kind: .expense
|
||||
)
|
||||
)
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -99,6 +99,13 @@ struct WatchAnalyticsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Аналитика") {
|
||||
NavigationStack {
|
||||
WatchAnalyticsView()
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
struct WatchTransactionsView: View {
|
||||
@Environment(\.modelContext) private var modelContext
|
||||
@Query(sort: \FinanceTransaction.date, order: .reverse)
|
||||
@@ -169,6 +176,13 @@ struct WatchTransactionsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Операции") {
|
||||
NavigationStack {
|
||||
WatchTransactionsView()
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
struct WatchBudgetsView: View {
|
||||
@Query private var budgets: [MonthlyBudget]
|
||||
@Query private var transactions: [FinanceTransaction]
|
||||
@@ -218,6 +232,13 @@ struct WatchBudgetsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Бюджеты") {
|
||||
NavigationStack {
|
||||
WatchBudgetsView()
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
private struct WatchBudgetEditor: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Environment(\.modelContext) private var modelContext
|
||||
@@ -242,7 +263,9 @@ private struct WatchBudgetEditor: View {
|
||||
var body: some View {
|
||||
Form {
|
||||
ForEach(categories) { category in
|
||||
TextField(category.name, value: binding(category.name), format: .number)
|
||||
Section(category.name) {
|
||||
TextField(category.name, value: binding(category.name), format: .number)
|
||||
}
|
||||
}
|
||||
Button("Сохранить", action: save)
|
||||
}
|
||||
@@ -278,6 +301,29 @@ private struct WatchBudgetEditor: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Лимиты") {
|
||||
NavigationStack {
|
||||
WatchBudgetEditor(
|
||||
budgets: [
|
||||
MonthlyBudget(
|
||||
categoryName: "Продукты",
|
||||
categoryIcon: "cart.fill",
|
||||
limit: 30_000,
|
||||
monthStart: .now
|
||||
),
|
||||
MonthlyBudget(
|
||||
categoryName: "Транспорт",
|
||||
categoryIcon: "car.fill",
|
||||
limit: 8_000,
|
||||
monthStart: .now
|
||||
)
|
||||
],
|
||||
monthStart: FinanceCalculations.monthInterval(containing: .now).start
|
||||
)
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
struct WatchCategoriesView: View {
|
||||
@Environment(\.modelContext) private var modelContext
|
||||
@Query(sort: \CustomCategory.createdAt) private var categories: [CustomCategory]
|
||||
@@ -323,6 +369,13 @@ struct WatchCategoriesView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Категории") {
|
||||
NavigationStack {
|
||||
WatchCategoriesView()
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
private struct WatchCategoryEditor: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Environment(\.modelContext) private var modelContext
|
||||
@@ -425,6 +478,28 @@ private struct WatchCategoryEditor: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Новая категория") {
|
||||
NavigationStack {
|
||||
WatchCategoryEditor()
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
#Preview("Редактирование категории") {
|
||||
NavigationStack {
|
||||
WatchCategoryEditor(
|
||||
category: CustomCategory(
|
||||
name: "Кофе",
|
||||
icon: "cup.and.saucer.fill",
|
||||
emoji: "☕️",
|
||||
colorName: "brown",
|
||||
kind: .expense
|
||||
)
|
||||
)
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
struct WatchBalanceAdjustmentView: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Environment(\.modelContext) private var modelContext
|
||||
@@ -465,6 +540,13 @@ struct WatchBalanceAdjustmentView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Корректировка баланса") {
|
||||
NavigationStack {
|
||||
WatchBalanceAdjustmentView()
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
|
||||
struct WatchSettingsView: View {
|
||||
@AppStorage("currencyCode") private var currencyCode = SupportedCurrency.RUB.rawValue
|
||||
@AppStorage("appTheme") private var appTheme = AppTheme.system.rawValue
|
||||
@@ -491,3 +573,10 @@ struct WatchSettingsView: View {
|
||||
.navigationTitle("Настройки")
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Настройки") {
|
||||
NavigationStack {
|
||||
WatchSettingsView()
|
||||
}
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
@@ -57,8 +57,9 @@ struct WatchRootView: View {
|
||||
showingAddTransaction = true
|
||||
} label: {
|
||||
Label("Добавить операцию", systemImage: "plus.circle.fill")
|
||||
.frame(maxWidth: .infinity)
|
||||
// .frame(maxWidth: .infinity)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.buttonStyle(.borderedProminent)
|
||||
|
||||
VStack(spacing: 4) {
|
||||
@@ -67,35 +68,41 @@ struct WatchRootView: View {
|
||||
} label: {
|
||||
Label("Аналитика", systemImage: "chart.xyaxis.line")
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
NavigationLink {
|
||||
WatchTransactionsView()
|
||||
} label: {
|
||||
Label("Все операции", systemImage: "list.bullet.rectangle")
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
NavigationLink {
|
||||
WatchBudgetsView()
|
||||
} label: {
|
||||
Label("Бюджеты", systemImage: "target")
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
NavigationLink {
|
||||
WatchCategoriesView()
|
||||
} label: {
|
||||
Label("Категории", systemImage: "square.grid.2x2")
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
NavigationLink {
|
||||
WatchBalanceAdjustmentView()
|
||||
} label: {
|
||||
Label("Корректировка", systemImage: "slider.horizontal.3")
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
NavigationLink {
|
||||
WatchSettingsView()
|
||||
} label: {
|
||||
Label("Настройки", systemImage: "gearshape")
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
|
||||
if !transactions.isEmpty {
|
||||
Text("Последние")
|
||||
Text("Последние операции")
|
||||
.font(.headline)
|
||||
ForEach(transactions.prefix(4)) { transaction in
|
||||
HStack(spacing: 8) {
|
||||
@@ -156,3 +163,8 @@ struct WatchRootView: View {
|
||||
return FinanceCategory.color(named: transaction.categoryColorName)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Обзор") {
|
||||
WatchRootView()
|
||||
.modelContainer(BalanceModelContainer.previewContainer)
|
||||
}
|
||||
Reference in new issue
Block a user