- Added /admin redirect to login page in nginx config - Fixed backend server.js route ordering for proper admin handling - Updated authentication middleware and routes - Added user management routes - Configured PostgreSQL integration - Updated environment configuration
226 lines
9.3 KiB
C#
226 lines
9.3 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using SkyArtShop.Models;
|
|
using SkyArtShop.Services;
|
|
using System.Text.Json;
|
|
|
|
namespace SkyArtShop.Controllers
|
|
{
|
|
[Route("admin/homepage")]
|
|
[Authorize(Roles = "Admin")]
|
|
public class AdminHomepageController : Controller
|
|
{
|
|
private readonly MongoDBService _mongoService;
|
|
private readonly IWebHostEnvironment _environment;
|
|
private readonly string _sectionsCollection = "HomepageSections";
|
|
private readonly string _settingsCollection = "SiteSettings";
|
|
|
|
public AdminHomepageController(MongoDBService mongoService, IWebHostEnvironment environment)
|
|
{
|
|
_mongoService = mongoService;
|
|
_environment = environment;
|
|
}
|
|
|
|
[HttpGet("")]
|
|
public async Task<IActionResult> Index()
|
|
{
|
|
var sections = await _mongoService.GetAllAsync<HomepageSection>(_sectionsCollection);
|
|
sections = sections.OrderBy(s => s.DisplayOrder).ToList();
|
|
|
|
var settingsList = await _mongoService.GetAllAsync<SiteSettings>(_settingsCollection);
|
|
var settings = settingsList.FirstOrDefault() ?? new SiteSettings();
|
|
|
|
ViewBag.Settings = settings;
|
|
return View(sections);
|
|
}
|
|
|
|
[HttpGet("section/{id}")]
|
|
public async Task<IActionResult> EditSection(string id)
|
|
{
|
|
var section = await _mongoService.GetByIdAsync<HomepageSection>(_sectionsCollection, id);
|
|
if (section == null)
|
|
{
|
|
TempData["ErrorMessage"] = "Section not found.";
|
|
return RedirectToAction("Index");
|
|
}
|
|
return View(section);
|
|
}
|
|
|
|
[HttpPost("section/update")]
|
|
public async Task<IActionResult> UpdateSection(HomepageSection section, IFormFile? imageFile)
|
|
{
|
|
// Remove Content validation error since it's optional for some section types
|
|
ModelState.Remove("Content");
|
|
ModelState.Remove("AdditionalData");
|
|
|
|
if (!ModelState.IsValid)
|
|
{
|
|
foreach (var error in ModelState.Values.SelectMany(v => v.Errors))
|
|
{
|
|
Console.WriteLine($"ModelState Error: {error.ErrorMessage}");
|
|
}
|
|
return View("EditSection", section);
|
|
}
|
|
|
|
Console.WriteLine($"Updating section with ID: {section.Id}");
|
|
Console.WriteLine($"Title: {section.Title}");
|
|
Console.WriteLine($"Subtitle: {section.Subtitle}");
|
|
Console.WriteLine($"Content length: {section.Content?.Length ?? 0}");
|
|
Console.WriteLine($"IsActive: {section.IsActive}");
|
|
|
|
// Get existing section to preserve data
|
|
var existingSection = await _mongoService.GetByIdAsync<HomepageSection>(_sectionsCollection, section.Id!);
|
|
if (existingSection == null)
|
|
{
|
|
Console.WriteLine($"ERROR: Section with ID {section.Id} not found!");
|
|
TempData["ErrorMessage"] = "Section not found.";
|
|
return RedirectToAction("Index");
|
|
}
|
|
|
|
Console.WriteLine($"Found existing section: {existingSection.Title}");
|
|
|
|
// Update fields
|
|
existingSection.SectionType = section.SectionType;
|
|
existingSection.Title = section.Title ?? string.Empty;
|
|
existingSection.Subtitle = section.Subtitle ?? string.Empty;
|
|
existingSection.Content = section.Content ?? string.Empty;
|
|
existingSection.ButtonText = section.ButtonText ?? string.Empty;
|
|
existingSection.ButtonUrl = section.ButtonUrl ?? string.Empty;
|
|
existingSection.IsActive = section.IsActive;
|
|
existingSection.UpdatedAt = DateTime.UtcNow;
|
|
|
|
// Handle image upload
|
|
if (imageFile != null && imageFile.Length > 0)
|
|
{
|
|
var uploadsFolder = Path.Combine(_environment.WebRootPath, "uploads", "images");
|
|
Directory.CreateDirectory(uploadsFolder);
|
|
|
|
var uniqueFileName = $"{Guid.NewGuid()}_{imageFile.FileName}";
|
|
var filePath = Path.Combine(uploadsFolder, uniqueFileName);
|
|
|
|
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
|
{
|
|
await imageFile.CopyToAsync(fileStream);
|
|
}
|
|
|
|
existingSection.ImageUrl = $"/uploads/images/{uniqueFileName}";
|
|
Console.WriteLine($"New image uploaded: {existingSection.ImageUrl}");
|
|
}
|
|
|
|
await _mongoService.UpdateAsync(_sectionsCollection, existingSection.Id!, existingSection);
|
|
Console.WriteLine($"Section updated successfully in database");
|
|
|
|
TempData["SuccessMessage"] = "Section updated successfully!";
|
|
return RedirectToAction("Index");
|
|
}
|
|
|
|
[HttpGet("section/create")]
|
|
public IActionResult CreateSection()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
[HttpPost("section/create")]
|
|
public async Task<IActionResult> CreateSection(HomepageSection section, IFormFile? imageFile)
|
|
{
|
|
// Remove Content validation error since it's optional for some section types
|
|
ModelState.Remove("Content");
|
|
ModelState.Remove("AdditionalData");
|
|
|
|
if (!ModelState.IsValid)
|
|
{
|
|
return View(section);
|
|
}
|
|
|
|
// Handle image upload
|
|
if (imageFile != null && imageFile.Length > 0)
|
|
{
|
|
var uploadsFolder = Path.Combine(_environment.WebRootPath, "uploads", "images");
|
|
Directory.CreateDirectory(uploadsFolder);
|
|
|
|
var uniqueFileName = $"{Guid.NewGuid()}_{imageFile.FileName}";
|
|
var filePath = Path.Combine(uploadsFolder, uniqueFileName);
|
|
|
|
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
|
{
|
|
await imageFile.CopyToAsync(fileStream);
|
|
}
|
|
|
|
section.ImageUrl = $"/uploads/images/{uniqueFileName}";
|
|
}
|
|
|
|
// Get the highest display order and add 1
|
|
var allSections = await _mongoService.GetAllAsync<HomepageSection>(_sectionsCollection);
|
|
section.DisplayOrder = allSections.Any() ? allSections.Max(s => s.DisplayOrder) + 1 : 0;
|
|
|
|
section.CreatedAt = DateTime.UtcNow;
|
|
section.UpdatedAt = DateTime.UtcNow;
|
|
|
|
await _mongoService.InsertAsync(_sectionsCollection, section);
|
|
|
|
TempData["SuccessMessage"] = "Section created successfully!";
|
|
return RedirectToAction("Index");
|
|
}
|
|
|
|
[HttpPost("section/delete/{id}")]
|
|
public async Task<IActionResult> DeleteSection(string id)
|
|
{
|
|
await _mongoService.DeleteAsync<HomepageSection>(_sectionsCollection, id);
|
|
TempData["SuccessMessage"] = "Section deleted successfully!";
|
|
return RedirectToAction("Index");
|
|
}
|
|
|
|
[HttpPost("section/reorder")]
|
|
public async Task<IActionResult> ReorderSections([FromBody] List<string> sectionIds)
|
|
{
|
|
for (int i = 0; i < sectionIds.Count; i++)
|
|
{
|
|
var section = await _mongoService.GetByIdAsync<HomepageSection>(_sectionsCollection, sectionIds[i]);
|
|
if (section != null)
|
|
{
|
|
section.DisplayOrder = i;
|
|
section.UpdatedAt = DateTime.UtcNow;
|
|
await _mongoService.UpdateAsync(_sectionsCollection, section.Id!, section);
|
|
}
|
|
}
|
|
return Json(new { success = true });
|
|
}
|
|
|
|
[HttpPost("section/toggle/{id}")]
|
|
public async Task<IActionResult> ToggleSection(string id)
|
|
{
|
|
var section = await _mongoService.GetByIdAsync<HomepageSection>(_sectionsCollection, id);
|
|
if (section != null)
|
|
{
|
|
section.IsActive = !section.IsActive;
|
|
section.UpdatedAt = DateTime.UtcNow;
|
|
await _mongoService.UpdateAsync(_sectionsCollection, section.Id!, section);
|
|
TempData["SuccessMessage"] = $"Section {(section.IsActive ? "activated" : "deactivated")} successfully!";
|
|
}
|
|
return RedirectToAction("Index");
|
|
}
|
|
|
|
[HttpPost("footer/update")]
|
|
public async Task<IActionResult> UpdateFooter(string footerText)
|
|
{
|
|
var settingsList = await _mongoService.GetAllAsync<SiteSettings>(_settingsCollection);
|
|
SiteSettings? settings = settingsList.FirstOrDefault();
|
|
|
|
if (settings == null)
|
|
{
|
|
settings = new SiteSettings { FooterText = footerText };
|
|
await _mongoService.InsertAsync(_settingsCollection, settings);
|
|
}
|
|
else
|
|
{
|
|
settings.FooterText = footerText;
|
|
settings.UpdatedAt = DateTime.UtcNow;
|
|
await _mongoService.UpdateAsync(_settingsCollection, settings.Id!, settings);
|
|
}
|
|
|
|
TempData["SuccessMessage"] = "Footer updated successfully!";
|
|
return RedirectToAction("Index");
|
|
}
|
|
}
|
|
}
|