2026-01-13 00:07:59 +09:00
|
|
|
/// 일정 모델
|
|
|
|
|
library;
|
|
|
|
|
|
2026-01-15 21:27:24 +09:00
|
|
|
/// 멤버 정보
|
|
|
|
|
class ScheduleMember {
|
|
|
|
|
final int id;
|
|
|
|
|
final String name;
|
|
|
|
|
|
|
|
|
|
ScheduleMember({required this.id, required this.name});
|
|
|
|
|
|
|
|
|
|
factory ScheduleMember.fromJson(Map<String, dynamic> json) {
|
|
|
|
|
return ScheduleMember(
|
|
|
|
|
id: json['id'] as int,
|
|
|
|
|
name: json['name'] as String,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 관련 일정 (콘서트 회차 등)
|
|
|
|
|
class RelatedDate {
|
|
|
|
|
final int id;
|
|
|
|
|
final String date;
|
|
|
|
|
final String? time;
|
|
|
|
|
|
|
|
|
|
RelatedDate({required this.id, required this.date, this.time});
|
|
|
|
|
|
|
|
|
|
factory RelatedDate.fromJson(Map<String, dynamic> json) {
|
|
|
|
|
return RelatedDate(
|
|
|
|
|
id: json['id'] as int,
|
|
|
|
|
date: json['date'] as String,
|
|
|
|
|
time: json['time'] as String?,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 일정 상세 모델
|
|
|
|
|
class ScheduleDetail {
|
|
|
|
|
final int id;
|
|
|
|
|
final String title;
|
|
|
|
|
final String date;
|
|
|
|
|
final String? time;
|
|
|
|
|
final String? description;
|
|
|
|
|
final int categoryId;
|
|
|
|
|
final String? categoryName;
|
|
|
|
|
final String? categoryColor;
|
|
|
|
|
final String? sourceUrl;
|
|
|
|
|
final String? sourceName;
|
|
|
|
|
final String? imageUrl;
|
|
|
|
|
final List<String> images;
|
|
|
|
|
final String? locationName;
|
|
|
|
|
final String? locationAddress;
|
|
|
|
|
final String? locationLat;
|
|
|
|
|
final String? locationLng;
|
|
|
|
|
final List<ScheduleMember> members;
|
|
|
|
|
final List<RelatedDate> relatedDates;
|
|
|
|
|
|
|
|
|
|
ScheduleDetail({
|
|
|
|
|
required this.id,
|
|
|
|
|
required this.title,
|
|
|
|
|
required this.date,
|
|
|
|
|
this.time,
|
|
|
|
|
this.description,
|
|
|
|
|
required this.categoryId,
|
|
|
|
|
this.categoryName,
|
|
|
|
|
this.categoryColor,
|
|
|
|
|
this.sourceUrl,
|
|
|
|
|
this.sourceName,
|
|
|
|
|
this.imageUrl,
|
|
|
|
|
this.images = const [],
|
|
|
|
|
this.locationName,
|
|
|
|
|
this.locationAddress,
|
|
|
|
|
this.locationLat,
|
|
|
|
|
this.locationLng,
|
|
|
|
|
this.members = const [],
|
|
|
|
|
this.relatedDates = const [],
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
factory ScheduleDetail.fromJson(Map<String, dynamic> json) {
|
|
|
|
|
return ScheduleDetail(
|
|
|
|
|
id: json['id'] as int,
|
|
|
|
|
title: json['title'] as String,
|
|
|
|
|
date: json['date'] as String,
|
|
|
|
|
time: json['time'] as String?,
|
|
|
|
|
description: json['description'] as String?,
|
|
|
|
|
categoryId: json['category_id'] as int,
|
|
|
|
|
categoryName: json['category_name'] as String?,
|
|
|
|
|
categoryColor: json['category_color'] as String?,
|
|
|
|
|
sourceUrl: json['source_url'] as String?,
|
|
|
|
|
sourceName: json['source_name'] as String?,
|
|
|
|
|
imageUrl: json['image_url'] as String?,
|
|
|
|
|
images: (json['images'] as List<dynamic>?)?.cast<String>() ?? [],
|
|
|
|
|
locationName: json['location_name'] as String?,
|
|
|
|
|
locationAddress: json['location_address'] as String?,
|
|
|
|
|
locationLat: json['location_lat'] as String?,
|
|
|
|
|
locationLng: json['location_lng'] as String?,
|
|
|
|
|
members: (json['members'] as List<dynamic>?)
|
|
|
|
|
?.map((m) => ScheduleMember.fromJson(m))
|
|
|
|
|
.toList() ??
|
|
|
|
|
[],
|
|
|
|
|
relatedDates: (json['related_dates'] as List<dynamic>?)
|
|
|
|
|
?.map((r) => RelatedDate.fromJson(r))
|
|
|
|
|
.toList() ??
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 시간 포맷 (HH:mm)
|
|
|
|
|
String? get formattedTime {
|
|
|
|
|
if (time == null) return null;
|
|
|
|
|
return time!.length >= 5 ? time!.substring(0, 5) : time;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-13 00:07:59 +09:00
|
|
|
class Schedule {
|
|
|
|
|
final int id;
|
|
|
|
|
final String title;
|
|
|
|
|
final String date;
|
|
|
|
|
final String? time;
|
|
|
|
|
final String? endDate;
|
|
|
|
|
final String? endTime;
|
|
|
|
|
final String? description;
|
|
|
|
|
final String? categoryName;
|
|
|
|
|
final String? categoryColor;
|
|
|
|
|
final String? memberNames;
|
|
|
|
|
final String? sourceUrl;
|
|
|
|
|
final String? sourceName;
|
|
|
|
|
|
|
|
|
|
Schedule({
|
|
|
|
|
required this.id,
|
|
|
|
|
required this.title,
|
|
|
|
|
required this.date,
|
|
|
|
|
this.time,
|
|
|
|
|
this.endDate,
|
|
|
|
|
this.endTime,
|
|
|
|
|
this.description,
|
|
|
|
|
this.categoryName,
|
|
|
|
|
this.categoryColor,
|
|
|
|
|
this.memberNames,
|
|
|
|
|
this.sourceUrl,
|
|
|
|
|
this.sourceName,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
factory Schedule.fromJson(Map<String, dynamic> json) {
|
|
|
|
|
return Schedule(
|
|
|
|
|
id: json['id'] as int,
|
|
|
|
|
title: json['title'] as String,
|
|
|
|
|
date: json['date'] as String,
|
|
|
|
|
time: json['time'] as String?,
|
|
|
|
|
endDate: json['end_date'] as String?,
|
|
|
|
|
endTime: json['end_time'] as String?,
|
|
|
|
|
description: json['description'] as String?,
|
|
|
|
|
categoryName: json['category_name'] as String?,
|
|
|
|
|
categoryColor: json['category_color'] as String?,
|
|
|
|
|
memberNames: json['member_names'] as String?,
|
|
|
|
|
sourceUrl: json['source_url'] as String?,
|
|
|
|
|
sourceName: json['source_name'] as String?,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 멤버 리스트 반환
|
|
|
|
|
List<String> get memberList {
|
|
|
|
|
if (memberNames == null || memberNames!.isEmpty) return [];
|
|
|
|
|
return memberNames!.split(',').map((n) => n.trim()).where((n) => n.isNotEmpty).toList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 시간 포맷 (HH:mm)
|
|
|
|
|
String? get formattedTime {
|
|
|
|
|
if (time == null) return null;
|
|
|
|
|
return time!.length >= 5 ? time!.substring(0, 5) : time;
|
|
|
|
|
}
|
|
|
|
|
}
|