Browse Source

Edit event creation page

pull/41/head
Berkan Sasmaz 6 years ago
parent
commit
44eccaffb4
  1. 2
      src/EventHub.Application.Contracts/Events/EventDetailDto.cs
  2. 1
      src/EventHub.Application/Events/EventAppService.cs
  3. 2
      src/EventHub.Domain.Shared/Localization/EventHub/en.json
  4. 2
      src/EventHub.Web/Pages/Events/Components/EventsArea/Default.cshtml
  5. 2
      src/EventHub.Web/Pages/Events/Components/EventsArea/EventsAreaViewComponent.cs
  6. 2
      src/EventHub.Web/Pages/Events/Components/LocationArea/Default.cshtml
  7. 8
      src/EventHub.Web/Pages/Events/Detail.cshtml
  8. 140
      src/EventHub.Web/Pages/Events/New.cshtml
  9. 70
      src/EventHub.Web/Pages/Events/New.cshtml.cs
  10. 55
      src/EventHub.Web/Pages/Events/New.js
  11. 28
      src/EventHub.Web/Pages/Organizations/Components/OrganizationsArea/_organizationListSection.cshtml
  12. 19
      src/EventHub.Web/Pages/Organizations/New.js

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

@ -9,6 +9,8 @@ namespace EventHub.Events
public string OrganizationDisplayName { get; set; }
public string OwnerEmail { get; set; }
public string Title { get; set; }
public string Description { get; set; }

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

@ -164,6 +164,7 @@ namespace EventHub.Events
dto.OrganizationName = organization.Name;
dto.OrganizationDisplayName = organization.DisplayName;
dto.OwnerEmail = (await _userRepository.GetAsync(organization.OwnerUserId)).Email;
dto.CoverImageContent = await GetCoverImageAsync(dto.Id);
return dto;

2
src/EventHub.Domain.Shared/Localization/EventHub/en.json

@ -56,7 +56,7 @@
"OrganizationProfilePictureInfo": "Upload 16:9 aspect ratio pictures for the best view. Maximum file size: 1MB.",
"Close": "Close",
"EventHub:CapacityOfEventFull": "\"{EventTitle}\" event capacity is full!",
"GoToEventAddress": "Go to Event Address",
"GoToOnlineAddress": "Go to Online Address",
"AttendeesCanSeeEventLocation": "Only attendees can see the event's {0}.",
"LoginToSeeLocation": "Login to see location",
"LocationHasNotSpecifiedYet": "Event {0} has not been specified yet.",

2
src/EventHub.Web/Pages/Events/Components/EventsArea/Default.cshtml

@ -6,7 +6,7 @@
<partial name="~/Pages/Events/Components/EventsArea/_eventListSection.cshtml" model="@Model.Events"/>
</div>
@if (Model.IsPagination && Model.TotalCount >= 10 && Model.TotalCount > Model.Events.Count)
@if (Model.IsPagination && Model.TotalCount > Model.MaxResultCount && Model.TotalCount > Model.Events.Count)
{
<div class="row load-more-section">
<div class="col text-center">

2
src/EventHub.Web/Pages/Events/Components/EventsArea/EventsAreaViewComponent.cs

@ -14,8 +14,6 @@ namespace EventHub.Web.Pages.Events.Components.EventsArea
public class EventsAreaViewComponent : AbpViewComponent
{
private readonly IEventAppService _eventAppService;
public List<EventInListDto> Events { get; set; }
public EventsAreaViewComponent(IEventAppService eventAppService)
{

2
src/EventHub.Web/Pages/Events/Components/LocationArea/Default.cshtml

@ -10,7 +10,7 @@
{
if (Model.OnlineLink != null)
{
<a class="detail-pin" href="@Model.OnlineLink"><img src="/assets/pin.svg"> @L["GoToEventAddress"]</a>
<a class="detail-pin" href="@Model.OnlineLink"><img src="/assets/pin.svg"> @L["GoToOnlineAddress"]</a>
}
else
{

8
src/EventHub.Web/Pages/Events/Detail.cshtml

@ -33,7 +33,7 @@
{
<h1 class="mt-4 mt-md-0">
@Model.Event.Title
<a href="/event/edit/@Model.Event.Url" class="btn btn-primary text-white">
<a href="/event/edit/@Model.Event.Url" class="btn btn-primary btn-xs text-white">
<i class="far fa-edit"></i>
</a>
</h1>
@ -44,11 +44,9 @@
}
@await Component.InvokeAsync(typeof(LocationAreaViewComponent), new {eventId = Model.Event.Id})
<h5 class="detail-head mt-4">Organizers</h5>
<h5 class="detail-head mt-4">Owner</h5>
<div>
<img src="/assets/avatar2.png" class="org-avatar">
<img src="/assets/avatar3.png" class="org-avatar">
<img src="/assets/avatar4.png" class="org-avatar">
<img gravatar-email="@Model.Event.OwnerEmail" default-image="Wavatar" gravatar-size="60" class="org-avatar avatar rounded-circle"/>
</div>
@await Component.InvokeAsync(typeof(RegistrationAreaViewComponent), new {eventId = Model.Event.Id})
</div>

140
src/EventHub.Web/Pages/Events/New.cshtml

@ -2,14 +2,12 @@
@inject IHtmlLocalizer<EventHubResource> L
@using EventHub.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@model EventHub.Web.Pages.Events.NewPageModel
@section scripts {
<abp-script src="/Pages/Events/New.js"/>
<abp-script src="/Pages/Events/New.js"/>
}
<h1>@L["NewEvent"]</h1>
@if (!Model.Organizations.Any())
{
<abp-alert alert-type="Danger">
@ -19,31 +17,111 @@
}
else
{
<form method="post" enctype="multipart/form-data">
<abp-select asp-for="Event.OrganizationId" />
<abp-input asp-for="Event.Title" />
<abp-input asp-for="Event.StartTime" />
<abp-input asp-for="Event.EndTime" />
<abp-input asp-for="Event.Description" />
<abp-input asp-for="Event.CoverImageFile" />
<abp-input asp-for="Event.IsOnline" />
<div id="event-link-group" style="display: none">
<abp-input asp-for="Event.OnlineLink" />
</div>
<div id="event-location-group">
<abp-select asp-for="Event.CountryId" />
<abp-input asp-for="Event.City" />
</div>
<abp-select asp-for="Event.Language" />
<abp-input asp-for="Event.Capacity" />
<abp-button size="Large" button-type="Primary" type="submit" text="@L["Submit"].Value" />
</form>
<abp-modal centered="true" scrollable="true" size="Small" id="cover-image-preview-modal">
<abp-modal-header title="Cover Image Preview"></abp-modal-header>
<abp-modal-body>
<img class="img-fluid" id="img-upload" alt="event-cover-image-preview"/>
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Close)"></abp-modal-footer>
</abp-modal>
}
<form method="post" enctype="multipart/form-data">
<div class="container pt-4">
<div class="row py-4">
<div class="col-md-9 mx-auto profile-content">
<div class="card">
<div class="card-body" style="min-height: 496px">
<h3 class="mb-4">Create New Event</h3>
<div class="form">
<div class="row">
<div class="col-md-6">
<div class="form-label-group">
<select asp-for="Event.OrganizationId" asp-items="Model.Organizations" class="form-select">
<option selected value="">Organization</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="text" id="inputTitle" asp-for="Event.Title" class="form-control" placeholder="Title">
<label for="inputTitle">Title</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input id="inputStartdate" asp-for="Event.StartTime" class="form-control" placeholder="Start Date">
<label for="inputStartdate">Start Date</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input id="inputEnddate" asp-for="Event.EndTime" class="form-control" placeholder="End Date">
<label for="inputEnddate">End Date</label>
</div>
</div>
<div class="col-md-12">
<div class="form-label-group">
<input type="text" id="inputDescription" asp-for="Event.Description" class="form-control" placeholder="Description">
<label for="inputDescription">Description</label>
</div>
</div>
<div class="col-md-12">
<h4 class="mb-4">Cover Image</h4>
<div class="row">
<div class="col-5">
<div class="image-area"><img id="imageResult" src="#" alt="" class="img-fluid rounded shadow-sm mx-auto d-block"></div>
</div>
<div class="col-7">
<div>
<p class="mb-3">For horizontal format 600x300 sized upload images.</p>
<input type="file" id="Event_CoverImageFile" asp-for="Event.CoverImageFile" class="form-control border-0" hidden>
<label id="upload-label" for="Event_CoverImageFile" class="btn btn-primary btn-lg text-white">Choose file</label>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<select class="form-select" asp-for="Event.IsOnline">
<option selected="selected" value="">Event Type</option>
<option value="@Boolean.TrueString">Online</option>
<option value="@Boolean.FalseString">In Person</option>
</select>
</div>
<div class="col-md-6 event-link-group" style="display: none">
<div class="form-label-group">
<input type="text" id="inputOnlineLink" asp-for="Event.OnlineLink" class="form-control" placeholder="Online Link">
<label for="inputOnlineLink">Online Link</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="number" id="inputCapacity" asp-for="Event.Capacity" class="form-control" placeholder="Capacity">
<label for="inputCapacity">Capacity</label>
</div>
</div>
<div class="col-md-6 event-location-group">
<select asp-for="Event.CountryId" asp-items="Model.Countries" class="form-select">
<option selected="" value="">Country</option>
</select>
</div>
<div class="col-md-6 event-location-group">
<div class="form-label-group">
<input type="text" id="inputCity" asp-for="Event.City" class="form-control" placeholder="City">
<label for="inputCity">City</label>
</div>
</div>
<div class="col-md-6">
<select asp-for="Event.Language" asp-items="Model.Languages" aria-label="en" class="form-select">
<option selected value="">Language</option>
</select>
</div>
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary btn-lg">
Publish New Event
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
}

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

@ -50,7 +50,38 @@ namespace EventHub.Web.Pages.Events
await FillCountriesAsync();
FillLanguages();
}
public async Task<IActionResult> OnPostAsync()
{
try
{
ValidateModel();
var input = ObjectMapper.Map<NewEventViewModel, CreateEventDto>(Event);
if (Event.CoverImageFile != null && Event.CoverImageFile.Length > 0)
{
using (var memoryStream = new MemoryStream())
{
await Event.CoverImageFile.CopyToAsync(memoryStream);
input.CoverImageContent = memoryStream.ToArray();
}
}
var eventDto = await _eventAppService.CreateAsync(input);
return RedirectToPage("/Events/Detail", new {url = eventDto.UrlCode});
}
catch (Exception exception)
{
ShowAlert(exception);
await FillOrganizationsAsync();
await FillCountriesAsync();
FillLanguages();
return Page();
}
}
private async Task FillOrganizationsAsync()
{
var result = await _organizationAppService.GetMyOrganizationsAsync();
@ -92,36 +123,6 @@ namespace EventHub.Web.Pages.Events
}
).ToList();
}
public async Task<IActionResult> OnPostAsync()
{
try
{
ValidateModel();
var input = ObjectMapper.Map<NewEventViewModel, CreateEventDto>(Event);
if (Event.CoverImageFile != null && Event.CoverImageFile.Length > 0)
{
using (var memoryStream = new MemoryStream())
{
await Event.CoverImageFile.CopyToAsync(memoryStream);
input.CoverImageContent = memoryStream.ToArray();
}
}
var eventDto = await _eventAppService.CreateAsync(input);
return RedirectToPage("/Events/Detail", new {url = eventDto.UrlCode});
}
catch (Exception exception)
{
ShowAlert(exception);
await FillOrganizationsAsync();
await FillCountriesAsync();
FillLanguages();
return Page();
}
}
public class NewEventViewModel
{
@ -134,10 +135,12 @@ namespace EventHub.Web.Pages.Events
public string Title { get; set; }
[Required]
public DateTime StartTime { get; set; }
[DataType(DataType.DateTime)]
public DateTime StartTime { get; set; } = DateTime.Now;
[Required]
public DateTime EndTime { get; set; }
[DataType(DataType.DateTime)]
public DateTime EndTime { get; set; } = DateTime.Now;
[Required]
[StringLength(EventConsts.MaxDescriptionLength, MinimumLength = EventConsts.MinDescriptionLength)]
@ -151,7 +154,8 @@ namespace EventHub.Web.Pages.Events
[AllowedExtensions(new string[] { ".jpg", ".png", ".jpeg" })]
public IFormFile CoverImageFile { get; set; }
public bool IsOnline { get; set; }
[Required]
public bool? IsOnline { get; set; }
[CanBeNull]
[StringLength(EventConsts.MaxOnlineLinkLength, MinimumLength = EventConsts.MinOnlineLinkLength)]

55
src/EventHub.Web/Pages/Events/New.js

@ -1,48 +1,63 @@
$(function () {
var l = abp.localization.getResource('EventHub');
$("#Event_CountryId").prepend("<option value='' selected='selected'></option>");
$("#Event_Language").prepend("<option value='' selected='selected'></option>");
$('#Event_IsOnline').click(function() {
if ($(this).is(':checked')) {
$("#event-link-group").show();
$("#event-location-group").hide();
var isOnline = $("#Event_IsOnline option:selected").val()
if (isOnline === "True") {
$(".event-link-group").show();
$(".event-location-group").hide();
}else{
$(".event-link-group").hide();
$(".event-location-group").show();
}
$('#Event_IsOnline').on('change', '', function() {
var isOnline = $("#Event_IsOnline option:selected").val()
if (isOnline === "True") {
$(".event-link-group").show();
$(".event-location-group").hide();
}else{
$("#event-link-group").hide();
$("#event-location-group").show();
$(".event-link-group").hide();
$(".event-location-group").show();
}
});
var infoArea = document.getElementById( 'upload-label' );
var fileInput = document.getElementById('Event_CoverImageFile');
var file;
fileInput.addEventListener('change', function () {
var showModal = true;
var showFile = true;
file = fileInput.files[0];
if (file === undefined){
$('#Event_CoverImageFile').val('');
$('#imageResult').attr('src', '#');
infoArea.textContent = 'Choose file'
return;
}
var permittedExtensions = ["jpg", "jpeg", "png"]
var fileExtension = $(this).val().split('.').pop();
if (permittedExtensions.indexOf(fileExtension) === -1) {
showModal = false;
showFile = false;
abp.message.error(l('EventCoverImageExtensionNotAllowed'))
.then(() => {
.then(() => {
$('#Event_CoverImageFile').val('');
file = null;
});
}
else if(file.size > 1024*1024) {
showModal = false;
showFile = false;
abp.message.error(l('EventCoverImageSizeExceedMessage'))
.then(() => {
.then(() => {
$('#Event_CoverImageFile').val('');
file = null;
});
}
var img = new Image();
img.onload = function() {
img.onload = function () {
var imageError = true;
var sizes = {
width: this.width,
@ -50,22 +65,22 @@ $(function () {
};
URL.revokeObjectURL(this.src);
if(showModal && imageError) {
if(showFile && imageError) {
readURL(file);
$('#cover-image-preview-modal').modal('show');
}
}
var objectURL = URL.createObjectURL(file);
img.src = objectURL;
});
function readURL(input) {
if (input) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img-upload').attr('src', e.target.result);
$('#imageResult').attr('src', e.target.result);
infoArea.textContent = 'File name: ' + input.name;
}
reader.readAsDataURL(input);

28
src/EventHub.Web/Pages/Organizations/Components/OrganizationsArea/_organizationListSection.cshtml

@ -0,0 +1,28 @@
@model List<EventHub.Organizations.OrganizationInListDto>
@foreach (var organization in Model)
{
<div class="col-lg-4 col-md-6 organization">
<div class="card">
@if (organization.ProfilePictureContent == null)
{
<img src="assets/card-img.png" class="card-img-top" alt="@organization.Name">
}
else
{
<img src="@($"data:image/png;base64,{Convert.ToBase64String(organization.ProfilePictureContent)}")" class="card-img-top" alt="@organization.Name">
}
<div class="card-body">
<div class="event-container">
<div class="event-info">
<h5>@organization.DisplayName</h5>
<p>
@organization.Description
</p>
</div>
<a href="@Url.Page("/Organizations/Profile", new {name = organization.Name})" class="btn btn-link p-0">Details <img src="assets/more-btn.svg"></a>
</div>
</div>
</div>
</div>
}

19
src/EventHub.Web/Pages/Organizations/New.js

@ -1,23 +1,33 @@
$(function () {
var l = abp.localization.getResource('EventHub');
var infoArea = document.getElementById( 'upload-label' );
var fileInput = document.getElementById('Organization_ProfilePictureFile');
var file;
fileInput.addEventListener('change', function () {
var showFile = true;
file = fileInput.files[0];
if (file === undefined){
$('#Organization_ProfilePictureFile').val('');
$('#imageResult').attr('src', '#');
infoArea.textContent = 'Choose file'
return;
}
var permittedExtensions = ["jpg", "jpeg", "png"]
var fileExtension = $(this).val().split('.').pop();
if (permittedExtensions.indexOf(fileExtension) === -1) {
abp.message.error(l('OrganizationCoverImageExtensionNotAllowed'))
showFile = false;
abp.message.error(l('OrganizationProfilePictureExtensionNotAllowed'))
.then(() => {
$('#Organization_ProfilePictureFile').val('');
file = null;
});
} else if (file.size > 1024 * 1024) {
abp.message.error(l('OrganizationCoverImageSizeExceedMessage'))
showFile = false;
abp.message.error(l('OrganizationProfilePictureSizeExceedMessage'))
.then(() => {
$('#Organization_ProfilePictureFile').val('');
file = null;
@ -33,7 +43,7 @@ $(function () {
};
URL.revokeObjectURL(this.src);
if (imageError) {
if (showFile && imageError) {
readURL(file);
}
}
@ -48,6 +58,7 @@ $(function () {
reader.onload = function (e) {
$('#imageResult').attr('src', e.target.result);
infoArea.textContent = 'File name: ' + input.name;
}
reader.readAsDataURL(input);

Loading…
Cancel
Save