summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Chebotar <s.chebotar@gmail.com>2023-06-03 07:41:46 +0300
committerSergey Chebotar <s.chebotar@gmail.com>2023-06-03 07:41:46 +0300
commit3bade8859bcd938b85c39ab16eaa0dcf8e01535f (patch)
tree9157e3f27d8007206c12d5ec0cf5f2936295c0e7
parent81c1fc0c14253457c3c4fc24735e787ace1db70b (diff)
Mass refactoring
-rw-r--r--Controllers/BundleController.cs147
-rw-r--r--Controllers/FigureController.cs166
-rw-r--r--Controllers/ProductsController.cs133
-rw-r--r--Migrations/20230603040054_Initial.Designer.cs (renamed from Migrations/20230303041621_Init.Designer.cs)34
-rw-r--r--Migrations/20230603040054_Initial.cs (renamed from Migrations/20230303041621_Init.cs)30
-rw-r--r--Migrations/DataContextModelSnapshot.cs30
-rw-r--r--Models/DataContext.cs8
-rw-r--r--Models/Figure.cs19
-rw-r--r--Models/LoginModel.cs2
-rw-r--r--Models/Product.cs15
-rw-r--r--Models/UnderwearBundle.cs11
-rw-r--r--Pages/Figure.cshtml124
-rw-r--r--Pages/Index.cshtml2
-rw-r--r--Pages/Shared/_Navigation.cshtml2
-rw-r--r--Pages/Shared/_Products.cshtml44
-rw-r--r--Pages/Shared/_Projects.cshtml39
-rw-r--r--Views/Account/Create.cshtml8
-rw-r--r--Views/Bundle/Create.cshtml33
-rw-r--r--Views/Bundle/Details.cshtml53
-rw-r--r--Views/Bundle/Index.cshtml49
-rw-r--r--Views/Figure/Details.cshtml45
-rw-r--r--Views/Products/Create.cshtml37
-rw-r--r--Views/Products/Details.cshtml60
-rw-r--r--Views/Products/Index.cshtml43
24 files changed, 639 insertions, 495 deletions
diff --git a/Controllers/BundleController.cs b/Controllers/BundleController.cs
deleted file mode 100644
index b1d61fd..0000000
--- a/Controllers/BundleController.cs
+++ /dev/null
@@ -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 });
- }
- }
- }
-} \ No newline at end of file
diff --git a/Controllers/FigureController.cs b/Controllers/FigureController.cs
index 9f6cf0c..bad8791 100644
--- a/Controllers/FigureController.cs
+++ b/Controllers/FigureController.cs
@@ -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 });
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/Controllers/ProductsController.cs b/Controllers/ProductsController.cs
new file mode 100644
index 0000000..14a4b27
--- /dev/null
+++ b/Controllers/ProductsController.cs
@@ -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 });
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Migrations/20230303041621_Init.Designer.cs b/Migrations/20230603040054_Initial.Designer.cs
index 833e097..cf1a728 100644
--- a/Migrations/20230303041621_Init.Designer.cs
+++ b/Migrations/20230603040054_Initial.Designer.cs
@@ -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");
});
diff --git a/Migrations/20230303041621_Init.cs b/Migrations/20230603040054_Initial.cs
index 788d447..80b5601 100644
--- a/Migrations/20230303041621_Init.cs
+++ b/Migrations/20230603040054_Initial.cs
@@ -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");
}
}
}
diff --git a/Migrations/DataContextModelSnapshot.cs b/Migrations/DataContextModelSnapshot.cs
index b2177d7..6a8e605 100644
--- a/Migrations/DataContextModelSnapshot.cs
+++ b/Migrations/DataContextModelSnapshot.cs
@@ -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");
});
diff --git a/Models/DataContext.cs b/Models/DataContext.cs
index 23e80ab..9fd10e0 100644
--- a/Models/DataContext.cs
+++ b/Models/DataContext.cs
@@ -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>();
}
} \ No newline at end of file
diff --git a/Models/Figure.cs b/Models/Figure.cs
index f63d842..8bbc591 100644
--- a/Models/Figure.cs
+++ b/Models/Figure.cs
@@ -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;
+ }
+ }
} \ No newline at end of file
diff --git a/Models/LoginModel.cs b/Models/LoginModel.cs
index 93485c8..6592135 100644
--- a/Models/LoginModel.cs
+++ b/Models/LoginModel.cs
@@ -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";
} \ No newline at end of file
diff --git a/Models/Product.cs b/Models/Product.cs
new file mode 100644
index 0000000..efb691c
--- /dev/null
+++ b/Models/Product.cs
@@ -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();
+ }
+ }
+} \ No newline at end of file
diff --git a/Models/UnderwearBundle.cs b/Models/UnderwearBundle.cs
deleted file mode 100644
index 1f451e6..0000000
--- a/Models/UnderwearBundle.cs
+++ /dev/null
@@ -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; }
- }
-} \ No newline at end of file
diff --git a/Pages/Figure.cshtml b/Pages/Figure.cshtml
new file mode 100644
index 0000000..76c2216
--- /dev/null
+++ b/Pages/Figure.cshtml
@@ -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}");
+ }
+ }
+ }
+} *@ \ No newline at end of file
diff --git a/Pages/Index.cshtml b/Pages/Index.cshtml
index a3ec3a5..9a887a6 100644
--- a/Pages/Index.cshtml
+++ b/Pages/Index.cshtml
@@ -9,5 +9,5 @@
<partial name="_Navigation" />
<partial name="_Masthead" />
<partial name="_About" />
-<partial name="_Projects" />
+<partial name="_Products" />
<partial name="_SignUp" /> \ No newline at end of file
diff --git a/Pages/Shared/_Navigation.cshtml b/Pages/Shared/_Navigation.cshtml
index 7c29a6b..736fd61 100644
--- a/Pages/Shared/_Navigation.cshtml
+++ b/Pages/Shared/_Navigation.cshtml
@@ -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>
diff --git a/Pages/Shared/_Products.cshtml b/Pages/Shared/_Products.cshtml
new file mode 100644
index 0000000..a82ac1c
--- /dev/null
+++ b/Pages/Shared/_Products.cshtml
@@ -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> \ No newline at end of file
diff --git a/Pages/Shared/_Projects.cshtml b/Pages/Shared/_Projects.cshtml
deleted file mode 100644
index 4b9a62e..0000000
--- a/Pages/Shared/_Projects.cshtml
+++ /dev/null
@@ -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> \ No newline at end of file
diff --git a/Views/Account/Create.cshtml b/Views/Account/Create.cshtml
index 2fff64a..f871673 100644
--- a/Views/Account/Create.cshtml
+++ b/Views/Account/Create.cshtml
@@ -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>
diff --git a/Views/Bundle/Create.cshtml b/Views/Bundle/Create.cshtml
deleted file mode 100644
index 5197909..0000000
--- a/Views/Bundle/Create.cshtml
+++ /dev/null
@@ -1,33 +0,0 @@
-@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-@model MyDarling.Models.UnderwearBundle
-
-<!DOCTYPE html>
-<html>
-
-<head>
- <title>New bundle</title>
- <link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
-</head>
-
-<body>
- <container>
- <form asp-action="Create" method="post" 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">Descrition:</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>
- <input asp-for="Price" class="form-control" />
- </div>
- <button type="submit" class="btn btn-primary mt-3">Submit</button>
- </form>
- </container>
-</body>
-
-</html> \ No newline at end of file
diff --git a/Views/Bundle/Details.cshtml b/Views/Bundle/Details.cshtml
deleted file mode 100644
index ac13624..0000000
--- a/Views/Bundle/Details.cshtml
+++ /dev/null
@@ -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> \ No newline at end of file
diff --git a/Views/Bundle/Index.cshtml b/Views/Bundle/Index.cshtml
deleted file mode 100644
index 9e1f293..0000000
--- a/Views/Bundle/Index.cshtml
+++ /dev/null
@@ -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> \ No newline at end of file
diff --git a/Views/Figure/Details.cshtml b/Views/Figure/Details.cshtml
index ace2a9a..3bb43ea 100644
--- a/Views/Figure/Details.cshtml
+++ b/Views/Figure/Details.cshtml
@@ -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> \ No newline at end of file
diff --git a/Views/Products/Create.cshtml b/Views/Products/Create.cshtml
new file mode 100644
index 0000000..4a6732c
--- /dev/null
+++ b/Views/Products/Create.cshtml
@@ -0,0 +1,37 @@
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
+@model MyDarling.Models.Product
+
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>New bundle</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="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">Название:</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>
+ <button type="submit" class="btn btn-outline-success mt-3">Сохранить</button>
+ </form>
+ </div>
+</body>
+
+</html> \ No newline at end of file
diff --git a/Views/Products/Details.cshtml b/Views/Products/Details.cshtml
new file mode 100644
index 0000000..3e45748
--- /dev/null
+++ b/Views/Products/Details.cshtml
@@ -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> \ No newline at end of file
diff --git a/Views/Products/Index.cshtml b/Views/Products/Index.cshtml
new file mode 100644
index 0000000..0725bb6
--- /dev/null
+++ b/Views/Products/Index.cshtml
@@ -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> \ No newline at end of file