Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2025-12-22 16:15:02 -06:00
parent e0d64a4c0e
commit 3a875c3c8e

View File

@ -0,0 +1,180 @@
//
// PrivacyPolicyView.swift
// CasinoKit
//
// A shared privacy policy view for casino game apps.
//
import SwiftUI
/// A view displaying the privacy policy for casino games.
/// This policy is designed for offline games that don't collect personal data.
public struct PrivacyPolicyView: View {
@Environment(\.dismiss) private var dismiss
/// The developer/company name to display in the policy.
public let developerName: String
/// Contact email for privacy inquiries.
public let contactEmail: String
/// Last updated date string.
public let lastUpdated: String
/// Creates a privacy policy view.
/// - Parameters:
/// - developerName: Your name or company name.
/// - contactEmail: Email for privacy questions.
/// - lastUpdated: Date string like "December 2024".
public init(
developerName: String,
contactEmail: String,
lastUpdated: String = "December 2024"
) {
self.developerName = developerName
self.contactEmail = contactEmail
self.lastUpdated = lastUpdated
}
public var body: some View {
NavigationStack {
ScrollView {
VStack(alignment: .leading, spacing: CasinoDesign.Spacing.large) {
// Header
Text(String(localized: "Privacy Policy", bundle: .module))
.font(.system(size: CasinoDesign.BaseFontSize.largeTitle, weight: .bold))
.foregroundStyle(.white)
Text(String(localized: "Last updated: \(lastUpdated)", bundle: .module))
.font(.system(size: CasinoDesign.BaseFontSize.body))
.foregroundStyle(.white.opacity(CasinoDesign.Opacity.medium))
Divider()
.background(Color.white.opacity(CasinoDesign.Opacity.subtle))
// Introduction
PolicySection(title: String(localized: "Introduction", bundle: .module)) {
Text(String(localized: "\(developerName) (\"we\", \"our\", or \"us\") respects your privacy. This Privacy Policy explains how our casino game apps handle your information.", bundle: .module))
}
// Data Collection
PolicySection(title: String(localized: "Information We Collect", bundle: .module)) {
Text(String(localized: "Our games are designed to work offline and we collect minimal data:", bundle: .module))
BulletPoint(String(localized: "Game progress and statistics are stored locally on your device", bundle: .module))
BulletPoint(String(localized: "If you enable iCloud sync, your game data is stored in your personal iCloud account", bundle: .module))
BulletPoint(String(localized: "We do not collect personal information such as your name, email, or location", bundle: .module))
BulletPoint(String(localized: "We do not use analytics or tracking services", bundle: .module))
BulletPoint(String(localized: "We do not display advertisements", bundle: .module))
}
// iCloud
PolicySection(title: String(localized: "iCloud Sync", bundle: .module)) {
Text(String(localized: "If you choose to enable iCloud sync:", bundle: .module))
BulletPoint(String(localized: "Your game progress syncs across your devices using your Apple ID", bundle: .module))
BulletPoint(String(localized: "This data is stored in your personal iCloud account, not on our servers", bundle: .module))
BulletPoint(String(localized: "Apple's iCloud terms and privacy policy apply to this data", bundle: .module))
BulletPoint(String(localized: "You can disable iCloud sync at any time in the app settings", bundle: .module))
}
// Data Storage
PolicySection(title: String(localized: "Data Storage", bundle: .module)) {
Text(String(localized: "All game data is stored:", bundle: .module))
BulletPoint(String(localized: "Locally on your device using iOS standard storage", bundle: .module))
BulletPoint(String(localized: "In your iCloud account if you enable sync", bundle: .module))
BulletPoint(String(localized: "We have no access to your game data", bundle: .module))
}
// Children
PolicySection(title: String(localized: "Children's Privacy", bundle: .module)) {
Text(String(localized: "Our games are simulated casino games for entertainment only. No real money gambling is involved. We do not knowingly collect information from children under 13.", bundle: .module))
}
// Third Parties
PolicySection(title: String(localized: "Third-Party Services", bundle: .module)) {
Text(String(localized: "Our apps do not integrate with third-party services that collect user data. We do not share any information with third parties.", bundle: .module))
}
// Changes
PolicySection(title: String(localized: "Changes to This Policy", bundle: .module)) {
Text(String(localized: "We may update this Privacy Policy from time to time. We will notify you of any changes by posting the new policy in the app and updating the \"Last updated\" date.", bundle: .module))
}
// Contact
PolicySection(title: String(localized: "Contact Us", bundle: .module)) {
Text(String(localized: "If you have questions about this Privacy Policy, please contact us at:", bundle: .module))
Text(contactEmail)
.font(.system(size: CasinoDesign.BaseFontSize.body, weight: .medium))
.foregroundStyle(.yellow)
}
Spacer(minLength: CasinoDesign.Spacing.xxLarge)
}
.padding(CasinoDesign.Spacing.large)
}
.background(Color.Sheet.background.ignoresSafeArea())
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button(String(localized: "Done", bundle: .module)) {
dismiss()
}
.foregroundStyle(.yellow)
}
}
.toolbarBackground(Color.Sheet.background, for: .navigationBar)
.toolbarColorScheme(.dark, for: .navigationBar)
}
}
}
// MARK: - Policy Section
private struct PolicySection<Content: View>: View {
let title: String
@ViewBuilder let content: () -> Content
var body: some View {
VStack(alignment: .leading, spacing: CasinoDesign.Spacing.small) {
Text(title)
.font(.system(size: CasinoDesign.BaseFontSize.xLarge, weight: .semibold))
.foregroundStyle(.white)
content()
.font(.system(size: CasinoDesign.BaseFontSize.body))
.foregroundStyle(.white.opacity(CasinoDesign.Opacity.strong))
}
}
}
// MARK: - Bullet Point
private struct BulletPoint: View {
let text: String
init(_ text: String) {
self.text = text
}
var body: some View {
HStack(alignment: .top, spacing: CasinoDesign.Spacing.small) {
Text("")
.foregroundStyle(.yellow)
Text(text)
}
.font(.system(size: CasinoDesign.BaseFontSize.body))
.foregroundStyle(.white.opacity(CasinoDesign.Opacity.strong))
}
}
// MARK: - Preview
#Preview {
PrivacyPolicyView(
developerName: "Casino Games Studio",
contactEmail: "privacy@example.com"
)
}