Browse Source

feat: add ability to preview event and refactor

pull/79/head
berkansasmaz 5 years ago
parent
commit
1a5fa1b42c
No known key found for this signature in database GPG Key ID: 884D815C3F32BE00
  1. 2
      src/EventHub.Application.Contracts/Events/IEventAppService.cs
  2. 30
      src/EventHub.Application/Events/EventAppService.cs
  3. 6
      src/EventHub.HttpApi/Controllers/Events/EventController.cs
  4. 2
      src/EventHub.Web/Controllers/EventController.cs
  5. 4
      src/EventHub.Web/Controllers/OrganizationController.cs
  6. 1
      src/EventHub.Web/Controllers/OrganizationMembershipController.cs
  7. 38
      src/EventHub.Web/Pages/Events/Components/CreateEventArea/CreateEventAreaViewComponent.cs
  8. 3
      src/EventHub.Web/Pages/Events/Components/CreateEventArea/Default.cshtml
  9. 28
      src/EventHub.Web/Pages/Events/Components/CreateEventArea/_addSessionSection.cshtml
  10. 2
      src/EventHub.Web/Pages/Events/Components/CreateEventArea/_addTrackSection.cshtml
  11. 32
      src/EventHub.Web/Pages/Events/Components/CreateEventArea/_newEventSection.cshtml
  12. 218
      src/EventHub.Web/Pages/Events/Components/CreateEventArea/_previewSection.cshtml
  13. 3
      src/EventHub.Web/Pages/Events/Components/CreateEventArea/create-event-area.js
  14. 2
      src/EventHub.Web/Pages/Events/New.cshtml.cs

2
src/EventHub.Application.Contracts/Events/IEventAppService.cs

@ -13,7 +13,7 @@ namespace EventHub.Events
Task<PagedResultDto<EventInListDto>> GetListAsync(EventListFilterDto input);
Task<List<EventInListDto>> GetDraftEventsByUserId(Guid userId);
Task<List<EventInListDto>> GetDraftEventsByCurrentUser();
Task<EventDetailDto> GetByUrlCodeAsync(string urlCode);

30
src/EventHub.Application/Events/EventAppService.cs

@ -13,7 +13,6 @@ using Volo.Abp.Authorization;
using Volo.Abp.BlobStoring;
using Volo.Abp.Content;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Volo.Abp.Users;
namespace EventHub.Events
@ -159,11 +158,12 @@ namespace EventHub.Events
}
[Authorize]
public async Task<List<EventInListDto>> GetDraftEventsByUserId(Guid userId)
public async Task<List<EventInListDto>> GetDraftEventsByCurrentUser()
{
var eventQueryable = await _eventRepository.GetQueryableAsync();
var organizationQueryable = await _organizationRepository.GetQueryableAsync();
var userId = CurrentUser.GetId();
var query = from @event in eventQueryable
join organization in organizationQueryable on @event.OrganizationId equals organization.Id
where organization.OwnerUserId == userId && @event.IsDraft
@ -177,6 +177,16 @@ namespace EventHub.Events
public async Task<EventDetailDto> GetByUrlCodeAsync(string urlCode)
{
var @event = await _eventRepository.GetAsync(x => x.UrlCode == urlCode, true);
if (@event.IsDraft)
{
if (!CurrentUser.Id.HasValue)
{
throw new AbpAuthorizationException();
}
await CheckIfValidOwnerAsync(@event);
}
var organization = await _organizationRepository.GetAsync(@event.OrganizationId);
var dto = ObjectMapper.Map<Event, EventDetailDto>(@event);
@ -254,7 +264,7 @@ namespace EventHub.Events
public async Task UpdateAsync(Guid id, UpdateEventDto input)
{
var @event = await _eventRepository.GetAsync(id);
await CheckIfValidOwner(@event);
await CheckIfValidOwnerAsync(@event);
await _eventManager.SetLocationAsync(@event, input.IsOnline, input.OnlineLink, input.CountryId, input.City);
@event.SetTitle(input.Title);
@ -275,7 +285,7 @@ namespace EventHub.Events
public async Task AddTrackAsync(Guid id, AddTractDto input)
{
var @event = await _eventRepository.GetAsync(id, true);
await CheckIfValidOwner(@event);
await CheckIfValidOwnerAsync(@event);
@event.AddTract(
GuidGenerator.Create(),
@ -289,7 +299,7 @@ namespace EventHub.Events
public async Task UpdateTrackAsync(Guid id, Guid trackId, UpdateTrackDto input)
{
var @event = await _eventRepository.GetAsync(id, true);
await CheckIfValidOwner(@event);
await CheckIfValidOwnerAsync(@event);
@event.UpdateTrack(
trackId,
@ -303,7 +313,7 @@ namespace EventHub.Events
public async Task DeleteTrackAsync(Guid id, Guid trackId)
{
var @event = await _eventRepository.GetAsync(id, true);
await CheckIfValidOwner(@event);
await CheckIfValidOwnerAsync(@event);
@event.RemoveTrack(trackId);
}
@ -313,7 +323,7 @@ namespace EventHub.Events
{
await CheckIfValidUserNamesAsync(input.SpeakerUserNames);
var @event = await _eventRepository.GetAsync(id);
await CheckIfValidOwner(@event);
await CheckIfValidOwnerAsync(@event);
@event.AddSession(
input.TrackId,
@ -334,7 +344,7 @@ namespace EventHub.Events
{
await CheckIfValidUserNamesAsync(input.SpeakerUserNames);
var @event = await _eventRepository.GetAsync(id);
await CheckIfValidOwner(@event);
await CheckIfValidOwnerAsync(@event);
@event.UpdateSession(
trackId,
@ -354,7 +364,7 @@ namespace EventHub.Events
public async Task DeleteSessionAsync(Guid id, Guid trackId, Guid sessionId)
{
var @event = await _eventRepository.GetAsync(id, true);
await CheckIfValidOwner(@event);
await CheckIfValidOwnerAsync(@event);
@event.RemoveSession(trackId, sessionId);
}
@ -391,7 +401,7 @@ namespace EventHub.Events
return await AsyncExecuter.ToListAsync(query);
}
private async Task CheckIfValidOwner(Event @event)
private async Task CheckIfValidOwnerAsync(Event @event)
{
var organization = await _organizationRepository.GetAsync(@event.OrganizationId);

6
src/EventHub.HttpApi/Controllers/Events/EventController.cs

@ -41,10 +41,10 @@ namespace EventHub.Controllers.Events
}
[HttpGet]
[Route("draft-events-by-user-id/{userId}")]
public async Task<List<EventInListDto>> GetDraftEventsByUserId(Guid userId)
[Route("draft-events-by-user-id")]
public async Task<List<EventInListDto>> GetDraftEventsByCurrentUser()
{
return await _eventAppService.GetDraftEventsByUserId(userId);
return await _eventAppService.GetDraftEventsByCurrentUser();
}
[HttpGet]

2
src/EventHub.Web/Controllers/EventController.cs

@ -6,7 +6,6 @@ using Volo.Abp.AspNetCore.Mvc;
namespace EventHub.Web.Controllers
{
[Route("api/event")]
public class EventController : AbpController
{
private readonly IEventAppService _eventAppService;
@ -17,7 +16,6 @@ namespace EventHub.Web.Controllers
}
[HttpGet]
[Route("get-list")]
public async Task<IActionResult> GetList(EventListFilterDto input)
{
ViewData.Model = (await _eventAppService.GetListAsync(input)).Items.ToList();

4
src/EventHub.Web/Controllers/OrganizationController.cs

@ -6,7 +6,6 @@ using Volo.Abp.AspNetCore.Mvc;
namespace EventHub.Web.Controllers
{
[Route("api/organization")]
public class OrganizationController : AbpController
{
private readonly IOrganizationAppService _organizationAppService;
@ -17,7 +16,6 @@ namespace EventHub.Web.Controllers
}
[HttpGet]
[Route("get-list")]
public async Task<IActionResult> GetList(OrganizationListFilterDto input)
{
ViewData.Model = (await _organizationAppService.GetListAsync(input)).Items.ToList();
@ -29,4 +27,4 @@ namespace EventHub.Web.Controllers
};
}
}
}
}

1
src/EventHub.Web/Controllers/OrganizationMembershipController.cs

@ -17,7 +17,6 @@ namespace EventHub.Web.Controllers
}
[HttpGet]
[Route("get-list")]
public async Task<IActionResult> GetList(OrganizationMemberListFilterDto input)
{
ViewData.Model = (await _organizationMembershipAppService.GetMembersAsync(input)).Items.ToList();

38
src/EventHub.Web/Pages/Events/Components/CreateEventArea/CreateEventAreaViewComponent.cs

@ -63,13 +63,35 @@ public class CreateEventAreaViewComponent : AbpViewComponent
};
ViewData["StepType"] = stepType.ToString();
ViewData["Organizations"] = await GetOrganizationsSelectItemAsync();
ViewData["Countries"] = await GetCountriesSelectItemAsync();
ViewData["Languages"] = GetLanguagesSelectItem();
switch (stepType)
{
case ProgressStepType.NewEvent:
ViewData["Organizations"] = await GetOrganizationsSelectItemAsync();
ViewData["Countries"] = await GetCountriesSelectItemAsync();
ViewData["Languages"] = GetLanguagesSelectItem();
break;
case ProgressStepType.NewSession:
ViewData["Languages"] = GetLanguagesSelectItem();
break;
case ProgressStepType.Preview:
ViewData["OrganizationName"] = await GetOrganizationNameAsync(model.OrganizationId);
if (model.CountryId is not null)
{
ViewData["CountryName"] = await GetCountryNameAsync(model.CountryId!.Value);
}
break;
}
return View("~/Pages/Events/Components/CreateEventArea/Default.cshtml", model);
}
private async Task<string> GetOrganizationNameAsync(Guid organizationId)
{
var organizationList = (await _organizationAppService.GetOrganizationsByUserIdAsync(_currentUser.GetId())).Items;
return organizationList.Single(x => x.Id == organizationId).Name;
}
private async Task<List<SelectListItem>> GetOrganizationsSelectItemAsync()
{
var result = await _organizationAppService.GetOrganizationsByUserIdAsync(_currentUser.GetId());
@ -83,6 +105,13 @@ public class CreateEventAreaViewComponent : AbpViewComponent
).ToList();
}
private async Task<string> GetCountryNameAsync(Guid countryId)
{
var countries = await _eventAppService.GetCountriesLookupAsync();
return countries.Single(x => x.Id == countryId).Name;
}
private async Task<List<SelectListItem>> GetCountriesSelectItemAsync()
{
var result = await _eventAppService.GetCountriesLookupAsync();
@ -175,6 +204,7 @@ public class CreateEventAreaViewComponent : AbpViewComponent
{
NewEvent = 0,
NewTrack,
NewSession
NewSession,
Preview
}
}

3
src/EventHub.Web/Pages/Events/Components/CreateEventArea/Default.cshtml

@ -27,6 +27,9 @@
<div id="CreateSessionContainer" style="@(stepType != CreateEventAreaViewComponent.ProgressStepType.NewSession ? "display: none" : "")">
<partial name="_addSessionSection.cshtml" model="@Model.Tracks"/>
</div>
<div id="PreviewContainer" style="@(stepType != CreateEventAreaViewComponent.ProgressStepType.Preview ? "display: none" : "")">
<partial name="_previewSection.cshtml" model="@Model"/>
</div>
<input type="hidden" id="EventId" value="@eventId"/>
<input type="hidden" id="EventUrlCode" value="@eventUrlCode"/>

28
src/EventHub.Web/Pages/Events/Components/CreateEventArea/_addSessionSection.cshtml

@ -5,19 +5,23 @@
@model List<EventHub.Events.TrackDto>
@{
var languages = ViewData["Languages"] as IList<SelectListItem>;
if (languages is null || !languages.Any())
var languages = new List<SelectListItem>();
@if (ViewData["StepType"]!.ToString() == CreateEventAreaViewComponent.ProgressStepType.NewSession.ToString())
{
throw new BadHttpRequestException("There is no language");
}
languages = languages.Select(l =>
{
if (l.Value == "en")
languages = ViewData["Languages"] as List<SelectListItem>;
if (languages is null || !languages.Any())
{
l.Selected = true;
throw new BadHttpRequestException("There is no language");
}
return l;
}).ToList();
languages = languages.Select(l =>
{
if (l.Value == "en")
{
l.Selected = true;
}
return l;
}).ToList();
}
}
<partial name="_progressSection.cshtml" model="@CreateEventAreaViewComponent.ProgressStepType.NewSession" />
@ -55,7 +59,7 @@
<input type="hidden" id="SpeakersOfSession-@session.Id" value="@(session.Speakers.Any() ? string.Join(", ", session.Speakers.Select(x => x.UserName)).EnsureEndsWith(',').EnsureEndsWith(' ') : "")"/>
<div class="track-item">
<span class="track-name truncate">@session.Title</span>
<span class="track-name">@session.Title.TruncateWithPostfix(25)</span>
<small class="text-primary d-block my-2">@EventDateHelper.GetTimeRangeText(TimeOnly.FromDateTime(session.StartTime), TimeOnly.FromDateTime(session.EndTime)) | @session.Language</small>
@foreach (var speaker in session.Speakers)
{
@ -97,7 +101,7 @@
Step </button>
</div>
<div class="col-6 text-end">
<button href="#" class="btn btn-success">Publish <i class="fa fa-arrow-right ms-2"></i></button>
<button id="PreviewButtonInSessionSection" data-target-step="@CreateEventAreaViewComponent.ProgressStepType.Preview" class="btn btn-primary step-transition">Preview <i class="fa fa-arrow-right ms-2"></i></button>
</div>
</div>
</div>

2
src/EventHub.Web/Pages/Events/Components/CreateEventArea/_addTrackSection.cshtml

@ -42,7 +42,7 @@
<button id="PreviousStepButtonInTrackSection" data-target-step="@CreateEventAreaViewComponent.ProgressStepType.NewEvent" class="btn btn-secondary step-transition"><i class="fa fa-arrow-left me-2"></i> Previous Step </button>
</div>
<div class="col-6 text-end">
<a href="#" class="btn btn-link">Skip This Step</a>
<button id="SkipThisStepButtonInTrackSection" data-target-step="@CreateEventAreaViewComponent.ProgressStepType.Preview" class="btn btn-link step-transition text-decoration-none">Skip This Step</button>
<button id="NextStepButtonInTrackSection" data-target-step="@CreateEventAreaViewComponent.ProgressStepType.NewSession" class="btn btn-primary step-transition">Next Step <i class="fa fa-arrow-right ms-2"></i></button>
</div>
</div>

32
src/EventHub.Web/Pages/Events/Components/CreateEventArea/_newEventSection.cshtml

@ -3,22 +3,28 @@
@model EventHub.Web.Pages.Events.Components.CreateEventArea.CreateEventAreaViewComponent.NewEventViewModel
@{
var organizations = ViewData["Organizations"] as IList<SelectListItem>;
if (organizations is null || !organizations.Any())
var organizations = new List<SelectListItem>();
var countries = new List<SelectListItem>();
var languages = new List<SelectListItem>();
@if (ViewData["StepType"]!.ToString() == CreateEventAreaViewComponent.ProgressStepType.NewEvent.ToString())
{
throw new BadHttpRequestException("There is no organization");
}
organizations = ViewData["Organizations"] as List<SelectListItem>;
if (organizations is null || !organizations.Any())
{
throw new BadHttpRequestException("There is no organization");
}
var countries = ViewData["Countries"] as IList<SelectListItem>;
if (countries is null || !countries.Any())
{
throw new BadHttpRequestException("There is no country");
}
countries = ViewData["Countries"] as List<SelectListItem>;
if (countries is null || !countries.Any())
{
throw new BadHttpRequestException("There is no country");
}
var languages = ViewData["Languages"] as IList<SelectListItem>;
if (languages is null || !languages.Any())
{
throw new BadHttpRequestException("There is no language");
languages = ViewData["Languages"] as List<SelectListItem>;
if (languages is null || !languages.Any())
{
throw new BadHttpRequestException("There is no language");
}
}
}

218
src/EventHub.Web/Pages/Events/Components/CreateEventArea/_previewSection.cshtml

@ -0,0 +1,218 @@
@using EventHub.Web.Pages.Events
@using EventHub.Web.Pages.Events.Components.CreateEventArea
@using Microsoft.AspNetCore.Http
@model EventHub.Web.Pages.Events.Components.CreateEventArea.CreateEventAreaViewComponent.NewEventViewModel
@{
var organizationName = "";
var countryName = "";
@if (ViewData["StepType"]!.ToString() == CreateEventAreaViewComponent.ProgressStepType.Preview.ToString())
{
organizationName = ViewData["OrganizationName"] as string;
if (organizationName.IsNullOrWhiteSpace())
{
throw new BadHttpRequestException("Organization name cannot be empty!");
}
countryName = ViewData["CountryName"] as string;
if (Model is {CountryId: { } } && countryName.IsNullOrWhiteSpace())
{
throw new BadHttpRequestException("Country name cannot be empty when CountryId exists!");
}
}
}
@if (Model is not null)
{
<div class="row">
<div class="col-md-10 mx-auto">
<div class="card">
<div class="card-body profile-content p-5" style="min-height: 480px;">
<h2 class="mb-5">Event Preview</h2>
<div class="row mb-4">
<div class="col-md-4">
<span>Organization Name:</span>
</div>
<div class="col-md-8">
<span class="preview-item">@organizationName</span>
</div>
</div>
<div class="row mb-4">
<div class="col-md-4">
<span>Title:</span>
</div>
<div class="col-md-8">
<span class="preview-item">@Model.Title</span>
</div>
</div>
<div class="row mb-4">
<div class="col-md-4">
<span>Start Date:</span>
</div>
<div class="col-md-8">
<span class="preview-item">@Model.StartTime.ToShortDateString() - @Model.StartTime.ToShortTimeString()</span>
</div>
</div>
<div class="row mb-4">
<div class="col-md-4">
<span>End Date:</span>
</div>
<div class="col-md-8">
<span class="preview-item">@Model.EndTime.ToShortDateString() - @Model.EndTime.ToShortTimeString()</span>
</div>
</div>
<div class="row mb-4">
<div class="col-md-4">
<span>Event’s Explanation:</span>
</div>
<div class="col-md-8">
<p class="preview-item">@Model.Description</p>
</div>
</div>
<div class="row mb-4">
<div class="col-md-4">
<span>Cover Image:</span>
</div>
<div class="col-md-8">
<img src="https://api.openeventhub.com/api/eventhub/event/cover-image/3a003fb9-611a-db0c-82b2-7299ff8e8ce7" class="w-100 rounded-3">
</div>
</div>
@if (Model.IsOnline != null && Model.IsOnline!.Value)
{
<div class="row mb-4">
<div class="col-md-4">
<span>Event Type:</span>
</div>
<div class="col-md-8">
<span class="preview-item">Online</span>
</div>
</div>
@if (!Model.OnlineLink.IsNullOrWhiteSpace())
{
<div class="row mb-4">
<div class="col-md-4">
<span>Url:</span>
</div>
<div class="col-md-8">
<span class="preview-item">@Model.OnlineLink</span>
</div>
</div>
}
}
else if (Model.CountryId.HasValue && !Model.City.IsNullOrEmpty())
{
<div class="row mb-4">
<div class="col-md-4">
<span>Country:</span>
</div>
<div class="col-md-8">
<span class="preview-item">@countryName</span>
</div>
</div>
<div class="row mb-4">
<div class="col-md-4">
<span>City:</span>
</div>
<div class="col-md-8">
<span class="preview-item">@Model.City</span>
</div>
</div>
}
@if (!Model.Language.IsNullOrWhiteSpace())
{
<div class="row mb-4">
<div class="col-md-4">
<span>Language:</span>
</div>
<div class="col-md-8">
<span class="preview-item">@Model.Language</span>
</div>
</div>
}
@if (Model.Capacity.HasValue)
{
<div class="row mb-4">
<div class="col-md-4">
<span>Capacity:</span>
</div>
<div class="col-md-8">
<span class="preview-item">@Model.Capacity</span>
</div>
</div>
}
@if (Model.Tracks.Any())
{
<div class="row mb-4">
<div class="col-md-4">
<span>Tracks:</span>
</div>
<div class="col-md-8">
<span class="preview-item">@Model.Tracks.Count</span>
</div>
</div>
<div class="row mb-4">
<div class="col-md-4">
<span>Sessions:</span>
</div>
</div>
<table class="table">
<thead>
<tr>
@foreach (var track in Model.Tracks)
{
<th class="text-center" width="25%">@track.Name</th>
}
</tr>
</thead>
<tbody>
<tr>
@foreach (var track in Model.Tracks)
{
<td>
@if (track.Sessions.Any())
{
@foreach (var session in track.Sessions)
{
<div class="track-item">
<span class="track-name">@session.Title.TruncateWithPostfix(25)</span>
<small class="text-primary d-block my-2">@EventDateHelper.GetTimeRangeText(TimeOnly.FromDateTime(session.StartTime), TimeOnly.FromDateTime(session.EndTime)) | @session.Language</small>
@foreach (var speaker in session.Speakers)
{
<span class="d-block mb-2">@speaker.UserName</span>
}
</div>
}
}
else
{
<div class="track-item">
<span class="track-name text-primary">There is no session!</span>
<span class="d-block mb-2">Please add session.</span>
</div>
}
</td>
}
</tr>
</tbody>
</table>
}
</div>
<div class="card-footer bg-white border-0 p-5 pt-1">
<div class="row">
<div class="col-6">
<button id="PreviousStepButtonInPreviewSection" data-target-step="@CreateEventAreaViewComponent.ProgressStepType.NewTrack" class="btn btn-secondary step-transition"><i class="fa fa-arrow-left me-2"></i> Previous Step </button>
</div>
<div class="col-6 text-end">
<button href="#" class="btn btn-success">Publish <i class="fa fa-arrow-right ms-2"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
}
else
{
<partial name="_modelNullErrorSection.cshtml" />
}

3
src/EventHub.Web/Pages/Events/Components/CreateEventArea/create-event-area.js

@ -6,7 +6,8 @@
var stepType = {
"NewEvent": "NewEvent",
"NewTrack": "NewTrack",
"NewSession": "NewSession"
"NewSession": "NewSession",
"Preview": "Preview"
}
var widgetManager = $wrapper.data('abp-widget-manager');

2
src/EventHub.Web/Pages/Events/New.cshtml.cs

@ -45,7 +45,7 @@ namespace EventHub.Web.Pages.Events
if (IsHasOrganizations && !IsCreateNew)
{
DraftEventList = await _eventAppService.GetDraftEventsByUserId(CurrentUser.GetId());
DraftEventList = await _eventAppService.GetDraftEventsByCurrentUser();
}
}
}

Loading…
Cancel
Save