5 Commits

Author SHA1 Message Date
07128948b0 Merge branch 'master' into DtoBuilders 2025-06-01 20:39:24 +02:00
efb71b24d3 fix: offload building DTOs to GUHF
DTO building allows for fully returning correct event's
skills and registrations
2025-06-01 20:33:58 +02:00
AleksDw
aa5caf4375 Update modify.html 2025-06-01 18:21:20 +02:00
426288d728 feat: enable adding relevant skills to events 2025-06-01 03:13:53 +02:00
72fbfe982f feat: skills endpoint, stylistic changes 2025-06-01 02:15:20 +02:00
16 changed files with 336 additions and 101 deletions

View File

@@ -1,18 +1,21 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using WebApp.Entities; using WebApp.Entities;
namespace WebApp.DTOs; namespace WebApp.DTOs;
// Output values in JSON file // Output values in JSON file
public record class EventDetailsDto public record class EventDetailsDto
( {
int EventId, public int EventId { get; set; }
[Required] int? OrganisationId, [Required] public int? OrganisationId { get; set; }
[Required] string? OrganisationName, [Required] public string? OrganisationName { get; set; }
[Required][StringLength(50)] string Title, [Required][StringLength(50)] public string Title { get; set; }
[StringLength(500)] string Description, [StringLength(500)] public string Description { get; set; }
[Required][StringLength(100)] string Location, [Required][StringLength(100)] public string Location { get; set; }
[Required] DateTime? EventDate, [Required] public DateTime? EventDate { get; set; }
ICollection<EventSkill> EventSkills, //ICollection<EventSkill> EventSkills,
ICollection<EventRegistration> EventRegistrations public ICollection<SkillSummaryDto> EventSkills { get; set; }
); public ICollection<EventRegistrationDto> EventRegistrations { get; set; }
public EventDetailsDto() { }
};

View File

@@ -3,9 +3,13 @@ using WebApp.Entities;
namespace WebApp.DTOs; namespace WebApp.DTOs;
// Output values in JSON file public record class EventRegistrationDto
public record class EventRegistrationDto( {
int EventId, public int EventId { get; set; }
int UserId, public int UserId { get; set; }
DateTime RegisteredAt public string UserName { get; set; }
); public DateTime RegisteredAt { get; set; }
public EventRegistrationDto() { }
};

View File

@@ -1,17 +1,19 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using WebApp.Entities; using WebApp.Entities;
namespace WebApp.DTOs; namespace WebApp.DTOs;
// Output values in JSON file // Output values in JSON file
public record class EventSummaryDto( public record class EventSummaryDto {
int EventId, public int EventId { get; set; }
[Required] string Organisation, [Required] public string Organisation { get; set; }
[Required] int OrganisationId, [Required] public int OrganisationId { get; set; }
[Required] [StringLength(50)] string Title, [Required] [StringLength(50)] public string Title { get; set; }
[StringLength(500)] string Description, [StringLength(500)] public string Description { get; set; }
[Required] [StringLength(100)] string Location, [Required] [StringLength(100)] public string Location { get; set; }
[Required] DateTime? EventDate, [Required] public DateTime? EventDate { get; set; }
ICollection<EventSkill> EventSkills, public ICollection<EventSkill> EventSkills { get; set; }
ICollection<EventRegistration> EventRegistrations public ICollection<EventRegistration> EventRegistrations { get; set; }
);
};

View File

@@ -1,4 +1,4 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using WebApp.Entities; using WebApp.Entities;
namespace WebApp.DTOs; namespace WebApp.DTOs;
@@ -13,4 +13,5 @@ public record class EventSummaryNoErDto(
[Required][StringLength(100)] string Location, [Required][StringLength(100)] string Location,
[Required] DateTime? EventDate, [Required] DateTime? EventDate,
ICollection<EventSkill> EventSkills ICollection<EventSkill> EventSkills
// ICollection<SkillSummaryDto> EventSkills
); );

View File

@@ -1,9 +1,13 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using WebApp.Entities;
namespace WebApp.DTOs; namespace WebApp.DTOs;
public record class SkillSummaryDto public record class SkillSummaryDto
( {
[Required] int SkillId, public int? SkillId { get; set; }
[Required] string SkillName public string? SkillName { get; set; }
);
public SkillSummaryDto() { }
};

View File

@@ -18,6 +18,7 @@ namespace WebApp.Endpoints
var group = app.MapGroup("api/auth") var group = app.MapGroup("api/auth")
.WithParameterValidation(); .WithParameterValidation();
// POST /api/auth/login
group.MapPost("/login", async (LoginDto dto, ApplicationDbContext context, GeneralUseHelpers guh) => group.MapPost("/login", async (LoginDto dto, ApplicationDbContext context, GeneralUseHelpers guh) =>
{ {
var user = await context.WebUsers.FirstOrDefaultAsync(u => u.Email == dto.Email); var user = await context.WebUsers.FirstOrDefaultAsync(u => u.Email == dto.Email);
@@ -38,6 +39,7 @@ namespace WebApp.Endpoints
}); });
}); });
// POST /api/auth/logout
group.MapPost("/logout", async (HttpContext httpContext, GeneralUseHelpers guh) => group.MapPost("/logout", async (HttpContext httpContext, GeneralUseHelpers guh) =>
{ {
var token = await guh.GetTokenFromHTTPContext(httpContext); var token = await guh.GetTokenFromHTTPContext(httpContext);
@@ -54,6 +56,7 @@ namespace WebApp.Endpoints
return Results.Ok(new { success = true }); return Results.Ok(new { success = true });
}); });
// GET /api/auth/my_account
group.MapGet("/my_account", async (HttpContext httpContext, GeneralUseHelpers guh) => group.MapGet("/my_account", async (HttpContext httpContext, GeneralUseHelpers guh) =>
{ {
var token = await guh.GetTokenFromHTTPContext(httpContext); var token = await guh.GetTokenFromHTTPContext(httpContext);
@@ -77,6 +80,7 @@ namespace WebApp.Endpoints
}) })
.WithName(GetUserEndpointName); .WithName(GetUserEndpointName);
// GET /api/auth/my_events
group.MapGet("/my_events", async (HttpContext httpContext, GeneralUseHelpers guh, ApplicationDbContext context) => group.MapGet("/my_events", async (HttpContext httpContext, GeneralUseHelpers guh, ApplicationDbContext context) =>
{ {
var token = await guh.GetTokenFromHTTPContext(httpContext); var token = await guh.GetTokenFromHTTPContext(httpContext);
@@ -129,13 +133,14 @@ namespace WebApp.Endpoints
}); });
// POST /api/auth/add_skill
group.MapPost("/add_skill", async (SingleSkillDto dto, HttpContext httpContext, ApplicationDbContext context, GeneralUseHelpers guh) => group.MapPost("/add_skill", async (SingleSkillDto dto, HttpContext httpContext, ApplicationDbContext context, GeneralUseHelpers guh) =>
{ {
// Uzyskaj użytkownika z tokenu // Uzyskaj użytkownika z tokenu
Token? token = await guh.GetTokenFromHTTPContext(httpContext); Token? token = await guh.GetTokenFromHTTPContext(httpContext);
User? user = await guh.GetUserFromToken(token); User? user = await guh.GetUserFromToken(token);
// Tylko wolontariusze powinno móc dodawać swoje skille // Tylko wolontariusze powinni móc dodawać swoje skille
if (user == null || user.IsOrganisation) { if (user == null || user.IsOrganisation) {
return Results.Json(new { message = "Unauthorized" }, statusCode: 401); return Results.Json(new { message = "Unauthorized" }, statusCode: 401);
} }
@@ -165,14 +170,14 @@ namespace WebApp.Endpoints
return Results.Json(new { message = "Skill added successfully!" }, statusCode: 201); return Results.Json(new { message = "Skill added successfully!" }, statusCode: 201);
}); });
// POST /api/auth/remove_skill
group.MapPost("/remove_skill", async (SingleSkillDto dto, HttpContext httpContext, ApplicationDbContext context, GeneralUseHelpers guh) => group.MapPost("/remove_skill", async (SingleSkillDto dto, HttpContext httpContext, ApplicationDbContext context, GeneralUseHelpers guh) =>
{ {
// Uzyskaj użytkownika z tokenu // Uzyskaj użytkownika z tokenu
Token? token = await guh.GetTokenFromHTTPContext(httpContext); Token? token = await guh.GetTokenFromHTTPContext(httpContext);
User? user = await guh.GetUserFromToken(token); User? user = await guh.GetUserFromToken(token);
// Tylko wolontariusze powinien móc usuwac swoje skille // Tylko wolontariusze powinni móc usuwać swoje skille
if (user == null || user.IsOrganisation) if (user == null || user.IsOrganisation)
{ {
return Results.Json(new { message = "Unauthorized" }, statusCode: 401); return Results.Json(new { message = "Unauthorized" }, statusCode: 401);
@@ -185,28 +190,28 @@ namespace WebApp.Endpoints
return Results.Json(new { message = "Skill not found" }, statusCode: 404); return Results.Json(new { message = "Skill not found" }, statusCode: 404);
} }
// Sprawdzamy, czy ten użytkownik ma już taki skill. Jeżeli nie ma, nie ma sensu usuwac go kilkukrotnie. // Sprawdzamy, czy ten użytkownik ma już taki skill. Jeżeli nie ma, to nie ma sensu usuwać czegoś, czego nie ma.
VolunteerSkill? vs = await context.VolunteerSkills.FirstOrDefaultAsync(v => v.UserId == user.UserId && v.SkillId == dto.Skill); VolunteerSkill? vs = await context.VolunteerSkills.FirstOrDefaultAsync(v => v.UserId == user.UserId && v.SkillId == dto.Skill);
if (vs is not null) if (vs is not null)
{ {
// Nie ma - zatem musimy dodać nowy VolunteerSkill do bazy // Ma - zatem musimy usunąć otrzymany VolunteerSkill z bazy
VolunteerSkill newVs = dto.ToVolunteerSkillEntity(user.UserId); VolunteerSkill newVs = dto.ToVolunteerSkillEntity(user.UserId);
await context.VolunteerSkills.Where(v => v.SkillId == dto.Skill) await context.VolunteerSkills.Where(v => v.SkillId == dto.Skill)
.ExecuteDeleteAsync(); .ExecuteDeleteAsync();
} }
else else
{ {
// Ma - (ta para UserId <-> SkillId już istnieje w bazie) użytkownik już ma ten skill // Nie ma - (ta para UserId <-> SkillId nie istnieje w bazie). Zwracamy błąd.
return Results.Json(new { message = "You don't have this skill" }, statusCode: 400); return Results.Json(new { message = "You don't have this skill" }, statusCode: 400);
} }
return Results.Json(new { message = "Skill deleted successfully!" }, statusCode: 201); return Results.Json(new { message = "Skill deleted successfully!" }, statusCode: 201);
}); });
group.MapGet("/get_skills", async (HttpContext httpContext, ApplicationDbContext context, GeneralUseHelpers guh) => // GET /api/auth/skills
group.MapGet("/skills", async (HttpContext httpContext, ApplicationDbContext context, GeneralUseHelpers guh) =>
{ {
// Uzyskaj użytkownika z tokenu // Uzyskaj użytkownika z tokenu
Token? token = await guh.GetTokenFromHTTPContext(httpContext); Token? token = await guh.GetTokenFromHTTPContext(httpContext);

View File

@@ -1,5 +1,7 @@
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Intrinsics.Arm;
using WebApp.Data; using WebApp.Data;
using WebApp.DTOs; using WebApp.DTOs;
using WebApp.Entities; using WebApp.Entities;
@@ -46,8 +48,11 @@ namespace WebApp.Endpoints
group.MapGet("/{id}", group.MapGet("/{id}",
async (int id, ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) => async (int id, ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) =>
{ {
Event? Eve = await dbContext.Events.FindAsync(id);
Event? Eve = await dbContext
.Events
.Include(e => e.Organisation)
.FirstOrDefaultAsync(e => e.EventId == id);
if (Eve is null) return Results.NotFound(); if (Eve is null) return Results.NotFound();
// Sprawdź, czy token należy do organizacji, a jeżeli tak, to do której. // Sprawdź, czy token należy do organizacji, a jeżeli tak, to do której.
@@ -55,16 +60,14 @@ namespace WebApp.Endpoints
Organisation? org = await guhf.GetOrganisationFromToken(token); Organisation? org = await guhf.GetOrganisationFromToken(token);
// Jeśli token należy do organizacji, która utworzyła to wydarzenie, // Jeśli token należy do organizacji, która utworzyła to wydarzenie,
// to zwróć także EventRegistrations. W przeciwnym razie usuń to pole // to zwróć także EventRegistrations. W przeciwnym razie niech będzie to
// przed jego wysłaniem! // puste pole.
if (org is null || org.OrganisationId != Eve.OrganisationId) Eve.EventRegistrations = []; List<EventDetailsDto> result = await guhf.BuildDetailedEventsDto(
dbContext,
(org is not null && Eve.Organisation == org)
);
// DLACZEGO? return Results.Ok(result.FirstOrDefault(e => e.EventId == id));
Eve.Organisation = await guhf.GetOrganisationFromId(Eve.OrganisationId);
EventDetailsDto EveDto = Eve.ToEventDetailsDto();
return Results.Ok(EveDto); //EventDetailsDto
}) })
.WithName(GetEventEndpointName); .WithName(GetEventEndpointName);
@@ -134,7 +137,7 @@ namespace WebApp.Endpoints
// Uzyskaj organizację z tokenu // Uzyskaj organizację z tokenu
Token? token = await guhf.GetTokenFromHTTPContext(httpContext); Token? token = await guhf.GetTokenFromHTTPContext(httpContext);
Organisation? org = await guhf.GetOrganisationFromToken(token); Organisation? org = await guhf.GetOrganisationFromToken(token);
if (org is null) return Results.StatusCode(403); if (org is null) return Results.Unauthorized();
// Sprawdź, czy organizacja ma prawo // Sprawdź, czy organizacja ma prawo
// do usunięcia tego (EventId = id) eventu. // do usunięcia tego (EventId = id) eventu.
@@ -161,7 +164,6 @@ namespace WebApp.Endpoints
List<EventSummaryDto> SearchResults = []; List<EventSummaryDto> SearchResults = [];
List<Event> AllEvents = await dbContext.Events.ToListAsync(); List<Event> AllEvents = await dbContext.Events.ToListAsync();
if (sort is null || sort.ToUpper() != "ASC") if (sort is null || sort.ToUpper() != "ASC")
{ {
@@ -215,6 +217,9 @@ namespace WebApp.Endpoints
// UWAGA! TO NIE POWINNO TAK DZIAŁAĆ! // UWAGA! TO NIE POWINNO TAK DZIAŁAĆ!
// KTOKOLWIEK WIDZIAŁ, KTOKOLWIEK WIE CZEMU Organisation JEST null? // KTOKOLWIEK WIDZIAŁ, KTOKOLWIEK WIE CZEMU Organisation JEST null?
//
// Odpowiedź: Bo pobieramy dane bez .Include(e => e.Organisation),
// co zapobiega masie innych problemów, m.in. rekurencyjnym importom.
e.Organisation = await guhf.GetOrganisationFromId(e.OrganisationId); e.Organisation = await guhf.GetOrganisationFromId(e.OrganisationId);
if (matchFound) SearchResults.Add(e.ToEventSummaryDto()); if (matchFound) SearchResults.Add(e.ToEventSummaryDto());
@@ -223,6 +228,91 @@ namespace WebApp.Endpoints
return Results.Ok(SearchResults); return Results.Ok(SearchResults);
}); });
// POST /events/1/add_skill
group.MapPost("/{id}/add_skill/",
async (int id, SingleSkillDto dto, ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) =>
{
Event? Eve = await dbContext.Events.FindAsync(id);
if (Eve is null) return Results.Json(new { message = "Event not found" }, statusCode: 404);
// Sprawdź, czy token należy do organizacji, a jeżeli tak, to do której.
Token? token = await guhf.GetTokenFromHTTPContext(httpContext);
Organisation? org = await guhf.GetOrganisationFromToken(token);
// Jeśli token należy do organizacji, która utworzyła to wydarzenie,
// to zwróć także EventRegistrations. W przeciwnym razie usuń to pole
// przed jego wysłaniem!
if (org is null || org.OrganisationId != Eve.OrganisationId) return Results.Unauthorized();
// Szukamy skilla w bazie o ID takim, jak w otrzymanym DTO
Skill? skill = await dbContext.Skills.FindAsync(dto.Skill);
if (skill is null)
{
return Results.Json(new { message = "Skill not found" }, statusCode: 404);
}
// Sprawdzamy, czy to wydarzenie nie ma już takiego skilla. Jeżeli ma, nie ma sensu dodawać go kilkukrotnie.
EventSkill? es = await dbContext.EventSkills.FirstOrDefaultAsync(e => e.EventId == id && e.SkillId == dto.Skill);
if (es is null)
{
// Nie ma - zatem musimy dodać nowy EventSkill do bazy
EventSkill newEs = dto.ToEventSkillEntity(Eve.EventId);
dbContext.EventSkills.Add(newEs);
await dbContext.SaveChangesAsync();
}
else
{
// Ma - (ta para EventId <-> SkillId już istnieje w bazie); ten Event posiada już ten skill
return Results.Json(new { message = "Skill already assinged to this event!" }, statusCode: 400);
}
return Results.Json(new { message = "Skill added to event successfully!" }, statusCode: 201);
});
// POST /events/1/renive_skill
group.MapPost("/{id}/remove_skill/",
async (int id, SingleSkillDto dto, ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) =>
{
Event? Eve = await dbContext.Events.FindAsync(id);
if (Eve is null) return Results.Json(new { message = "Event not found" }, statusCode: 404);
// Sprawdź, czy token należy do organizacji, a jeżeli tak, to do której.
Token? token = await guhf.GetTokenFromHTTPContext(httpContext);
Organisation? org = await guhf.GetOrganisationFromToken(token);
// Jeśli token należy do organizacji, która utworzyła to wydarzenie,
// to zwróć także EventRegistrations. W przeciwnym razie usuń to pole
// przed jego wysłaniem!
if (org is null || org.OrganisationId != Eve.OrganisationId) return Results.Unauthorized();
// Szukamy skilla w bazie o ID takim, jak w otrzymanym DTO
Skill? skill = await dbContext.Skills.FindAsync(dto.Skill);
if (skill is null)
{
return Results.Json(new { message = "Skill not found" }, statusCode: 404);
}
// Sprawdzamy, czy to wydarzenie nie ma już takiego skilla. Jeżeli nie ma, to nie ma sensu kasować czegoś, czego nie ma.
EventSkill? es = await dbContext.EventSkills.FirstOrDefaultAsync(e => e.EventId == id && e.SkillId == dto.Skill);
if (es is not null)
{
// Ma - zatem musimy usunąć ten EventSkill z bazy
await dbContext.EventSkills.Where(e => e.SkillId == dto.Skill)
.ExecuteDeleteAsync();
}
else
{
// Nie ma - (ta para EventId <-> SkillId nie istnieje w bazie); ten Event nie posiada tego skill'a
return Results.Json(new { message = "This skill isn't assinged to this event!" }, statusCode: 400);
}
return Results.Json(new { message = "Skill removed from event successfully!" }, statusCode: 201);
});
return group; return group;
} }
} }

View File

@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using WebApp.Data; using WebApp.Data;
using WebApp.DTOs;
using WebApp.Entities; using WebApp.Entities;
namespace WebApp.Endpoints; namespace WebApp.Endpoints;
@@ -112,4 +113,49 @@ public class GeneralUseHelpers
// Sprawdza, czy któreś ze słów pasuje (nawet częściowo) do searchTerm // Sprawdza, czy któreś ze słów pasuje (nawet częściowo) do searchTerm
return words.Any(word => word.Contains(searchTerm, StringComparison.OrdinalIgnoreCase)); return words.Any(word => word.Contains(searchTerm, StringComparison.OrdinalIgnoreCase));
} }
public async Task<List<EventDetailsDto>> BuildDetailedEventsDto(ApplicationDbContext context, bool includeEventRegistrations = false)
{
// https://khalidabuhakmeh.com/ef-core-and-aspnet-core-cycle-issue-and-solution
// Jeśli token należy do organizacji, która utworzyła to wydarzenie,
// to zwróć także EventRegistrations. W przeciwnym razie niech będzie to
// puste pole.
ICollection<EventRegistrationDto> ERs = new List<EventRegistrationDto>();
if (includeEventRegistrations)
{
ERs = await context
.EventRegistrations
.Select(er => new EventRegistrationDto
{
EventId = er.EventId,
UserId = er.UserId,
UserName = er.User.FirstName + " " + er.User.LastName,
RegisteredAt = er.RegisteredAt
}).ToListAsync();
}
List<EventDetailsDto> result = await context
.Events
.Select(e => new EventDetailsDto
{
EventId = e.EventId,
OrganisationId = e.OrganisationId,
OrganisationName = e.Organisation.Name,
Title = e.Title,
Description = e.Description,
Location = e.Location,
EventDate = e.EventDate,
EventSkills = e
.EventSkills
.Select(es => new SkillSummaryDto
{
SkillId = es.SkillId,
SkillName = es.Skill.Name
}).ToList(),
EventRegistrations = ERs
}).ToListAsync();
return result;
}
} }

View File

@@ -0,0 +1,26 @@
using Microsoft.EntityFrameworkCore;
using WebApp.Data;
using WebApp.Mapping;
namespace WebApp.Endpoints;
public static class SkillsEndpoints
{
const string GetSkillEndpointName = "GetSkill";
public static RouteGroupBuilder MapSkillsEndpoints(this WebApplication app)
{
var group = app.MapGroup("api/skills").WithParameterValidation();
// GET /skills
group.MapGet("/",
async (ApplicationDbContext dbContext) =>
await dbContext.Skills
.OrderBy(Sk => Sk.SkillId)
.Select(Sk => Sk.ToSkillSummaryDto()) // SkillSummaryDto
.AsNoTracking()
.ToListAsync());
return group;
}
}

View File

@@ -1,4 +1,4 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using WebApp.DTOs; using WebApp.DTOs;
using WebApp.Entities; using WebApp.Entities;
@@ -34,20 +34,21 @@ public static class EventMapping
public static EventSummaryDto ToEventSummaryDto(this Event myEvent) public static EventSummaryDto ToEventSummaryDto(this Event myEvent)
{ {
return new EventSummaryDto( return new EventSummaryDto {
myEvent.EventId, EventId = myEvent.EventId,
myEvent.Organisation!.Name, Organisation = myEvent.Organisation!.Name,
myEvent.OrganisationId, OrganisationId = myEvent.OrganisationId,
myEvent.Title, Title = myEvent.Title,
myEvent.Description, Description = myEvent.Description,
myEvent.Location, Location = myEvent.Location,
myEvent.EventDate, EventDate = myEvent.EventDate,
myEvent.EventSkills, EventSkills = myEvent.EventSkills,
myEvent.EventRegistrations EventRegistrations = myEvent.EventRegistrations
); };
} }
public static EventSummaryNoErDto ToEventSummaryNoErDto(this Event myEvent) public static EventSummaryNoErDto ToEventSummaryNoErDto(this Event myEvent)
{ {
return new EventSummaryNoErDto( return new EventSummaryNoErDto(
myEvent.EventId, myEvent.EventId,
myEvent.Organisation!.Name, myEvent.Organisation!.Name,
@@ -60,18 +61,42 @@ public static class EventMapping
); );
} }
public static EventRegistrationDto ToEventRegistrationDto(this EventRegistration myER)
{
return new EventRegistrationDto {
EventId = myER.EventId,
UserId = myER.UserId,
UserName = myER.User.FirstName + " " + myER.User.LastName,
RegisteredAt = myER.RegisteredAt
};
}
public static EventDetailsDto ToEventDetailsDto(this Event myEvent) public static EventDetailsDto ToEventDetailsDto(this Event myEvent)
{ {
return new EventDetailsDto( List<SkillSummaryDto> ssdto = new List<SkillSummaryDto>();
myEvent.EventId, List<EventRegistrationDto> erdto = new List<EventRegistrationDto>();
myEvent.OrganisationId,
myEvent.Organisation.Name, foreach (EventSkill es in myEvent.EventSkills)
myEvent.Title, {
myEvent.Description, ssdto.Add(es.ToSkillSummaryDto());
myEvent.Location, }
myEvent.EventDate,
myEvent.EventSkills, foreach (EventRegistration er in myEvent.EventRegistrations)
myEvent.EventRegistrations {
); erdto.Add(er.ToEventRegistrationDto());
}
return new EventDetailsDto {
EventId = myEvent.EventId,
OrganisationId = myEvent.OrganisationId,
OrganisationName = myEvent.Organisation.Name,
Title = myEvent.Title,
Description = myEvent.Description,
Location = myEvent.Location,
EventDate = myEvent.EventDate,
EventSkills = ssdto,
EventRegistrations = erdto
};
} }
} }

View File

@@ -0,0 +1,24 @@
using WebApp.DTOs;
using WebApp.Entities;
namespace WebApp.Mapping;
public static class EventSkillMapping
{
public static EventSkill ToEventSkillEntity(this SingleSkillDto SSDto, int eid)
{
return new EventSkill()
{
EventId = eid,
SkillId = SSDto.Skill,
};
}
public static SkillSummaryDto ToSkillSummaryDto(this EventSkill es)
{
return new SkillSummaryDto{
SkillId = es.SkillId,
SkillName = es.Skill.Name
};
}
}

View File

@@ -1,4 +1,4 @@
using WebApp.DTOs; using WebApp.DTOs;
using WebApp.Entities; using WebApp.Entities;
namespace WebApp.Mapping namespace WebApp.Mapping
@@ -16,10 +16,10 @@ namespace WebApp.Mapping
public static SkillSummaryDto ToSkillSummaryDto(this Skill s) public static SkillSummaryDto ToSkillSummaryDto(this Skill s)
{ {
return new SkillSummaryDto( return new SkillSummaryDto {
s.SkillId, SkillId = s.SkillId,
s.Name SkillName = s.Name
); };
} }
} }
} }

View File

@@ -1,17 +1,16 @@
using WebApp.DTOs; using WebApp.DTOs;
using WebApp.Entities; using WebApp.Entities;
namespace WebApp.Mapping namespace WebApp.Mapping;
public static class VolunteerSkillMapping
{ {
public static class VolunteerSkillMapping public static VolunteerSkill ToVolunteerSkillEntity(this SingleSkillDto SSDto, int uid)
{ {
public static VolunteerSkill ToVolunteerSkillEntity(this SingleSkillDto SSDto, int uid) return new VolunteerSkill()
{ {
return new VolunteerSkill() UserId = uid,
{ SkillId = SSDto.Skill,
UserId = uid, };
SkillId = SSDto.Skill,
};
}
} }
} }

View File

@@ -53,6 +53,7 @@ app.UseRouting(); // Enables routing to match incoming request to endpoints
app.MapEventsEndpoints(); app.MapEventsEndpoints();
app.MapOrganizationsEndpoints(); app.MapOrganizationsEndpoints();
app.MapAuthEndpoints(); app.MapAuthEndpoints();
app.MapSkillsEndpoints();
app.MapEventsRegistrationEndpoints(); app.MapEventsRegistrationEndpoints();
app.Run(); app.Run();

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
@@ -68,12 +68,16 @@
<input type="password" id="password" class="form-control input-field" required /> <input type="password" id="password" class="form-control input-field" required />
</div> </div>
<br/> <br />
<button id="logInBtn" class="button" type="submit"> <button id="logInBtn" class="button" type="submit">
<span>Log in</span> <span>Log in</span>
<span>&#11166;</span> <span>&#11166;</span>
</button> </button>
<button id="signUpBtn" class="button" type="button" onclick="alert('Coming soon!')">
<span>Sign up</span>
<span>&#11166;</span>
</button>
<p id="message" style="color: red;"></p> <p id="message" style="color: red;"></p>
</form> </form>

View File

@@ -80,6 +80,7 @@
<script type="module" src="/js/eventModify.js"></script> <script type="module" src="/js/eventModify.js"></script>
<script type="module" src="/js/generalUseHelpers.js"></script> <script type="module" src="/js/generalUseHelpers.js"></script>
<script type="module" src="/js/auth.js"></script>
</body> </body>