Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Drinks-App.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Drinks_App</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ConsoleTableExt" Version="3.3.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="RestSharp" Version="112.1.0" />
</ItemGroup>

</Project>
24 changes: 24 additions & 0 deletions Drinks-App.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Drinks-App", "Drinks-App.csproj", "{B047A06B-5EBC-A5CD-3168-16CC1D06A23F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B047A06B-5EBC-A5CD-3168-16CC1D06A23F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B047A06B-5EBC-A5CD-3168-16CC1D06A23F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B047A06B-5EBC-A5CD-3168-16CC1D06A23F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B047A06B-5EBC-A5CD-3168-16CC1D06A23F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0CC91901-3627-45F7-B887-53A9EFCADBE9}
EndGlobalSection
EndGlobal
101 changes: 101 additions & 0 deletions DrinksService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using Drinks_App.Models;
using Newtonsoft.Json;
using RestSharp;
using System.Reflection;
using System.Web;
using static Drinks_App.Models.Drink;
using static Drinks_App.Models.DrinkDetails;

namespace Drinks_App
{
internal class DrinksService
{
internal List<Category> GetCategories()
{
var client = new RestClient("http://www.thecocktaildb.com/api/json/v1/1/");
var request = new RestRequest("list.php?c=list");
var response = client.ExecuteAsync(request);

List<Category> categories = new();

if (response.Result.StatusCode == System.Net.HttpStatusCode.OK)
{
string rawResponse = response.Result.Content;
var serialise = JsonConvert.DeserializeObject<Categories>(rawResponse);

categories = serialise.CategoriesList;

TableVisualizationEngine.ShowTable(categories, "Categories Menu");

return categories;
}
return categories;
}
internal List<Drink> GetDrinks(string? category)
{
var client = new RestClient("http://www.thecocktaildb.com/api/json/v1/1/");
var request = new RestRequest($"filter.php?c={ HttpUtility.UrlEncode(category)}");
var response = client.ExecuteAsync(request);

List<Drink> drinks = new();

if (response.Result.StatusCode == System.Net.HttpStatusCode.OK)
{
string rawResponse = response.Result.Content;
var serialise = JsonConvert.DeserializeObject<Drinks>(rawResponse);

drinks = serialise.DrinksList;

TableVisualizationEngine.ShowTable(drinks, "Drinks Menu");

return drinks;
}

return drinks;
}

internal void GetDrink(string? drinkId)
{
var client = new RestClient("http://www.thecocktaildb.com/api/json/v1/1/");
var request = new RestRequest($"lookup.php?i={HttpUtility.UrlEncode(drinkId)}");
var response = client.ExecuteAsync(request);

if (response.Result.StatusCode == System.Net.HttpStatusCode.OK)
{
string rawResponse = response.Result.Content;
var serialise = JsonConvert.DeserializeObject<DrinkDetailObject>(rawResponse);

List<DrinkDetail> returnedList = serialise.DrinkDetailList;

DrinkDetail drinkDetail = returnedList[0];

List<object> prepList = new();


string formattedName = "";

foreach (PropertyInfo prop in drinkDetail.GetType().GetProperties())
{

if (prop.Name.Contains("str"))
{
formattedName = prop.Name.Substring(3);
}

if (!string.IsNullOrEmpty(prop.GetValue(drinkDetail)?.ToString()))
{
prepList.Add(new
{
Key = formattedName,
Value = prop.GetValue(drinkDetail)
});
}
}

TableVisualizationEngine.ShowTable(prepList, drinkDetail.strDrink);

}
}

}
}
16 changes: 16 additions & 0 deletions Models/Category.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

using Newtonsoft.Json;

namespace Drinks_App.Models
{
public class Category
{
public string strCategory { get; set; }
}

public class Categories
{
[JsonProperty("drinks")]
public List<Category> CategoriesList { get; set; }
}
}
16 changes: 16 additions & 0 deletions Models/Drink.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Newtonsoft.Json;

namespace Drinks_App.Models
{
public class Drinks
{
[JsonProperty("drinks")]
public List<Drink> DrinksList { get; set; }
}

public class Drink
{
public string idDrink { get; set; }
public string strDrink { get; set; }
}
}
66 changes: 66 additions & 0 deletions Models/DrinkDetails.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Newtonsoft.Json;

namespace Drinks_App.Models
{
internal class DrinkDetails
{
internal class DrinkDetailObject
{
[JsonProperty("drinks")]
public List<DrinkDetail> DrinkDetailList { get; set; }
}
internal class DrinkDetail
{
public string strDrink { get; set; }
public object strDrinkAlternate { get; set; }
public object strTags { get; set; }
public object strVideo { get; set; }
public string strCategory { get; set; }
public object strIBA { get; set; }
public string strAlcoholic { get; set; }
public string strGlass { get; set; }
public string strInstructions { get; set; }
public object strInstructionsES { get; set; }
public string strInstructionsDE { get; set; }
public object strInstructionsFR { get; set; }
public string strInstructionsIT { get; set; }
public object strInstructionsZHHANS { get; set; }
public object 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 object strIngredient5 { get; set; }
public object strIngredient6 { get; set; }
public object strIngredient7 { get; set; }
public object strIngredient8 { get; set; }
public object strIngredient9 { get; set; }
public object strIngredient10 { get; set; }
public object strIngredient11 { get; set; }
public object strIngredient12 { get; set; }
public object strIngredient13 { get; set; }
public object strIngredient14 { get; set; }
public object strIngredient15 { get; set; }
public string strMeasure1 { get; set; }
public string strMeasure2 { get; set; }
public string strMeasure3 { get; set; }
public string strMeasure4 { get; set; }
public object strMeasure5 { get; set; }
public object strMeasure6 { get; set; }
public object strMeasure7 { get; set; }
public object strMeasure8 { get; set; }
public object strMeasure9 { get; set; }
public object strMeasure10 { get; set; }
public object strMeasure11 { get; set; }
public object strMeasure12 { get; set; }
public object strMeasure13 { get; set; }
public object strMeasure14 { get; set; }
public object strMeasure15 { get; set; }
public object strImageSource { get; set; }
public object strImageAttribution { get; set; }
public string strCreativeCommonsConfirmed { get; set; }
public string dateModified { get; set; }
}
}
}
5 changes: 5 additions & 0 deletions Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Drinks_App;

UserInput userInput = new();

userInput.GetCategoriesInput();
36 changes: 36 additions & 0 deletions TableVisualizationEngine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Diagnostics.CodeAnalysis;
using ConsoleTableExt;

namespace Drinks_App
{
class TableVisualizationEngine
{
/*
* Displays any list of objects as a console table.
*
* <T> is a generic type parameter:
* - When you call this method, T becomes the actual model type
* (e.g., User, Product, Order, etc.).
* - This allows a single method to handle tables for any model,
* instead of writing one method per model type.
*
* tableData : List<T> → the list of objects to print
* tableName : string? → optional header name (can be null)
*/
public static void ShowTable <T>(List<T> TableData, [AllowNull] string TableName) where T : class
{
Console.Clear();

if (TableName == null) TableName = "";

Console.WriteLine("\n\n");

ConsoleTableBuilder
.From(TableData).WithColumn(TableName).WithFormat(ConsoleTableBuilderFormat.Alternative)
.ExportAndWriteLine(TableAligntment.Center);

Console.WriteLine("\n\n");

}
}
}
59 changes: 59 additions & 0 deletions UserInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

using Drinks_App.Models;

namespace Drinks_App
{
internal class UserInput
{
DrinksService drinksService = new();

internal void GetCategoriesInput ()
{
var categories = drinksService.GetCategories();

Console.WriteLine("Select a Category");
string category = Console.ReadLine();

while(!Validator.ValidCategory(category))
{
Console.WriteLine("Invalid Category");
category = Console.ReadLine();
}

if (!categories.Any(x => x.strCategory == category))
{
Console.WriteLine("Category doesn't exist.");
GetCategoriesInput();
}

GetDrinksByCategory(category);
}

public void GetDrinksByCategory(string? category)
{
var drinks = drinksService.GetDrinks(category);

Console.WriteLine("Choose a Drink Id or Enter 0 to return to Categories Menue");

string drinkId = Console.ReadLine();

if(drinkId == "0")
{
GetCategoriesInput();
}
while(!Validator.ValidateDrinkId(drinkId))
{
Console.WriteLine("Invalid Drink");
drinkId = Console.ReadLine();
}
if (!drinks.Any(x => x.idDrink == drinkId))
{
Console.WriteLine("Drink doesn't exist.");
GetDrinksByCategory(category);
}


drinksService.GetDrink(drinkId);
}
}
}
49 changes: 49 additions & 0 deletions Validator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Drinks_App.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Drinks_App
{
class Validator
{


internal static bool ValidCategory(string? category)
{
if(string.IsNullOrEmpty(category))
{
return false;
}

foreach (char c in category)
{
if (!Char.IsLetter(c) && c != '/' && c != ' ')
{
return false;
}
}

return true;
}
internal static bool ValidateDrinkId(string? drinkId)
{
if (string.IsNullOrEmpty(drinkId))
{
return false;
}

foreach (char c in drinkId)
{
if (!Char.IsDigit(c))
{
return false;
}
}

return true;
}
}
}