222 lines
5.1 KiB
Swift
222 lines
5.1 KiB
Swift
import Foundation
|
|
import SwiftUI
|
|
|
|
// MARK: - Question
|
|
|
|
struct Question: Codable, Identifiable, Hashable, Sendable {
|
|
let id: String
|
|
var text: String
|
|
var type: String // "text" | "multiple_choice" | "scale"
|
|
var options: [String]?
|
|
var scaleMin: Int?
|
|
var scaleMax: Int?
|
|
var categoryId: String?
|
|
var packId: String?
|
|
}
|
|
|
|
struct QuestionCategory: Codable, Identifiable, Hashable, Sendable {
|
|
let id: String
|
|
var name: String
|
|
var description: String?
|
|
var icon: String?
|
|
var color: String?
|
|
var packId: String?
|
|
var order: Int?
|
|
}
|
|
|
|
struct QuestionPack: Codable, Identifiable, Hashable, Sendable {
|
|
let id: String
|
|
var name: String
|
|
var description: String?
|
|
var categories: [String]?
|
|
var isPremium: Bool
|
|
}
|
|
|
|
// MARK: - Question Threads
|
|
|
|
struct QuestionThread: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var questionId: String
|
|
var senderId: String
|
|
var status: String // "pending" | "answered" | "revealed"
|
|
var createdAt: Date
|
|
}
|
|
|
|
struct QuestionMessage: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var threadId: String
|
|
var userId: String
|
|
var text: String
|
|
var createdAt: Date
|
|
}
|
|
|
|
struct QuestionReaction: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var threadId: String
|
|
var userId: String
|
|
var emoji: String
|
|
var createdAt: Date
|
|
}
|
|
|
|
struct QuestionSession: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var gameType: String
|
|
var status: String
|
|
var startedAt: Date
|
|
var completedAt: Date?
|
|
var createdBy: String
|
|
}
|
|
|
|
// MARK: - Date Ideas
|
|
|
|
struct DateIdea: Codable, Identifiable, Hashable, Sendable {
|
|
let id: String
|
|
var title: String
|
|
var description: String?
|
|
var category: String?
|
|
var cost: String? // "free" | "low" | "medium" | "high"
|
|
var duration: String? // "short" | "medium" | "long"
|
|
var location: String? // "indoor" | "outdoor" | "both"
|
|
var imageUrl: String?
|
|
}
|
|
|
|
struct DateSwipe: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var dateIdeaId: String
|
|
var userId: String
|
|
var action: String // "love" | "pass"
|
|
var swipedAt: Date
|
|
}
|
|
|
|
struct DateMatch: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var coupleId: String
|
|
var dateIdeaId: String
|
|
var matchedAt: Date
|
|
}
|
|
|
|
struct DatePlan: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var coupleId: String
|
|
var title: String
|
|
var description: String?
|
|
var date: Date?
|
|
var location: String?
|
|
var notes: String?
|
|
var createdBy: String
|
|
var createdAt: Date
|
|
}
|
|
|
|
struct BucketListItem: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var title: String
|
|
var description: String?
|
|
var createdBy: String
|
|
var completed: Bool
|
|
var completedAt: Date?
|
|
var createdAt: Date
|
|
}
|
|
|
|
// MARK: - Challenges & Capsules
|
|
|
|
struct ConnectionChallenge: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var title: String
|
|
var description: String
|
|
var durationDays: Int
|
|
var tasks: [ChallengeTask]
|
|
var isPremium: Bool
|
|
}
|
|
|
|
struct ChallengeTask: Codable, Sendable {
|
|
var day: Int
|
|
var title: String
|
|
var description: String
|
|
}
|
|
|
|
struct ChallengeState: Codable, Sendable {
|
|
var challengeId: String
|
|
var currentDay: Int
|
|
var completedDays: [Int]
|
|
var startedAt: Date
|
|
var status: String // "active" | "completed" | "abandoned"
|
|
}
|
|
|
|
struct MemoryCapsule: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var title: String
|
|
var content: String?
|
|
var imageUrls: [String]?
|
|
var status: String // "sealed" | "unlocked"
|
|
var unlockAt: Date
|
|
var createdBy: String
|
|
var createdAt: Date
|
|
}
|
|
|
|
struct TimeCapsule: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var title: String
|
|
var message: String
|
|
var status: String
|
|
var unlockAt: Date
|
|
var createdBy: String
|
|
var createdAt: Date
|
|
}
|
|
|
|
// MARK: - Streaks
|
|
|
|
enum StreakType: Sendable {
|
|
case couple(count: Int, lastActiveDate: Date?, includesToday: Bool)
|
|
case personal(count: Int, lastActiveDate: Date?, includesToday: Bool)
|
|
case weeklyRhythm(count: Int, lastActiveDate: Date?, includesToday: Bool)
|
|
}
|
|
|
|
struct StreakResult: Sendable {
|
|
let coupleStreak: StreakType
|
|
let personalStreak: StreakType
|
|
let weeklyRhythm: StreakType
|
|
let milestoneCopy: String?
|
|
let canRepair: Bool
|
|
let repairDueDate: Date?
|
|
}
|
|
|
|
// MARK: - Game Types
|
|
|
|
enum GameType: String, Sendable {
|
|
case wheel = "wheel"
|
|
case thisOrThat = "this_or_that"
|
|
case howWell = "how_well"
|
|
case desireSync = "desire_sync"
|
|
case connectionChallenges = "connection_challenges"
|
|
}
|
|
|
|
// MARK: - Local Answer Caching
|
|
|
|
struct LocalAnswer: Codable, Sendable {
|
|
let questionId: String
|
|
let answer: String
|
|
let answeredAt: Date
|
|
var isRevealed: Bool
|
|
}
|
|
|
|
// MARK: - Weekly Recap
|
|
|
|
struct WeeklyRecap: Codable, Sendable {
|
|
var weekStart: Date
|
|
var streakCount: Int
|
|
var answersShared: Int
|
|
var gamesPlayed: Int
|
|
var badgesEarned: [String]
|
|
}
|
|
|
|
// MARK: - Answer Model
|
|
|
|
struct Answer: Codable, Identifiable, Sendable {
|
|
let id: String
|
|
var coupleId: String
|
|
var questionId: String
|
|
var userId: String
|
|
var answerText: String
|
|
var createdAt: Date
|
|
var isRevealed: Bool
|
|
} |