Fix admin route access and backend configuration

- 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
This commit is contained in:
Local Server
2025-12-13 22:34:11 -06:00
parent 8bb6430a70
commit 703ab57984
253 changed files with 29870 additions and 157 deletions

View File

@@ -0,0 +1,273 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using System;
using System.ComponentModel.DataAnnotations;
namespace SkyArtShop.Models
{
public class Page
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[Required]
public string PageName { get; set; } = string.Empty;
public string PageSlug { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public string Subtitle { get; set; } = string.Empty;
public string HeroImage { get; set; } = string.Empty;
public string Content { get; set; } = string.Empty;
public string MetaDescription { get; set; } = string.Empty;
public List<string> ImageGallery { get; set; } = new List<string>(); // Right sidebar images
public List<TeamMember> TeamMembers { get; set; } = new List<TeamMember>(); // Team section
public bool IsActive { get; set; } = true;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
public class TeamMember
{
public string Name { get; set; } = string.Empty;
public string Role { get; set; } = string.Empty;
public string Bio { get; set; } = string.Empty;
public string PhotoUrl { get; set; } = string.Empty;
}
public class PortfolioCategory
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[Required]
public string Name { get; set; } = string.Empty;
[Required]
public string Slug { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string ThumbnailImage { get; set; } = string.Empty;
public string FeaturedImage { get; set; } = string.Empty;
public int DisplayOrder { get; set; }
public bool IsActive { get; set; } = true;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
public class PortfolioProject
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[Required]
public string Title { get; set; } = string.Empty;
[Required]
public string CategoryId { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string FeaturedImage { get; set; } = string.Empty;
public List<string> Images { get; set; } = new List<string>();
public string ProjectDate { get; set; } = string.Empty;
public int DisplayOrder { get; set; }
public bool IsActive { get; set; } = true;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
public class Product
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[Required]
public string Name { get; set; } = string.Empty;
public string Slug { get; set; } = string.Empty;
public string SKU { get; set; } = string.Empty;
public string ShortDescription { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
[Required]
public decimal Price { get; set; }
public string Category { get; set; } = string.Empty;
public string Color { get; set; } = string.Empty; // Legacy single color (kept for backward compatibility)
public List<string> Colors { get; set; } = new List<string>(); // Multiple colors
// Primary image used in listings/forms
public string ImageUrl { get; set; } = string.Empty;
public List<string> Images { get; set; } = new List<string>();
public bool IsFeatured { get; set; }
public bool IsTopSeller { get; set; }
public int StockQuantity { get; set; }
public bool IsActive { get; set; } = true;
// Sales Tracking
public int UnitsSold { get; set; } = 0;
public decimal TotalRevenue { get; set; } = 0;
public double AverageRating { get; set; } = 0;
public int TotalReviews { get; set; } = 0;
public decimal CostPrice { get; set; } = 0; // For profit margin calculation
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
public class Order
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
public string CustomerEmail { get; set; } = string.Empty;
public string CustomerName { get; set; } = string.Empty;
public List<OrderItem> Items { get; set; } = new List<OrderItem>();
public decimal TotalAmount { get; set; }
public string Status { get; set; } = "Pending"; // Pending, Completed, Cancelled
public DateTime OrderDate { get; set; } = DateTime.UtcNow;
public DateTime? CompletedDate { get; set; }
}
public class OrderItem
{
public string ProductId { get; set; } = string.Empty;
public string ProductName { get; set; } = string.Empty;
public string SKU { get; set; } = string.Empty;
public int Quantity { get; set; }
public decimal Price { get; set; }
public decimal Subtotal { get; set; }
}
public class ProductView
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
public string ProductId { get; set; } = string.Empty;
public string SessionId { get; set; } = string.Empty;
public string IpAddress { get; set; } = string.Empty;
public DateTime ViewedAt { get; set; } = DateTime.UtcNow;
}
public class BlogPost
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[Required]
public string Title { get; set; } = string.Empty;
[Required]
public string Slug { get; set; } = string.Empty;
public string Content { get; set; } = string.Empty;
public string Excerpt { get; set; } = string.Empty;
public string FeaturedImage { get; set; } = string.Empty;
public string Author { get; set; } = string.Empty;
public List<string> Tags { get; set; } = new List<string>();
public bool IsPublished { get; set; } = true;
public DateTime PublishedDate { get; set; } = DateTime.UtcNow;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
public class MenuItem
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[Required]
public string Label { get; set; } = string.Empty;
[Required]
public string Url { get; set; } = string.Empty;
public int DisplayOrder { get; set; }
public bool IsActive { get; set; } = true;
public bool ShowInNavbar { get; set; } = true;
public bool ShowInDropdown { get; set; } = true;
public bool OpenInNewTab { get; set; } = false;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
[BsonIgnoreExtraElements]
public class SiteSettings
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
public string SiteName { get; set; } = "Sky Art Shop";
public string SiteTagline { get; set; } = "Scrapbooking and Journaling Fun";
public string ContactEmail { get; set; } = "info@skyartshop.com";
public string ContactPhone { get; set; } = "+501 608-0409";
public string InstagramUrl { get; set; } = "#";
public string FooterText { get; set; } = "© 2035 by Sky Art Shop. Powered and secured by Wix";
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
public class HomepageSection
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
public string SectionType { get; set; } = string.Empty; // hero, inspiration, collection, promotion
public string Title { get; set; } = string.Empty;
public string Subtitle { get; set; } = string.Empty;
public string Content { get; set; } = string.Empty;
public string ImageUrl { get; set; } = string.Empty;
public string ButtonText { get; set; } = string.Empty;
public string ButtonUrl { get; set; } = string.Empty;
public int DisplayOrder { get; set; }
public bool IsActive { get; set; } = true;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
// Additional properties for specific section types
public Dictionary<string, string> AdditionalData { get; set; } = new Dictionary<string, string>();
}
public class CollectionItem
{
public string Title { get; set; } = string.Empty;
public string ImageUrl { get; set; } = string.Empty;
public string Link { get; set; } = string.Empty;
}
public class PromotionCard
{
public string Title { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string ButtonText { get; set; } = string.Empty;
public string ButtonUrl { get; set; } = string.Empty;
public bool IsFeatured { get; set; }
}
public class AdminUser
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; } = string.Empty;
[Required]
public string PasswordHash { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public bool IsActive { get; set; } = true;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime LastLogin { get; set; }
}
}