299 lines
7.9 KiB
Dart
299 lines
7.9 KiB
Dart
/* -------------------- RESPONSE -------------------- */
|
|
|
|
class AttractionsResponse {
|
|
final List<Attraction> attractions;
|
|
final List<Category> categories;
|
|
|
|
AttractionsResponse({
|
|
required this.attractions,
|
|
required this.categories,
|
|
});
|
|
|
|
factory AttractionsResponse.fromJson(Map<String, dynamic> json) {
|
|
return AttractionsResponse(
|
|
attractions: (json['attractions'] as List<dynamic>?)
|
|
?.map((e) => Attraction.fromJson(e))
|
|
.toList() ??
|
|
[],
|
|
categories: (json['categories'] as List<dynamic>?)
|
|
?.map((e) => Category.fromJson(e))
|
|
.toList() ??
|
|
[],
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'attractions': attractions.map((e) => e.toJson()).toList(),
|
|
'categories': categories.map((e) => e.toJson()).toList(),
|
|
};
|
|
}
|
|
}
|
|
|
|
/* -------------------- ATTRACTION -------------------- */
|
|
|
|
class Attraction {
|
|
final int id;
|
|
final String title;
|
|
final String description;
|
|
final String urlSlug;
|
|
final num cityXid;
|
|
final num cardTypeXid;
|
|
final num partnerXid;
|
|
final String productCode;
|
|
|
|
final bool isBookingRequired;
|
|
final bool isPartnerAccess;
|
|
final String bookingEmail;
|
|
final String bookingPhoneNumber;
|
|
|
|
final num latitudeCoordinate;
|
|
final num longitudeCoordinate;
|
|
final String address;
|
|
|
|
final num? ticketPriceAdult;
|
|
final num? ticketPriceChild;
|
|
final num durations;
|
|
final num groupSize;
|
|
final String ageRange;
|
|
|
|
final String seoTitle;
|
|
final String seoDescription;
|
|
final String attractionStatus;
|
|
final bool isActive;
|
|
|
|
final String createdAt;
|
|
final String updatedAt;
|
|
|
|
final List<CardModel> cards;
|
|
final List<Category> categories;
|
|
final List<Gallery> galleries;
|
|
|
|
Attraction({
|
|
required this.id,
|
|
required this.title,
|
|
required this.description,
|
|
required this.urlSlug,
|
|
required this.cityXid,
|
|
required this.cardTypeXid,
|
|
required this.partnerXid,
|
|
required this.productCode,
|
|
required this.isBookingRequired,
|
|
required this.isPartnerAccess,
|
|
required this.bookingEmail,
|
|
required this.bookingPhoneNumber,
|
|
required this.latitudeCoordinate,
|
|
required this.longitudeCoordinate,
|
|
required this.address,
|
|
this.ticketPriceAdult,
|
|
this.ticketPriceChild,
|
|
required this.durations,
|
|
required this.groupSize,
|
|
required this.ageRange,
|
|
required this.seoTitle,
|
|
required this.seoDescription,
|
|
required this.attractionStatus,
|
|
required this.isActive,
|
|
required this.createdAt,
|
|
required this.updatedAt,
|
|
required this.cards,
|
|
required this.categories,
|
|
required this.galleries,
|
|
});
|
|
|
|
factory Attraction.fromJson(Map<String, dynamic> json) {
|
|
return Attraction(
|
|
id: json['id'] ?? 0,
|
|
title: json['title'] ?? '',
|
|
description: json['description'] ?? '',
|
|
urlSlug: json['urlSlug'] ?? '',
|
|
cityXid: json['cityXid'] ?? 0,
|
|
cardTypeXid: json['cardTypeXid'] ?? 0,
|
|
partnerXid: json['partnerXid'] ?? 0,
|
|
productCode: json['productCode'] ?? '',
|
|
isBookingRequired: json['isBookingRequired'] ?? false,
|
|
isPartnerAccess: json['isPartnerAccess'] ?? false,
|
|
bookingEmail: json['bookingEmail'] ?? '',
|
|
bookingPhoneNumber: json['bookingPhonenumber'] ?? '',
|
|
latitudeCoordinate: (json['latitudeCoordinate'] as num?) ?? 0,
|
|
longitudeCoordinate: (json['longitudeCoordinate'] as num?) ?? 0,
|
|
address: json['address'] ?? '',
|
|
ticketPriceAdult: json['ticketPriceAdult'] as num?,
|
|
ticketPriceChild: json['ticketPriceChild'] as num?,
|
|
durations: json['durations'] ?? 0,
|
|
groupSize: json['groupSize'] ?? 0,
|
|
ageRange: json['ageRange'] ?? '',
|
|
seoTitle: json['seoTitle'] ?? '',
|
|
seoDescription: json['seoDescription'] ?? '',
|
|
attractionStatus: json['attractionStatus'] ?? '',
|
|
isActive: json['isActive'] ?? false,
|
|
createdAt: json['createdAt'] ?? '',
|
|
updatedAt: json['updatedAt'] ?? '',
|
|
cards: (json['cards'] as List<dynamic>?)
|
|
?.map((e) => CardModel.fromJson(e))
|
|
.toList() ??
|
|
[],
|
|
categories: (json['categories'] as List<dynamic>?)
|
|
?.map((e) => Category.fromJson(e))
|
|
.toList() ??
|
|
[],
|
|
galleries: (json['galleries'] as List<dynamic>?)
|
|
?.map((e) => Gallery.fromJson(e))
|
|
.toList() ??
|
|
[],
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'id': id,
|
|
'title': title,
|
|
'description': description,
|
|
'urlSlug': urlSlug,
|
|
'cityXid': cityXid,
|
|
'cardTypeXid': cardTypeXid,
|
|
'partnerXid': partnerXid,
|
|
'productCode': productCode,
|
|
'isBookingRequired': isBookingRequired,
|
|
'isPartnerAccess': isPartnerAccess,
|
|
'bookingEmail': bookingEmail,
|
|
'bookingPhonenumber': bookingPhoneNumber,
|
|
'latitudeCoordinate': latitudeCoordinate,
|
|
'longitudeCoordinate': longitudeCoordinate,
|
|
'address': address,
|
|
'ticketPriceAdult': ticketPriceAdult,
|
|
'ticketPriceChild': ticketPriceChild,
|
|
'durations': durations,
|
|
'groupSize': groupSize,
|
|
'ageRange': ageRange,
|
|
'seoTitle': seoTitle,
|
|
'seoDescription': seoDescription,
|
|
'attractionStatus': attractionStatus,
|
|
'isActive': isActive,
|
|
'createdAt': createdAt,
|
|
'updatedAt': updatedAt,
|
|
'cards': cards.map((e) => e.toJson()).toList(),
|
|
'categories': categories.map((e) => e.toJson()).toList(),
|
|
'galleries': galleries.map((e) => e.toJson()).toList(),
|
|
};
|
|
}
|
|
|
|
/// 🟢 Helper: Cover image URL (UI-safe)
|
|
String get coverImageUrl {
|
|
if (galleries.isEmpty) return '';
|
|
return galleries
|
|
.firstWhere(
|
|
(g) => g.isCoverImage,
|
|
orElse: () => galleries.first,
|
|
)
|
|
.filePathUrl;
|
|
}
|
|
}
|
|
|
|
/* -------------------- CARD -------------------- */
|
|
|
|
class CardModel {
|
|
final int id;
|
|
final String title;
|
|
final num cardTypeXid;
|
|
final num adultPrice;
|
|
final num childPrice;
|
|
final String cardStatus;
|
|
|
|
CardModel({
|
|
required this.id,
|
|
required this.title,
|
|
required this.cardTypeXid,
|
|
required this.adultPrice,
|
|
required this.childPrice,
|
|
required this.cardStatus,
|
|
});
|
|
|
|
factory CardModel.fromJson(Map<String, dynamic> json) {
|
|
return CardModel(
|
|
id: json['id'] ?? 0,
|
|
title: json['title'] ?? '',
|
|
cardTypeXid: json['cardTypeXid'] ?? 0,
|
|
adultPrice: json['adultPrice'] ?? 0,
|
|
childPrice: json['childPrice'] ?? 0,
|
|
cardStatus: json['cardStatus'] ?? '',
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'id': id,
|
|
'title': title,
|
|
'cardTypeXid': cardTypeXid,
|
|
'adultPrice': adultPrice,
|
|
'childPrice': childPrice,
|
|
'cardStatus': cardStatus,
|
|
};
|
|
}
|
|
}
|
|
|
|
/* -------------------- GALLERY -------------------- */
|
|
|
|
class Gallery {
|
|
final int id;
|
|
final String fileType;
|
|
final String filePathUrl;
|
|
final String altText;
|
|
final bool isCoverImage;
|
|
|
|
Gallery({
|
|
required this.id,
|
|
required this.fileType,
|
|
required this.filePathUrl,
|
|
required this.altText,
|
|
required this.isCoverImage,
|
|
});
|
|
|
|
factory Gallery.fromJson(Map<String, dynamic> json) {
|
|
return Gallery(
|
|
id: json['id'] ?? 0,
|
|
fileType: json['fileType'] ?? '',
|
|
filePathUrl: json['filePathUrl'] ?? '',
|
|
altText: json['altText'] ?? '',
|
|
isCoverImage: json['isCoverImage'] ?? false,
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'id': id,
|
|
'fileType': fileType,
|
|
'filePathUrl': filePathUrl,
|
|
'altText': altText,
|
|
'isCoverImage': isCoverImage,
|
|
};
|
|
}
|
|
|
|
bool get hasImage => filePathUrl.isNotEmpty;
|
|
}
|
|
|
|
/* -------------------- CATEGORY -------------------- */
|
|
|
|
class Category {
|
|
final int id;
|
|
final String categoryName;
|
|
|
|
Category({
|
|
required this.id,
|
|
required this.categoryName,
|
|
});
|
|
|
|
factory Category.fromJson(Map<String, dynamic> json) {
|
|
return Category(
|
|
id: json['id'] ?? 0,
|
|
categoryName: json['categoryName'] ?? '',
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'id': id,
|
|
'categoryName': categoryName,
|
|
};
|
|
}
|
|
} |