Browse Source

Revise event edit page

pull/41/head
Berkan Sasmaz 5 years ago
parent
commit
6d87dd3414
  1. 8
      src/EventHub.Application.Contracts/Events/EventDetailDto.cs
  2. 4
      src/EventHub.Application.Contracts/Events/IEventAppService.cs
  3. 3
      src/EventHub.Application.Contracts/Events/UpdateEventDto.cs
  4. 1
      src/EventHub.Application/EventHubApplicationAutoMapperProfile.cs
  5. 24
      src/EventHub.Application/Events/EventAppService.cs
  6. 31
      src/EventHub.Web/Controllers/EventController.cs
  7. 1
      src/EventHub.Web/EventHubWebAutoMapperProfile.cs
  8. 187
      src/EventHub.Web/Pages/Events/Edit.cshtml
  9. 135
      src/EventHub.Web/Pages/Events/Edit.cshtml.cs
  10. 224
      src/EventHub.Web/Pages/Events/Edit.js
  11. 37
      src/EventHub.Web/Pages/Events/New.cshtml.cs
  12. 9
      src/EventHub.Web/Pages/Organizations/Edit.cshtml
  13. 4
      src/EventHub.Web/Pages/Organizations/Edit.cshtml.cs

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

@ -5,6 +5,8 @@ namespace EventHub.Events
{
public class EventDetailDto : EntityDto<Guid>
{
public Guid OrganizationId { get; set; }
public string OrganizationName { get; set; }
public string OrganizationDisplayName { get; set; }
@ -22,6 +24,12 @@ namespace EventHub.Events
public byte[] CoverImageContent { get; set; }
public bool IsOnline { get; set; }
public string OnlineLink { get; set; }
public Guid? CountryId { get; set; }
public string City { get; set; }
public bool IsLive { get; set; }

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

@ -21,9 +21,5 @@ namespace EventHub.Events
Task<bool> IsEventOwnerAsync(Guid id);
Task UpdateAsync(Guid id, UpdateEventDto input);
Task UpdateEventTimingAsync(Guid id, UpdateEventTimingDto input);
Task SaveCoverImageAsync(Guid id, byte[] coverImageContent);
}
}

3
src/EventHub.Application.Contracts/Events/UpdateEventDto.cs

@ -13,6 +13,9 @@ namespace EventHub.Events
[Required]
[StringLength(EventConsts.MaxDescriptionLength, MinimumLength = EventConsts.MinDescriptionLength)]
public string Description { get; set; }
[CanBeNull]
public byte[] CoverImageContent { get; set; }
public bool IsOnline { get; set; }

1
src/EventHub.Application/EventHubApplicationAutoMapperProfile.cs

@ -24,6 +24,7 @@ namespace EventHub
.Ignore(x => x.OrganizationDisplayName)
.Ignore(x => x.IsLiveNow);
CreateMap<Event, EventDetailDto>()
.Ignore(x => x.OrganizationId)
.Ignore(x => x.OrganizationName)
.Ignore(x => x.OrganizationDisplayName);

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

@ -176,6 +176,7 @@ namespace EventHub.Events
var dto = ObjectMapper.Map<Event, EventDetailDto>(@event);
dto.OrganizationId = organization.Id;
dto.OrganizationName = organization.Name;
dto.OrganizationDisplayName = organization.DisplayName;
dto.OwnerEmail = (await _userRepository.GetAsync(organization.OwnerUserId)).Email;
@ -249,29 +250,16 @@ namespace EventHub.Events
@event.Language = input.Language;
await _eventManager.SetCapacityAsync(@event, input.Capacity);
await _eventRepository.UpdateAsync(@event);
}
[Authorize]
public async Task UpdateEventTimingAsync(Guid id, UpdateEventTimingDto input)
{
var @event = await _eventRepository.GetAsync(id);
if (@event.TimingChangeCount >= EventConsts.MaxTimingChangeCountForUser)
if (input.CoverImageContent != null && input.CoverImageContent.Length > 0)
{
throw new BusinessException(EventHubErrorCodes.CantChangeEventTiming)
.WithData("MaxTimingChangeLimit", EventConsts.MaxTimingChangeCountForUser);
await SaveCoverImageAsync(@event.Id, input.CoverImageContent);
}
@event.SetTime(input.StartTime, input.EndTime);
@event.TimingChangeCount++;
await _eventRepository.UpdateAsync(@event);
}
[Authorize]
public async Task SaveCoverImageAsync(Guid id, byte[] coverImageContent)
private async Task SaveCoverImageAsync(Guid id, byte[] coverImageContent)
{
var blobName = id.ToString();

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

@ -1,12 +1,8 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using EventHub.Events;
using EventHub.Web.Pages.Events;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
using EditPageModel = EventHub.Web.Pages.Events.EditPageModel;
namespace EventHub.Web.Controllers
{
@ -32,32 +28,5 @@ namespace EventHub.Web.Controllers
ViewData = ViewData
};
}
[Authorize]
[HttpPost]
[Route("update-timing")]
public async Task UpdateEventTiming(EditPageModel.EditEventTimingViewModel input)
{
await _eventAppService.UpdateEventTimingAsync(input.Id, new UpdateEventTimingDto { StartTime = input.StartTime, EndTime = input.EndTime });
}
[HttpPost]
[Authorize]
[Route("save-cover-image")]
public async Task SaveCoverImage([FromForm] EventCoverImageInput input)
{
var coverImageContent = new byte[] {};
if (input.CoverImageFile.Length > 0)
{
using (var memoryStream = new MemoryStream())
{
await input.CoverImageFile.CopyToAsync(memoryStream);
coverImageContent = memoryStream.ToArray();
}
await _eventAppService.SaveCoverImageAsync(input.EventId, coverImageContent);
}
}
}
}

1
src/EventHub.Web/EventHubWebAutoMapperProfile.cs

@ -18,7 +18,6 @@ namespace EventHub.Web
CreateMap<EditOrganizationViewModel, UpdateOrganizationDto>();
CreateMap<EventDetailDto, EditPageModel.EditEventViewModel>();
CreateMap<EditPageModel.EditEventViewModel, UpdateEventDto>();
CreateMap<EventDetailDto, EditPageModel.EditEventTimingViewModel>();
}
}
}

187
src/EventHub.Web/Pages/Events/Edit.cshtml

@ -2,90 +2,127 @@
@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.EditPageModel
@section scripts {
<abp-script src="/Pages/Events/Edit.js"/>
}
<input type="hidden" value="@Model.Url" id="event-detail-url"/>
<div class="container mb-4">
<h1>@L["EditEvent"]</h1>
<abp-tabs tab-style="Pill">
<abp-tab title="@(L["EventInformation"].Value)">
<form method="post" class="mt-3" id="Event_Information_Form">
<abp-input asp-for="Event.Id"/>
<abp-input asp-for="Event.Title"/>
<abp-input asp-for="Event.Description"/>
<abp-input asp-for="Event.IsOnline"/>
<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 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>
<div class="card">
<div class="card-body" style="min-height: 496px">
<h3 class="mb-4">Edit Event</h3>
<div class="form">
<div class="row">
<input type="hidden" value="@Model.Url" id="event-detail-url"/>
<abp-input asp-for="Event.Id"/>
<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>
<abp-select asp-for="Event.Language"/>
<abp-input label="@(L["EventCapacityLabel"].Value)" info="@(L["EventCapacityInfo", Model.AttendeeCount].Value)" asp-for="Event.Capacity" name="capacity" min="@Model.AttendeeCount"/>
<div class="col-md-12">
<h4 class="mb-4">Cover Image</h4>
<div class="row">
<div class="col-5">
<div class="image-area">
@if (Model.CoverImageContent != null && Model.CoverImageContent.Length > 0)
{
<img id="imageResult" src="@($"data:image/png;base64,{Convert.ToBase64String(Model.CoverImageContent)}")" alt="" class="img-fluid rounded shadow-sm mx-auto d-block">
}
else
{
<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>
<abp-button size="Large" button-type="Primary" type="submit" text="@L["Submit"].Value"/>
</form>
</abp-tab>
<abp-tab title="@(L["EventTiming"].Value)">
<div class="alert alert-info mt-3" role="alert" >
<b>@L["Note"]</b> : @L["EventTimingChangeCountWarningMessage"]
</div>
<div class="alert alert-warning mt-3" role="alert">
<b>@L["Note"]</b> : @L["EventTimingChangeEmailNotificationMessage"]
</div>
<form method="post" id="Event_Timing_Form">
<abp-input asp-for="EventTiming.Id"/>
<abp-input asp-for="EventTiming.StartTime"/>
<abp-input asp-for="EventTiming.EndTime"/>
<abp-button size="Large" button-type="Primary" type="button" id="btn-event-timing" text="@L["Submit"].Value"/>
</form>
</abp-tab>
<abp-tab title="@(L["EventCoverImage"].Value)">
<form method="post" id="cover-image-form" class="mt-3">
<input type="hidden" id="event-id" value="@Model.Event.Id"/>
<abp-row>
<abp-column size="_12" v-align="Center">
<div class="form-group">
<label>@L["CoverImage"]</label>
<div class="custom-file">
<input id="event-cover-image-input" type="file" class="custom-file-input form-control">
<label id="choose-cover-image" class="custom-file-label" for="customFile">@L["ChooseEventCoverImage"]</label>
<small id="event-cover-image-info-text" class="form-text text-muted mt-2">@L["ChooseEventCoverImageInfo"]</small>
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary btn-lg">
Edit Event
</button>
</div>
</div>
</div>
</abp-column>
</abp-row>
<abp-button class="btn-block" id="event-cover-image-btnSubmit" button-type="Primary" type="submit" text="@L["Submit"].Value" />
</form>
</abp-tab>
</abp-tabs>
<abp-modal centered="true" scrollable="true" size="Large" id="event-timing-preview-modal">
<abp-modal-header title="@(L["EventTimingPreview"].Value)"></abp-modal-header>
<abp-modal-body>
@L["EventTimingChangeEmailNotificationMessage"]
</abp-modal-body>
<abp-modal-footer>
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<button type="button" id="event-timing-confirm" class="btn btn-success">Confirm</button>
</abp-modal-footer>
</abp-modal>
<abp-modal centered="true" scrollable="true" size="Small" id="cover-image-preview-modal">
<abp-modal-header title="@(L["CoverImagePreview"].Value)"></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>
</div>
</div>
</div>
</div>
</div>
</div>
</form>

135
src/EventHub.Web/Pages/Events/Edit.cshtml.cs

@ -3,10 +3,11 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using EventHub.Events;
using EventHub.Events.Registrations;
using EventHub.Organizations;
using EventHub.Web.Helpers;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
@ -25,38 +26,34 @@ namespace EventHub.Web.Pages.Events
[BindProperty]
public EditEventViewModel Event { get; set; }
[BindProperty]
public EditEventTimingViewModel EventTiming { get; set; }
public int AttendeeCount { get; set; }
public List<SelectListItem> Organizations { get; private set; }
public List<SelectListItem> Countries { get; private set; }
public List<SelectListItem> Languages { get; private set; }
public byte[] CoverImageContent { get; private set; }
private readonly IEventAppService _eventAppService;
private readonly IEventRegistrationAppService _eventRegistrationAppService;
private readonly IOrganizationAppService _organizationAppService;
public EditPageModel(IEventAppService eventAppService, IEventRegistrationAppService eventRegistrationAppService)
public EditPageModel(
IEventAppService eventAppService,
IOrganizationAppService organizationAppService)
{
_eventAppService = eventAppService;
_eventRegistrationAppService = eventRegistrationAppService;
_organizationAppService = organizationAppService;
}
public async Task OnGetAsync()
{
var urlCode = EventUrlCodeHelper.GetCodeFromUrl(Url);
var eventDetailDto = await _eventAppService.GetByUrlCodeAsync(urlCode);
CoverImageContent = eventDetailDto.CoverImageContent;
Event = ObjectMapper.Map<EventDetailDto, EditEventViewModel>(eventDetailDto);
EventTiming = ObjectMapper.Map<EventDetailDto, EditEventTimingViewModel>(eventDetailDto);
FillLanguages();
await FillOrganizationsAsync();
await FillCountriesAsync();
await GetLocationInfoAsync();
AttendeeCount = await _eventRegistrationAppService.GetAttendeeCountAsync(Event.Id);
FillLanguages();
}
public async Task<IActionResult> OnPostAsync()
{
try
@ -64,6 +61,16 @@ namespace EventHub.Web.Pages.Events
ValidateModel();
var input = ObjectMapper.Map<EditEventViewModel, UpdateEventDto>(Event);
if (Event.CoverImageFile != null && Event.CoverImageFile.Length > 0)
{
using (var memoryStream = new MemoryStream())
{
await Event.CoverImageFile.CopyToAsync(memoryStream);
input.CoverImageContent = memoryStream.ToArray();
}
}
await _eventAppService.UpdateAsync(Event.Id, input);
return RedirectToPage("./Detail", new { url = Url });
@ -71,11 +78,29 @@ namespace EventHub.Web.Pages.Events
catch (Exception exception)
{
ShowAlert(exception);
FillLanguages();
await FillOrganizationsAsync();
await FillCountriesAsync();
FillLanguages();
return Page();
}
}
private async Task FillOrganizationsAsync()
{
var result = await _organizationAppService.GetMyOrganizationsAsync();
Organizations = result.Items.Select(
organization => new SelectListItem
{
Value = organization.Id.ToString(),
Text = organization.DisplayName
}
).ToList();
if (Event.OrganizationId != Guid.Empty)
{
Organizations.Single(x => x.Value == Event.OrganizationId.ToString()).Selected = true;
}
}
private async Task FillCountriesAsync()
{
@ -88,6 +113,11 @@ namespace EventHub.Web.Pages.Events
Text = country.Name
}
).ToList();
if (Event.CountryId.HasValue)
{
Countries.Single(x => x.Value == Event.CountryId.ToString()).Selected = true;
}
}
private void FillLanguages()
@ -105,78 +135,67 @@ namespace EventHub.Web.Pages.Events
Text = cultureInfo.EnglishName
}
).ToList();
}
private async Task GetLocationInfoAsync()
{
var eventLocationDto = await _eventAppService.GetLocationAsync(Event.Id);
Event.City = eventLocationDto.City;
Event.OnlineLink = eventLocationDto.OnlineLink;
Event.CountryId = Guid.TryParse(
Countries.FirstOrDefault(x => x.Text == eventLocationDto.Country)?.Value,
out var countryId
)
? countryId
: null;
if (!string.IsNullOrWhiteSpace(Event.Language))
{
Languages.Single(x => x.Value == Event.Language).Selected = true;
}
}
public class EditEventViewModel
{
[HiddenInput]
public Guid Id { get; set; }
[SelectItems(nameof(Organizations))]
[DisplayName("Organization")]
public Guid OrganizationId { get; set; }
[Required]
[StringLength(EventConsts.MaxTitleLength, MinimumLength = EventConsts.MinTitleLength)]
public string Title { get; set; }
[Required]
[DataType(DataType.DateTime)]
public DateTime StartTime { get; set; } = DateTime.Now;
[Required]
[DataType(DataType.DateTime)]
public DateTime EndTime { get; set; } = DateTime.Now;
[Required]
[StringLength(EventConsts.MaxDescriptionLength, MinimumLength = EventConsts.MinDescriptionLength)]
[TextArea]
public string Description { get; set; }
[CanBeNull]
[Display(Name = "Cover Image")]
[DataType(DataType.Upload)]
[MaxFileSize(EventConsts.MaxCoverImageFileSize)]
[AllowedExtensions(new string[] { ".jpg", ".png", ".jpeg" })]
public IFormFile CoverImageFile { get; set; }
[Required]
public bool IsOnline { get; set; }
[CanBeNull]
[StringLength(EventConsts.MaxOnlineLinkLength, MinimumLength = EventConsts.MinOnlineLinkLength)]
public string OnlineLink { get; set; }
[SelectItems(nameof(Countries))]
[DisplayName("Country")]
public Guid? CountryId { get; set; }
[CanBeNull]
[StringLength(EventConsts.MaxCityLength, MinimumLength = EventConsts.MinCityLength)]
public string City { get; set; }
[SelectItems(nameof(Languages))]
[DisplayName("Language")]
public string Language { get; set; }
[Range(1, int.MaxValue)]
public int? Capacity { get; set; }
}
public class EditEventTimingViewModel
{
[HiddenInput]
public Guid Id { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}
public class EventCoverImageInput
{
[Required]
public Guid EventId { get; set; }
[Required]
[DataType(DataType.Upload)]
[MaxFileSize(EventConsts.MaxCoverImageFileSize)]
[AllowedExtensions(new string[] { ".jpg", ".png", ".jpeg" })]
public IFormFile CoverImageFile { get; set; }
}
}

224
src/EventHub.Web/Pages/Events/Edit.js

@ -1,178 +1,90 @@
$(function () {
var l = abp.localization.getResource('EventHub');
$("#Event_CountryId").prepend("<option value=''></option>");
$("#Event_Language").prepend("<option value=''></option>");
if($("#Event_IsOnline").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').click(function() {
if ($(this).is(':checked')) {
$("#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();
}
});
$("#btn-event-timing").click(function () {
$("#event-timing-preview-modal").modal("show");
});
$("#event-timing-confirm").click(function () {
$("#Event_Timing_Form").submit();
$("#event-timing-preview-modal").modal("hide");
})
$("#Event_Timing_Form").submit(function (e) {
e.preventDefault();
if(!$(this).valid()) {
return false;
}
var data = {
id: $('#EventTiming_Id').val(),
startTime: $('#EventTiming_StartTime').val(),
endTime: $('#EventTiming_EndTime').val()
};
$.ajax({
url: abp.appPath + `api/event/update-timing`,
type: 'POST',
dataType: 'json',
data: data,
success: function (data) {
abp.message
.success(l("EventTimingChangeSuccessMessage"))
.then(data => window.location.href = "/events/" + $("#event-detail-url").val());
},
error: function (data) {
abp.message.error(data.responseJSON.error.message);
}
});
})
// Cover Image Section
$('#event-cover-image-btnSubmit').prop( "disabled", true );
var fileInput = document.getElementById('event-cover-image-input');
var infoArea = document.getElementById('upload-label');
var fileInput = document.getElementById('Event_CoverImageFile');
var file;
fileInput.addEventListener('change', function () {
var showModal = true;
if (fileInput !== null) {
fileInput.addEventListener('change', function () {
var showFile = true;
file = fileInput.files[0];
file = fileInput.files[0];
if (file === undefined){
$('#event-cover-image-input').val('');
$("#choose-cover-image").html(l("ChooseEventCoverImage"));
$('#event-cover-image-btnSubmit').prop( "disabled", true );
return;
}else{
document.getElementById("choose-cover-image").innerHTML = file.name;
}
var permittedExtensions = ["jpg", "jpeg", "png"]
var fileExtension = $(this).val().split('.').pop();
if (permittedExtensions.indexOf(fileExtension) === -1) {
showModal = false;
abp.message.error(l('EventCoverImageExtensionNotAllowed'))
.then(() => {
$('#event-cover-image-file').val('');
$("#choose-cover-image").html(l("ChooseEventCoverImage"));
file = null;
});
}
else if(file.size > 1024*1024) {
showModal = false;
abp.message.error(l('EventCoverImageSizeExceedMessage'))
.then(() => {
$('#event-cover-image-file').val('');
$("#choose-cover-image").html(l("ChooseEventCoverImage"));
file = null;
});
}
var img = new Image();
img.onload = function() {
var imageError = true;
var sizes = {
width: this.width,
height: this.height
};
URL.revokeObjectURL(this.src);
if(showModal && imageError) {
readURL(file);
$('#cover-image-preview-modal').modal('show');
if (file === undefined) {
$('#Event_CoverImageFile').val('');
$('#imageResult').attr('src', '#');
infoArea.textContent = 'Choose file'
return;
}
}
var objectURL = URL.createObjectURL(file);
img.src = objectURL;
if (file.size > 0 && file.size < 1024*1024){
$('#event-cover-image-btnSubmit').prop( "disabled", false);
}
});
function readURL(input) {
if (input) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img-upload').attr('src', e.target.result);
var permittedExtensions = ["jpg", "jpeg", "png"]
var fileExtension = $(this).val().split('.').pop();
if (permittedExtensions.indexOf(fileExtension) === -1) {
showFile = false;
abp.message.error(l('EventCoverImageExtensionNotAllowed'))
.then(() => {
$('#Event_CoverImageFile').val('');
file = null;
});
} else if (file.size > 1024 * 1024) {
showFile = false;
abp.message.error(l('EventCoverImageSizeExceedMessage'))
.then(() => {
$('#Event_CoverImageFile').val('');
file = null;
});
}
reader.readAsDataURL(input);
}
}
$('form#cover-image-form').submit(function (e) {
e.preventDefault();
var eventId = document.getElementById("event-id").value;
var img = new Image();
img.onload = function () {
var imageError = true;
var sizes = {
width: this.width,
height: this.height
};
URL.revokeObjectURL(this.src);
if (showFile && imageError) {
readURL(file);
}
}
if(!$(this).valid()) {
return false;
}
var objectURL = URL.createObjectURL(file);
img.src = objectURL;
});
var formData = new FormData();
formData.append("EventId", eventId);
formData.append("CoverImageFile", file);
function readURL(input) {
if (input) {
var reader = new FileReader();
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
if(percentComplete !== 100){
fileInput.prop( "disabled", true );
$('#event-cover-image-btnSubmit').prop( "disabled", true );
}
}
}, false);
reader.onload = function (e) {
$('#imageResult').attr('src', e.target.result);
infoArea.textContent = 'File name: ' + input.name;
}
return xhr;
},
url: abp.appPath + `api/event/save-cover-image`,
data: formData,
type: 'POST',
contentType: false,
processData: false,
success: function(data){
abp.message
.success(l('EventCoverImageEditSuccessMessage'))
.then(data => window.location.href = "/events/" + $("#event-detail-url").val());
},
error: function (data) {
abp.message.error(data.responseJSON.error.message);
reader.readAsDataURL(input);
}
});
});
}
}
});

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

@ -20,8 +20,7 @@ namespace EventHub.Web.Pages.Events
{
public class NewPageModel : EventHubPageModel
{
[BindProperty]
public NewEventViewModel Event { get; set; }
[BindProperty] public NewEventViewModel Event { get; set; }
public List<SelectListItem> Organizations { get; private set; }
public List<SelectListItem> Countries { get; private set; }
@ -50,7 +49,7 @@ namespace EventHub.Web.Pages.Events
await FillCountriesAsync();
FillLanguages();
}
public async Task<IActionResult> OnPostAsync()
{
try
@ -81,7 +80,7 @@ namespace EventHub.Web.Pages.Events
return Page();
}
}
private async Task FillOrganizationsAsync()
{
var result = await _organizationAppService.GetMyOrganizationsAsync();
@ -93,11 +92,11 @@ namespace EventHub.Web.Pages.Events
}
).ToList();
}
private async Task FillCountriesAsync()
{
var result = await _eventAppService.GetCountriesLookupAsync();
Countries = result.Select(
country => new SelectListItem
{
@ -146,35 +145,33 @@ namespace EventHub.Web.Pages.Events
[StringLength(EventConsts.MaxDescriptionLength, MinimumLength = EventConsts.MinDescriptionLength)]
[TextArea]
public string Description { get; set; }
[CanBeNull]
[Display(Name = "Cover Image")]
[DataType(DataType.Upload)]
[MaxFileSize(EventConsts.MaxCoverImageFileSize)]
[AllowedExtensions(new string[] { ".jpg", ".png", ".jpeg" })]
[MaxFileSize(EventConsts.MaxCoverImageFileSize)]
[AllowedExtensions(new string[] {".jpg", ".png", ".jpeg"})]
public IFormFile CoverImageFile { get; set; }
[Required]
public bool? IsOnline { get; set; }
[Required] public bool? IsOnline { get; set; }
[CanBeNull]
[StringLength(EventConsts.MaxOnlineLinkLength, MinimumLength = EventConsts.MinOnlineLinkLength)]
public string OnlineLink { get; set; }
[SelectItems(nameof(Countries))]
[DisplayName("Country")]
public Guid? CountryId { get; set; }
[SelectItems(nameof(Languages))]
[DisplayName("Language")]
public string Language { get; set; }
[CanBeNull]
[StringLength(EventConsts.MaxCityLength, MinimumLength = EventConsts.MinCityLength)]
public string City { get; set; }
[Range(1, int.MaxValue)]
public int? Capacity { get; set; }
[SelectItems(nameof(Languages))]
[DisplayName("Language")]
public string Language { get; set; }
[Range(1, int.MaxValue)] public int? Capacity { get; set; }
}
}
}
}

9
src/EventHub.Web/Pages/Organizations/Edit.cshtml

@ -26,7 +26,14 @@
<div class="row">
<div class="col-4">
<div class="image-area">
<img id="imageResult" src="#" alt="" class="img-fluid rounded shadow-sm mx-auto d-block">
@if (Model.ProfilePictureContent != null && Model.ProfilePictureContent.Length > 0)
{
<img id="imageResult" src="@($"data:image/png;base64,{Convert.ToBase64String(Model.ProfilePictureContent)}")" alt="" class="img-fluid rounded shadow-sm mx-auto d-block">
}
else
{
<img id="imageResult" src="#" alt="" class="img-fluid rounded shadow-sm mx-auto d-block">
}
</div>
</div>

4
src/EventHub.Web/Pages/Organizations/Edit.cshtml.cs

@ -20,7 +20,8 @@ namespace EventHub.Web.Pages.Organizations
[BindProperty]
public EditOrganizationViewModel Organization { get; set; }
public byte[] ProfilePictureContent { get; private set; }
private readonly IOrganizationAppService _organizationAppService;
public EditPageModel(IOrganizationAppService organizationAppService)
@ -31,6 +32,7 @@ namespace EventHub.Web.Pages.Organizations
public async Task OnGetAsync()
{
var organizationProfileDto = await _organizationAppService.GetProfileAsync(Name);
ProfilePictureContent = organizationProfileDto.ProfilePictureContent;
Organization = ObjectMapper.Map<OrganizationProfileDto, EditOrganizationViewModel>(organizationProfileDto);
}

Loading…
Cancel
Save