SettingsView.swift 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import SwiftUI
  2. struct SettingsView: View {
  3. @Bindable var viewModel: SettingsViewModel
  4. @EnvironmentObject private var subscriptions: SubscriptionManager
  5. @EnvironmentObject private var appRating: AppRatingManager
  6. @Environment(AppearanceManager.self) private var appearance
  7. private enum Layout {
  8. static let horizontalPadding: CGFloat = 24
  9. }
  10. var body: some View {
  11. VStack(spacing: 0) {
  12. header
  13. ScrollView {
  14. VStack(alignment: .leading, spacing: 12) {
  15. appearanceSection
  16. linksSection
  17. }
  18. .frame(maxWidth: .infinity, alignment: .leading)
  19. .padding(.horizontal, Layout.horizontalPadding)
  20. .padding(.top, 12)
  21. .padding(.bottom, 24)
  22. }
  23. }
  24. .background(AppTheme.background)
  25. }
  26. private var header: some View {
  27. VStack(spacing: 0) {
  28. HStack(spacing: 14) {
  29. ModernSidebarIconView(kind: .settings, size: 40)
  30. VStack(alignment: .leading, spacing: 2) {
  31. Text("Settings")
  32. .font(.system(size: 18, weight: .semibold))
  33. .foregroundStyle(AppTheme.textPrimary)
  34. Text("Manage app preferences")
  35. .font(.system(size: 11))
  36. .foregroundStyle(AppTheme.textSecondary)
  37. }
  38. Spacer()
  39. }
  40. .padding(.horizontal, 24)
  41. .padding(.vertical, 16)
  42. FullWidthDivider()
  43. }
  44. }
  45. private var appearanceSection: some View {
  46. PostFormCard(
  47. title: "Appearance",
  48. subtitle: "Customize how the app looks"
  49. ) {
  50. SettingsToggleRow(
  51. icon: "moon.fill",
  52. title: "Dark Mode",
  53. subtitle: appearance.isDarkMode ? "On" : "Off",
  54. isOn: Binding(
  55. get: { appearance.isDarkMode },
  56. set: { appearance.isDarkMode = $0 }
  57. )
  58. )
  59. }
  60. }
  61. private var linksSection: some View {
  62. PostFormCard(
  63. title: "About",
  64. subtitle: "Website, legal, and help resources"
  65. ) {
  66. VStack(spacing: 8) {
  67. if subscriptions.hasPremiumAccess {
  68. SettingsLinkRow(
  69. icon: "star.fill",
  70. title: "Rate App",
  71. subtitle: "Leave a review on the App Store"
  72. ) {
  73. appRating.requestReviewFromSettings()
  74. }
  75. }
  76. SettingsLinkRow(
  77. icon: "globe",
  78. title: "Website",
  79. subtitle: AppLinks.website.host
  80. ) {
  81. viewModel.openWebsite()
  82. }
  83. SettingsLinkRow(
  84. icon: "hand.raised.fill",
  85. title: "Privacy Policy",
  86. subtitle: "How we handle your data"
  87. ) {
  88. viewModel.openPrivacyPolicy()
  89. }
  90. SettingsLinkRow(
  91. icon: "doc.text.fill",
  92. title: "Terms & Conditions",
  93. subtitle: "Terms of service"
  94. ) {
  95. viewModel.openTermsAndConditions()
  96. }
  97. SettingsLinkRow(
  98. icon: "lifepreserver.fill",
  99. title: "Support",
  100. subtitle: "Get help or send feedback"
  101. ) {
  102. viewModel.openSupport()
  103. }
  104. }
  105. }
  106. }
  107. }
  108. #Preview {
  109. SettingsView(viewModel: SettingsViewModel())
  110. .environmentObject(SubscriptionManager())
  111. .environmentObject(AppRatingManager())
  112. .environment(AppearanceManager.shared)
  113. .frame(width: 800, height: 600)
  114. }