/opt/canhelp/apps/mobile/lib/models
NameSizeModeActions
app_notification.dart24230644editdlrm
availability.dart7590644editdlrm
category.dart12940644editdlrm
chat_room.dart57590644editdlrm
dashboard_data.dart40160644editdlrm
location.dart14310644editdlrm
offer.dart26480644editdlrm
portfolio_item.dart9470644editdlrm
price_list.dart39330644editdlrm
review.dart15750644editdlrm
specialist_card.dart52650644editdlrm
task.dart62600644editdlrm
user.dart64170644editdlrm
Edit: /opt/canhelp/apps/mobile/lib/models/user.dart (6417B)
double? _toDouble(dynamic v) { if (v == null) return null; if (v is num) return v.toDouble(); return double.tryParse(v.toString()); } int? _toInt(dynamic v) { if (v == null) return null; if (v is int) return v; if (v is num) return v.toInt(); return int.tryParse(v.toString()); } class User { final String id; final String email; final String firstName; final String lastName; final String fullName; final String role; final bool isHelperReady; final bool hasOffers; final String? phone; final String? bio; final String? avatar; final List? skills; final String locale; final bool isActive; final bool isOnline; final double balance; final double rating; final int reviewCount; final String? planId; final String planTier; final bool notifMessages; final bool notifyNewTasks; final bool emailVerified; final List languages; final DateTime createdAt; // Extended profile fields (from /users/:id/profile) final bool hasVerifiedBadge; final List activeStatuses; final List? specialistCategories; final List? specialistLocations; final String? personalSiteSlug; final String? todayStatus; final List> cards; final Map? siteSettings; User({ required this.id, required this.email, required this.firstName, required this.lastName, required this.fullName, required this.role, this.isHelperReady = false, this.hasOffers = false, this.phone, this.bio, this.avatar, this.skills, this.locale = 'el', this.isActive = true, this.isOnline = false, this.balance = 0.0, this.rating = 0.0, this.reviewCount = 0, this.planId, this.planTier = 'free', this.notifMessages = true, this.notifyNewTasks = false, this.emailVerified = false, this.languages = const [], required this.createdAt, this.hasVerifiedBadge = false, this.activeStatuses = const [], this.specialistCategories, this.specialistLocations, this.personalSiteSlug, this.todayStatus, this.cards = const [], this.siteSettings, }); String? get profileBackgroundImage { final value = siteSettings?['profileBackgroundImage']; if (value is String && value.trim().isNotEmpty) { return value; } return null; } bool get isSpecialist => isHelperReady || role == 'specialist' || role == 'helper'; bool get isCustomer => role == 'user' || role == 'customer' || role == 'requester'; bool get isAdmin => role == 'admin'; factory User.fromJson(Map json) { return User( id: json['id'] as String? ?? json['_id'] as String, email: json['email'] as String? ?? '', firstName: json['firstName'] as String? ?? '', lastName: json['lastName'] as String? ?? '', fullName: json['fullName'] as String? ?? '${json['firstName'] ?? ''} ${json['lastName'] ?? ''}'.trim(), role: json['role'] as String? ?? 'user', isHelperReady: json['isHelperReady'] as bool? ?? ((json['legacyMarketRole'] as String?) == 'specialist'), hasOffers: json['hasOffers'] as bool? ?? false, phone: json['phone'] as String?, bio: json['bio'] as String?, // Better Auth uses 'image'; old API used 'avatar' avatar: json['image'] as String? ?? json['avatar'] as String?, skills: (json['skills'] as List?) ?.map((e) => e as String) .toList(), locale: json['locale'] as String? ?? 'el', isActive: json['isActive'] as bool? ?? true, isOnline: json['isOnline'] as bool? ?? false, balance: _toDouble(json['balance']) ?? 0.0, rating: _toDouble(json['rating']) ?? 0.0, reviewCount: _toInt(json['reviewCount']) ?? 0, planId: json['planId'] as String?, planTier: json['planTier'] as String? ?? 'free', notifMessages: json['notifMessages'] as bool? ?? true, notifyNewTasks: json['notifyNewTasks'] as bool? ?? false, emailVerified: json['emailVerified'] as bool? ?? false, languages: (json['languages'] as List?) ?.map((e) => e as String) .toList() ?? const [], createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt'] as String) : DateTime.now(), hasVerifiedBadge: json['hasVerifiedBadge'] as bool? ?? false, activeStatuses: (json['activeStatuses'] as List?) ?.map((e) => e as String) .toList() ?? const [], specialistCategories: (json['specialistCategories'] as List?) ?.map((e) => e as String) .toList(), specialistLocations: (json['specialistLocations'] as List?) ?.map((e) => e as String) .toList(), personalSiteSlug: json['personalSiteSlug'] as String?, todayStatus: json['todayStatus'] as String?, cards: (json['cards'] as List?) ?.map((e) => Map.from(e as Map)) .toList() ?? const [], siteSettings: json['siteSettings'] is Map ? Map.from(json['siteSettings'] as Map) : null, ); } Map toJson() { return { 'id': id, 'email': email, 'firstName': firstName, 'lastName': lastName, 'fullName': fullName, 'role': role, 'isHelperReady': isHelperReady, 'hasOffers': hasOffers, 'phone': phone, 'bio': bio, 'image': avatar, 'skills': skills, 'locale': locale, 'isActive': isActive, 'isOnline': isOnline, 'balance': balance, 'rating': rating, 'reviewCount': reviewCount, 'planId': planId, 'planTier': planTier, 'notifMessages': notifMessages, 'notifyNewTasks': notifyNewTasks, 'emailVerified': emailVerified, 'languages': languages, 'createdAt': createdAt.toIso8601String(), 'hasVerifiedBadge': hasVerifiedBadge, 'activeStatuses': activeStatuses, 'specialistCategories': specialistCategories, 'specialistLocations': specialistLocations, 'personalSiteSlug': personalSiteSlug, 'todayStatus': todayStatus, 'cards': cards, 'siteSettings': siteSettings, }; } }