using System.Text; using MeetTheTeacher.Export; using MeetTheTeacher.Import; using MeetTheTeacher.Model; using Spectre.Console; Console.OutputEncoding = Encoding.UTF8; Clear(); AnsiConsole.Markup("[orange3]Press any key to load HTL-Leonding teacher data[/] "); Console.ReadKey(); // data loading bool loadRealData = AskForDataToUse(); // wrapping IEnumerable in List, because we will iterate multiple times var data = new List(LoadData(loadRealData)); var tableGenerator = new SpectreTableExporter(); tableGenerator.Export(data, string.Empty); // fake loading Clear(); await DisplayFakeProgress(); Clear(); AnsiConsole.Write(tableGenerator.Table); PrintStatistics(data); // user input WriteRule("Sort Order"); var order = AskForSortOrder(); WriteRule("Export Format"); var format = AskForExportFormat(); WriteRule("File Name"); string fileName = AnsiConsole.Ask("Which [blue]file name[/] should be used?"); // export var exporter = new Exporter(order, format, new DefaultExporterProvider()); exporter.Export(fileName, data); // done WriteRule(string.Empty); AnsiConsole.Write(new FigletText("All Done!").Centered().Color(Color.Green)); DrawDog(); return; static void Clear() { Console.Clear(); AnsiConsole.Write(new FigletText("Teacher Data").Centered().Color(Color.Blue)); } static void WriteRule(string text) { AnsiConsole.Write(new Rule($"[blue]{text}[/]").LeftJustified()); } static IEnumerable LoadData(bool realData) { string generalDataFilePath = "Data/teachers.csv"; string businessCardDataFilePath = "Data/teachers-with-business-card.csv"; if (!File.Exists(generalDataFilePath)) { AnsiConsole.MarkupLine($"[red]Error:[/] File '{generalDataFilePath}' not found"); return []; } ITeacherDataImporter importer = realData ? new TeacherDataCsvImporter(generalDataFilePath, businessCardDataFilePath) : new TeacherDataFakeImporter(); return importer.LoadTeacherData(); } static Task DisplayFakeProgress() { const double Increase = 4.5; const double ReducedIncrease = Increase * 0.8D; return AnsiConsole.Progress() .StartAsync(async ctx => { // we are actually already done, but want to fake some complex operation // to have the user appreciate the hard work our application is doing :) var task1 = ctx.AddTask("[green]Loading Data[/]"); var task2 = ctx.AddTask("[green]Processing Data[/]"); while (!ctx.IsFinished) { task1.Increment(Increase); task2.Increment(ReducedIncrease); await Task.Delay(TimeSpan.FromMilliseconds(125)); } }); } static void PrintStatistics(IReadOnlyCollection teachers) { var hasConsultingHours = 0; var hasBusinessCard = 0; foreach (var teacher in teachers) { if (teacher.ConsultingHour != null) { hasConsultingHours++; } if (teacher is TeacherWithBusinessCard) { hasBusinessCard++; } } double total = teachers.Count; var cPercentage = (int) (hasConsultingHours / total * 100); int ncPercentage = 100 - cPercentage; var bPercentage = (int) (hasBusinessCard / total * 100); AnsiConsole.Write(new BarChart() .Width(60) .Label($"[blue underline]Statistics ({total:F0} teachers)[/]") .CenterLabel() .AddItem("Has consulting hour", cPercentage, Color.Green) .AddItem("Has no consulting hour", ncPercentage, Color.Red) .AddItem("Has business card", bPercentage, Color.Purple)); } static SortOrder AskForSortOrder() { var options = new Dictionary { ["Name Asc."] = SortOrder.ByNameAsc, ["Name Desc."] = SortOrder.ByNameDesc, ["Hour Asc."] = SortOrder.ByHourAsc, ["Hour Desc."] = SortOrder.ByHourDesc, ["Room"] = SortOrder.Room }; string order = AnsiConsole.Prompt(new SelectionPrompt() .Title("How do you wish to [blue]sort[/] the data?") .PageSize(3) .MoreChoicesText("[grey](Move up and down to reveal more options)[/]") .AddChoices(options.Keys)); AnsiConsole.MarkupLine($"Selected: [green]{order}[/]"); return options[order]; } static ExportFormat AskForExportFormat() { const string Csv = "Csv"; const string Html = "Html"; string dataToUse = AnsiConsole.Prompt(new SelectionPrompt() .Title("Do you want to load [blue]real[/] or [blue]sample[/] data?") .AddChoices(Csv, Html)); AnsiConsole.MarkupLine($"Selected: [green]{dataToUse}[/]"); return dataToUse == Csv ? ExportFormat.Csv : ExportFormat.Html; } static bool AskForDataToUse() { const string Real = "Real"; string dataToUse = AnsiConsole.Prompt(new SelectionPrompt() .Title("Do you want to load [blue]real[/] or [blue]sample[/] data?") .AddChoices(Real, "Sample")); AnsiConsole.MarkupLine($"Selected: [green]{dataToUse}[/]"); return dataToUse == Real; } static void DrawDog() { var image = new CanvasImage("happy-dog.png"); image.MaxWidth(36); AnsiConsole.Write(image); }