264 lines
11 KiB
C#
264 lines
11 KiB
C#
|
|
using SkyArtShop.Services;
|
||
|
|
using SkyArtShop.Models;
|
||
|
|
using System.Security.Cryptography;
|
||
|
|
using System.Text;
|
||
|
|
using Microsoft.EntityFrameworkCore;
|
||
|
|
using Microsoft.AspNetCore.Identity;
|
||
|
|
|
||
|
|
var builder = WebApplication.CreateBuilder(args);
|
||
|
|
|
||
|
|
// Configure URLs based on environment
|
||
|
|
if (builder.Environment.IsProduction())
|
||
|
|
{
|
||
|
|
// Production: Listen on all interfaces, port 80 and 443
|
||
|
|
builder.WebHost.UseUrls("http://*:80");
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// Development: Listen only on localhost, port 5001
|
||
|
|
builder.WebHost.UseUrls("http://localhost:5001");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Add services to the container
|
||
|
|
builder.Services.AddControllersWithViews();
|
||
|
|
builder.Services.AddRazorPages();
|
||
|
|
|
||
|
|
// Add EF Core (SQLite) for Identity (separate from MongoDB content storage)
|
||
|
|
var identityConnection = builder.Configuration.GetConnectionString("IdentityConnection") ?? "Data Source=identity.db";
|
||
|
|
builder.Services.AddDbContext<SkyArtShop.Data.ApplicationDbContext>(options =>
|
||
|
|
options.UseSqlite(identityConnection));
|
||
|
|
|
||
|
|
// Add Identity
|
||
|
|
builder.Services.AddIdentity<SkyArtShop.Data.ApplicationUser, IdentityRole>(options =>
|
||
|
|
{
|
||
|
|
options.Password.RequireDigit = false;
|
||
|
|
options.Password.RequireLowercase = false;
|
||
|
|
options.Password.RequireUppercase = false;
|
||
|
|
options.Password.RequireNonAlphanumeric = false;
|
||
|
|
options.Password.RequiredLength = 6;
|
||
|
|
})
|
||
|
|
.AddEntityFrameworkStores<SkyArtShop.Data.ApplicationDbContext>()
|
||
|
|
.AddDefaultTokenProviders();
|
||
|
|
|
||
|
|
builder.Services.ConfigureApplicationCookie(options =>
|
||
|
|
{
|
||
|
|
options.LoginPath = "/admin/login";
|
||
|
|
options.AccessDeniedPath = "/admin/login";
|
||
|
|
});
|
||
|
|
|
||
|
|
// Configure MongoDB
|
||
|
|
builder.Services.Configure<MongoDBSettings>(
|
||
|
|
builder.Configuration.GetSection("MongoDB"));
|
||
|
|
|
||
|
|
builder.Services.AddSingleton<MongoDBService>();
|
||
|
|
builder.Services.AddSingleton<SlugService>();
|
||
|
|
|
||
|
|
// Add session support
|
||
|
|
builder.Services.AddDistributedMemoryCache();
|
||
|
|
builder.Services.AddSession(options =>
|
||
|
|
{
|
||
|
|
options.IdleTimeout = TimeSpan.FromHours(2);
|
||
|
|
options.Cookie.HttpOnly = true;
|
||
|
|
options.Cookie.IsEssential = true;
|
||
|
|
});
|
||
|
|
|
||
|
|
// Add HttpContextAccessor
|
||
|
|
builder.Services.AddHttpContextAccessor();
|
||
|
|
|
||
|
|
var app = builder.Build();
|
||
|
|
|
||
|
|
// Initialize database with default data
|
||
|
|
await InitializeDatabase(app.Services);
|
||
|
|
|
||
|
|
// Configure the HTTP request pipeline
|
||
|
|
if (!app.Environment.IsDevelopment())
|
||
|
|
{
|
||
|
|
app.UseExceptionHandler("/Home/Error");
|
||
|
|
app.UseHsts();
|
||
|
|
}
|
||
|
|
|
||
|
|
// app.UseHttpsRedirection(); // Disabled for HTTP-only development
|
||
|
|
app.UseStaticFiles();
|
||
|
|
|
||
|
|
app.UseRouting();
|
||
|
|
|
||
|
|
app.UseSession();
|
||
|
|
app.UseAuthentication();
|
||
|
|
app.UseAuthorization();
|
||
|
|
|
||
|
|
app.MapControllerRoute(
|
||
|
|
name: "default",
|
||
|
|
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||
|
|
|
||
|
|
app.Run();
|
||
|
|
|
||
|
|
async Task InitializeDatabase(IServiceProvider services)
|
||
|
|
{
|
||
|
|
using var scope = services.CreateScope();
|
||
|
|
var mongoService = scope.ServiceProvider.GetRequiredService<MongoDBService>();
|
||
|
|
var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
|
||
|
|
|
||
|
|
// Apply Identity migrations and seed admin user/role
|
||
|
|
var dbContext = scope.ServiceProvider.GetRequiredService<SkyArtShop.Data.ApplicationDbContext>();
|
||
|
|
await dbContext.Database.EnsureCreatedAsync();
|
||
|
|
|
||
|
|
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
|
||
|
|
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<SkyArtShop.Data.ApplicationUser>>();
|
||
|
|
|
||
|
|
const string adminRole = "Admin";
|
||
|
|
if (!await roleManager.RoleExistsAsync(adminRole))
|
||
|
|
{
|
||
|
|
await roleManager.CreateAsync(new IdentityRole(adminRole));
|
||
|
|
}
|
||
|
|
|
||
|
|
var adminEmail = configuration["AdminUser:Email"] ?? "admin@skyartshop.com";
|
||
|
|
var existingAdmin = await userManager.FindByEmailAsync(adminEmail);
|
||
|
|
if (existingAdmin == null)
|
||
|
|
{
|
||
|
|
var adminUser = new SkyArtShop.Data.ApplicationUser
|
||
|
|
{
|
||
|
|
UserName = adminEmail,
|
||
|
|
Email = adminEmail,
|
||
|
|
DisplayName = configuration["AdminUser:Name"] ?? "Admin"
|
||
|
|
};
|
||
|
|
var createResult = await userManager.CreateAsync(adminUser, configuration["AdminUser:Password"] ?? "Admin123!");
|
||
|
|
if (createResult.Succeeded)
|
||
|
|
{
|
||
|
|
await userManager.AddToRoleAsync(adminUser, adminRole);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Initialize site settings
|
||
|
|
var settings = await mongoService.GetAllAsync<SiteSettings>("SiteSettings");
|
||
|
|
if (!settings.Any())
|
||
|
|
{
|
||
|
|
var defaultSettings = new SiteSettings
|
||
|
|
{
|
||
|
|
SiteName = "Sky Art Shop",
|
||
|
|
SiteTagline = "Scrapbooking and Journaling Fun",
|
||
|
|
ContactEmail = "info@skyartshop.com",
|
||
|
|
ContactPhone = "+501 608-0409",
|
||
|
|
FooterText = "© 2035 by Sky Art Shop. Powered and secured by Wix",
|
||
|
|
UpdatedAt = DateTime.UtcNow
|
||
|
|
};
|
||
|
|
|
||
|
|
await mongoService.InsertAsync("SiteSettings", defaultSettings);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Initialize default portfolio categories
|
||
|
|
var categories = await mongoService.GetAllAsync<PortfolioCategory>("PortfolioCategories");
|
||
|
|
if (!categories.Any())
|
||
|
|
{
|
||
|
|
var defaultCategories = new[]
|
||
|
|
{
|
||
|
|
new PortfolioCategory { Name = "Displays", Slug = "displays", Description = "Creative display projects showcasing our work", DisplayOrder = 1, IsActive = true },
|
||
|
|
new PortfolioCategory { Name = "Personal Craft Projects", Slug = "personal-craft-projects", Description = "Personal creative projects and handmade crafts", DisplayOrder = 2, IsActive = true },
|
||
|
|
new PortfolioCategory { Name = "Card Making Projects", Slug = "card-making", Description = "Handmade cards for every occasion", DisplayOrder = 3, IsActive = true },
|
||
|
|
new PortfolioCategory { Name = "Scrapbook Albums", Slug = "scrapbook-albums", Description = "Preserving memories through creative scrapbooking", DisplayOrder = 4, IsActive = true }
|
||
|
|
};
|
||
|
|
|
||
|
|
foreach (var category in defaultCategories)
|
||
|
|
{
|
||
|
|
await mongoService.InsertAsync("PortfolioCategories", category);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Initialize About page
|
||
|
|
var pages = await mongoService.GetAllAsync<Page>("Pages");
|
||
|
|
if (!pages.Any(p => p.PageSlug == "about"))
|
||
|
|
{
|
||
|
|
var aboutPage = new Page
|
||
|
|
{
|
||
|
|
PageName = "About",
|
||
|
|
PageSlug = "about",
|
||
|
|
Title = "About Sky Art Shop",
|
||
|
|
Subtitle = "Creating moments, one craft at a time",
|
||
|
|
Content = @"
|
||
|
|
<h2>Our Story</h2>
|
||
|
|
<p>Sky Art Shop specializes in scrapbooking, journaling, cardmaking, and collaging stationery. We are passionate about helping people express their creativity and preserve their memories.</p>
|
||
|
|
<p>Our mission is to promote mental health and wellness through creative art activities. We believe that crafting is more than just a hobby—it's a therapeutic journey that brings joy, mindfulness, and self-expression.</p>
|
||
|
|
|
||
|
|
<h2>What We Offer</h2>
|
||
|
|
<ul>
|
||
|
|
<li>Washi tape in various designs and patterns</li>
|
||
|
|
<li>Unique stickers for journaling and scrapbooking</li>
|
||
|
|
<li>High-quality journals and notebooks</li>
|
||
|
|
<li>Card making supplies and kits</li>
|
||
|
|
<li>Scrapbooking materials and embellishments</li>
|
||
|
|
<li>Collage papers and ephemera</li>
|
||
|
|
</ul>",
|
||
|
|
IsActive = true,
|
||
|
|
CreatedAt = DateTime.UtcNow,
|
||
|
|
UpdatedAt = DateTime.UtcNow
|
||
|
|
};
|
||
|
|
|
||
|
|
await mongoService.InsertAsync("Pages", aboutPage);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Initialize menu items
|
||
|
|
var menuItems = await mongoService.GetAllAsync<MenuItem>("MenuItems");
|
||
|
|
if (!menuItems.Any())
|
||
|
|
{
|
||
|
|
var defaultMenuItems = new[]
|
||
|
|
{
|
||
|
|
new MenuItem { Label = "Home", Url = "/", DisplayOrder = 1, IsActive = true },
|
||
|
|
new MenuItem { Label = "Shop", Url = "/Shop", DisplayOrder = 2, IsActive = true },
|
||
|
|
new MenuItem { Label = "Top Sellers", Url = "/#top-sellers", DisplayOrder = 3, IsActive = true },
|
||
|
|
new MenuItem { Label = "Promotion", Url = "/#promotion", DisplayOrder = 4, IsActive = true },
|
||
|
|
new MenuItem { Label = "Portfolio", Url = "/Portfolio", DisplayOrder = 5, IsActive = true },
|
||
|
|
new MenuItem { Label = "Blog", Url = "/Blog", DisplayOrder = 6, IsActive = true },
|
||
|
|
new MenuItem { Label = "About", Url = "/About", DisplayOrder = 7, IsActive = true },
|
||
|
|
new MenuItem { Label = "Instagram", Url = "#instagram", DisplayOrder = 8, IsActive = true },
|
||
|
|
new MenuItem { Label = "Contact", Url = "/Contact", DisplayOrder = 9, IsActive = true },
|
||
|
|
new MenuItem { Label = "My Wishlist", Url = "#wishlist", DisplayOrder = 10, IsActive = true }
|
||
|
|
};
|
||
|
|
|
||
|
|
foreach (var item in defaultMenuItems)
|
||
|
|
{
|
||
|
|
await mongoService.InsertAsync("MenuItems", item);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Initialize homepage sections
|
||
|
|
var sections = await mongoService.GetAllAsync<HomepageSection>("HomepageSections");
|
||
|
|
if (!sections.Any())
|
||
|
|
{
|
||
|
|
var defaultSections = new[]
|
||
|
|
{
|
||
|
|
new HomepageSection
|
||
|
|
{
|
||
|
|
SectionType = "hero",
|
||
|
|
Title = "Scrapbooking and Journaling Fun",
|
||
|
|
Subtitle = "Explore the world of creativity and self-expression.",
|
||
|
|
ButtonText = "Shop Now",
|
||
|
|
ButtonUrl = "/Shop",
|
||
|
|
ImageUrl = "/assets/images/hero-craft.jpg",
|
||
|
|
DisplayOrder = 0,
|
||
|
|
IsActive = true
|
||
|
|
},
|
||
|
|
new HomepageSection
|
||
|
|
{
|
||
|
|
SectionType = "inspiration",
|
||
|
|
Title = "Our Inspiration",
|
||
|
|
Content = @"<p>Sky Art Shop specializes in scrapbooking, journaling, cardmaking, and collaging stationery. We aim to promote mental health through creative art activities.</p><p>Our offerings include washi tape, stickers, journals, and more.</p>",
|
||
|
|
ImageUrl = "/assets/images/craft-supplies.jpg",
|
||
|
|
DisplayOrder = 1,
|
||
|
|
IsActive = true
|
||
|
|
},
|
||
|
|
new HomepageSection
|
||
|
|
{
|
||
|
|
SectionType = "promotion",
|
||
|
|
Title = "Special Offers",
|
||
|
|
Content = @"<div class='promo-card featured'><h2>Large Stationery Mystery Bags</h2><p>Enjoy $70 worth of items for only $25. Think Larger and heavier items.</p><a href='tel:+5016080409' class='btn btn-primary'>Message Us</a></div>",
|
||
|
|
DisplayOrder = 2,
|
||
|
|
IsActive = true
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
foreach (var section in defaultSections)
|
||
|
|
{
|
||
|
|
await mongoService.InsertAsync("HomepageSections", section);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|