import 'package:dartboard_resume/models/dartboard_misc.dart'; import 'package:dartboard_resume/models/date_range.dart'; import 'package:dartboard_resume/models/document_text.dart'; import 'package:dartboard_resume/models/experience.dart'; import 'package:dartboard_resume/models/theme.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart'; import 'package:toml/toml.dart'; class DartboardData { DartboardData({ required this.fullName, required this.phoneNumber, required this.email, // required this.address, required this.imagePath, required this.dartboardTheme, required this.experiences, required this.miscList, }); factory DartboardData.fromToml(String tomlFilePath) { final tomlData = TomlDocument.loadSync(tomlFilePath).toMap(); final List exps = tomlData.entries .where((e) => Experience.filter(e.value)) .map((MapEntry expsEntry) { final String subsection = tomlData['${expsEntry.key}_name'] as String? ?? _getSubsectionFromKey(expsEntry.key); final exps = (expsEntry.value as List).map((e) => e as Map).toList(); return exps.map((exp) { final TomlLocalDate? start = exp['start'] as TomlLocalDate?; final TomlLocalDate? end = exp['end'] as TomlLocalDate?; return Experience( title: exp['title'] as String, subsection: subsection, range: DateRange( start: start == null ? null : DateTime(start.date.year, start.date.month), end: end == null ? null : DateTime(end.date.year, end.date.month), ), attributes: (exp['attributes'] as List) .where((e) => e is String && e.isNotEmpty) .map((e) => DocumentText(content: e as String)) .toList(), location: exp['location'] as String?, ); }).toList(); }) .expand((i) => i) .toList(); final List misc = tomlData.entries.where((e) => DartboardMisc.filter(e.value)).map((MapEntry listEntry) { final String subsection = tomlData['${listEntry.key}_name'] as String? ?? _getSubsectionFromKey(listEntry.key); return DartboardMisc( subsection: subsection, attributes: (listEntry.value as List) .map((e) => (e as Map)['attributes'] as List) .expand((i) => i) .where((e) => e is String && e.isNotEmpty) .map((e) => DocumentText(content: e as String)) .toList(), ); }).toList(); return DartboardData( fullName: tomlData['full_name'] as String, phoneNumber: tomlData['phone_number'] as String?, email: tomlData['email'] as String?, imagePath: tomlData['image'] as String?, dartboardTheme: DocumentTheme.fromToml(tomlData), experiences: exps, miscList: misc, ); } final String fullName; final String? phoneNumber; final String? email; final String? imagePath; final DocumentTheme dartboardTheme; final List experiences; final List miscList; Font get font => dartboardTheme.font; PdfColor get primaryColor => dartboardTheme.primaryColor; PdfColor get accentColor => dartboardTheme.accentColor; PdfColor get backgroundColor => dartboardTheme.backgroundColor; TextStyle get headerTextStyle => TextStyle(fontSize: 18, font: font, fontWeight: FontWeight.bold, color: const PdfColorGrey(0.18)); TextStyle get subheaderTextStyle => TextStyle(fontSize: 14, font: font, color: const PdfColorGrey(0.3)); TextStyle get defaultTextStyle => TextStyle(fontSize: 10, font: font, color: const PdfColorGrey(0.45)); Map> get groupedExperiences { final Map> exps = {}; for (final Experience exp in experiences) { if (!exps.containsKey(exp.subsection)) { exps[exp.subsection] = []; } exps[exp.subsection]!.add(exp); } return exps; } Map> get groupedMisc { final Map> miscs = {}; for (final DartboardMisc misc in miscList) { if (!miscs.containsKey(misc.subsection)) { miscs[misc.subsection] = []; } miscs[misc.subsection]!.add(misc); } return miscs; } @override int get hashCode { return Object.hashAll([fullName, phoneNumber, email, imagePath, dartboardTheme, ...experiences, ...miscList]); } @override bool operator ==(Object other) { return super.hashCode == other.hashCode; } } String _getSubsectionFromKey(String key) { switch (key) { case 'exp': return 'Experience'; case 'misc': return 'Miscelaneous'; case 'edu': return 'Education'; case '': default: return ''; } }