0
0

Mass refactoring

This commit is contained in:
Sergey Chebotar 2023-06-03 07:41:46 +03:00
parent 81c1fc0c14
commit 3bade8859b
23 changed files with 614 additions and 470 deletions

View File

@ -1,147 +0,0 @@
using System.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MyDarling.Models;
namespace MyDarling.Controllers
{
[Authorize]
public class BundleController : Controller
{
private DataContext context;
private IWebHostEnvironment environment;
public BundleController(DataContext context, IWebHostEnvironment environment)
{
this.environment = environment;
this.context = context;
}
public ActionResult Index()
{
return View(context.UnderwearBundles.Include(b => b.Figures));
}
public ActionResult Create()
{
return View();
}
[HttpPost]
public async Task<ActionResult> Create([Bind] UnderwearBundle bundle)
{
try
{
if (ModelState.IsValid)
{
await context.UnderwearBundles.AddAsync(bundle);
context.SaveChanges();
return RedirectToAction(nameof(Index));
}
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save changes");
}
return View(bundle);
}
public async Task<ActionResult> Details(int id)
{
return View(await context.UnderwearBundles.Include(b => b.Figures).Where(b => b.Id == id).FirstOrDefaultAsync());
}
public async Task<ActionResult> Edit(int id)
{
return View(nameof(Details), await context.UnderwearBundles.FindAsync(id));
}
[HttpPost]
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var bundle = await context.UnderwearBundles.FindAsync(id);
if (bundle == null)
{
return NotFound();
}
var file = Request.Form.Files.FirstOrDefault();
if (await TryUpdateModelAsync<UnderwearBundle>(
bundle,
"",
b => b.Name, b => b.Description, b => b.Figures, b => b.Price))
{
if (file != null)
{
var newFigure = new Figure();
bundle.Figures.Add(newFigure);
newFigure.FilePath = $"/Content/{bundle.Id}/{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
var savePath = environment.WebRootPath + "/Content/" + bundle.Id + "/";
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
using var fileStream = new FileStream(environment.WebRootPath + newFigure.FilePath, FileMode.Create);
await file.CopyToAsync(fileStream);
}
try
{
await context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (System.Exception)
{
ModelState.AddModelError("", "Unable to save changes");
}
}
return View(bundle);
}
[HttpPost]
public async Task<ActionResult> Delete(int id)
{
var bundleToDelete = await context.UnderwearBundles.FindAsync(id);
if (bundleToDelete == null)
{
return NotFound();
}
try
{
var bundleDirPath = String.Concat(environment.WebRootPath,
"/Content/",
bundleToDelete.Id);
if (Directory.Exists(bundleDirPath))
{
Directory.Delete(bundleDirPath, true);
}
// foreach (var figure in bundleToDelete.Figures)
// {
// using FigureController controller = new(context, environment);
// await controller.Delete(figure.Id);
// }
context.UnderwearBundles.Remove(bundleToDelete);
await context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException)
{
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
}
}

View File

@ -6,84 +6,104 @@ using MyDarling.Models;
namespace MyDarling.Controllers
{
[Authorize]
public class FigureController : Controller
{
private DataContext context;
private IWebHostEnvironment environment;
public FigureController(DataContext context, IWebHostEnvironment environment)
{
this.context = context;
this.environment = environment;
}
[Authorize]
public class FigureController : Controller
{
private DataContext context;
private IWebHostEnvironment environment;
public FigureController(DataContext context, IWebHostEnvironment environment)
{
this.context = context;
this.environment = environment;
}
public async Task<IActionResult> Details(int id)
{
return View(await context.Figures.Where(f => f.Id == id).FirstOrDefaultAsync());
}
public async Task<IActionResult> Details(string id)
{
var figure = await context.Figures
.Where(f => f.Id.Equals(id))
.FirstOrDefaultAsync();
if (figure == null)
{
return NotFound();
}
var product = await context.Products
.Where(b => b.Figures.Contains(figure))
.FirstOrDefaultAsync();
if (product == null)
{
return NotFound();
}
return View(figure);
}
[HttpPost]
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
[HttpPost]
public async Task<IActionResult> Edit(string id)
{
if (id == null)
{
return NotFound();
}
var figure = await context.Figures.FindAsync(id);
var figure = await context.Figures
.Where(f => f.Id.Equals(id))
.FirstOrDefaultAsync();
if (figure == null)
{
return NotFound();
}
if (figure == null)
{
return NotFound();
}
var bundle = await context.UnderwearBundles
.Where(b => b.Figures.Contains(figure))
.FirstOrDefaultAsync();
var product = await context.Products
.Where(b => b.Figures.Contains(figure))
.FirstOrDefaultAsync();
if (await TryUpdateModelAsync<Figure>(
figure,
"",
f => f.Description))
{
try
{
await context.SaveChangesAsync();
return RedirectToAction("Details", "Bundle", new { Id = bundle?.Id});
}
catch (SystemException)
{
ModelState.AddModelError("", "Unable to save changes");
}
}
return View(figure);
}
[HttpPost]
public async Task<ActionResult> Delete(int id)
{
var figureToDelete = await context.Figures.FindAsync(id);
if (figureToDelete == null)
{
return NotFound();
}
if (await TryUpdateModelAsync<Figure>(
figure,
"",
f => f.Description))
{
try
{
await context.SaveChangesAsync();
return RedirectToAction("Details", "Products", new { Id = product?.Id });
}
catch (SystemException)
{
ModelState.AddModelError("", "Unable to save changes");
}
}
return View(figure);
}
try
{
FileInfo figureFile = new FileInfo(environment.WebRootPath + figureToDelete.FilePath);
if (figureFile.Exists)
{
figureFile.Delete();
}
context.Figures.Remove(figureToDelete);
await context.SaveChangesAsync();
return RedirectToAction(nameof(Index), "Bundle");
}
catch (DbUpdateException)
{
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
}
[HttpPost]
public async Task<ActionResult> Delete(string id)
{
var figure = await context.Figures.FindAsync(id);
if (figure == null)
{
return NotFound();
}
var product = await context.Products
.Where(b => b.Figures.Contains(figure))
.FirstAsync();
try
{
string filePath = $"/Content/{product.Id}/{figure.Id}.jpg";
FileInfo figureFile = new FileInfo(environment.WebRootPath + filePath);
if (figureFile.Exists)
{
figureFile.Delete();
}
context.Figures.Remove(figure);
await context.SaveChangesAsync();
return RedirectToAction("Details", "Products", new { Id = product?.Id });
}
catch (DbUpdateException)
{
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
}
}

View File

@ -0,0 +1,133 @@
using System.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MyDarling.Models;
namespace MyDarling.Controllers
{
[Authorize]
public class ProductsController : Controller
{
private DataContext context;
private IWebHostEnvironment environment;
public ProductsController(DataContext context, IWebHostEnvironment environment)
{
this.environment = environment;
this.context = context;
}
public IActionResult Index()
{
return View(context.Products.Include(b => b.Figures));
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Create([Bind] Product bundle)
{
try
{
if (ModelState.IsValid)
{
await context.Products.AddAsync(bundle);
context.SaveChanges();
return RedirectToAction(nameof(Index));
}
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save changes");
}
return View(bundle);
}
public async Task<IActionResult> Details(string id)
{
return View(await context.Products.Include(b => b.Figures).Where(b => b.Id.Equals(id)).FirstOrDefaultAsync());
}
[HttpPost]
public async Task<IActionResult> Edit(string id)
{
if (string.IsNullOrEmpty(id))
{
return NotFound();
}
var product = await context.Products.FindAsync(id);
if (product == null)
{
return NotFound();
}
var file = Request.Form.Files.FirstOrDefault();
if (await TryUpdateModelAsync<Product>(
product,
"",
b => b.Name, b => b.Description, b => b.Figures, b => b.Price))
{
if (file != null)
{
var newFigure = new Figure(string.Empty, product.Id);
product.Figures.Add(newFigure);
string filePath = $"/Content/{product.Id}/{newFigure.Id}.jpg";
var savePath = environment.WebRootPath + "/Content/" + product.Id + "/";
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
using var fileStream = new FileStream(environment.WebRootPath + filePath, FileMode.Create);
await file.CopyToAsync(fileStream);
}
try
{
await context.SaveChangesAsync();
return RedirectToAction("Details", "Products", new { Id = product?.Id});
}
catch (System.Exception)
{
ModelState.AddModelError("", "Unable to save changes");
}
}
return View(product);
}
[HttpPost]
public async Task<IActionResult> Delete(string id)
{
var productToDelete = await context.Products.FindAsync(id);
if (productToDelete == null)
{
return NotFound();
}
try
{
var bundleDirPath = String.Concat(environment.WebRootPath,
"/Content/",
productToDelete.Id);
if (Directory.Exists(bundleDirPath))
{
Directory.Delete(bundleDirPath, true);
}
context.Products.Remove(productToDelete);
await context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException)
{
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
}
}

View File

@ -1,5 +1,4 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
@ -11,8 +10,8 @@ using MyDarling.Models;
namespace MyDarling.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20230303041621_Init")]
partial class Init
[Migration("20230603040054_Initial")]
partial class Initial
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -22,33 +21,28 @@ namespace MyDarling.Migrations
modelBuilder.Entity("MyDarling.Models.Figure", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("FilePath")
b.Property<string>("ProductId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int?>("UnderwearBundleId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("UnderwearBundleId");
b.HasIndex("ProductId");
b.ToTable("Figures");
});
modelBuilder.Entity("MyDarling.Models.UnderwearBundle", b =>
modelBuilder.Entity("MyDarling.Models.Product", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("Description")
.IsRequired()
@ -63,17 +57,19 @@ namespace MyDarling.Migrations
b.HasKey("Id");
b.ToTable("UnderwearBundles");
b.ToTable("Products");
});
modelBuilder.Entity("MyDarling.Models.Figure", b =>
{
b.HasOne("MyDarling.Models.UnderwearBundle", null)
b.HasOne("MyDarling.Models.Product", null)
.WithMany("Figures")
.HasForeignKey("UnderwearBundleId");
.HasForeignKey("ProductId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("MyDarling.Models.UnderwearBundle", b =>
modelBuilder.Entity("MyDarling.Models.Product", b =>
{
b.Navigation("Figures");
});

View File

@ -5,50 +5,48 @@
namespace MyDarling.Migrations
{
/// <inheritdoc />
public partial class Init : Migration
public partial class Initial : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "UnderwearBundles",
name: "Products",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Id = table.Column<string>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: false),
Description = table.Column<string>(type: "TEXT", nullable: false),
Price = table.Column<decimal>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UnderwearBundles", x => x.Id);
table.PrimaryKey("PK_Products", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Figures",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Id = table.Column<string>(type: "TEXT", nullable: false),
Description = table.Column<string>(type: "TEXT", nullable: false),
FilePath = table.Column<string>(type: "TEXT", nullable: false),
UnderwearBundleId = table.Column<int>(type: "INTEGER", nullable: true)
ProductId = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Figures", x => x.Id);
table.ForeignKey(
name: "FK_Figures_UnderwearBundles_UnderwearBundleId",
column: x => x.UnderwearBundleId,
principalTable: "UnderwearBundles",
principalColumn: "Id");
name: "FK_Figures_Products_ProductId",
column: x => x.ProductId,
principalTable: "Products",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Figures_UnderwearBundleId",
name: "IX_Figures_ProductId",
table: "Figures",
column: "UnderwearBundleId");
column: "ProductId");
}
/// <inheritdoc />
@ -58,7 +56,7 @@ namespace MyDarling.Migrations
name: "Figures");
migrationBuilder.DropTable(
name: "UnderwearBundles");
name: "Products");
}
}
}

View File

@ -1,5 +1,4 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
@ -19,33 +18,28 @@ namespace MyDarling.Migrations
modelBuilder.Entity("MyDarling.Models.Figure", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("FilePath")
b.Property<string>("ProductId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int?>("UnderwearBundleId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("UnderwearBundleId");
b.HasIndex("ProductId");
b.ToTable("Figures");
});
modelBuilder.Entity("MyDarling.Models.UnderwearBundle", b =>
modelBuilder.Entity("MyDarling.Models.Product", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("Description")
.IsRequired()
@ -60,17 +54,19 @@ namespace MyDarling.Migrations
b.HasKey("Id");
b.ToTable("UnderwearBundles");
b.ToTable("Products");
});
modelBuilder.Entity("MyDarling.Models.Figure", b =>
{
b.HasOne("MyDarling.Models.UnderwearBundle", null)
b.HasOne("MyDarling.Models.Product", null)
.WithMany("Figures")
.HasForeignKey("UnderwearBundleId");
.HasForeignKey("ProductId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("MyDarling.Models.UnderwearBundle", b =>
modelBuilder.Entity("MyDarling.Models.Product", b =>
{
b.Navigation("Figures");
});

View File

@ -14,13 +14,7 @@ namespace MyDarling.Models
{
opts.UseSqlite(configuration.GetConnectionString("MyDarlingDb"));
}
// protected override void OnModelCreating(ModelBuilder builder)
// {
// builder.Entity<UnderwearBundle>().HasMany(b => b.Figures).WithOne();
// }
public DbSet<UnderwearBundle> UnderwearBundles => Set<UnderwearBundle>();
public DbSet<Product> Products => Set<Product>();
public DbSet<Figure> Figures => Set<Figure>();
}
}

View File

@ -1,9 +1,16 @@
namespace MyDarling.Models
{
public class Figure
{
public int Id { get; set; }
public string Description { get; set; } = string.Empty;
public string FilePath { get; set; } = string.Empty;
}
public class Figure
{
public string Id { get; set; }
public string Description { get; set; } = string.Empty;
public string ProductId { get; set; }
public Figure(string description, string productId)
{
Id = Guid.NewGuid().ToString();
Description = description;
ProductId = productId;
}
}
}

View File

@ -9,5 +9,5 @@ public class LoginModel
[Required]
public string? Password { get; set; }
public string ReturnUrl { get; set; } = "/Bundle";
public string ReturnUrl { get; set; } = "/Products";
}

15
Models/Product.cs Normal file
View File

@ -0,0 +1,15 @@
namespace MyDarling.Models
{
public class Product
{
public string Id { get; set; }
public string Name { get; set; } = string.Empty;
public List<Figure> Figures { get; set; } = new List<Figure>();
public string Description { get; set; } = string.Empty;
public decimal Price { get; set; } = 1000M;
public Product()
{
Id = Guid.NewGuid().ToString();
}
}
}

View File

@ -1,11 +0,0 @@
namespace MyDarling.Models
{
public class UnderwearBundle
{
public int Id { get; set; }
public string Name { get; set; } = "My Darling Bundle";
public List<Figure> Figures { get; set; } = new List<Figure>();
public string Description { get; set; } = string.Empty;
public decimal Price { get; set; }
}
}

124
Pages/Figure.cshtml Normal file
View File

@ -0,0 +1,124 @@
@* @page "{id}"
@model FigureModel;
@using MyDarling.Models;
@using Microsoft.EntityFrameworkCore;
@using Microsoft.AspNetCore.Mvc.RazorPages
<!DOCTYPE html>
<html>
<head>
<title>Редактирование фотографии</title>
<link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<nav class="navbar navbar-dark bg-primary">
<a class="navbar-brand mx-4" href="/Bundle"><img height="30" src="/assets/img/logo.svg"></a>
<a href="/Account/logout"><button class="btn btn-outline-light mx-4">Выйти</button></a>
</nav>
<div class="container">
<div class="row row-cols-xl-3 row-cols-md-2 justify-content-center mt-3">
<div class="col">
<div class="thumbnail">
<a href="@Model.FilePath">
<img src="@Model.FilePath" class="img-thumbnail img-fluid" alt="@Model.Figure?.Description">
</a>
</div>
<form method="post" class="m-2">
@Html.AntiForgeryToken()
<div class="form-group">
<label class="form-label">Описание:</label>
<input name="description" class="form-control" value="@Model.Figure?.Description" />
</div>
<button type="submit" class="btn btn-outline-success mt-2">Сохранить</button>
</form>
<form asp-page-handler="Delete" method="post">
<button type="submit" class="btn btn-outline-danger mt-2">Удалить</button>
</form>
</div>
</div>
</div>
</body>
</html>
@functions
{
public class FigureModel : PageModel
{
private DataContext context;
private IWebHostEnvironment environment;
public string? FilePath { get; set; }
public Figure? Figure { get; set; }
public UnderwearBundle? Bundle { get; set; }
public FigureModel(DataContext context, IWebHostEnvironment environment)
{
this.context = context;
this.environment = environment;
}
public async Task<IActionResult> OnGetAsync(string id)
{
Figure = await context.Figures
.Where(f => f.Id.Equals(id))
.FirstOrDefaultAsync();
if (Figure == null)
{
return NotFound();
}
Bundle = await context.UnderwearBundles
.Where(b => b.Figures.Contains(Figure))
.FirstOrDefaultAsync();
if (Bundle == null)
{
return NotFound();
}
FilePath = $"/Content/{Bundle.Id}/{Figure.Id}.jpg";
return Page();
}
public async Task<IActionResult> OnPostAsync(string id, string description)
{
Figure = await context.Figures
.Where(f => f.Id.Equals(id))
.FirstOrDefaultAsync();
if (Figure != null)
{
Figure.Description = description ?? string.Empty;
}
await context.SaveChangesAsync();
return RedirectToPage();
}
public async Task<IActionResult> OnPostDeleteAsync(string id)
{
Figure = await context.Figures.FindAsync(id);
if (Figure == null)
{
return NotFound();
}
var parentBundle = await context.UnderwearBundles
.Where(b => b.Figures.Contains(Figure))
.FirstAsync();
try
{
string filePath = $"/Content/{parentBundle.Id}/{Figure}.jpg";
FileInfo figureFile = new FileInfo(environment.WebRootPath + filePath);
if (figureFile.Exists)
{
figureFile.Delete();
}
context.Figures.Remove(Figure);
await context.SaveChangesAsync();
return RedirectToPage($"/Bundle/{Bundle.Id}");
}
catch (DbUpdateException)
{
return RedirectToPage($"/Bundle/{Bundle.Id}");
}
}
}
} *@

View File

@ -9,5 +9,5 @@
<partial name="_Navigation" />
<partial name="_Masthead" />
<partial name="_About" />
<partial name="_Projects" />
<partial name="_Products" />
<partial name="_SignUp" />

View File

@ -10,7 +10,7 @@
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" href="#about">О нас</a></li>
<li class="nav-item"><a class="nav-link" href="#projects">Комплекты</a></li>
<li class="nav-item"><a class="nav-link" href="#products">Комплекты</a></li>
<li class="nav-item"><a class="nav-link" href="#signup">Заказать</a></li>
</ul>
</div>

View File

@ -0,0 +1,44 @@
@using System.Globalization
@using Microsoft.EntityFrameworkCore
@using MyDarling.Models
@inject DataContext context
@{
var products = context.Products
.Include(b => b.Figures)
.Where(b => b.Price != 0 && b.Figures.Count > 0)
.OrderByDescending(b => b.Id);
}
<section class="projects-section bg-light" id="products">
<div class="container px-3 px-lg-4 mt-4">
<div class="row gx-4 gx-lg-5 row-cols-2 row-cols-md-3 row-cols-xl-4 justify-content-center">
@foreach (var product in products)
{
<div class="col mb-5">
<div class="card h-100">
@{
var figure = product.Figures.First();
var filePath = $"/Content/{product.Id}/{figure.Id}.jpg";
}
<a data-src="@filePath" data-fancybox="@product.Id"
data-caption="@figure.Description"><img class="card-img-top"
src="@filePath" alt="@product.Name" /></a>
@for (int i = 1; i < product.Figures.Count(); i++)
{
filePath = $"/Content/{product.Id}/{product.Figures[i].Id}.jpg";
<a data-src="@filePath" data-fancybox="@product.Id"
data-caption="@product.Figures[i].Description"></a>
}
<div class="card-body p-4">
<div class="text-center">
<h5 class="fw-bolder">@product.Name</h5>
@String.Format(new CultureInfo("ru-RU"), "{0:C0}", product.Price)
</div>
</div>
</div>
</div>
}
</div>
</div>
</section>

View File

@ -1,39 +0,0 @@
@using System.Globalization
@using Microsoft.EntityFrameworkCore
@using MyDarling.Models
@inject DataContext context
@{
var bundles = context.UnderwearBundles
.Include(b => b.Figures)
.Where(b => b.Price != 0 && b.Figures.Count > 0)
.OrderByDescending(b => b.Id);
}
<section class="projects-section bg-light" id="projects">
<div class="container px-3 px-lg-4 mt-4">
<div class="row gx-4 gx-lg-5 row-cols-2 row-cols-md-3 row-cols-xl-4 justify-content-center">
@foreach (var bundle in bundles)
{
<div class="col mb-5">
<div class="card h-100">
<a data-src="@bundle.Figures[0].FilePath" data-fancybox="@bundle.Id"
data-caption="@bundle.Figures[0].Description"><img class="card-img-top"
src="@bundle.Figures[0].FilePath" alt="@bundle.Name" /></a>
@for (int i = 1; i < @bundle.Figures.Count(); i++)
{
<a data-src="@bundle.Figures[i].FilePath" data-fancybox="@bundle.Id"
data-caption="@bundle.Figures[i].Description"></a>
}
<div class="card-body p-4">
<div class="text-center">
<h5 class="fw-bolder">@bundle.Name</h5>
@String.Format(new CultureInfo("ru-RU"), "{0:C0}", @bundle.Price)
</div>
</div>
</div>
</div>
}
</div>
</div>
</section>

View File

@ -5,7 +5,7 @@
<html>
<head>
<title>User Acccounts</title>
<title>User Acсounts</title>
<link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
@ -14,7 +14,7 @@
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label>User Name</label>
<label>Имя пользователя</label>
<input name="UserName" class="form-control" value="@Model.UserName" />
</div>
<div class="form-group">
@ -22,11 +22,11 @@
<input name="Email" class="form-control" value="@Model.Email" />
</div>
<div class="form-group">
<label>Password</label>
<label>Пароль</label>
<input name="Password" class="form-control" value="" />
</div>
<div class="py-2">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="submit" class="btn btn-primary">Сохранить</button>
<a class="btn btn-secondary" asp-page="list">Back</a>
</div>
</form>

View File

@ -1,53 +0,0 @@
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model MyDarling.Models.UnderwearBundle
<!DOCTYPE html>
<html>
<head>
<title>Bundles list</title>
<link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<container>
<form asp-action="Edit" asp-route-id="@Model.Id" method="post" enctype="multipart/form-data" class="m-2">
<div asp-validation-summary="All"></div>
<div class="form-group">
<label asp-for="Name" class="form-label">Name:</label>
<input asp-for="Name" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Description" class="form-label">Description:</label>
@Html.TextAreaFor(model => model.Description, new { @class="form-control", @rows = 2 })
</div>
<div>
<label class="form-label">Figures:</label>
<div class="row gx-4 gx-lg-5 row-cols-2 row-cols-md-3 row-cols-xl-4">
@foreach (var figure in @Model.Figures)
{
<div class="col mb-5">
<div class="thumbnail h-100">
<a asp-controller="Figure" asp-action="Details" asp-route-id="@figure.Id">
<img src="@figure.FilePath" class="img-thumbnail img-fluid" alt="@figure.Description">
</a>
</div>
</div>
}
</div>
</div>
<div class="form-group">
<input type="file" name="file" />
</div>
<div class="form-group">
<label asp-for="Price" class="form-label">Price:</label>
<input asp-for="Price" class="form-control" />
</div>
<button type="submit" class="btn btn-primary mt-3">Save</button>
<button asp-action="Delete" asp-route-id="@Model.Id" method="post"
class="btn btn-primary mt-3">Delete</button>
</form>
</container>
</body>
</html>

View File

@ -1,49 +0,0 @@
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model IQueryable<MyDarling.Models.UnderwearBundle>
<!DOCTYPE html>
<html>
<head>
<title>Bundles list</title>
<link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col">
<span class="navbar-brand ml-2">Underwear bundle list</span>
</div>
<div class="col-2 text-right">
<a class="btn btn-sm btn-primary" href="/account/logout">Log Out</a>
</div>
</div>
</div>
<container>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Descrition</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
@foreach (var bundle in Model)
{
<tr>
<th scope="row">@bundle.Id</th>
<td><a asp-action="Details" asp-route-id="@bundle.Id">@bundle.Name</a></td>
<td>@bundle.Description</td>
<td>@bundle.Price</td>
</tr>
}
</tbody>
</table>
<a asp-action="Create">Add bundle</a>
</container>
</body>
</html>

View File

@ -5,30 +5,39 @@
<html>
<head>
<title>Figure</title>
<title>Редактирование фотографии</title>
<link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="row gx-4 gx-lg-5 row-cols-2 row-cols-md-3 row-cols-xl-4 justify-content-center">
<div class="col mb-5">
<div class="thumbnail h-100">
<a href="@Model.FilePath">
<img src="@Model.FilePath" class="img-thumbnail img-fluid" alt="@Model.Description">
</a>
<nav class="navbar navbar-dark bg-primary">
<a class="navbar-brand mx-4" href="/Products"><img height="30" src="/assets/img/logo.svg"></a>
<a href="/Account/logout"><button class="btn btn-outline-light mx-4">Выйти</button></a>
</nav>
<div class="container">
<div class="row row-cols-xl-3 row-cols-md-2 justify-content-center mt-3">
<div class="col">
<div class="thumbnail">
@{
var filePath = $"/Content/{Model.ProductId}/{Model.Id}.jpg";
}
<a href="@filePath">
<img src="@filePath" class="img-thumbnail img-fluid" alt="@Model.Description">
</a>
</div>
<form asp-action="Edit" asp-route-id="@Model.Id" method="post" class="m-2">
<div asp-validation-summary="All"></div>
<div class="form-group">
<label asp-for="Description" class="form-label">Описание:</label>
@Html.TextAreaFor(model => model.Description, new { @class="form-control", @rows = 2 })
</div>
<button type="submit" class="btn btn-outline-success mt-3">Сохранить</button>
<button asp-action="Delete" asp-route-id="@Model.Id" method="post"
class="btn btn-outline-danger mt-3">Удалить</button>
</form>
</div>
</div>
</div>
<form asp-action="Edit" asp-route-id="@Model.Id" method="post" class="m-2">
<div asp-validation-summary="All"></div>
<div class="form-group">
<label asp-for="Description" class="form-label">Description:</label>
@Html.TextAreaFor(model => model.Description, new { @class="form-control", @rows = 2 })
</div>
<button type="submit" class="btn btn-primary mt-3">Save</button>
<button asp-action="Delete" asp-route-id="@Model.Id" method="post" class="btn btn-primary mt-3">Delete</button>
</form>
</body>
</html>
</html>

View File

@ -1,5 +1,5 @@
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model MyDarling.Models.UnderwearBundle
@model MyDarling.Models.Product
<!DOCTYPE html>
<html>
@ -10,24 +10,28 @@
</head>
<body>
<container>
<form asp-action="Create" method="post" class="m-2">
<nav class="navbar navbar-dark bg-primary" aria-label="breadcrumb">
<a class="navbar-brand mx-4" href="/Products"><img height="30" src="/assets/img/logo.svg"></a>
<a href="/Account/logout"><button class="btn btn-outline-light mx-4">Выйти</button></a>
</nav>
<div class="row container-fluid justify-content-center">
<form asp-action="Create" method="post" class="m-2 col-8">
<div asp-validation-summary="All"></div>
<div class="form-group">
<label asp-for="Name" class="form-label">Name:</label>
<label asp-for="Name" class="form-label">Название:</label>
<input asp-for="Name" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Description" class="form-label">Descrition:</label>
<label asp-for="Description" class="form-label">Описание:</label>
@Html.TextAreaFor(model => model.Description, new { @class="form-control", @rows = 2 })
</div>
<div class="form-group">
<label asp-for="Price" class="form-label">Price:</label>
<label asp-for="Price" class="form-label">Цена:</label>
<input asp-for="Price" class="form-control" />
</div>
<button type="submit" class="btn btn-primary mt-3">Submit</button>
<button type="submit" class="btn btn-outline-success mt-3">Сохранить</button>
</form>
</container>
</div>
</body>
</html>

View File

@ -0,0 +1,60 @@
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model MyDarling.Models.Product
<!DOCTYPE html>
<html>
<head>
<title>Комплект: @Model.Name</title>
<link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<nav class="navbar navbar-dark bg-primary" aria-label="breadcrumb">
<a class="navbar-brand mx-4" href="/Products"><img height="30" src="/assets/img/logo.svg"></a>
<a href="/Account/logout"><button class="btn btn-outline-light mx-4">Выйти</button></a>
</nav>
<div class="row container-fluid justify-content-center">
<form asp-action="Edit" asp-route-id="@Model.Id" method="post" enctype="multipart/form-data" class="m-2 col-8">
<div asp-validation-summary="All"></div>
<div class="form-group">
<label asp-for="Name" class="form-label">Название:</label>
<input asp-for="Name" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Description" class="form-label">Описание:</label>
@Html.TextAreaFor(model => model.Description, new { @class="form-control", @rows = 2 })
</div>
<div class="form-group">
<label asp-for="Price" class="form-label">Цена:</label>
<input asp-for="Price" class="form-control" />
</div>
<div>
<label class="form-label">Фотографии:</label>
<div class="row row-cols-md-2 row-cols-xl-3">
@foreach (var figure in @Model.Figures)
{
<div class="mb-3">
<div class="thumbnail h-100">
<a href="/Figure/Details/@figure.Id">
@{
var filePath = $"/Content/{@Model.Id}/{figure.Id}.jpg";
}
<img src="@filePath" class="img-thumbnail img-fluid" alt="@figure.Description">
</a>
</div>
</div>
}
<div class="form-group mb-3">
<input type="file" name="file" />
</div>
</div>
</div>
<button type="submit" class="btn btn-outline-success">Сохранить</button>
<button asp-action="Delete" asp-route-id="@Model.Id" method="post"
class="btn btn-outline-danger">Удалить</button>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,43 @@
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model IQueryable<MyDarling.Models.Product>
<!DOCTYPE html>
<html>
<head>
<title>My Darling Underwear</title>
<link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<nav class="navbar navbar-dark bg-primary">
<a class="navbar-brand mx-4" href="/Products"><img height="30" src="/assets/img/logo.svg"></a>
<a href="/Account/logout"><button class="btn btn-outline-light mx-4">Выйти</button></a>
</nav>
<div class="row container-fluid justify-content-center row-cols-xl-2">
<div class="col">
<table class="table">
<thead>
<tr>
<th scope="col">Название</th>
<th scope="col">Описание</th>
<th scope="col">Цена</th>
</tr>
</thead>
<tbody>
@foreach (var bundle in Model)
{
<tr>
<td><a asp-action="Details" asp-route-id="@bundle.Id">@bundle.Name</a></td>
<td>@bundle.Description</td>
<td>@bundle.Price</td>
</tr>
}
</tbody>
</table>
<a asp-action="Create"><button class="btn btn-primary">Добавить</button></a>
</div>
</div>
</body>
</html>