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
Binary file added ER-diagram-extension.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions api-cinema-challenge/api-cinema-challenge.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3C371BAA-344D-4C8A-AF08-7829816D726F}"
ProjectSection(SolutionItems) = preProject
..\.gitignore = ..\.gitignore
..\ER-diagram-extension.jpg = ..\ER-diagram-extension.jpg
..\README.md = ..\README.md
EndProjectSection
EndProject
Expand Down
16 changes: 16 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTO/CustomerDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;

namespace api_cinema_challenge.DTO
{
public class CustomerDTO
{

public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }

}
}
9 changes: 9 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTO/CustomerPost.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace api_cinema_challenge.DTO
{
public class CustomerPost
{
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
}
14 changes: 14 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTO/MovieDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations.Schema;

namespace api_cinema_challenge.DTO
{
public class MovieDTO
{
public string Title { get; set; }
public string Rating { get; set; }
public string Description { get; set; }
public int RuntimeMins { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
}
10 changes: 10 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTO/MoviePost.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace api_cinema_challenge.DTO
{
public class MoviePost
{
public string Title { get; set; }
public string Rating { get; set; }
public string Description { get; set; }
public int RuntimeMins { get; set; }
}
}
12 changes: 12 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTO/ScreeningDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace api_cinema_challenge.DTO
{
public class ScreeningDTO
{
public int Id { get; set; }
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public DateTime StartsAt { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace api_cinema_challenge.DTO
{
public class ScreeningPost
{
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public DateTime StartsAt { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using Microsoft.EntityFrameworkCore;
using api_cinema_challenge.Models;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;

namespace api_cinema_challenge.Data
{
public class CinemaContext : DbContext
{
private string _connectionString;
public CinemaContext(DbContextOptions<CinemaContext> options) : base(options)
public CinemaContext()
{
var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
_connectionString = configuration.GetValue<string>("ConnectionStrings:DefaultConnectionString")!;
Expand All @@ -22,5 +23,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
{

}
public DbSet<Movie> Movies { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Screening> Screenings { get; set; }
}
}
58 changes: 58 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/Data/Seeder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using api_cinema_challenge.Models;
using Microsoft.EntityFrameworkCore.Query.Internal;

namespace api_cinema_challenge.Data
{
public static class Seeder
{
public async static void SeedData(this WebApplication app)
{
using (var db = new CinemaContext())
{
if (!db.Movies.Any())
{
db.Movies.Add(new Movie
{
Title = "Dodgeball",
Rating = "PG-13",
Description = "The greatest movie ever made.",
RuntimeMins = 126,
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now
});

await db.SaveChangesAsync();
}

if (!db.Screenings.Any())
{
db.Screenings.Add(new Screening
{
MovieId = 1,
ScreenNumber = 5,
Capacity = 40,
StartsAt = new DateTime(2025, 4, 20, 23, 0, 0),
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now
});

await db.SaveChangesAsync();
}

if (!db.Customers.Any())
{
db.Customers.Add(new Customer
{
Name = "John",
Email = "Doe",
Phone = "+44729388192",
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now
});

await db.SaveChangesAsync();
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using api_cinema_challenge.DTO;
using api_cinema_challenge.Models;
using api_cinema_challenge.Repository;
using AutoMapper;

namespace api_cinema_challenge.Endpoints
{
public static class CustomerEndpoints
{
public static void ConfigureCustomerEndpoints(this WebApplication app)
{
var movieGroup = app.MapGroup("/customers");

movieGroup.MapGet("/", GetCustomers);
movieGroup.MapPost("/", AddCustomer);
movieGroup.MapPut("/{id}", UpdateCustomer);
movieGroup.MapDelete("/{id}", DeleteCustomer);
}

public static async Task<IResult> GetCustomers(IRepository<Customer> repo, IMapper mapper)
{
var movies = await repo.Get();

return Results.Ok(mapper.Map<List<Customer>>(movies));

}

public static async Task<IResult> AddCustomer(IRepository<Customer> repo, CustomerPost customer, IMapper mapper)
{
Customer newCustomer = new Customer
{
Name = customer.Name,
Email = customer.Email,
Phone = customer.Phone,
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
};

var result = await repo.Add(newCustomer);
return Results.Ok(mapper.Map<CustomerDTO>(result));
}

public static async Task<IResult> UpdateCustomer(IRepository<Customer> repo, int id, CustomerPost customer, IMapper mapper)
{
var existingCustomer = await repo.GetById(id);
if (existingCustomer == null)
{
return Results.NotFound();
}
existingCustomer.Name = customer.Name;
existingCustomer.Email = customer.Email;
existingCustomer.Phone = customer.Phone;
existingCustomer.UpdatedAt = DateTime.Now;
var result = await repo.Update(existingCustomer);
return Results.Ok(mapper.Map<Customer>(result));
}

public static async Task<IResult> DeleteCustomer(IRepository<Customer> repo, int id)
{
var existingCustomer = await repo.GetById(id);
if (existingCustomer == null)
{
return Results.NotFound();
}
var result = await repo.Delete(id);
return Results.Ok(result);
}

}
}

109 changes: 109 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/Endpoints/MovieEndpoints.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System.Security.Cryptography.X509Certificates;
using api_cinema_challenge.DTO;
using api_cinema_challenge.Models;
using api_cinema_challenge.Repository;
using AutoMapper;
using Microsoft.EntityFrameworkCore;

namespace api_cinema_challenge.Endpoints
{
public static class MovieEndpoints
{
public static void ConfigureMovieEndpoints(this WebApplication app)
{
var movieGroup = app.MapGroup("/movies");

movieGroup.MapGet("/", GetMovies);
movieGroup.MapPost("/", AddMovie);
movieGroup.MapPut("/{id}", UpdateMovie);
movieGroup.MapDelete("/{id}", DeleteMovie);
movieGroup.MapGet("/{id}/screenings", GetScreenings);
movieGroup.MapPost("/{id}/screenings", AddScreening);
}

public static async Task<IResult> GetMovies(IRepository<Movie> repo, IMapper mapper)
{
var movies = await repo.Get();

return Results.Ok(mapper.Map<List<Movie>>(movies));

}

public static async Task<IResult> AddMovie(IRepository<Movie> repo, MoviePost movie, IMapper mapper)
{
Movie newMovie = new Movie
{
Title = movie.Title,
Rating = movie.Rating,
Description = movie.Description,
RuntimeMins = movie.RuntimeMins,
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
};

var result = await repo.Add(newMovie);
return Results.Ok(mapper.Map<MovieDTO>(result));
}

public static async Task<IResult> UpdateMovie(IRepository<Movie> repo, int id, MoviePost movie, IMapper mapper)
{
Movie existingMovie = await repo.GetById(id);
if (existingMovie == null)
{
return Results.NotFound();
}
existingMovie.Title = movie.Title;
existingMovie.Rating = movie.Rating;
existingMovie.Description = movie.Description;
existingMovie.RuntimeMins = movie.RuntimeMins;
existingMovie.UpdatedAt = DateTime.Now;
var result = await repo.Update(existingMovie);
return Results.Ok(mapper.Map<MovieDTO>(result));
}

public static async Task<IResult> DeleteMovie(IRepository<Movie> repo, int id)
{
var existingMovie = await repo.GetById(id);
if (existingMovie == null)
{
return Results.NotFound();
}
var result = await repo.Delete(id);
return Results.Ok(result);
}

public static async Task<IResult> GetScreenings(IRepository<Screening> screenRepo , int id, IMapper mapper)
{
List<Screening> screen = await screenRepo.GetQuery().Where(s => s.MovieId == id).ToListAsync();


return Results.Ok(mapper.Map<List<ScreeningDTO>>(screen));

}

public static async Task<IResult> AddScreening(IRepository<Screening> screenRepo, IRepository<Movie> movieRepo, ScreeningPost screening, IMapper mapper, int id)
{
Movie movie = await movieRepo.GetById(id);

if(movie == null) return Results.NotFound();

Screening newScreening = new Screening
{
MovieId = movie.Id,
ScreenNumber = screening.ScreenNumber,
Capacity = screening.Capacity,
StartsAt = screening.StartsAt,
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
};

var result = await screenRepo.Add(newScreening);

var screeningDto = mapper.Map<ScreeningDTO>(result);

return Results.Ok(screeningDto);
}


}
}
Loading