From 54814cbcce6e4b63ca1cf490b4a57fba57f6f670 Mon Sep 17 00:00:00 2001 From: Berack96 Date: Tue, 20 Jan 2026 12:12:55 +0100 Subject: [PATCH] Movie Table (#2) * Table to search movies implemented * OMDB service for API connection Reviewed-on: https://git.berack.net/Berack/test-alebro/pulls/2 Co-authored-by: Berack96 Co-committed-by: Berack96 --- .gitignore | 3 ++ Components/Pages/Favorites.razor | 11 ++++++ Components/Pages/Home.razor | 52 +++++++++++++++++++++++++-- Components/Pages/Movie.razor | 11 ++++++ Components/Routes.razor | 3 +- Models/Movie.cs | 20 +++++++++++ Models/MovieSearch.cs | 15 ++++++++ Program.cs | 3 ++ README.md | 11 +++++- Services/OmdbService.cs | 61 ++++++++++++++++++++++++++++++++ test-alebro.sln | 24 +++++++++++++ 11 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 Components/Pages/Movie.razor create mode 100644 Models/Movie.cs create mode 100644 Models/MovieSearch.cs create mode 100644 Services/OmdbService.cs create mode 100644 test-alebro.sln diff --git a/.gitignore b/.gitignore index 0501afc..6869105 100644 --- a/.gitignore +++ b/.gitignore @@ -396,3 +396,6 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml +# ======= +# MINE +APIKey.txt diff --git a/Components/Pages/Favorites.razor b/Components/Pages/Favorites.razor index a638a0d..2662792 100644 --- a/Components/Pages/Favorites.razor +++ b/Components/Pages/Favorites.razor @@ -4,4 +4,15 @@

TODO

+ +@inject OmdbService OmdbService +@inject IJSRuntime JSRuntime + +@code { + private async Task FaiCose() + { + var movies = await OmdbService.FetchMovies("Matrix"); + var movieDetail = await OmdbService.FetchMovieDetail("tt11749868"); + } +} diff --git a/Components/Pages/Home.razor b/Components/Pages/Home.razor index 9001e0b..7d5fc28 100644 --- a/Components/Pages/Home.razor +++ b/Components/Pages/Home.razor @@ -2,6 +2,54 @@ Home -

Hello, world!

+
+ +
+ +

@((movies == null) ? "" : movies.TotalResults + " results found")

+
+
-Welcome to your new app. + + + + + + + + + + @if (movies?.Search != null) + { + @foreach (var movie in movies.Search) + { + + + + + + } + } + +
TitleYear
@movie.Title@movie.Year
+ + +@inject OmdbService OmdbService +@inject NavigationManager NavigationManager + +@code { + private string searchTitle = ""; + private MovieSearch? movies = null; + + private async Task OnMovieSelected(string imdbID) + { + NavigationManager.NavigateTo($"/movie/{imdbID}"); + } + + private async Task OnSearch() + { + movies = await OmdbService.FetchMovies(searchTitle); + } +} \ No newline at end of file diff --git a/Components/Pages/Movie.razor b/Components/Pages/Movie.razor new file mode 100644 index 0000000..a415d3b --- /dev/null +++ b/Components/Pages/Movie.razor @@ -0,0 +1,11 @@ +@page "/movie/{id}" + +Movie Details + +

TODO

+

Movie ID: @id

+ +@code { + [Parameter] + public string id { get; set; } +} diff --git a/Components/Routes.razor b/Components/Routes.razor index 105855d..43d695d 100644 --- a/Components/Routes.razor +++ b/Components/Routes.razor @@ -1,4 +1,5 @@ - +@rendermode InteractiveServer + diff --git a/Models/Movie.cs b/Models/Movie.cs new file mode 100644 index 0000000..e59d11b --- /dev/null +++ b/Models/Movie.cs @@ -0,0 +1,20 @@ + + +using System.Text.Json.Serialization; + + +/// +/// Rappresenta un film con le sue proprietà principali. +/// Non ho preso tutte le proprietà disponibili dall'API OMDB, solo quelle richieste. +/// +class Movie +{ + public required string Title { get; set; } + public required string Year { get; set; } + [JsonPropertyName("imdbID")] + public required string IdIMDB { get; set; } + public required string Poster { get; set; } + public string Runtime { get; set; } = "N/A"; + public string Plot { get; set; } = "N/A"; + +} \ No newline at end of file diff --git a/Models/MovieSearch.cs b/Models/MovieSearch.cs new file mode 100644 index 0000000..d1a7f83 --- /dev/null +++ b/Models/MovieSearch.cs @@ -0,0 +1,15 @@ + + +using System.Text.Json.Serialization; + + +/// +/// Modello per rappresentare i risultati di una ricerca di film. +/// Ha solo scopo di deserializzazione della risposta JSON dell'API OMDB. +/// +class MovieSearch +{ + public required Movie[] Search { get; set; } + [JsonPropertyName("totalResults")] + public required string TotalResults { get; set; } +} \ No newline at end of file diff --git a/Program.cs b/Program.cs index f2f6806..e4ac6c2 100644 --- a/Program.cs +++ b/Program.cs @@ -6,6 +6,9 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); +// Mine services +builder.Services.AddSingleton(); + var app = builder.Build(); // Configure the HTTP request pipeline. diff --git a/README.md b/README.md index 0a35fb1..798337a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ # test-alebro -Test per colloquio \ No newline at end of file +Test per colloquio + +## Istruzioni per l'esecuzione + +Dopo aver clonato il repository, crea un file APIKey.txt nella cartella radice del progetto e inserisci l'API Key di OMDb. + +Poi esegui il progetto con: +```bash +dotnet run +``` diff --git a/Services/OmdbService.cs b/Services/OmdbService.cs new file mode 100644 index 0000000..1b0d66b --- /dev/null +++ b/Services/OmdbService.cs @@ -0,0 +1,61 @@ +using System.Net; +using System.Text.Json; + +/// +/// Servizio per interagire con l'API OMDB. +/// Semplifica le richieste per ottenere dettagli sui film. +/// +class OmdbService +{ + private readonly string url; + private readonly HttpClient httpClient = new(); + + public OmdbService() + { + var apiKey = File.ReadAllText("APIKey.txt").Trim(); + apiKey = WebUtility.UrlEncode(apiKey); + + url = "http://www.omdbapi.com/?apikey=" + apiKey + + "&type=movie" + + "&r=json"; + } + + /// + /// Recupera i dettagli di un film dato il suo ID IMDB. + /// + /// ID IMDB del film da cercare. + /// Un oggetto Movie con i dettagli del film. + public async Task FetchMovieDetail(string id) + { + return await FetchAsync("i", id); + } + + + /// + /// Recupera una lista di film che corrispondono al titolo di ricerca. + /// + /// Titolo dei film da cercare. + /// >Una lista di oggetti Movie che corrispondono alla ricerca. + public async Task FetchMovies(string searchTitle) + { + return await FetchAsync("s", searchTitle); + } + + /// + /// Esegue una richiesta HTTP GET e deserializza la risposta JSON in un oggetto del tipo specificato. + /// + /// Tipo dell'oggetto di ritorno. + /// Parametro della query HTTP. + /// Valore del parametro della query HTTP. + /// Un oggetto del tipo specificato deserializzato dalla risposta JSON. + private async Task FetchAsync(string query, string value) + { + var requestUrl = url + "&" + query + "=" + WebUtility.UrlEncode(value); + var response = await httpClient.GetStringAsync(requestUrl); + try { + return JsonSerializer.Deserialize(response)!; + } catch (JsonException) { + return default; + } + } +} \ No newline at end of file diff --git a/test-alebro.sln b/test-alebro.sln new file mode 100644 index 0000000..4dc2df2 --- /dev/null +++ b/test-alebro.sln @@ -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}") = "test-alebro", "test-alebro.csproj", "{80C175CB-7DB0-93BB-681F-01F9DB017FB2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {80C175CB-7DB0-93BB-681F-01F9DB017FB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {80C175CB-7DB0-93BB-681F-01F9DB017FB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {80C175CB-7DB0-93BB-681F-01F9DB017FB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {80C175CB-7DB0-93BB-681F-01F9DB017FB2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4E9E6522-3307-4F89-B6D6-2D4D61E7B65B} + EndGlobalSection +EndGlobal