- 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
467 lines
20 KiB
C#
467 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
using Npgsql;
|
|
using NpgsqlTypes;
|
|
using SkyArtShop.Models;
|
|
|
|
namespace SkyArtShop.Services;
|
|
|
|
public class PostgreSQLService
|
|
{
|
|
private readonly string _connectionString;
|
|
|
|
public PostgreSQLService(string connectionString)
|
|
{
|
|
_connectionString = connectionString;
|
|
}
|
|
|
|
private async Task<NpgsqlConnection> GetConnectionAsync()
|
|
{
|
|
NpgsqlConnection conn = new NpgsqlConnection(_connectionString);
|
|
await conn.OpenAsync();
|
|
return conn;
|
|
}
|
|
|
|
public async Task<List<T>> GetAllAsync<T>(string tableName) where T : class, new()
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "SELECT * FROM " + tableName.ToLower();
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
using NpgsqlDataReader reader = await cmd.ExecuteReaderAsync();
|
|
List<T> results = new List<T>();
|
|
while (await reader.ReadAsync())
|
|
{
|
|
results.Add(MapToObject<T>(reader));
|
|
}
|
|
return results;
|
|
}
|
|
|
|
public async Task<T?> GetByIdAsync<T>(string tableName, string id) where T : class, new()
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "SELECT * FROM " + tableName.ToLower() + " WHERE id = @id";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
cmd.Parameters.AddWithValue("id", id);
|
|
using NpgsqlDataReader reader = await cmd.ExecuteReaderAsync();
|
|
if (await reader.ReadAsync())
|
|
{
|
|
return MapToObject<T>(reader);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public async Task<AdminUser?> GetUserByEmailAsync(string email)
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "SELECT * FROM adminusers WHERE LOWER(email) = LOWER(@email) AND isactive = true";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
cmd.Parameters.AddWithValue("email", email);
|
|
using NpgsqlDataReader reader = await cmd.ExecuteReaderAsync();
|
|
if (await reader.ReadAsync())
|
|
{
|
|
return MapToAdminUser(reader);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public async Task UpdateUserLastLoginAsync(string userId, DateTime lastLogin)
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "UPDATE adminusers SET lastlogin = @lastlogin WHERE id = @id";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
cmd.Parameters.AddWithValue("id", userId);
|
|
cmd.Parameters.AddWithValue("lastlogin", lastLogin);
|
|
await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
|
|
public async Task CreateAdminUserAsync(AdminUser user)
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "INSERT INTO adminusers (id, email, passwordhash, name, role, permissions, isactive, createdby, createdat)\n VALUES (@id, @email, @passwordhash, @name, @role, @permissions::jsonb, @isactive, @createdby, @createdat)";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
cmd.Parameters.AddWithValue("id", Guid.NewGuid().ToString());
|
|
cmd.Parameters.AddWithValue("email", user.Email);
|
|
cmd.Parameters.AddWithValue("passwordhash", user.PasswordHash);
|
|
cmd.Parameters.AddWithValue("name", user.Name);
|
|
cmd.Parameters.AddWithValue("role", user.Role);
|
|
cmd.Parameters.AddWithValue("permissions", JsonSerializer.Serialize(user.Permissions));
|
|
cmd.Parameters.AddWithValue("isactive", user.IsActive);
|
|
cmd.Parameters.AddWithValue("createdby", user.CreatedBy);
|
|
cmd.Parameters.AddWithValue("createdat", user.CreatedAt);
|
|
await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
|
|
public async Task<List<Product>> GetProductsAsync()
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "SELECT * FROM products WHERE isactive = true ORDER BY createdat DESC";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
using NpgsqlDataReader reader = await cmd.ExecuteReaderAsync();
|
|
List<Product> results = new List<Product>();
|
|
while (await reader.ReadAsync())
|
|
{
|
|
results.Add(MapToProduct(reader));
|
|
}
|
|
return results;
|
|
}
|
|
|
|
public async Task<Product?> GetProductBySlugAsync(string slug)
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "SELECT * FROM products WHERE slug = @slug AND isactive = true";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
cmd.Parameters.AddWithValue("slug", slug);
|
|
using NpgsqlDataReader reader = await cmd.ExecuteReaderAsync();
|
|
if (await reader.ReadAsync())
|
|
{
|
|
return MapToProduct(reader);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public async Task<Page?> GetPageBySlugAsync(string slug)
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "SELECT * FROM pages WHERE pageslug = @slug AND isactive = true";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
cmd.Parameters.AddWithValue("slug", slug);
|
|
using NpgsqlDataReader reader = await cmd.ExecuteReaderAsync();
|
|
if (await reader.ReadAsync())
|
|
{
|
|
return MapToPage(reader);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public async Task<SiteSettings?> GetSiteSettingsAsync()
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "SELECT * FROM sitesettings LIMIT 1";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
using NpgsqlDataReader reader = await cmd.ExecuteReaderAsync();
|
|
if (await reader.ReadAsync())
|
|
{
|
|
return MapToSiteSettings(reader);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public async Task<List<MenuItem>> GetMenuItemsAsync()
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "SELECT * FROM menuitems WHERE isactive = true ORDER BY displayorder";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
using NpgsqlDataReader reader = await cmd.ExecuteReaderAsync();
|
|
List<MenuItem> results = new List<MenuItem>();
|
|
while (await reader.ReadAsync())
|
|
{
|
|
results.Add(MapToMenuItem(reader));
|
|
}
|
|
return results;
|
|
}
|
|
|
|
public async Task InsertAsync<T>(string tableName, T entity) where T : class
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
Type typeFromHandle = typeof(T);
|
|
List<PropertyInfo> list = (from p in typeFromHandle.GetProperties()
|
|
where p.CanRead && p.Name != "Id"
|
|
select p).ToList();
|
|
PropertyInfo property = typeFromHandle.GetProperty("Id");
|
|
if (property != null && string.IsNullOrEmpty(property.GetValue(entity)?.ToString()))
|
|
{
|
|
property.SetValue(entity, Guid.NewGuid().ToString());
|
|
}
|
|
string value = string.Join(", ", list.Select((PropertyInfo p) => p.Name.ToLower()).Prepend("id"));
|
|
string value2 = string.Join(", ", list.Select((PropertyInfo p) => "@" + p.Name.ToLower()).Prepend("@id"));
|
|
string cmdText = $"INSERT INTO {tableName.ToLower()} ({value}) VALUES ({value2})";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
cmd.Parameters.AddWithValue("id", property?.GetValue(entity)?.ToString() ?? Guid.NewGuid().ToString());
|
|
foreach (PropertyInfo item in list)
|
|
{
|
|
object value3 = item.GetValue(entity);
|
|
string parameterName = item.Name.ToLower();
|
|
if (value3 == null)
|
|
{
|
|
cmd.Parameters.AddWithValue(parameterName, DBNull.Value);
|
|
}
|
|
else if (item.PropertyType == typeof(List<string>) || item.PropertyType == typeof(List<ProductVariant>) || item.PropertyType == typeof(List<TeamMember>) || item.PropertyType == typeof(Dictionary<string, string>))
|
|
{
|
|
cmd.Parameters.AddWithValue(parameterName, NpgsqlDbType.Jsonb, JsonSerializer.Serialize(value3));
|
|
}
|
|
else if (item.PropertyType == typeof(DateTime) || item.PropertyType == typeof(DateTime?))
|
|
{
|
|
cmd.Parameters.AddWithValue(parameterName, value3);
|
|
}
|
|
else if (item.PropertyType == typeof(bool) || item.PropertyType == typeof(bool?))
|
|
{
|
|
cmd.Parameters.AddWithValue(parameterName, value3);
|
|
}
|
|
else
|
|
{
|
|
cmd.Parameters.AddWithValue(parameterName, value3);
|
|
}
|
|
}
|
|
await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
|
|
public async Task UpdateAsync<T>(string tableName, string id, T entity) where T : class
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
Type typeFromHandle = typeof(T);
|
|
List<PropertyInfo> list = (from p in typeFromHandle.GetProperties()
|
|
where p.CanRead && p.Name != "Id"
|
|
select p).ToList();
|
|
string value = string.Join(", ", list.Select((PropertyInfo p) => p.Name.ToLower() + " = @" + p.Name.ToLower()));
|
|
string cmdText = $"UPDATE {tableName.ToLower()} SET {value} WHERE id = @id";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
cmd.Parameters.AddWithValue("id", id);
|
|
foreach (PropertyInfo item in list)
|
|
{
|
|
object value2 = item.GetValue(entity);
|
|
string parameterName = item.Name.ToLower();
|
|
if (value2 == null)
|
|
{
|
|
cmd.Parameters.AddWithValue(parameterName, DBNull.Value);
|
|
}
|
|
else if (item.PropertyType == typeof(List<string>) || item.PropertyType == typeof(List<ProductVariant>) || item.PropertyType == typeof(List<TeamMember>) || item.PropertyType == typeof(Dictionary<string, string>))
|
|
{
|
|
cmd.Parameters.AddWithValue(parameterName, NpgsqlDbType.Jsonb, JsonSerializer.Serialize(value2));
|
|
}
|
|
else if (item.PropertyType == typeof(DateTime) || item.PropertyType == typeof(DateTime?))
|
|
{
|
|
cmd.Parameters.AddWithValue(parameterName, value2);
|
|
}
|
|
else if (item.PropertyType == typeof(bool) || item.PropertyType == typeof(bool?))
|
|
{
|
|
cmd.Parameters.AddWithValue(parameterName, value2);
|
|
}
|
|
else
|
|
{
|
|
cmd.Parameters.AddWithValue(parameterName, value2);
|
|
}
|
|
}
|
|
await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
|
|
public async Task DeleteAsync<T>(string tableName, string id) where T : class
|
|
{
|
|
using NpgsqlConnection conn = await GetConnectionAsync();
|
|
string cmdText = "DELETE FROM " + tableName.ToLower() + " WHERE id = @id";
|
|
using NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn);
|
|
cmd.Parameters.AddWithValue("id", id);
|
|
await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
|
|
private T MapToObject<T>(NpgsqlDataReader reader) where T : class, new()
|
|
{
|
|
Type typeFromHandle = typeof(T);
|
|
if (typeFromHandle == typeof(AdminUser))
|
|
{
|
|
return (MapToAdminUser(reader) as T) ?? new T();
|
|
}
|
|
if (typeFromHandle == typeof(Product))
|
|
{
|
|
return (MapToProduct(reader) as T) ?? new T();
|
|
}
|
|
if (typeFromHandle == typeof(Page))
|
|
{
|
|
return (MapToPage(reader) as T) ?? new T();
|
|
}
|
|
if (typeFromHandle == typeof(MenuItem))
|
|
{
|
|
return (MapToMenuItem(reader) as T) ?? new T();
|
|
}
|
|
if (typeFromHandle == typeof(SiteSettings))
|
|
{
|
|
return (MapToSiteSettings(reader) as T) ?? new T();
|
|
}
|
|
if (typeFromHandle == typeof(PortfolioCategory))
|
|
{
|
|
return (MapToPortfolioCategory(reader) as T) ?? new T();
|
|
}
|
|
if (typeFromHandle == typeof(PortfolioProject))
|
|
{
|
|
return (MapToPortfolioProject(reader) as T) ?? new T();
|
|
}
|
|
if (typeFromHandle == typeof(BlogPost))
|
|
{
|
|
return (MapToBlogPost(reader) as T) ?? new T();
|
|
}
|
|
if (typeFromHandle == typeof(HomepageSection))
|
|
{
|
|
return (MapToHomepageSection(reader) as T) ?? new T();
|
|
}
|
|
return new T();
|
|
}
|
|
|
|
private AdminUser MapToAdminUser(NpgsqlDataReader reader)
|
|
{
|
|
AdminUser adminUser = new AdminUser();
|
|
adminUser.Id = reader["id"].ToString();
|
|
adminUser.Email = reader["email"].ToString() ?? "";
|
|
adminUser.PasswordHash = reader["passwordhash"].ToString() ?? "";
|
|
adminUser.Name = reader["name"].ToString() ?? "";
|
|
adminUser.Role = reader["role"].ToString() ?? "Admin";
|
|
adminUser.Permissions = JsonSerializer.Deserialize<List<string>>(reader["permissions"].ToString() ?? "[]") ?? new List<string>();
|
|
adminUser.IsActive = (reader["isactive"] as bool?) ?? true;
|
|
adminUser.CreatedBy = reader["createdby"]?.ToString() ?? "";
|
|
adminUser.CreatedAt = (reader["createdat"] as DateTime?) ?? DateTime.UtcNow;
|
|
adminUser.LastLogin = (reader.IsDBNull(reader.GetOrdinal("lastlogin")) ? ((DateTime?)null) : new DateTime?(reader.GetDateTime(reader.GetOrdinal("lastlogin"))));
|
|
adminUser.Phone = reader["phone"]?.ToString() ?? "";
|
|
adminUser.Notes = reader["notes"]?.ToString() ?? "";
|
|
return adminUser;
|
|
}
|
|
|
|
private Product MapToProduct(NpgsqlDataReader reader)
|
|
{
|
|
Product product = new Product();
|
|
product.Id = reader["id"].ToString();
|
|
product.Name = reader["name"].ToString() ?? "";
|
|
product.Slug = reader["slug"].ToString() ?? "";
|
|
product.SKU = reader["sku"]?.ToString() ?? "";
|
|
product.ShortDescription = reader["shortdescription"]?.ToString() ?? "";
|
|
product.Description = reader["description"]?.ToString() ?? "";
|
|
product.Price = (reader["price"] as decimal?).GetValueOrDefault();
|
|
product.Category = reader["category"]?.ToString() ?? "";
|
|
product.Color = reader["color"]?.ToString() ?? "";
|
|
product.Colors = JsonSerializer.Deserialize<List<string>>(reader["colors"].ToString() ?? "[]") ?? new List<string>();
|
|
product.ImageUrl = reader["imageurl"]?.ToString() ?? "";
|
|
product.Images = JsonSerializer.Deserialize<List<string>>(reader["images"].ToString() ?? "[]") ?? new List<string>();
|
|
product.IsFeatured = reader["isfeatured"] as bool? == true;
|
|
product.IsTopSeller = reader["istopseller"] as bool? == true;
|
|
product.StockQuantity = (reader["stockquantity"] as int?).GetValueOrDefault();
|
|
product.IsActive = (reader["isactive"] as bool?) ?? true;
|
|
product.UnitsSold = (reader["unitssold"] as int?).GetValueOrDefault();
|
|
product.TotalRevenue = (reader["totalrevenue"] as decimal?).GetValueOrDefault();
|
|
product.AverageRating = (reader["averagerating"] as double?).GetValueOrDefault();
|
|
product.TotalReviews = (reader["totalreviews"] as int?).GetValueOrDefault();
|
|
product.CostPrice = (reader["costprice"] as decimal?).GetValueOrDefault();
|
|
product.Tags = JsonSerializer.Deserialize<List<string>>(reader["tags"].ToString() ?? "[]") ?? new List<string>();
|
|
product.MetaDescription = reader["metadescription"]?.ToString() ?? "";
|
|
product.CreatedAt = (reader["createdat"] as DateTime?) ?? DateTime.UtcNow;
|
|
product.UpdatedAt = (reader["updatedat"] as DateTime?) ?? DateTime.UtcNow;
|
|
return product;
|
|
}
|
|
|
|
private Page MapToPage(NpgsqlDataReader reader)
|
|
{
|
|
Page page = new Page();
|
|
page.Id = reader["id"].ToString();
|
|
page.PageName = reader["pagename"].ToString() ?? "";
|
|
page.PageSlug = reader["pageslug"].ToString() ?? "";
|
|
page.Title = reader["title"]?.ToString() ?? "";
|
|
page.Subtitle = reader["subtitle"]?.ToString() ?? "";
|
|
page.HeroImage = reader["heroimage"]?.ToString() ?? "";
|
|
page.Content = reader["content"]?.ToString() ?? "";
|
|
page.MetaDescription = reader["metadescription"]?.ToString() ?? "";
|
|
page.ImageGallery = JsonSerializer.Deserialize<List<string>>(reader["imagegallery"].ToString() ?? "[]") ?? new List<string>();
|
|
page.IsActive = (reader["isactive"] as bool?) ?? true;
|
|
page.CreatedAt = (reader["createdat"] as DateTime?) ?? DateTime.UtcNow;
|
|
page.UpdatedAt = (reader["updatedat"] as DateTime?) ?? DateTime.UtcNow;
|
|
return page;
|
|
}
|
|
|
|
private MenuItem MapToMenuItem(NpgsqlDataReader reader)
|
|
{
|
|
MenuItem menuItem = new MenuItem();
|
|
menuItem.Id = reader["id"].ToString();
|
|
menuItem.Label = reader["label"].ToString() ?? "";
|
|
menuItem.Url = reader["url"].ToString() ?? "";
|
|
menuItem.DisplayOrder = (reader["displayorder"] as int?).GetValueOrDefault();
|
|
menuItem.IsActive = (reader["isactive"] as bool?) ?? true;
|
|
menuItem.ShowInNavbar = (reader["showinnavbar"] as bool?) ?? true;
|
|
menuItem.ShowInDropdown = (reader["showindropdown"] as bool?) ?? true;
|
|
menuItem.OpenInNewTab = reader["openinnewtab"] as bool? == true;
|
|
menuItem.CreatedAt = (reader["createdat"] as DateTime?) ?? DateTime.UtcNow;
|
|
return menuItem;
|
|
}
|
|
|
|
private SiteSettings MapToSiteSettings(NpgsqlDataReader reader)
|
|
{
|
|
SiteSettings siteSettings = new SiteSettings();
|
|
siteSettings.Id = reader["id"].ToString();
|
|
siteSettings.SiteName = reader["sitename"]?.ToString() ?? "Sky Art Shop";
|
|
siteSettings.SiteTagline = reader["sitetagline"]?.ToString() ?? "";
|
|
siteSettings.ContactEmail = reader["contactemail"]?.ToString() ?? "";
|
|
siteSettings.ContactPhone = reader["contactphone"]?.ToString() ?? "";
|
|
siteSettings.InstagramUrl = reader["instagramurl"]?.ToString() ?? "#";
|
|
siteSettings.FooterText = reader["footertext"]?.ToString() ?? "";
|
|
siteSettings.UpdatedAt = (reader["updatedat"] as DateTime?) ?? DateTime.UtcNow;
|
|
return siteSettings;
|
|
}
|
|
|
|
private PortfolioCategory MapToPortfolioCategory(NpgsqlDataReader reader)
|
|
{
|
|
PortfolioCategory portfolioCategory = new PortfolioCategory();
|
|
portfolioCategory.Id = reader["id"].ToString();
|
|
portfolioCategory.Name = reader["name"].ToString() ?? "";
|
|
portfolioCategory.Slug = reader["slug"].ToString() ?? "";
|
|
portfolioCategory.Description = reader["description"]?.ToString() ?? "";
|
|
portfolioCategory.ThumbnailImage = reader["thumbnailimage"]?.ToString() ?? "";
|
|
portfolioCategory.FeaturedImage = reader["featuredimage"]?.ToString() ?? "";
|
|
portfolioCategory.DisplayOrder = (reader["displayorder"] as int?).GetValueOrDefault();
|
|
portfolioCategory.IsActive = (reader["isactive"] as bool?) ?? true;
|
|
portfolioCategory.CreatedAt = (reader["createdat"] as DateTime?) ?? DateTime.UtcNow;
|
|
portfolioCategory.UpdatedAt = (reader["updatedat"] as DateTime?) ?? DateTime.UtcNow;
|
|
return portfolioCategory;
|
|
}
|
|
|
|
private BlogPost MapToBlogPost(NpgsqlDataReader reader)
|
|
{
|
|
BlogPost blogPost = new BlogPost();
|
|
blogPost.Id = reader["id"].ToString();
|
|
blogPost.Title = reader["title"].ToString() ?? "";
|
|
blogPost.Slug = reader["slug"].ToString() ?? "";
|
|
blogPost.Content = reader["content"]?.ToString() ?? "";
|
|
blogPost.Excerpt = reader["excerpt"]?.ToString() ?? "";
|
|
blogPost.FeaturedImage = reader["featuredimage"]?.ToString() ?? "";
|
|
blogPost.Author = reader["author"]?.ToString() ?? "";
|
|
blogPost.Tags = JsonSerializer.Deserialize<List<string>>(reader["tags"].ToString() ?? "[]") ?? new List<string>();
|
|
blogPost.IsPublished = (reader["ispublished"] as bool?) ?? true;
|
|
blogPost.PublishedDate = (reader["publisheddate"] as DateTime?) ?? DateTime.UtcNow;
|
|
blogPost.CreatedAt = (reader["createdat"] as DateTime?) ?? DateTime.UtcNow;
|
|
blogPost.UpdatedAt = (reader["updatedat"] as DateTime?) ?? DateTime.UtcNow;
|
|
return blogPost;
|
|
}
|
|
|
|
private HomepageSection MapToHomepageSection(NpgsqlDataReader reader)
|
|
{
|
|
HomepageSection homepageSection = new HomepageSection();
|
|
homepageSection.Id = reader["id"].ToString();
|
|
homepageSection.Title = reader["title"]?.ToString() ?? "";
|
|
homepageSection.Subtitle = reader["subtitle"]?.ToString() ?? "";
|
|
homepageSection.Content = reader["content"]?.ToString() ?? "";
|
|
homepageSection.SectionType = reader["sectiontype"]?.ToString() ?? "";
|
|
homepageSection.ImageUrl = reader["imageurl"]?.ToString() ?? "";
|
|
homepageSection.ButtonText = reader["buttontext"]?.ToString() ?? "";
|
|
homepageSection.ButtonUrl = reader["buttonurl"]?.ToString() ?? "";
|
|
homepageSection.IsActive = (reader["isactive"] as bool?) ?? true;
|
|
homepageSection.DisplayOrder = (reader["displayorder"] as int?).GetValueOrDefault();
|
|
homepageSection.AdditionalData = JsonSerializer.Deserialize<Dictionary<string, string>>(reader["additionaldata"]?.ToString() ?? "{}") ?? new Dictionary<string, string>();
|
|
homepageSection.CreatedAt = (reader["createdat"] as DateTime?) ?? DateTime.UtcNow;
|
|
homepageSection.UpdatedAt = (reader["updatedat"] as DateTime?) ?? DateTime.UtcNow;
|
|
return homepageSection;
|
|
}
|
|
|
|
private PortfolioProject MapToPortfolioProject(NpgsqlDataReader reader)
|
|
{
|
|
PortfolioProject portfolioProject = new PortfolioProject();
|
|
portfolioProject.Id = reader["id"].ToString();
|
|
portfolioProject.CategoryId = reader["categoryid"]?.ToString() ?? "";
|
|
portfolioProject.Title = reader["title"]?.ToString() ?? "";
|
|
portfolioProject.Description = reader["description"]?.ToString() ?? "";
|
|
portfolioProject.FeaturedImage = reader["featuredimage"]?.ToString() ?? "";
|
|
portfolioProject.Images = JsonSerializer.Deserialize<List<string>>(reader["images"].ToString() ?? "[]") ?? new List<string>();
|
|
portfolioProject.DisplayOrder = (reader["displayorder"] as int?).GetValueOrDefault();
|
|
portfolioProject.IsActive = (reader["isactive"] as bool?) ?? true;
|
|
portfolioProject.CreatedAt = (reader["createdat"] as DateTime?) ?? DateTime.UtcNow;
|
|
portfolioProject.UpdatedAt = (reader["updatedat"] as DateTime?) ?? DateTime.UtcNow;
|
|
return portfolioProject;
|
|
}
|
|
}
|