@page "/sysadmin/manage-tours" @using System.ComponentModel.DataAnnotations @using DevExpress.Blazor.Internal @using DevExpress.Blazor.Office @using TIAM.Entities.Transfers @using TIAMWebApp.Shared.Application.Interfaces @using TIAMWebApp.Shared.Application.Models @using TIAMWebApp.Shared.Application.Services @using TIAMSharedUI.Shared @using DevExpress.Blazor @inject ITransferDataService TransferDataService @inject TourService TourService @inject NavigationManager Navigation @layout AdminLayout Manage Tours

Manage Tours

Create New Tour

@foreach (var dest in TransferDestinations) { }
@if (!string.IsNullOrEmpty(UploadStatus)) {
@UploadStatus
}
@if (IsEditing) { }

Existing Tours

@if (Tours.Any()) {
@foreach (var tour in Tours) { var dest = TransferDestinations.FirstOrDefault(d => d.Id == tour.TransferDestinationId);
@if (!string.IsNullOrEmpty(tour.CoverImageUrl)) { Tour cover image }
@tour?.Title
@if (!string.IsNullOrEmpty(tour.Bio)) {
Short Description:
@((MarkupString)tour.Bio)
} @if (!string.IsNullOrEmpty(tour.FancyDescription)) {
Description:
@((MarkupString)tour.FancyDescription)
} @if (dest != null) {
Destination: @dest.Name (@dest.AddressString)
}
}
} else {

No tours available.

}
@code { private List TransferDestinations = []; private List Tours = []; private TourFormModel newTour = new(); private IBrowserFile? uploadedFile; private string UploadStatus = string.Empty; private bool IsEditing = false; private Guid? EditingTourId = null; void OnCustomizeToolbar(IToolbar toolbar) { // Returns the first group IBarGroup firstGroup = toolbar.Groups[0]; // Returns the "Table" group IBarGroup tableGroup = toolbar.Groups[HtmlEditorToolbarGroupNames.Table]; } protected override async Task OnInitializedAsync() { TransferDestinations = (await TransferDataService.GetDestinationsAsync()).ToList(); Tours = (await TourService.GetAllAsync()).ToList(); } private void EditTour(TourInfo tour) { newTour = new TourFormModel { TransferDestinationId = tour.TransferDestinationId, Name = tour.Title, Bio = tour.Bio ?? string.Empty, Description = tour.FancyDescription ?? string.Empty, ImageBytes = null, ImageFileName = tour.CoverImageUrl }; IsEditing = true; EditingTourId = tour.Id; UploadStatus = string.Empty; } private void CancelEdit() { newTour = new TourFormModel(); uploadedFile = null; IsEditing = false; EditingTourId = null; UploadStatus = string.Empty; } private async Task HandleSubmit() { if (uploadedFile is not null) { using var stream = uploadedFile.OpenReadStream(maxAllowedSize: 5 * 1024 * 1024); using var ms = new MemoryStream(); await stream.CopyToAsync(ms); newTour.ImageBytes = ms.ToArray(); newTour.ImageFileName = uploadedFile.Name; } if (IsEditing && EditingTourId.HasValue) { var updatedTour = new TourInfo { Id = EditingTourId.Value, TransferDestinationId = newTour.TransferDestinationId, Title = newTour.Name, Bio = newTour.Bio, FancyDescription = newTour.Description, CoverImageUrl = newTour.ImageFileName // assume your service handles image URL logic }; await TourService.UpdateAsync(updatedTour, uploadedFile); } else { var tourToCreate = new TourInfo { TransferDestinationId = newTour.TransferDestinationId, Title = newTour.Name, Bio = newTour.Bio, FancyDescription = newTour.Description, CoverImageUrl = newTour.ImageFileName }; await TourService.CreateAsync(tourToCreate, uploadedFile); } // Reset form newTour = new TourFormModel(); uploadedFile = null; IsEditing = false; EditingTourId = null; UploadStatus = string.Empty; Tours = (await TourService.GetAllAsync()).ToList(); } private void HandleFileChange(InputFileChangeEventArgs e) { uploadedFile = e.File; UploadStatus = $"Selected: {uploadedFile.Name}"; } private async Task DeleteTourAsync(Guid id) { await TourService.DeleteAsync(id); Tours = (await TourService.GetAllAsync()).ToList(); } public class TourFormModel { [Required] public Guid TransferDestinationId { get; set; } [Required] [StringLength(100, ErrorMessage = "Tour name cannot exceed 100 characters.")] public string Name { get; set; } = string.Empty; public string Bio { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public byte[]? ImageBytes { get; set; } public string? ImageFileName { get; set; } } }