diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana.slnx b/DrinksInfo.Ledana/DrinksInfo.Ledana.slnx new file mode 100644 index 00000000..4f32197c --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana.slnx @@ -0,0 +1,3 @@ + + + diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Controllers/FavouriteDrinkController.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Controllers/FavouriteDrinkController.cs new file mode 100644 index 00000000..f10db243 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Controllers/FavouriteDrinkController.cs @@ -0,0 +1,79 @@ +using DrinksInfo.Ledana.Data; +using DrinksInfo.Ledana.Models; + +namespace DrinksInfo.Ledana.Controllers +{ + internal class FavouriteDrinkController + { + internal static void AddDrinkToFavourites(DrinkDetail favouriteDrink) + { + try + { + using var context = new FavouritesDrinkContext(); + context.FavouriteDrinks.Add(favouriteDrink); + context.SaveChanges(); + } + catch(Exception e) + { + Console.WriteLine("Something went wrong! " + e.Message); + } + } + + internal static async Task DeleteAllFavourites() + { + try + { + using var context = new FavouritesDrinkContext(); + context.FavouriteDrinks.RemoveRange(context.FavouriteDrinks); + await context.SaveChangesAsync(); + } + catch (Exception e) + { + Console.WriteLine("Something went wrong! " + e.Message); + } + } + + internal static void DeleteFavourite(string? drink) + { + try + { + using var context = new FavouritesDrinkContext(); + var drinkToDelete = context.FavouriteDrinks.Where(d => d.idDrink == drink).First(); + context.FavouriteDrinks.Remove(drinkToDelete); + context.SaveChanges(); + } + catch(Exception e) + { + Console.WriteLine("Something went wrong! " + e.Message); + } +} + + internal static List GetFavouriteDrinks() + { + try + { + using var context = new FavouritesDrinkContext(); + return context.FavouriteDrinks.ToList(); + } + catch (Exception e) + { + Console.WriteLine("Something went wrong! " + e.Message); + return null; + } + } + + internal static bool HasDrink(string? drink) + { + try + { + using var context = new FavouritesDrinkContext(); + return context.FavouriteDrinks.Any(d => d.idDrink == drink); + } + catch (Exception e) + { + Console.WriteLine("Something went wrong! " + e.Message); + return false; + } + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Data/FavouritesDrinkContext.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Data/FavouritesDrinkContext.cs new file mode 100644 index 00000000..fda1c50d --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Data/FavouritesDrinkContext.cs @@ -0,0 +1,23 @@ +using DrinksInfo.Ledana.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; + +namespace DrinksInfo.Ledana.Data +{ + internal class FavouritesDrinkContext : DbContext + { + public DbSet FavouriteDrinks { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appSettings.json", optional: false, reloadOnChange: true) + .Build(); + + var connectionString = config.GetConnectionString("FavouriteDrinksDb"); + + optionsBuilder.UseSqlServer(connectionString); + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/DrinksInfo.Ledana.csproj b/DrinksInfo.Ledana/DrinksInfo.Ledana/DrinksInfo.Ledana.csproj new file mode 100644 index 00000000..0b3e9718 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/DrinksInfo.Ledana.csproj @@ -0,0 +1,35 @@ + + + + Exe + net10.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + PreserveNewest + + + + diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506070842_InitialCreate.Designer.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506070842_InitialCreate.Designer.cs new file mode 100644 index 00000000..d5909805 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506070842_InitialCreate.Designer.cs @@ -0,0 +1,189 @@ +// +using DrinksInfo.Ledana.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DrinksInfo.Ledana.Migrations +{ + [DbContext(typeof(FavouritesDrinkContext))] + [Migration("20260506070842_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DrinksInfo.Ledana.Models.DrinkDetail", b => + { + b.Property("idDrink") + .HasColumnType("nvarchar(450)"); + + b.Property("dateModified") + .HasColumnType("nvarchar(max)"); + + b.Property("strAlcoholic") + .HasColumnType("nvarchar(max)"); + + b.Property("strCategory") + .HasColumnType("nvarchar(max)"); + + b.Property("strCreativeCommonsConfirmed") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrink") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrinkAlternate") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrinkThumb") + .HasColumnType("nvarchar(max)"); + + b.Property("strGlass") + .HasColumnType("nvarchar(max)"); + + b.Property("strIBA") + .HasColumnType("nvarchar(max)"); + + b.Property("strImageAttribution") + .HasColumnType("nvarchar(max)"); + + b.Property("strImageSource") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient1") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient10") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient11") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient12") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient13") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient14") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient15") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient2") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient3") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient4") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient5") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient6") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient7") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient8") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient9") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructions") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsDE") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsES") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsFR") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsIT") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsZHHANS") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsZHHANT") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure1") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure10") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure11") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure12") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure13") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure14") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure15") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure2") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure3") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure4") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure5") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure6") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure7") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure8") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure9") + .HasColumnType("nvarchar(max)"); + + b.Property("strTags") + .HasColumnType("nvarchar(max)"); + + b.Property("strVideo") + .HasColumnType("nvarchar(max)"); + + b.HasKey("idDrink"); + + b.ToTable("FavouriteDrinks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506070842_InitialCreate.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506070842_InitialCreate.cs new file mode 100644 index 00000000..c1f96f57 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506070842_InitialCreate.cs @@ -0,0 +1,82 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DrinksInfo.Ledana.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "FavouriteDrinks", + columns: table => new + { + idDrink = table.Column(type: "nvarchar(450)", nullable: false), + strDrink = table.Column(type: "nvarchar(max)", nullable: true), + strDrinkAlternate = table.Column(type: "nvarchar(max)", nullable: true), + strTags = table.Column(type: "nvarchar(max)", nullable: true), + strVideo = table.Column(type: "nvarchar(max)", nullable: true), + strCategory = table.Column(type: "nvarchar(max)", nullable: true), + strIBA = table.Column(type: "nvarchar(max)", nullable: true), + strAlcoholic = table.Column(type: "nvarchar(max)", nullable: true), + strGlass = table.Column(type: "nvarchar(max)", nullable: true), + strInstructions = table.Column(type: "nvarchar(max)", nullable: true), + strInstructionsES = table.Column(type: "nvarchar(max)", nullable: true), + strInstructionsDE = table.Column(type: "nvarchar(max)", nullable: true), + strInstructionsFR = table.Column(type: "nvarchar(max)", nullable: true), + strInstructionsIT = table.Column(type: "nvarchar(max)", nullable: true), + strInstructionsZHHANS = table.Column(type: "nvarchar(max)", nullable: true), + strInstructionsZHHANT = table.Column(type: "nvarchar(max)", nullable: true), + strDrinkThumb = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient1 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient2 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient3 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient4 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient5 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient6 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient7 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient8 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient9 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient10 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient11 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient12 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient13 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient14 = table.Column(type: "nvarchar(max)", nullable: true), + strIngredient15 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure1 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure2 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure3 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure4 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure5 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure6 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure7 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure8 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure9 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure10 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure11 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure12 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure13 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure14 = table.Column(type: "nvarchar(max)", nullable: true), + strMeasure15 = table.Column(type: "nvarchar(max)", nullable: true), + strImageSource = table.Column(type: "nvarchar(max)", nullable: true), + strImageAttribution = table.Column(type: "nvarchar(max)", nullable: true), + strCreativeCommonsConfirmed = table.Column(type: "nvarchar(max)", nullable: true), + dateModified = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_FavouriteDrinks", x => x.idDrink); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "FavouriteDrinks"); + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085503_AddViewCount.Designer.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085503_AddViewCount.Designer.cs new file mode 100644 index 00000000..5b84ad88 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085503_AddViewCount.Designer.cs @@ -0,0 +1,192 @@ +// +using DrinksInfo.Ledana.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DrinksInfo.Ledana.Migrations +{ + [DbContext(typeof(FavouritesDrinkContext))] + [Migration("20260506085503_AddViewCount")] + partial class AddViewCount + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DrinksInfo.Ledana.Models.DrinkDetail", b => + { + b.Property("idDrink") + .HasColumnType("nvarchar(450)"); + + b.Property("dateModified") + .HasColumnType("nvarchar(max)"); + + b.Property("strAlcoholic") + .HasColumnType("nvarchar(max)"); + + b.Property("strCategory") + .HasColumnType("nvarchar(max)"); + + b.Property("strCreativeCommonsConfirmed") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrink") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrinkAlternate") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrinkThumb") + .HasColumnType("nvarchar(max)"); + + b.Property("strGlass") + .HasColumnType("nvarchar(max)"); + + b.Property("strIBA") + .HasColumnType("nvarchar(max)"); + + b.Property("strImageAttribution") + .HasColumnType("nvarchar(max)"); + + b.Property("strImageSource") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient1") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient10") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient11") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient12") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient13") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient14") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient15") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient2") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient3") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient4") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient5") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient6") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient7") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient8") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient9") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructions") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsDE") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsES") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsFR") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsIT") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsZHHANS") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsZHHANT") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure1") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure10") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure11") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure12") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure13") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure14") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure15") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure2") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure3") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure4") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure5") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure6") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure7") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure8") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure9") + .HasColumnType("nvarchar(max)"); + + b.Property("strTags") + .HasColumnType("nvarchar(max)"); + + b.Property("strVideo") + .HasColumnType("nvarchar(max)"); + + b.Property("viewCount") + .HasColumnType("int"); + + b.HasKey("idDrink"); + + b.ToTable("FavouriteDrinks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085503_AddViewCount.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085503_AddViewCount.cs new file mode 100644 index 00000000..3acbeb55 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085503_AddViewCount.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DrinksInfo.Ledana.Migrations +{ + /// + public partial class AddViewCount : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "viewCount", + table: "FavouriteDrinks", + type: "int", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "viewCount", + table: "FavouriteDrinks"); + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085721_RemovedDeafaultValue.Designer.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085721_RemovedDeafaultValue.Designer.cs new file mode 100644 index 00000000..a24823e4 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085721_RemovedDeafaultValue.Designer.cs @@ -0,0 +1,192 @@ +// +using DrinksInfo.Ledana.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DrinksInfo.Ledana.Migrations +{ + [DbContext(typeof(FavouritesDrinkContext))] + [Migration("20260506085721_RemovedDeafaultValue")] + partial class RemovedDeafaultValue + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DrinksInfo.Ledana.Models.DrinkDetail", b => + { + b.Property("idDrink") + .HasColumnType("nvarchar(450)"); + + b.Property("dateModified") + .HasColumnType("nvarchar(max)"); + + b.Property("strAlcoholic") + .HasColumnType("nvarchar(max)"); + + b.Property("strCategory") + .HasColumnType("nvarchar(max)"); + + b.Property("strCreativeCommonsConfirmed") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrink") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrinkAlternate") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrinkThumb") + .HasColumnType("nvarchar(max)"); + + b.Property("strGlass") + .HasColumnType("nvarchar(max)"); + + b.Property("strIBA") + .HasColumnType("nvarchar(max)"); + + b.Property("strImageAttribution") + .HasColumnType("nvarchar(max)"); + + b.Property("strImageSource") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient1") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient10") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient11") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient12") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient13") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient14") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient15") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient2") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient3") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient4") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient5") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient6") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient7") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient8") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient9") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructions") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsDE") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsES") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsFR") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsIT") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsZHHANS") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsZHHANT") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure1") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure10") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure11") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure12") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure13") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure14") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure15") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure2") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure3") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure4") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure5") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure6") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure7") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure8") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure9") + .HasColumnType("nvarchar(max)"); + + b.Property("strTags") + .HasColumnType("nvarchar(max)"); + + b.Property("strVideo") + .HasColumnType("nvarchar(max)"); + + b.Property("viewCount") + .HasColumnType("int"); + + b.HasKey("idDrink"); + + b.ToTable("FavouriteDrinks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085721_RemovedDeafaultValue.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085721_RemovedDeafaultValue.cs new file mode 100644 index 00000000..09a24497 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/20260506085721_RemovedDeafaultValue.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DrinksInfo.Ledana.Migrations +{ + /// + public partial class RemovedDeafaultValue : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/FavouritesDrinkContextModelSnapshot.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/FavouritesDrinkContextModelSnapshot.cs new file mode 100644 index 00000000..9744d400 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Migrations/FavouritesDrinkContextModelSnapshot.cs @@ -0,0 +1,189 @@ +// +using DrinksInfo.Ledana.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DrinksInfo.Ledana.Migrations +{ + [DbContext(typeof(FavouritesDrinkContext))] + partial class FavouritesDrinkContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DrinksInfo.Ledana.Models.DrinkDetail", b => + { + b.Property("idDrink") + .HasColumnType("nvarchar(450)"); + + b.Property("dateModified") + .HasColumnType("nvarchar(max)"); + + b.Property("strAlcoholic") + .HasColumnType("nvarchar(max)"); + + b.Property("strCategory") + .HasColumnType("nvarchar(max)"); + + b.Property("strCreativeCommonsConfirmed") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrink") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrinkAlternate") + .HasColumnType("nvarchar(max)"); + + b.Property("strDrinkThumb") + .HasColumnType("nvarchar(max)"); + + b.Property("strGlass") + .HasColumnType("nvarchar(max)"); + + b.Property("strIBA") + .HasColumnType("nvarchar(max)"); + + b.Property("strImageAttribution") + .HasColumnType("nvarchar(max)"); + + b.Property("strImageSource") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient1") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient10") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient11") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient12") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient13") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient14") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient15") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient2") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient3") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient4") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient5") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient6") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient7") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient8") + .HasColumnType("nvarchar(max)"); + + b.Property("strIngredient9") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructions") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsDE") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsES") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsFR") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsIT") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsZHHANS") + .HasColumnType("nvarchar(max)"); + + b.Property("strInstructionsZHHANT") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure1") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure10") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure11") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure12") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure13") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure14") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure15") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure2") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure3") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure4") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure5") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure6") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure7") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure8") + .HasColumnType("nvarchar(max)"); + + b.Property("strMeasure9") + .HasColumnType("nvarchar(max)"); + + b.Property("strTags") + .HasColumnType("nvarchar(max)"); + + b.Property("strVideo") + .HasColumnType("nvarchar(max)"); + + b.Property("viewCount") + .HasColumnType("int"); + + b.HasKey("idDrink"); + + b.ToTable("FavouriteDrinks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Categories.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Categories.cs new file mode 100644 index 00000000..84dcd78e --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Categories.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Serialization; + +namespace DrinksInfo.Ledana.Models +{ + internal class Categories + { + [JsonPropertyName("drinks")] + public List CategoriesList { get; set; } = []; + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Category.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Category.cs new file mode 100644 index 00000000..f320574f --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Category.cs @@ -0,0 +1,7 @@ +namespace DrinksInfo.Ledana.Models +{ + internal class Category + { + public string? strCategory { get; set; } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Drink.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Drink.cs new file mode 100644 index 00000000..78e300a6 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Drink.cs @@ -0,0 +1,11 @@ +namespace DrinksInfo.Ledana.Models +{ + internal class Drink + { + public string? strDrink { get; set; } + public string? strDrinkThumb { get; set; } + public string? idDrink { get; set; } + public int viewCount { get; set; } + + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/DrinkDetail.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/DrinkDetail.cs new file mode 100644 index 00000000..e7d49067 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/DrinkDetail.cs @@ -0,0 +1,67 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; + +namespace DrinksInfo.Ledana.Models +{ + internal class DrinkDetailObject + { + [JsonPropertyName("drinks")] + public List DrinkDetailList { get; set; } = []; + } + internal class DrinkDetail + { + [Key] + public string? idDrink { get; set; } + public int viewCount { get; set; } + public string? strDrink { get; set; } + public string? strDrinkAlternate { get; set; } + public string? strTags { get; set; } + public string? strVideo { get; set; } + public string? strCategory { get; set; } + public string? strIBA { get; set; } + public string? strAlcoholic { get; set; } + public string? strGlass { get; set; } + public string? strInstructions { get; set; } + public string? strInstructionsES { get; set; } + public string? strInstructionsDE { get; set; } + public string? strInstructionsFR { get; set; } + public string? strInstructionsIT { get; set; } + public string? strInstructionsZHHANS { get; set; } + public string? strInstructionsZHHANT { get; set; } + public string? strDrinkThumb { get; set; } + public string? strIngredient1 { get; set; } + public string? strIngredient2 { get; set; } + public string? strIngredient3 { get; set; } + public string? strIngredient4 { get; set; } + public string? strIngredient5 { get; set; } + public string? strIngredient6 { get; set; } + public string? strIngredient7 { get; set; } + public string? strIngredient8 { get; set; } + public string? strIngredient9 { get; set; } + public string? strIngredient10 { get; set; } + public string? strIngredient11 { get; set; } + public string? strIngredient12 { get; set; } + public string? strIngredient13 { get; set; } + public string? strIngredient14 { get; set; } + public string? strIngredient15 { get; set; } + public string? strMeasure1 { get; set; } + public string? strMeasure2 { get; set; } + public string? strMeasure3 { get; set; } + public string? strMeasure4 { get; set; } + public string? strMeasure5 { get; set; } + public string? strMeasure6 { get; set; } + public string? strMeasure7 { get; set; } + public string? strMeasure8 { get; set; } + public string? strMeasure9 { get; set; } + public string? strMeasure10 { get; set; } + public string? strMeasure11 { get; set; } + public string? strMeasure12 { get; set; } + public string? strMeasure13 { get; set; } + public string? strMeasure14 { get; set; } + public string? strMeasure15 { get; set; } + public string? strImageSource { get; set; } + public string? strImageAttribution { get; set; } + public string? strCreativeCommonsConfirmed { get; set; } + public string? dateModified { get; set; } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Drinks.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Drinks.cs new file mode 100644 index 00000000..bff55810 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Models/Drinks.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Serialization; + +namespace DrinksInfo.Ledana.Models +{ + internal class Drinks + { + [JsonPropertyName("drinks")] + public List DrinksList { get; set; } = []; + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Program.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Program.cs new file mode 100644 index 00000000..48254739 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Program.cs @@ -0,0 +1,22 @@ +using DrinksInfo.Ledana; + +class Program +{ + static async Task Main() + { + UserInput userInput = new(); + while(true) + { + await userInput.GetCategoriesInput(); + Console.WriteLine("Press 'x' to exit or any other key to look into another drink"); + var input = Console.ReadLine(); + if (input is not null && input.ToLower() == "x") + { + Console.WriteLine("Good bye!"); + break; + } + } + + } +} + diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Services/DrinkService.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Services/DrinkService.cs new file mode 100644 index 00000000..42489d51 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Services/DrinkService.cs @@ -0,0 +1,163 @@ +using DrinksInfo.Ledana.Models; +using System.Net.Http.Headers; +using System.Reflection; +using System.Web; +using System.Text.Json; + + +namespace DrinksInfo.Ledana.Services +{ + internal class DrinkService + { + internal async Task?> GetCategoriesByHttpClient() + { + try + { + using HttpClient client = new(); + client.DefaultRequestHeaders.Accept.Clear(); + client.DefaultRequestHeaders.Accept.Add( + new MediaTypeWithQualityHeaderValue("application/json")); + + string url = "https://www.thecocktaildb.com/api/json/v1/1/list.php?c=list"; + var response = await client.GetAsync(url); + + if (response.IsSuccessStatusCode) + { + using var stream = await response.Content.ReadAsStreamAsync(); + + var serialize = await JsonSerializer.DeserializeAsync(stream, + new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + if (serialize is null) return null; + + return serialize.CategoriesList; + } + else return null; + } + catch (Exception e) + { + Console.WriteLine("Something is not working!" + e.Message); + return null; + } + } + + internal async Task?> GetDrinksByCategory(string? category) + { + try + { + using HttpClient client = new(); + client.DefaultRequestHeaders.Accept.Clear(); + client.DefaultRequestHeaders.Accept.Add( + new MediaTypeWithQualityHeaderValue("application/json")); + + string url = $"https://www.thecocktaildb.com/api/json/v1/1/filter.php?c={HttpUtility.UrlEncode(category)}"; + var response = await client.GetAsync(url); + + if (response.IsSuccessStatusCode) + { + using var stream = await response.Content.ReadAsStreamAsync(); + + var serialize = await JsonSerializer.DeserializeAsync(stream, + new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + return serialize!.DrinksList; + } + else + return null; + } + catch (Exception e) + { + Console.WriteLine("Something is not working!" + e.Message); + return null; + } + } + + internal async Task?> GetDrink(string? drink) + { + try + { + using HttpClient client = new(); + client.DefaultRequestHeaders.Accept.Clear(); + client.DefaultRequestHeaders.Accept.Add( + new MediaTypeWithQualityHeaderValue("application/json")); + + string url = $"https://www.thecocktaildb.com/api/json/v1/1/lookup.php?i={drink}"; + var response = await client.GetAsync(url); + + if (response.IsSuccessStatusCode) + { + using var stream = await response.Content.ReadAsStreamAsync(); + + var serializer = await JsonSerializer.DeserializeAsync(stream, + new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + + if (serializer is null) return null; + + List returnedList = serializer.DrinkDetailList; + if (returnedList is null || returnedList.Count == 0) + return null; + + DrinkDetail drinkDetail = returnedList[0]; + + List<(string Key, string Value)> prepList = []; + + foreach (PropertyInfo prop in drinkDetail.GetType().GetProperties()) + { + var value = prop.GetValue(drinkDetail)?.ToString(); + + if (!string.IsNullOrEmpty(value)) + { + string formattedName = prop.Name.StartsWith("str") + ? prop.Name.Substring(3) + : prop.Name; + + prepList.Add((formattedName, value)); + } + } + return prepList; + } + else + return null; + } + catch (Exception e) + { + Console.WriteLine("Something is not working!" + e.Message); + return null; + } + } + public async Task GetDrinkDetail(string? drink) + { + try + { + using HttpClient client = new(); + client.DefaultRequestHeaders.Accept.Clear(); + client.DefaultRequestHeaders.Accept.Add( + new MediaTypeWithQualityHeaderValue("application/json")); + + string url = $"https://www.thecocktaildb.com/api/json/v1/1/lookup.php?i={drink}"; + var response = await client.GetAsync(url); + + if (response.IsSuccessStatusCode) + { + using var stream = await response.Content.ReadAsStreamAsync(); + + var serializer = await JsonSerializer.DeserializeAsync(stream); + + if (serializer is null) return null; + + List returnedList = serializer.DrinkDetailList; + if (returnedList is null || returnedList.Count == 0) + return null; + + return returnedList[0]; + } + else + return null; + } + catch (Exception e) + { + Console.WriteLine("Something is not working!" + e.Message); + return null; + + } + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/TableVisualisationEngine.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/TableVisualisationEngine.cs new file mode 100644 index 00000000..06c1f641 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/TableVisualisationEngine.cs @@ -0,0 +1,96 @@ +using DrinksInfo.Ledana.Models; +using Microsoft.EntityFrameworkCore; +using Spectre.Console; + +namespace DrinksInfo.Ledana +{ + internal class TableVisualisationEngine + { + internal static void ShowCategoriesHttpTable(List? categories) + { + Console.Clear(); + + var table = new Table(); + table.AddColumn("Categories: "); + + if (categories is null) + { + Console.WriteLine("Table is empty or API is down!"); + return; + } + + foreach (var item in categories) + { + table.AddRow(item.strCategory); + } + table.AddRow("Favourites"); + + AnsiConsole.Write(table); + Console.Write("Type 'x' to exit or Choose category : "); + } + + internal static void ShowDrinkHttp(List<(string Key, string Value)> drinkTable) + { + var table = new Table() + .ShowRowSeparators(); + table.AddColumn("Property"); + table.AddColumn("Value"); + + foreach (var item in drinkTable) + { + table.AddRow(item.Key, item.Value); + } + AnsiConsole.Write(table); + } + + internal static void ShowDrinksHttpTable(List? drinks) + { + var table = new Table().Title("Drinks: "); + + table.AddColumn("Id"); + table.AddColumn("Name"); + + if (drinks is null) + { + Console.WriteLine("Table empty or API is down!"); + return; + } + + foreach (var item in drinks) + { + table.AddRow(item.idDrink.ToString(), item.strDrink); + } + AnsiConsole.Write(table); + Console.Write("Type 'x' to exit or Choose drink id: "); + } + + internal static void ShowFavouriteDrinksHttpTable(List favouriteDrinks) + { + var table = new Table(); + table.AddColumn("Property"); + table.AddColumn("Value"); + + List drinks = []; + foreach(var item in favouriteDrinks) + { + drinks.Add(DetailToDrink(item)); + } + + foreach (var item in drinks) + { + table.AddRow(item.idDrink.ToString(), item.strDrink); + } + + AnsiConsole.Write(table); + Console.Write("Type 'x' to exit or Choose drink id: "); + } + private static Drink DetailToDrink(DrinkDetail drink) + { + return new Drink() + { + idDrink = drink.idDrink, + strDrink = drink.strDrink + }; + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/UserInput.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/UserInput.cs new file mode 100644 index 00000000..a47259ef --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/UserInput.cs @@ -0,0 +1,157 @@ +using DrinksInfo.Ledana.Controllers; +using DrinksInfo.Ledana.Models; +using DrinksInfo.Ledana.Services; + +namespace DrinksInfo.Ledana +{ + internal class UserInput + { + private readonly DrinkService drinksService = new(); + + internal async Task GetCategoriesInput() + { + var categories = await drinksService.GetCategoriesByHttpClient(); + + if (categories is null) return; + + TableVisualisationEngine.ShowCategoriesHttpTable(categories); + + string? category = Console.ReadLine(); + if (category is not null && category.ToLower() == "x") return; + + if (!string.IsNullOrEmpty(category) && category.ToLower() == "favourites") + { + FavouritesMenu(); + string? input = Console.ReadLine(); + if (input is null) return; + + switch (input) + { + case "1": + await SeeAllFavourites(); + break; + case "2": + await DeleteAllFavourites(); + break; + case "3": + DeleteOneFavourite(); + break; + default: + break; + } + + return; + } + + while (!Validator.IsCategoryValid(category, categories)) + { + Console.WriteLine("\nInvalid category. Type 'x' to exit or try again."); + category = Console.ReadLine(); + if (category == "x") return; + } + + await GetDrinksInput(category); + } + + private void DeleteOneFavourite() + { + List favouriteDrinks = FavouriteDrinkController.GetFavouriteDrinks(); + if (favouriteDrinks is null) return; + + TableVisualisationEngine.ShowFavouriteDrinksHttpTable(favouriteDrinks); + + string? drink = Console.ReadLine(); + + while (!Validator.IsIdValid(drink, favouriteDrinks)) + { + Console.WriteLine("\nInvalid drink. Type 'x' to exit or try again."); + drink = Console.ReadLine(); + if (drink == "x") return; + } + + FavouriteDrinkController.DeleteFavourite(drink); + Console.WriteLine($"Drink with id {drink} has been deleted!"); + } + + private async Task DeleteAllFavourites() + { + await FavouriteDrinkController.DeleteAllFavourites(); + Console.WriteLine("Successfully deleted all favourites!"); + } + + public async Task SeeAllFavourites() + { + List favouriteDrinks = FavouriteDrinkController.GetFavouriteDrinks(); + if (favouriteDrinks is null) return; + + TableVisualisationEngine.ShowFavouriteDrinksHttpTable(favouriteDrinks); + + string? drink = Console.ReadLine(); + if (drink is not null && drink.ToLower() == "x") return; + + while (!Validator.IsIdValid(drink, favouriteDrinks)) + { + Console.WriteLine("\nInvalid drink. Type 'x' to exit or try again."); + drink = Console.ReadLine(); + if (drink == "x") return; + } + + var drinkTable = await drinksService.GetDrink(drink); + + if (drinkTable is null) return; + + TableVisualisationEngine.ShowDrinkHttp(drinkTable); + return; + } + private void FavouritesMenu() + { + Console.WriteLine("1. See all favourites"); + Console.WriteLine("2. Delete all favourites"); + Console.WriteLine("3. Delete one favourite"); + } + + private async Task GetDrinksInput(string? category) + { + var drinks = await drinksService.GetDrinksByCategory(category); + + if (drinks is null) return; + + TableVisualisationEngine.ShowDrinksHttpTable(drinks); + + string? drink = Console.ReadLine(); + + if (drink is not null && drink.ToLower() == "x") return; + + while (!Validator.IsIdValid(drink, drinks)) + { + Console.WriteLine("\nInvalid drink. Type 'x' to exit or try again."); + drink = Console.ReadLine(); + if (drink == "x") return; + } + + var drinkTable = await drinksService.GetDrink(drink); + + if (drinkTable is null) return; + + TableVisualisationEngine.ShowDrinkHttp(drinkTable); + + if (!FavouriteDrinkController.HasDrink(drink)) + await AskForFavourite(drink); + } + + public async Task AskForFavourite(string? drink) + { + Console.WriteLine("Do you want to add this category to your favourites? (y/n): "); + var input = Console.ReadLine(); + if (input is not null && input.ToLower() == "y") + { + DrinkDetail? favouriteDrink = await drinksService.GetDrinkDetail(drink); + if (favouriteDrink is null) return; + + FavouriteDrinkController.AddDrinkToFavourites(favouriteDrink); + + Console.WriteLine("Drink added into favourites successfully!"); + } + } + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/Validator.cs b/DrinksInfo.Ledana/DrinksInfo.Ledana/Validator.cs new file mode 100644 index 00000000..e8df1a28 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/Validator.cs @@ -0,0 +1,44 @@ +using DrinksInfo.Ledana.Models; + +namespace DrinksInfo.Ledana +{ + internal class Validator + { + internal static bool IsIdValid(string? drink, List drinks) + { + if (string.IsNullOrEmpty(drink) || !drinks.Any(d => d.idDrink == drink)) return false; + + foreach (char c in drink) + { + if (!char.IsDigit(c)) + return false; + } + return true; + } + internal static bool IsIdValid(string? drink, List drinks) + { + if (string.IsNullOrEmpty(drink) || !drinks.Any(d => d.idDrink == drink)) return false; + + foreach (char c in drink) + { + if (!char.IsDigit(c)) + return false; + } + return true; + } + + internal static bool IsCategoryValid(string? category, List categories) + { + if (string.IsNullOrEmpty(category)) return false; + + foreach (char c in category) + { + if ((!char.IsLetter(c) && c != '/' && c != ' ') || (!categories.Any(c => c.strCategory.ToLower() == category.ToLower()))) + return false; + } + + return true; + } + + } +} diff --git a/DrinksInfo.Ledana/DrinksInfo.Ledana/appSettings.json b/DrinksInfo.Ledana/DrinksInfo.Ledana/appSettings.json new file mode 100644 index 00000000..e5448285 --- /dev/null +++ b/DrinksInfo.Ledana/DrinksInfo.Ledana/appSettings.json @@ -0,0 +1,5 @@ +{ + "ConnectionStrings": { + "FavouriteDrinksDb": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=FavouriteDrinksDb;Trust Server Certificate=True;" + } +}