526 lines
13 KiB
Dart
526 lines
13 KiB
Dart
import 'package:hive/hive.dart';
|
|
import 'teaching_plan.dart';
|
|
|
|
part 'user_profile.g.dart';
|
|
|
|
/// User's relationship status
|
|
@HiveType(typeId: 0)
|
|
enum RelationshipStatus {
|
|
@HiveField(0)
|
|
single,
|
|
|
|
@HiveField(1)
|
|
engaged,
|
|
|
|
@HiveField(2)
|
|
married,
|
|
}
|
|
|
|
/// Fertility tracking goal for married users
|
|
@HiveType(typeId: 1)
|
|
enum FertilityGoal {
|
|
@HiveField(0)
|
|
tryingToConceive, // TTC
|
|
|
|
@HiveField(1)
|
|
tryingToAvoid, // TTA - NFP
|
|
|
|
@HiveField(2)
|
|
justTracking,
|
|
}
|
|
|
|
@HiveType(typeId: 9)
|
|
enum BibleTranslation {
|
|
@HiveField(0)
|
|
esv,
|
|
@HiveField(1)
|
|
niv,
|
|
@HiveField(2)
|
|
nkjv,
|
|
@HiveField(3)
|
|
nlt,
|
|
@HiveField(4)
|
|
nasb,
|
|
@HiveField(5)
|
|
kjv,
|
|
@HiveField(6)
|
|
msg,
|
|
}
|
|
|
|
@HiveType(typeId: 11)
|
|
enum AppThemeMode {
|
|
@HiveField(0)
|
|
system,
|
|
@HiveField(1)
|
|
light,
|
|
@HiveField(2)
|
|
dark,
|
|
}
|
|
|
|
@HiveType(typeId: 13)
|
|
enum PadType {
|
|
@HiveField(0)
|
|
pantyLiner,
|
|
@HiveField(1)
|
|
regular,
|
|
@HiveField(2)
|
|
super_pad,
|
|
@HiveField(3)
|
|
overnight,
|
|
@HiveField(4)
|
|
tampon_regular,
|
|
@HiveField(5)
|
|
tampon_super,
|
|
@HiveField(6)
|
|
menstrualCup,
|
|
@HiveField(7)
|
|
menstrualDisc,
|
|
@HiveField(8)
|
|
periodUnderwear,
|
|
}
|
|
|
|
extension PadTypeExtension on PadType {
|
|
String get label {
|
|
switch (this) {
|
|
case PadType.pantyLiner:
|
|
return 'Liner';
|
|
case PadType.regular:
|
|
return 'Regular Pad';
|
|
case PadType.super_pad:
|
|
return 'Super Pad';
|
|
case PadType.overnight:
|
|
return 'Overnight';
|
|
case PadType.tampon_regular:
|
|
return 'Tampon (Regular)';
|
|
case PadType.tampon_super:
|
|
return 'Tampon (Super)';
|
|
case PadType.menstrualCup:
|
|
return 'Cup';
|
|
case PadType.menstrualDisc:
|
|
return 'Disc';
|
|
case PadType.periodUnderwear:
|
|
return 'Period Underwear';
|
|
}
|
|
}
|
|
}
|
|
|
|
@HiveType(typeId: 12)
|
|
class SupplyItem extends HiveObject {
|
|
@HiveField(0)
|
|
String brand;
|
|
@HiveField(1)
|
|
PadType type;
|
|
@HiveField(2)
|
|
int absorbency; // 1-5
|
|
@HiveField(3)
|
|
int count;
|
|
|
|
SupplyItem({
|
|
required this.brand,
|
|
required this.type,
|
|
required this.absorbency,
|
|
required this.count,
|
|
});
|
|
|
|
SupplyItem copyWith({
|
|
String? brand,
|
|
PadType? type,
|
|
int? absorbency,
|
|
int? count,
|
|
}) {
|
|
return SupplyItem(
|
|
brand: brand ?? this.brand,
|
|
type: type ?? this.type,
|
|
absorbency: absorbency ?? this.absorbency,
|
|
count: count ?? this.count,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// User profile model
|
|
@HiveType(typeId: 2)
|
|
class UserProfile extends HiveObject {
|
|
@HiveField(0)
|
|
String id;
|
|
|
|
@HiveField(1)
|
|
String name;
|
|
|
|
@HiveField(2, defaultValue: RelationshipStatus.single)
|
|
RelationshipStatus relationshipStatus;
|
|
|
|
@HiveField(3)
|
|
FertilityGoal? fertilityGoal;
|
|
|
|
@HiveField(4, defaultValue: 28)
|
|
int averageCycleLength;
|
|
|
|
@HiveField(5, defaultValue: 5)
|
|
int averagePeriodLength;
|
|
|
|
@HiveField(6)
|
|
DateTime? lastPeriodStartDate;
|
|
|
|
@HiveField(7)
|
|
DateTime? lastPadChangeTime;
|
|
|
|
@HiveField(8, defaultValue: true)
|
|
bool notificationsEnabled;
|
|
|
|
@HiveField(9, defaultValue: false)
|
|
bool hasCompletedOnboarding;
|
|
|
|
@HiveField(10)
|
|
DateTime createdAt;
|
|
|
|
@HiveField(11)
|
|
DateTime updatedAt;
|
|
|
|
@HiveField(12)
|
|
String? partnerName; // For married users
|
|
|
|
@HiveField(14, defaultValue: UserRole.wife)
|
|
UserRole role;
|
|
|
|
@HiveField(15, defaultValue: false)
|
|
bool isIrregularCycle;
|
|
|
|
@HiveField(41, defaultValue: 21)
|
|
int minCycleLength;
|
|
|
|
@HiveField(42, defaultValue: 40)
|
|
int maxCycleLength;
|
|
|
|
@HiveField(16, defaultValue: BibleTranslation.esv)
|
|
BibleTranslation bibleTranslation;
|
|
|
|
@HiveField(17)
|
|
List<String>? favoriteFoods;
|
|
|
|
@HiveField(18, defaultValue: false)
|
|
bool isDataShared;
|
|
|
|
@HiveField(19, defaultValue: AppThemeMode.system)
|
|
AppThemeMode themeMode;
|
|
|
|
@HiveField(20, defaultValue: '0xFFA8C5A8')
|
|
String accentColor;
|
|
|
|
// Sharing settings
|
|
@HiveField(21, defaultValue: true)
|
|
bool shareMoods;
|
|
|
|
@HiveField(22, defaultValue: true)
|
|
bool shareSymptoms;
|
|
|
|
@HiveField(23, defaultValue: true)
|
|
bool shareCravings;
|
|
|
|
@HiveField(24, defaultValue: true)
|
|
bool shareEnergyLevels;
|
|
|
|
@HiveField(25, defaultValue: true)
|
|
bool shareSleep;
|
|
|
|
@HiveField(26, defaultValue: true)
|
|
bool shareIntimacy;
|
|
|
|
// Pad Tracking
|
|
@HiveField(27, defaultValue: false)
|
|
bool isPadTrackingEnabled;
|
|
|
|
@HiveField(28)
|
|
int? typicalFlowIntensity; // 1-5
|
|
|
|
@HiveField(29)
|
|
String? padBrand;
|
|
|
|
@HiveField(30)
|
|
int? padAbsorbency; // 1-5 scale
|
|
|
|
@HiveField(31, defaultValue: 0)
|
|
int padInventoryCount;
|
|
|
|
@HiveField(32, defaultValue: 5)
|
|
int lowInventoryThreshold;
|
|
|
|
@HiveField(33, defaultValue: true)
|
|
bool isAutoInventoryEnabled;
|
|
|
|
@HiveField(34)
|
|
DateTime? lastInventoryUpdate;
|
|
|
|
@HiveField(38)
|
|
List<SupplyItem>? padSupplies;
|
|
|
|
// Granular Notification Settings
|
|
@HiveField(35, defaultValue: true)
|
|
bool notifyPeriodEstimate;
|
|
|
|
@HiveField(36, defaultValue: true)
|
|
bool notifyPeriodStart;
|
|
|
|
@HiveField(37, defaultValue: true)
|
|
bool notifyLowSupply;
|
|
|
|
@HiveField(39, defaultValue: true)
|
|
bool showPadTimerMinutes;
|
|
|
|
@HiveField(40, defaultValue: false)
|
|
bool showPadTimerSeconds;
|
|
|
|
@HiveField(43, defaultValue: false)
|
|
bool notifyPad1Hour;
|
|
|
|
@HiveField(44, defaultValue: false)
|
|
bool notifyPad2Hours;
|
|
|
|
@HiveField(45)
|
|
String? privacyPin;
|
|
|
|
@HiveField(46, defaultValue: false)
|
|
bool isBioProtected;
|
|
|
|
@HiveField(47, defaultValue: false)
|
|
bool isHistoryProtected;
|
|
|
|
@HiveField(48, defaultValue: false)
|
|
bool notifyPad30Mins;
|
|
|
|
@HiveField(49, defaultValue: true)
|
|
bool notifyPadNow;
|
|
|
|
@HiveField(50, defaultValue: false)
|
|
bool isLogProtected;
|
|
|
|
@HiveField(51, defaultValue: false)
|
|
bool isCalendarProtected;
|
|
|
|
@HiveField(52, defaultValue: false)
|
|
bool isSuppliesProtected;
|
|
|
|
@HiveField(53)
|
|
List<TeachingPlan>? teachingPlans;
|
|
|
|
UserProfile({
|
|
required this.id,
|
|
required this.name,
|
|
this.relationshipStatus = RelationshipStatus.single,
|
|
this.fertilityGoal,
|
|
this.averageCycleLength = 28,
|
|
this.averagePeriodLength = 5,
|
|
this.lastPeriodStartDate,
|
|
this.notificationsEnabled = true,
|
|
this.hasCompletedOnboarding = false,
|
|
required this.createdAt,
|
|
required this.updatedAt,
|
|
this.partnerName,
|
|
this.role = UserRole.wife,
|
|
this.isIrregularCycle = false,
|
|
this.minCycleLength = 21,
|
|
this.maxCycleLength = 40,
|
|
this.bibleTranslation = BibleTranslation.esv,
|
|
this.favoriteFoods,
|
|
this.isDataShared = false,
|
|
this.themeMode = AppThemeMode.system,
|
|
this.accentColor = '0xFFA8C5A8',
|
|
this.shareMoods = true,
|
|
this.shareSymptoms = true,
|
|
this.shareCravings = true,
|
|
this.shareEnergyLevels = true,
|
|
this.shareSleep = true,
|
|
this.shareIntimacy = true,
|
|
this.isPadTrackingEnabled = false,
|
|
this.typicalFlowIntensity,
|
|
this.padBrand,
|
|
this.padAbsorbency,
|
|
this.padInventoryCount = 0,
|
|
this.lowInventoryThreshold = 5,
|
|
this.isAutoInventoryEnabled = true,
|
|
this.lastInventoryUpdate,
|
|
this.notifyPeriodEstimate = true,
|
|
this.notifyPeriodStart = true,
|
|
this.notifyLowSupply = true,
|
|
this.lastPadChangeTime,
|
|
this.padSupplies,
|
|
this.showPadTimerMinutes = true,
|
|
this.showPadTimerSeconds = false,
|
|
this.notifyPad1Hour = false,
|
|
this.notifyPad2Hours = false,
|
|
this.privacyPin,
|
|
this.isBioProtected = false,
|
|
this.isHistoryProtected = false,
|
|
this.notifyPad30Mins = false,
|
|
this.notifyPadNow = true,
|
|
this.isLogProtected = false,
|
|
this.isCalendarProtected = false,
|
|
this.isSuppliesProtected = false,
|
|
this.teachingPlans,
|
|
});
|
|
|
|
/// Check if user is married
|
|
bool get isMarried => relationshipStatus == RelationshipStatus.married;
|
|
|
|
/// Check if user is trying to conceive
|
|
bool get isTTC => fertilityGoal == FertilityGoal.tryingToConceive;
|
|
|
|
/// Check if user is practicing NFP
|
|
bool get isNFP => fertilityGoal == FertilityGoal.tryingToAvoid;
|
|
|
|
/// Check if user is husband
|
|
bool get isHusband => role == UserRole.husband;
|
|
|
|
/// Should show fertility content
|
|
bool get showFertilityContent =>
|
|
!isHusband &&
|
|
isMarried &&
|
|
fertilityGoal != FertilityGoal.justTracking &&
|
|
fertilityGoal != null;
|
|
|
|
/// Should show intimacy recommendations
|
|
bool get showIntimacyContent => isMarried;
|
|
|
|
/// Copy with updated fields
|
|
UserProfile copyWith({
|
|
String? id,
|
|
String? name,
|
|
RelationshipStatus? relationshipStatus,
|
|
FertilityGoal? fertilityGoal,
|
|
int? averageCycleLength,
|
|
int? averagePeriodLength,
|
|
DateTime? lastPeriodStartDate,
|
|
bool? notificationsEnabled,
|
|
bool? hasCompletedOnboarding,
|
|
DateTime? createdAt,
|
|
DateTime? updatedAt,
|
|
String? partnerName,
|
|
UserRole? role,
|
|
bool? isIrregularCycle,
|
|
int? minCycleLength,
|
|
int? maxCycleLength,
|
|
BibleTranslation? bibleTranslation,
|
|
List<String>? favoriteFoods,
|
|
bool? isDataShared,
|
|
AppThemeMode? themeMode,
|
|
String? accentColor,
|
|
bool? shareMoods,
|
|
bool? shareSymptoms,
|
|
bool? shareCravings,
|
|
bool? shareEnergyLevels,
|
|
bool? shareSleep,
|
|
bool? shareIntimacy,
|
|
bool? isPadTrackingEnabled,
|
|
int? typicalFlowIntensity,
|
|
String? padBrand,
|
|
int? padAbsorbency,
|
|
int? padInventoryCount,
|
|
int? lowInventoryThreshold,
|
|
bool? isAutoInventoryEnabled,
|
|
DateTime? lastInventoryUpdate,
|
|
bool? notifyPeriodEstimate,
|
|
bool? notifyPeriodStart,
|
|
bool? notifyLowSupply,
|
|
DateTime? lastPadChangeTime,
|
|
List<SupplyItem>? padSupplies,
|
|
bool? showPadTimerMinutes,
|
|
bool? showPadTimerSeconds,
|
|
bool? notifyPad1Hour,
|
|
bool? notifyPad2Hours,
|
|
String? privacyPin,
|
|
bool? isBioProtected,
|
|
bool? isHistoryProtected,
|
|
bool? notifyPad30Mins,
|
|
bool? notifyPadNow,
|
|
bool? isLogProtected,
|
|
bool? isCalendarProtected,
|
|
bool? isSuppliesProtected,
|
|
List<TeachingPlan>? teachingPlans,
|
|
}) {
|
|
return UserProfile(
|
|
id: id ?? this.id,
|
|
name: name ?? this.name,
|
|
relationshipStatus: relationshipStatus ?? this.relationshipStatus,
|
|
fertilityGoal: fertilityGoal ?? this.fertilityGoal,
|
|
averageCycleLength: averageCycleLength ?? this.averageCycleLength,
|
|
averagePeriodLength: averagePeriodLength ?? this.averagePeriodLength,
|
|
lastPeriodStartDate: lastPeriodStartDate ?? this.lastPeriodStartDate,
|
|
notificationsEnabled: notificationsEnabled ?? this.notificationsEnabled,
|
|
hasCompletedOnboarding:
|
|
hasCompletedOnboarding ?? this.hasCompletedOnboarding,
|
|
createdAt: createdAt ?? this.createdAt,
|
|
updatedAt: updatedAt ?? DateTime.now(),
|
|
partnerName: partnerName ?? this.partnerName,
|
|
role: role ?? this.role,
|
|
isIrregularCycle: isIrregularCycle ?? this.isIrregularCycle,
|
|
minCycleLength: minCycleLength ?? this.minCycleLength,
|
|
maxCycleLength: maxCycleLength ?? this.maxCycleLength,
|
|
bibleTranslation: bibleTranslation ?? this.bibleTranslation,
|
|
favoriteFoods: favoriteFoods ?? this.favoriteFoods,
|
|
isDataShared: isDataShared ?? this.isDataShared,
|
|
themeMode: themeMode ?? this.themeMode,
|
|
accentColor: accentColor ?? this.accentColor,
|
|
shareMoods: shareMoods ?? this.shareMoods,
|
|
shareSymptoms: shareSymptoms ?? this.shareSymptoms,
|
|
shareCravings: shareCravings ?? this.shareCravings,
|
|
shareEnergyLevels: shareEnergyLevels ?? this.shareEnergyLevels,
|
|
shareSleep: shareSleep ?? this.shareSleep,
|
|
shareIntimacy: shareIntimacy ?? this.shareIntimacy,
|
|
isPadTrackingEnabled: isPadTrackingEnabled ?? this.isPadTrackingEnabled,
|
|
typicalFlowIntensity: typicalFlowIntensity ?? this.typicalFlowIntensity,
|
|
padBrand: padBrand ?? this.padBrand,
|
|
padAbsorbency: padAbsorbency ?? this.padAbsorbency,
|
|
padInventoryCount: padInventoryCount ?? this.padInventoryCount,
|
|
lowInventoryThreshold: lowInventoryThreshold ?? this.lowInventoryThreshold,
|
|
isAutoInventoryEnabled: isAutoInventoryEnabled ?? this.isAutoInventoryEnabled,
|
|
lastInventoryUpdate: lastInventoryUpdate ?? this.lastInventoryUpdate,
|
|
notifyPeriodEstimate: notifyPeriodEstimate ?? this.notifyPeriodEstimate,
|
|
notifyPeriodStart: notifyPeriodStart ?? this.notifyPeriodStart,
|
|
notifyLowSupply: notifyLowSupply ?? this.notifyLowSupply,
|
|
lastPadChangeTime: lastPadChangeTime ?? this.lastPadChangeTime,
|
|
padSupplies: padSupplies ?? this.padSupplies,
|
|
showPadTimerMinutes: showPadTimerMinutes ?? this.showPadTimerMinutes,
|
|
showPadTimerSeconds: showPadTimerSeconds ?? this.showPadTimerSeconds,
|
|
notifyPad1Hour: notifyPad1Hour ?? this.notifyPad1Hour,
|
|
notifyPad2Hours: notifyPad2Hours ?? this.notifyPad2Hours,
|
|
privacyPin: privacyPin ?? this.privacyPin,
|
|
isBioProtected: isBioProtected ?? this.isBioProtected,
|
|
isHistoryProtected: isHistoryProtected ?? this.isHistoryProtected,
|
|
notifyPad30Mins: notifyPad30Mins ?? this.notifyPad30Mins,
|
|
notifyPadNow: notifyPadNow ?? this.notifyPadNow,
|
|
isLogProtected: isLogProtected ?? this.isLogProtected,
|
|
isCalendarProtected: isCalendarProtected ?? this.isCalendarProtected,
|
|
isSuppliesProtected: isSuppliesProtected ?? this.isSuppliesProtected,
|
|
teachingPlans: teachingPlans ?? this.teachingPlans,
|
|
);
|
|
}
|
|
}
|
|
|
|
extension BibleTranslationExtension on BibleTranslation {
|
|
String get label {
|
|
switch (this) {
|
|
case BibleTranslation.esv:
|
|
return 'ESV';
|
|
case BibleTranslation.niv:
|
|
return 'NIV';
|
|
case BibleTranslation.nkjv:
|
|
return 'NKJV';
|
|
case BibleTranslation.nlt:
|
|
return 'NLT';
|
|
case BibleTranslation.nasb:
|
|
return 'NASB';
|
|
case BibleTranslation.kjv:
|
|
return 'KJV';
|
|
case BibleTranslation.msg:
|
|
return 'MSG';
|
|
}
|
|
}
|
|
}
|
|
|
|
@HiveType(typeId: 8)
|
|
enum UserRole {
|
|
@HiveField(0)
|
|
wife,
|
|
@HiveField(1)
|
|
husband,
|
|
}
|