Compare commits
17 Commits
master
...
kaniko-tes
Author | SHA1 | Date | |
---|---|---|---|
surtur | 3a155798a9 | ||
surtur | 3f775a110b | ||
surtur | 42c6dfd3ba | ||
surtur | 1cc3df6619 | ||
surtur | befe7880fc | ||
surtur | 15d7de1996 | ||
surtur | 5ed341f4ae | ||
surtur | 732cd7d717 | ||
surtur | 11a9ab07ab | ||
surtur | a581457326 | ||
surtur | 1ef9a6831f | ||
surtur | 11d796f0dd | ||
surtur | 4b58c3f584 | ||
surtur | 63601f7f47 | ||
surtur | 54fb45ec65 | ||
surtur | eece1e3dba | ||
surtur | 907a4702d8 |
|
@ -1,13 +0,0 @@
|
|||
docker-compose.yml
|
||||
.dockerignore
|
||||
.gitignore
|
||||
bin/
|
||||
obj/
|
||||
.git
|
||||
.vs
|
||||
.vscode
|
||||
.aspnet
|
||||
.dotnet
|
||||
.nuget
|
||||
.local
|
||||
.*.env
|
58
.drone.yml
58
.drone.yml
|
@ -7,75 +7,33 @@ platform:
|
|||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/master
|
||||
- refs/heads/feature-*
|
||||
- refs/pull/*/head
|
||||
- refs/tags/*
|
||||
|
||||
steps:
|
||||
- name: restore
|
||||
pull: always
|
||||
image: mcr.microsoft.com/dotnet/core/sdk:3.1-alpine
|
||||
volumes:
|
||||
- name: pkgcache
|
||||
path: /root/.nuget/packages
|
||||
depends_on: [clone]
|
||||
commands:
|
||||
- dotnet restore
|
||||
|
||||
- name: debug
|
||||
pull: always
|
||||
image: mcr.microsoft.com/dotnet/core/sdk:3.1-alpine
|
||||
volumes:
|
||||
- name: pkgcache
|
||||
path: /root/.nuget/packages
|
||||
depends_on: [restore]
|
||||
image: mcr.microsoft.com/dotnet/core/sdk:2.1-alpine
|
||||
commands:
|
||||
- dotnet restore
|
||||
- dotnet build .
|
||||
|
||||
- name: release
|
||||
pull: always
|
||||
image: mcr.microsoft.com/dotnet/core/sdk:3.1-alpine
|
||||
volumes:
|
||||
- name: pkgcache
|
||||
path: /root/.nuget/packages
|
||||
depends_on: [restore]
|
||||
image: mcr.microsoft.com/dotnet/core/sdk:2.1-alpine
|
||||
commands:
|
||||
- dotnet publish -c Release -o out
|
||||
|
||||
- name: hadolint release
|
||||
image: hadolint/hadolint:v1.23.0-8-gb01c5a9-alpine
|
||||
depends_on: [clone]
|
||||
commands:
|
||||
- hadolint --version
|
||||
- hadolint Dockerfile
|
||||
|
||||
- name: hadolint debug
|
||||
image: hadolint/hadolint:v1.23.0-8-gb01c5a9-alpine
|
||||
depends_on: [clone]
|
||||
commands:
|
||||
- hadolint --version
|
||||
- hadolint Dockerfile.dev
|
||||
- dotnet restore
|
||||
- dotnet clean
|
||||
- dotnet publish -c Release
|
||||
|
||||
- name: docker-release-build
|
||||
pull: always
|
||||
image: immawanderer/drone-kaniko:linux-amd64
|
||||
depends_on: [release, hadolint release]
|
||||
image: banzaicloud/drone-kaniko
|
||||
settings:
|
||||
dockerfile: Dockerfile
|
||||
context: .
|
||||
|
||||
- name: docker-debug-build
|
||||
pull: always
|
||||
image: immawanderer/drone-kaniko:linux-amd64
|
||||
depends_on: [debug, hadolint debug]
|
||||
image: banzaicloud/drone-kaniko
|
||||
settings:
|
||||
dockerfile: Dockerfile.dev
|
||||
context: .
|
||||
|
||||
volumes:
|
||||
- name: pkgcache
|
||||
temp: {}
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
tab_width = 4
|
||||
|
||||
[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}]
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[{*.yaml,*.yml}]
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.js.map]
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,hlsl,hlsli,hlslinc,master,nuspec,paml,razor,resw,resx,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
|
||||
end_of_line = lf
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
tab_width = 4
|
|
@ -1,3 +0,0 @@
|
|||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=a6a204ca41effac89a0696ec8c652ba8b6b668129d55b5085eb4453ccb214343481bd0a61b889f1e2ec2ad58d267edf623898892b6cd042f93ad17610871da58
|
||||
POSTGRES_INITDB_ARGS="--data-checksums"
|
|
@ -1,3 +0,0 @@
|
|||
DOTNET_CLI_TELEMETRY_OPTOUT=true
|
||||
ASPNETCORE_ENVIRONMENT=Production
|
||||
DB_CONNECTION_STRING="User ID=postgres;Password=a6a204ca41effac89a0696ec8c652ba8b6b668129d55b5085eb4453ccb214343481bd0a61b889f1e2ec2ad58d267edf623898892b6cd042f93ad17610871da58;Server=db;Port=5432;Database=pwt;Integrated Security=true;Pooling=true;"
|
|
@ -4,17 +4,3 @@ obj/
|
|||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
*.swp
|
||||
.dotnet/
|
||||
.aspnet/
|
||||
.nuget/
|
||||
.local/
|
||||
.idea/
|
||||
.vscode/
|
||||
.vs/
|
||||
.ash_history
|
||||
|
||||
*.jpg
|
||||
*.jpeg
|
||||
*.png
|
||||
|
||||
.*.env
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
ignored:
|
||||
# ad "SC2039 In POSIX sh, UID is undefined." - it's a var defined by us
|
||||
- SC2039
|
|
@ -1,125 +1,98 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using pwt_0x01_ng.Models;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
using pwt_0x01_ng.Models.Dbfake;
|
||||
|
||||
namespace pwt_0x01_ng.Areas.Admin.Controllers
|
||||
{
|
||||
[Area("Admin")]
|
||||
[Authorize(Roles = nameof(Roles.Admin) + "," + nameof(Roles.Manager))]
|
||||
public class CarouselController : Controller
|
||||
{
|
||||
IWebHostEnvironment hosting_env;
|
||||
readonly DBContext dbctx;
|
||||
[Area("Admin")]
|
||||
public class CarouselController : Controller
|
||||
{
|
||||
IHostingEnvironment hosting_env;
|
||||
private IList<Carousel> Carousels = Dbfake.Carousels;
|
||||
|
||||
public CarouselController(DBContext dbctx, IWebHostEnvironment hosting_env){
|
||||
this.dbctx = dbctx;
|
||||
this.hosting_env = hosting_env;
|
||||
}
|
||||
public CarouselController(IHostingEnvironment hosting_env){
|
||||
this.hosting_env = hosting_env;
|
||||
}
|
||||
|
||||
// GET
|
||||
public async Task <IActionResult> Select()
|
||||
{
|
||||
CarouselViewModel carousel = new CarouselViewModel();
|
||||
carousel.Carousels = await dbctx.Carousel.ToListAsync();
|
||||
return View(carousel);
|
||||
}
|
||||
// GET
|
||||
public IActionResult Select()
|
||||
{
|
||||
CarouselViewModel carousel = new CarouselViewModel();
|
||||
carousel.Carousels = Carousels;
|
||||
return View(carousel);
|
||||
}
|
||||
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Create(Carousel carousel)
|
||||
{
|
||||
if (ModelState.IsValid) {
|
||||
MegaUpload mega_upload = new MegaUpload(hosting_env.WebRootPath, "carousels", "image");
|
||||
if ((carousel.ImageSrc = await mega_upload.DoMegaUpload(carousel.Image)) != string.Empty){/* all good here */}
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Create(Carousel carousel)
|
||||
{
|
||||
carousel.ImageSrc = string.Empty;
|
||||
MegaUpload mega_upload = new MegaUpload(hosting_env);
|
||||
await mega_upload.DoMegaUpload(carousel);
|
||||
|
||||
dbctx.Carousel.Add(carousel);
|
||||
await dbctx.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Select));
|
||||
} else {
|
||||
string errors = "";
|
||||
for (int i = 0; i < ModelState.Values.Count(); i++){
|
||||
for (int j = 0; j < ModelState.Values.ElementAt(i).Errors.Count(); j++){
|
||||
errors += "\n " + ModelState.Values.ElementAt(i).Errors.ElementAt(j).ToString();
|
||||
}
|
||||
}
|
||||
ViewData["Message"] = $"error creating Carousel => \n{errors}" + errors;
|
||||
return View(carousel);
|
||||
}
|
||||
}
|
||||
Carousels.Add(carousel);
|
||||
return RedirectToAction(nameof(Select));
|
||||
}
|
||||
|
||||
public IActionResult Edit(int id)
|
||||
{
|
||||
Carousel carousel_item = dbctx.Carousel.Where(c_item => c_item.id == id).FirstOrDefault();
|
||||
if (carousel_item != null)
|
||||
{
|
||||
ViewData["ImageSrc"] = new SelectList(dbctx.Carousel, "ImageSrc", carousel_item.ImageSrc);
|
||||
return View(carousel_item);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
public IActionResult Edit(int id)
|
||||
{
|
||||
Carousel carousel_item = Carousels.Where(c_item => c_item.id == id).FirstOrDefault();
|
||||
if (carousel_item != null)
|
||||
{
|
||||
return View(carousel_item);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Edit(Carousel carousel)
|
||||
{
|
||||
Carousel carousel_item = dbctx.Carousel.Where(c_item => c_item.id == carousel.id).FirstOrDefault();
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Edit(Carousel carousel)
|
||||
{
|
||||
Carousel carousel_item = Carousels.Where(c_item => c_item.id == carousel.id).FirstOrDefault();
|
||||
|
||||
if (carousel_item != null)
|
||||
{
|
||||
if (ModelState.IsValid) {
|
||||
carousel_item.id = carousel.id;
|
||||
carousel_item.DataTarget = carousel.DataTarget;
|
||||
carousel_item.ImageAlt = carousel.ImageAlt;
|
||||
carousel_item.CarouselContent = carousel.CarouselContent;
|
||||
if (carousel_item != null)
|
||||
{
|
||||
carousel_item.id = carousel.id;
|
||||
carousel_item.DataTarget = carousel.DataTarget;
|
||||
carousel_item.ImageAlt = carousel.ImageAlt;
|
||||
carousel_item.CarouselContent = carousel.CarouselContent;
|
||||
|
||||
MegaUpload mega_upload = new MegaUpload(hosting_env.WebRootPath, "carousels", "image");
|
||||
if ((carousel.ImageSrc = await mega_upload.DoMegaUpload(carousel.Image)) != string.Empty){
|
||||
carousel_item.ImageSrc = carousel.ImageSrc;
|
||||
}
|
||||
await dbctx.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Select));
|
||||
}
|
||||
string errors = "";
|
||||
for (int i = 0; i < ModelState.Values.Count(); i++){
|
||||
for (int j = 0; j < ModelState.Values.ElementAt(i).Errors.Count(); j++){
|
||||
errors += "\n " + ModelState.Values.ElementAt(i).Errors.ElementAt(j).ToString();
|
||||
}
|
||||
}
|
||||
ViewData["Message"] = "error editing Carousel => \n" + errors;
|
||||
return View(carousel_item);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
MegaUpload mega_upload = new MegaUpload(hosting_env);
|
||||
if (await mega_upload.DoMegaUpload(carousel)){
|
||||
carousel_item.ImageSrc = carousel.ImageSrc;
|
||||
}
|
||||
return RedirectToAction(nameof(Select));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task <IActionResult> Delete(int id)
|
||||
{
|
||||
Carousel carousel_item = dbctx.Carousel.Where(c_item => c_item.id == id).FirstOrDefault();
|
||||
if (carousel_item != null)
|
||||
{
|
||||
dbctx.Carousel.Remove(carousel_item);
|
||||
await dbctx.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Select));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
public IActionResult Delete(int id)
|
||||
{
|
||||
Carousel carousel_item = Carousels.Where(c_item => c_item.id == id).FirstOrDefault();
|
||||
if (carousel_item != null)
|
||||
{
|
||||
Carousels.Remove(carousel_item);
|
||||
return RedirectToAction(nameof(Select));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,168 +0,0 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using pwt_0x01_ng.Models;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
|
||||
namespace pwt_0x01_ng.Areas.Admin.Controllers
|
||||
{
|
||||
[Area("Admin")]
|
||||
[Authorize(Roles = nameof(Roles.Admin))]
|
||||
public class OrderItemController : Controller
|
||||
{
|
||||
private readonly DBContext _context;
|
||||
|
||||
public OrderItemController(DBContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: Admin/OrderItem
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
var dBContext = _context.OrderItem.Include(o => o.Order).Include(o => o.Product);
|
||||
return View(await dBContext.ToListAsync());
|
||||
}
|
||||
|
||||
// GET: Admin/OrderItem/Details/5
|
||||
public async Task<IActionResult> Details(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var orderItem = await _context.OrderItem
|
||||
.Include(o => o.Order)
|
||||
.Include(o => o.Product)
|
||||
.FirstOrDefaultAsync(m => m.id == id);
|
||||
if (orderItem == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return View(orderItem);
|
||||
}
|
||||
|
||||
// GET: Admin/OrderItem/Create
|
||||
public IActionResult Create()
|
||||
{
|
||||
ViewData["Order_id"] = new SelectList(_context.Order, "id", "Order_Number");
|
||||
ViewData["Product_id"] = new SelectList(_context.Product, "id", "Description");
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: Admin/OrderItem/Create
|
||||
// To protect from overposting attacks, enable the specific properties you want to bind to, for
|
||||
// more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Create([Bind("Order_id,Product_id,Amount,Price,id,Created,Updated")] OrderItem orderItem)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Add(orderItem);
|
||||
await _context.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
ViewData["Order_id"] = new SelectList(_context.Order, "id", "Order_Number", orderItem.Order_id);
|
||||
ViewData["Product_id"] = new SelectList(_context.Product, "id", "Description", orderItem.Product_id);
|
||||
return View(orderItem);
|
||||
}
|
||||
|
||||
// GET: Admin/OrderItem/Edit/5
|
||||
public async Task<IActionResult> Edit(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var orderItem = await _context.OrderItem.FindAsync(id);
|
||||
if (orderItem == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
ViewData["Order_id"] = new SelectList(_context.Order, "id", "Order_Number", orderItem.Order_id);
|
||||
ViewData["Product_id"] = new SelectList(_context.Product, "id", "Description", orderItem.Product_id);
|
||||
return View(orderItem);
|
||||
}
|
||||
|
||||
// POST: Admin/OrderItem/Edit/5
|
||||
// To protect from overposting attacks, enable the specific properties you want to bind to, for
|
||||
// more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Edit(int id, [Bind("Order_id,Product_id,Amount,Price,id,new.Created,new.Updated")] OrderItem orderItem)
|
||||
{
|
||||
if (id != orderItem.id)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
try
|
||||
{
|
||||
_context.Update(orderItem);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!OrderItemExists(orderItem.id))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
ViewData["Order_id"] = new SelectList(_context.Order, "id", "Order_Number", orderItem.Order_id);
|
||||
ViewData["Product_id"] = new SelectList(_context.Product, "id", "Description", orderItem.Product_id);
|
||||
return View(orderItem);
|
||||
}
|
||||
|
||||
// GET: Admin/OrderItem/Delete/5
|
||||
public async Task<IActionResult> Delete(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var orderItem = await _context.OrderItem
|
||||
.Include(o => o.Order)
|
||||
.Include(o => o.Product)
|
||||
.FirstOrDefaultAsync(m => m.id == id);
|
||||
if (orderItem == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return View(orderItem);
|
||||
}
|
||||
|
||||
// POST: Admin/OrderItem/Delete/5
|
||||
[HttpPost, ActionName("Delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> DeleteConfirmed(int id)
|
||||
{
|
||||
var orderItem = await _context.OrderItem.FindAsync(id);
|
||||
_context.OrderItem.Remove(orderItem);
|
||||
await _context.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
private bool OrderItemExists(int id)
|
||||
{
|
||||
return _context.OrderItem.Any(e => e.id == id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,158 +0,0 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using pwt_0x01_ng.Models;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
|
||||
namespace pwt_0x01_ng.Areas.Admin.Controllers
|
||||
{
|
||||
[Area("Admin")]
|
||||
[Authorize(Roles = nameof(Roles.Admin) + "," + nameof(Roles.Manager))]
|
||||
public class OrdersController : Controller
|
||||
{
|
||||
private readonly DBContext _context;
|
||||
|
||||
public OrdersController(DBContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: Admin/Orders
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
return View(await _context.Order.ToListAsync());
|
||||
}
|
||||
|
||||
// GET: Admin/Orders/Details/5
|
||||
public async Task<IActionResult> Details(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var order = await _context.Order
|
||||
.FirstOrDefaultAsync(m => m.id == id);
|
||||
if (order == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
ViewData["User_id"] = new SelectList(_context.Users, "Id", "Id", order.User_id);
|
||||
return View(order);
|
||||
}
|
||||
|
||||
// GET: Admin/Orders/Create
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: Admin/Orders/Create
|
||||
// To protect from overposting attacks, enable the specific properties you want to bind to, for
|
||||
// more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Create([Bind("Order_Number,id,User_id,Price_total,Created,Updated")] Order order)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Add(order);
|
||||
await _context.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
return View(order);
|
||||
}
|
||||
|
||||
// GET: Admin/Orders/Edit/5
|
||||
public async Task<IActionResult> Edit(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var order = await _context.Order.FindAsync(id);
|
||||
if (order == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
ViewData["User_id"] = new SelectList(_context.Users, "Id", "Id", order.User_id);
|
||||
return View(order);
|
||||
}
|
||||
|
||||
// POST: Admin/Orders/Edit/5
|
||||
// To protect from overposting attacks, enable the specific properties you want to bind to, for
|
||||
// more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Edit(int id, [Bind("Order_Number,id,User_id,Price_total,new.Created,new.Updated")] Order order)
|
||||
{
|
||||
if (id != order.id)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
try
|
||||
{
|
||||
_context.Update(order);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!OrderExists(order.id))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
ViewData["User_id"] = new SelectList(_context.Users, "Id", "Id", order.User_id);
|
||||
return View(order);
|
||||
}
|
||||
|
||||
// GET: Admin/Orders/Delete/5
|
||||
public async Task<IActionResult> Delete(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var order = await _context.Order
|
||||
.FirstOrDefaultAsync(m => m.id == id);
|
||||
if (order == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return View(order);
|
||||
}
|
||||
|
||||
// POST: Admin/Orders/Delete/5
|
||||
[HttpPost, ActionName("Delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> DeleteConfirmed(int id)
|
||||
{
|
||||
var order = await _context.Order.FindAsync(id);
|
||||
_context.Order.Remove(order);
|
||||
await _context.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
private bool OrderExists(int id)
|
||||
{
|
||||
return _context.Order.Any(e => e.id == id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using pwt_0x01_ng.Models;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace pwt_0x01_ng.Areas.Admin.Controllers
|
||||
{
|
||||
[Area("Admin")]
|
||||
[Authorize(Roles = nameof(Roles.Admin) + "," + nameof(Roles.Manager))]
|
||||
public class ProductController : Controller
|
||||
{
|
||||
IWebHostEnvironment hosting_env;
|
||||
readonly DBContext dbctx;
|
||||
|
||||
public ProductController(DBContext dbctx, IWebHostEnvironment hosting_env){
|
||||
this.dbctx = dbctx;
|
||||
this.hosting_env = hosting_env;
|
||||
}
|
||||
|
||||
public async Task <IActionResult> Select()
|
||||
{
|
||||
ProductViewModel product = new ProductViewModel();
|
||||
product.Products = await dbctx.Product.ToListAsync();
|
||||
return View(product);
|
||||
}
|
||||
|
||||
public async Task<IActionResult> Create()
|
||||
{
|
||||
ProductViewModel product = new ProductViewModel();
|
||||
product.Products = await dbctx.Product.ToListAsync();
|
||||
ViewData["prods"] = product.Products;
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Create(Product product)
|
||||
{
|
||||
if (ModelState.IsValid) {
|
||||
MegaUpload mega_upload = new MegaUpload(hosting_env.WebRootPath, "products", "image");
|
||||
if ((product.ImageSrc = await mega_upload.DoMegaUpload(product.Image)) != string.Empty){/* all good here */};
|
||||
|
||||
dbctx.Product.Add(product);
|
||||
await dbctx.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Select));
|
||||
} else {
|
||||
ViewData["Message"] = "error creating Product";
|
||||
return View(product);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IActionResult> Edit(int id)
|
||||
{
|
||||
ProductViewModel product = new ProductViewModel();
|
||||
product.Products = await dbctx.Product.ToListAsync();
|
||||
ViewData["prods"] = product.Products;
|
||||
|
||||
Product item = dbctx.Product.Where(p_item => p_item.id == id).FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
IList<Similar> s = await dbctx.Similar.Where(p_item => p_item.prod_id == id).ToListAsync();
|
||||
IList<SimilarProduct> similar = new List<SimilarProduct>();
|
||||
foreach (var prod in product.Products) {
|
||||
SimilarProduct sp = new SimilarProduct();
|
||||
sp.id = prod.id;
|
||||
sp.Selected = prod.Selected;
|
||||
similar.Add(sp);
|
||||
}
|
||||
foreach (var s_item in s)
|
||||
{
|
||||
var prodpls = await dbctx.Product.Where(p_item => p_item.id == s_item.similar_prod_id).FirstOrDefaultAsync();
|
||||
if(prodpls != null){
|
||||
for (int i = 0; i < similar.Count; i++)
|
||||
{
|
||||
if(similar[i].id == prodpls.id){
|
||||
similar[i].Selected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
item.Similar = similar;
|
||||
ViewData["ImageSrc"] = new SelectList(dbctx.Product, "ImageSrc", item.ImageSrc);
|
||||
return View(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Edit(Product product)
|
||||
{
|
||||
Product item = dbctx.Product.Where(p_item => p_item.id == product.id).FirstOrDefault();
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
if (ModelState.IsValid) {
|
||||
item.id = product.id;
|
||||
item.Name = product.Name;
|
||||
item.Price = product.Price;
|
||||
item.Description = product.Description;
|
||||
item.ImageAlt = product.ImageAlt;
|
||||
|
||||
MegaUpload mega_upload = new MegaUpload(hosting_env.WebRootPath, "products", "image");
|
||||
if ((product.ImageSrc = await mega_upload.DoMegaUpload(product.Image)) != string.Empty){
|
||||
item.ImageSrc = product.ImageSrc;
|
||||
}
|
||||
|
||||
if (product.Similar != null) {
|
||||
IList<SimilarProduct> similar = new List<SimilarProduct>();
|
||||
foreach (var prod in product.Similar) {
|
||||
SimilarProduct sp = new SimilarProduct();
|
||||
sp.id = prod.id;
|
||||
sp.Selected = prod.Selected;
|
||||
similar.Add(sp);
|
||||
}
|
||||
if(similar.Count > 0){
|
||||
foreach (var prod in similar)
|
||||
{
|
||||
Similar s = dbctx.Similar.Where(p_item => p_item.prod_id == item.id && p_item.similar_prod_id == prod.id).FirstOrDefault();
|
||||
if(prod.Selected){
|
||||
if (s == null) {
|
||||
s = new Similar();
|
||||
s.prod_id = item.id;
|
||||
s.similar_prod_id = prod.id;
|
||||
dbctx.Similar.Add(s);
|
||||
}
|
||||
} else {
|
||||
if (s != null) {
|
||||
dbctx.Similar.Remove(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await dbctx.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Select));
|
||||
}
|
||||
var errors = ModelState.Values.SelectMany(v => v.Errors);
|
||||
ViewData["Message"] = "error editing Product";
|
||||
return View(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task <IActionResult> Delete(int id)
|
||||
{
|
||||
Product item = dbctx.Product.Where(p_item => p_item.id == id).FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
dbctx.Product.Remove(item);
|
||||
await dbctx.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Select));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace pwt_0x01_ng.Areas.Admin.Controllers
|
||||
{
|
||||
[Area("Admin")]
|
||||
[Authorize(Roles = nameof(Roles.Admin))]
|
||||
public class UsersController : Controller
|
||||
{
|
||||
private readonly DBContext _context;
|
||||
|
||||
public UsersController(DBContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: Admin/Users
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
return View(await _context.Users.ToListAsync());
|
||||
}
|
||||
|
||||
// GET: Admin/Users/Details/5
|
||||
public async Task<IActionResult> Details(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var user = await _context.Users
|
||||
.FirstOrDefaultAsync(m => m.Id == id);
|
||||
if (user == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return View(user);
|
||||
}
|
||||
|
||||
// GET: Admin/Users/Create
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: Admin/Users/Create
|
||||
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
|
||||
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Create([Bind("Name,LastName,Id,UserName,NormalizedUserName,Email,NormalizedEmail,EmailConfirmed,PasswordHash,SecurityStamp,ConcurrencyStamp,TwoFactorEnabled,LockoutEnd,LockoutEnabled,AccessFailedCount")] User user)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Add(user);
|
||||
await _context.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
return View(user);
|
||||
}
|
||||
|
||||
// GET: Admin/Users/Edit/5
|
||||
public async Task<IActionResult> Edit(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var user = await _context.Users.FindAsync(id);
|
||||
if (user == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return View(user);
|
||||
}
|
||||
|
||||
// POST: Admin/Users/Edit/5
|
||||
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
|
||||
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Edit(int id, [Bind("Name,LastName,Id,UserName,NormalizedUserName,Email,NormalizedEmail,EmailConfirmed,PasswordHash,SecurityStamp,ConcurrencyStamp,TwoFactorEnabled,LockoutEnd,LockoutEnabled,AccessFailedCount")] User user)
|
||||
{
|
||||
if (id != user.Id)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
try
|
||||
{
|
||||
_context.Update(user);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!UserExists(user.Id))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
return View(user);
|
||||
}
|
||||
|
||||
// GET: Admin/Users/Delete/5
|
||||
public async Task<IActionResult> Delete(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var user = await _context.Users
|
||||
.FirstOrDefaultAsync(m => m.Id == id);
|
||||
if (user == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return View(user);
|
||||
}
|
||||
|
||||
// POST: Admin/Users/Delete/5
|
||||
[HttpPost, ActionName("Delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> DeleteConfirmed(int id)
|
||||
{
|
||||
var user = await _context.Users.FindAsync(id);
|
||||
_context.Users.Remove(user);
|
||||
await _context.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
private bool UserExists(int id)
|
||||
{
|
||||
return _context.Users.Any(e => e.Id == id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
@using pwt_0x01_ng.Areas.Admin.Controllers;
|
||||
@model Carousel
|
||||
@{
|
||||
ViewData["Title"] = "Carousel Creation";
|
||||
ViewData["Title"] = "Carousel Creation";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
@ -10,8 +9,3 @@
|
|||
|
||||
@{ViewBag.Action = "Create";}
|
||||
@await Html.PartialAsync("PartialForm_EditCreate", Model)
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
<script defer src="~/js/validation/file_type.js"></script>
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
@using pwt_0x01_ng.Areas.Admin.Controllers;
|
||||
@model Carousel
|
||||
@{
|
||||
ViewData["Title"] = "Carousel Editing";
|
||||
ViewData["Title"] = "Carousel Editing";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
@ -9,9 +8,4 @@
|
|||
<p>Edit carousel item.</p>
|
||||
|
||||
@{ViewBag.Action = "Edit";}
|
||||
<partial name="PartialForm_EditCreate" model="Model"/>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
<script defer src="~/js/validation/file_type.js"></script>
|
||||
}
|
||||
<partial name="PartialForm_EditCreate" model="Model">
|
||||
|
|
|
@ -1,41 +1,36 @@
|
|||
@using pwt_0x01_ng.Areas.Admin.Controllers;
|
||||
@model Carousel
|
||||
@{
|
||||
if((!String.IsNullOrEmpty(ViewBag.Action))||(!String.IsNullOrWhiteSpace(ViewBag.Action)))
|
||||
{
|
||||
<div class="row">
|
||||
<form asp-action="@ViewBag.Action" enctype="multipart/form-data" method="post">
|
||||
<div class="form-group col-sm-4">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
@{if (@ViewBag.Action == nameof(CarouselController.Edit)){
|
||||
<input type="hidden" asp-for="@Model.id" class="form-control" aria-describedby="carousel id edit">
|
||||
}}
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.DataTarget"></label>
|
||||
<input asp-for="@Model.DataTarget" class="form-control" aria-describedby="css selector id of the image" placeholder="Data Target">
|
||||
<span asp-validation-for="@Model.DataTarget" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Image"></label>
|
||||
<input id="file" asp-for="@Model.Image" accept="image/*" class="form-inline" aria-describedby="the image">
|
||||
<span asp-validation-for="@Model.Image" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.ImageAlt"></label>
|
||||
<input asp-for="@Model.ImageAlt" class="form-control" aria-describedby="image alt text" placeholder="Image alt">
|
||||
<span asp-validation-for="@Model.ImageAlt" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.CarouselContent"></label>
|
||||
<textarea asp-for="@Model.CarouselContent" class="form-control" aria-describedby="image description" placeholder="Image description"></textarea>
|
||||
<span asp-validation-for="@Model.CarouselContent" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
else {
|
||||
<h2>Error: Action is not set</h2>
|
||||
}
|
||||
if((!String.IsNullOrEmpty(ViewBag.Action))||(!String.IsNullOrWhiteSpace(ViewBag.Action)))
|
||||
{
|
||||
<div class="row">
|
||||
<form asp-action="@ViewBag.Action" enctype="multipart/form-data" method="post">
|
||||
<div class="form-group col-sm-4">
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.id"></label>
|
||||
<input asp-for="@Model.id" class="form-control" id="inputCarousel" aria-describedby="carouselHelp" placeholder="id">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.DataTarget"></label>
|
||||
<input asp-for="@Model.DataTarget" class="form-control" id="inputCarousel" aria-describedby="carouselHelp" placeholder="Data Target">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Image"></label>
|
||||
<input asp-for="@Model.Image" accept="image/*" class="form-inline" id="inputCarousel" aria-describedby="carouselHelp">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.ImageAlt"></label>
|
||||
<input asp-for="@Model.ImageAlt" class="form-control" id="inputCarousel" aria-describedby="carouselHelp" placeholder="Image alt">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.CarouselContent"></label>
|
||||
<input asp-for="@Model.CarouselContent" class="form-control" id="inputCarousel" aria-describedby="carouselHelp" placeholder="Image description">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
else {
|
||||
<h2>Error: Action is not set</h2>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@model CarouselViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Carousel Select";
|
||||
ViewData["Title"] = "Carousel Select";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
@ -11,35 +11,40 @@
|
|||
<br/><br/>
|
||||
|
||||
@{
|
||||
if (Model?.Carousels != null && Model.Carousels.Count > 0) {
|
||||
<table id="carousel_table" class="table table-responsive table-striped table-bordered">
|
||||
<tr>
|
||||
<th class="col-sm-1">@Html.DisplayNameFor(model => model.Carousels[0].id)</th>
|
||||
<th class="col-sm-1">@Html.DisplayNameFor(model => model.Carousels[0].DataTarget)</th>
|
||||
<th class="col-sm-2">@Html.DisplayNameFor(model => model.Carousels[0].ImageSrc)</th>
|
||||
<th class="col-sm-2">@Html.DisplayNameFor(model => model.Carousels[0].ImageAlt)</th>
|
||||
<th class="col-sm-4">@Html.DisplayNameFor(model => model.Carousels[0].CarouselContent)</th>
|
||||
<th class="col-sm-1">Edit</th>
|
||||
<th class="col-sm-1">Delete</th>
|
||||
</tr>
|
||||
@{
|
||||
foreach (var carousel_item in Model.Carousels)
|
||||
{
|
||||
<tr>
|
||||
<td class="col-sm-1">@carousel_item.id</td>
|
||||
<td class="col-sm-1">@carousel_item.DataTarget</td>
|
||||
<td class="col-sm-2">@carousel_item.ImageSrc</td>
|
||||
<td class="col-sm-2">@carousel_item.ImageAlt</td>
|
||||
<td class="col-sm-4">@carousel_item.CarouselContent</td>
|
||||
<td class="col-sm-1"><a asp-action="Edit" asp-route-id="@carousel_item.id">Edit</a></td>
|
||||
<td class="col-sm-1"><a asp-action="Delete" asp-route-id="@carousel_item.id" onclick="return item_deletion_confirmation();">Delete</a></td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</table>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h2>Carousel is empty</h2>
|
||||
}
|
||||
if (Model?.Carousels != null && Model.Carousels.Count > 0) {
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<th class="col-sm-1">@Html.DisplayNameFor(model => model.Carousels[0].id)</th>
|
||||
<th class="col-sm-2">@Html.DisplayNameFor(model => model.Carousels[0].DataTarget)</th>
|
||||
<th class="col-sm-2">@Html.DisplayNameFor(model => model.Carousels[0].ImageSrc)</th>
|
||||
<th class="col-sm-2">@Html.DisplayNameFor(model => model.Carousels[0].ImageAlt)</th>
|
||||
<th class="col-sm-4">@Html.DisplayNameFor(model => model.Carousels[0].CarouselContent)</th>
|
||||
<th class="col-sm-1">Edit</th>
|
||||
<th class="col-sm-1">Delete</th>
|
||||
</tr>
|
||||
@{
|
||||
foreach (var carousel_item in Model.Carousels)
|
||||
{
|
||||
<tr>
|
||||
<td class="col-sm-1">@carousel_item.id</td>
|
||||
<td class="col-sm-2">@carousel_item.DataTarget</td>
|
||||
<td class="col-sm-2">@carousel_item.ImageSrc</td>
|
||||
<td class="col-sm-2">@carousel_item.ImageAlt</td>
|
||||
<td class="col-sm-4">@carousel_item.CarouselContent</td>
|
||||
<td class="col-sm-2"><a asp-action="Edit" asp-route-id="@carousel_item.id">Edit</a></td>
|
||||
<td class="col-sm-2"><a asp-action="Delete" asp-route-id="@carousel_item.id" onclick="return c_item_deletion_confirmation();">Delete</a></td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</table>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h2>Carousel is empty</h2>
|
||||
}
|
||||
}
|
||||
|
||||
@section Scripts
|
||||
{
|
||||
<script src="~/js/ultimate_script.js"></script>
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.OrderItem
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Create";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<h4>OrderItem</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form asp-action="Create">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Order_id" class="control-label"></label>
|
||||
<select asp-for="Order_id" class ="form-control" asp-items="ViewBag.Order_id"></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Product_id" class="control-label"></label>
|
||||
<select asp-for="Product_id" class ="form-control" asp-items="ViewBag.Product_id"></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Amount" class="control-label"></label>
|
||||
<input asp-for="Amount" class="form-control" />
|
||||
<span asp-validation-for="Amount" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Price" class="control-label"></label>
|
||||
<input asp-for="Price" class="form-control" />
|
||||
<span asp-validation-for="Price" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Create" class="btn btn-primary" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
|
@ -1,57 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.OrderItem
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Delete";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<h3>Are you sure you want to delete this?</h3>
|
||||
<div>
|
||||
<h4>OrderItem</h4>
|
||||
<hr />
|
||||
<dl class="row">
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Amount)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Amount)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Price)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Price)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Order)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Order.Order_Number)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Product)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Product.Description)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Created)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Created)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Updated)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Updated)
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<form asp-action="Delete">
|
||||
<input type="hidden" asp-for="id" />
|
||||
<input type="submit" value="Delete" class="btn btn-danger" /> |
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</form>
|
||||
</div>
|
|
@ -1,54 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.OrderItem
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Details";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<div>
|
||||
<h4>OrderItem</h4>
|
||||
<hr />
|
||||
<dl class="row">
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Amount)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Amount)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Price)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Price)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Order)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Order.Order_Number)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Product)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Product.Description)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Created)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Created)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Updated)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Updated)
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div>
|
||||
<a asp-action="Edit" asp-route-id="@Model.id">Edit</a> |
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
|
@ -1,45 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.OrderItem
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Edit";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<h4>OrderItem</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form asp-action="Edit">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Order_id" class="control-label"></label>
|
||||
<select asp-for="Order_id" class="form-control" asp-items="ViewBag.Order_id"></select>
|
||||
<span asp-validation-for="Order_id" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Product_id" class="control-label"></label>
|
||||
<select asp-for="Product_id" class="form-control" asp-items="ViewBag.Product_id"></select>
|
||||
<span asp-validation-for="Product_id" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Amount" class="control-label"></label>
|
||||
<input asp-for="Amount" class="form-control" />
|
||||
<span asp-validation-for="Amount" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Price" class="control-label"></label>
|
||||
<input asp-for="Price" class="form-control" />
|
||||
<span asp-validation-for="Price" class="text-danger"></span>
|
||||
</div>
|
||||
<input type="hidden" asp-for="id" />
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Save" class="btn btn-primary" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
|
@ -1,65 +0,0 @@
|
|||
@model IEnumerable<pwt_0x01_ng.Models.OrderItem>
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "OrderItem";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<p>
|
||||
<a asp-action="Create">Create New</a>
|
||||
</p>
|
||||
<table class="table table-responsive table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Amount)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Price)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Order)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Product)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Created)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Updated)
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model) {
|
||||
<tr>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Amount)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Price)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Order.Order_Number)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Product.Description)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Created)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Updated)
|
||||
</td>
|
||||
<td>
|
||||
<a asp-action="Edit" asp-route-id="@item.id">Edit</a> |
|
||||
<a asp-action="Details" asp-route-id="@item.id">Details</a> |
|
||||
<a asp-action="Delete" asp-route-id="@item.id">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
|
@ -1,34 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.Order
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Create";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<h4>Order</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form asp-action="Create">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Order_Number" class="control-label"></label>
|
||||
<input asp-for="Order_Number" class="form-control" />
|
||||
<span asp-validation-for="Order_Number" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="User_id" class="control-label"></label>
|
||||
<input asp-for="User_id" class="form-control" />
|
||||
<span asp-validation-for="User_id" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Create" class="btn btn-primary" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
|
@ -1,51 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.Order
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Delete";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<h3>Are you sure you want to delete this?</h3>
|
||||
<div>
|
||||
<h4>Order</h4>
|
||||
<hr />
|
||||
<dl class="row">
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Order_Number)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Order_Number)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.User_id)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.User_id)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Price_total)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Price_total)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Created)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Created)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Updated)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Updated)
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<form asp-action="Delete">
|
||||
<input type="hidden" asp-for="id" />
|
||||
<input type="submit" value="Delete" class="btn btn-danger" /> |
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</form>
|
||||
</div>
|
|
@ -1,48 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.Order
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Details";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<div>
|
||||
<h4>Order</h4>
|
||||
<hr />
|
||||
<dl class="row">
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Order_Number)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Order_Number)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.User_id)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.User_id)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Price_total)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Price_total)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Created)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Created)
|
||||
</dd>
|
||||
<dt class = "col-sm-2">
|
||||
@Html.DisplayNameFor(model => model.Updated)
|
||||
</dt>
|
||||
<dd class = "col-sm-10">
|
||||
@Html.DisplayFor(model => model.Updated)
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div>
|
||||
<a asp-action="Edit" asp-route-id="@Model.id">Edit</a> |
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
|
@ -1,40 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.Order
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Edit";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<h4>Order</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form asp-action="Edit">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Order_Number" class="control-label"></label>
|
||||
<input asp-for="Order_Number" class="form-control" />
|
||||
<span asp-validation-for="Order_Number" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="User_id" class="control-label"></label>
|
||||
<input asp-for="User_id" class="form-control" />
|
||||
<span asp-validation-for="User_id" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Price_total" class="control-label"></label>
|
||||
<input asp-for="Price_total" class="form-control" />
|
||||
<span asp-validation-for="Price_total" class="text-danger"></span>
|
||||
</div>
|
||||
<input type="hidden" asp-for="id" />
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Save" class="btn btn-primary" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
|
@ -1,58 +0,0 @@
|
|||
@model IEnumerable<pwt_0x01_ng.Models.Order>
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Order Index";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
<p>
|
||||
<a asp-action="Create">Create New</a>
|
||||
</p>
|
||||
<table class="table table-responsive table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Order_Number)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.User_id)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Price_total)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Created)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Updated)
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model) {
|
||||
<tr>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Order_Number)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.User_id)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Price_total)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Created)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Updated)
|
||||
</td>
|
||||
<td>
|
||||
<a asp-action="Edit" asp-route-id="@item.id">Edit</a> |
|
||||
<a asp-action="Details" asp-route-id="@item.id">Details</a> |
|
||||
<a asp-action="Delete" asp-route-id="@item.id">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
|
@ -1,16 +0,0 @@
|
|||
@model Product
|
||||
@{
|
||||
ViewData["Title"] = "Product - Create";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<p>Create new item.</p>
|
||||
|
||||
@{ViewBag.Action = "Create";}
|
||||
@await Html.PartialAsync("edit-create_part", Model)
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
<script defer src="~/js/validation/file_type.js"></script>
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
@model Product
|
||||
@{
|
||||
ViewData["Title"] = "Product - Edit";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<p>Edit product.</p>
|
||||
|
||||
@{ViewBag.Action = "Edit";}
|
||||
<partial name="edit-create_part" model="Model"/>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
<script defer src="~/js/validation/file_type.js"></script>
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
@model ProductViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Products";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<p>All product data.</p>
|
||||
<a asp-action="Create">Create new item</a>
|
||||
<br/><br/>
|
||||
|
||||
@{
|
||||
if (Model?.Products != null && Model.Products.Count > 0) {
|
||||
<table id="product_table" class="table table-responsive table-striped table-bordered">
|
||||
<tr>
|
||||
<th class="col-sm">@Html.DisplayNameFor(model => model.Products[0].id)</th>
|
||||
<th class="col-sm-2">@Html.DisplayNameFor(model => model.Products[0].Name)</th>
|
||||
<th class="col-sm-1">@Html.DisplayNameFor(model => model.Products[0].Price)</th>
|
||||
<th class="col-sm-3">@Html.DisplayNameFor(model => model.Products[0].Description)</th>
|
||||
<th class="col-sm-3">@Html.DisplayNameFor(model => model.Products[0].ImageSrc)</th>
|
||||
<th class="col-sm-2">@Html.DisplayNameFor(model => model.Products[0].ImageAlt)</th>
|
||||
<th class="col-sm">Edit</th>
|
||||
<th class="col-sm">Delete</th>
|
||||
</tr>
|
||||
@{
|
||||
foreach (var item in Model.Products)
|
||||
{
|
||||
<tr>
|
||||
<td class="col-sm">@item.id</td>
|
||||
<td class="col-sm-2">@item.Name</td>
|
||||
<td class="col-sm-1">@item.Price</td>
|
||||
<td class="col-sm-3">@item.Description</td>
|
||||
<td class="col-sm-3">@item.ImageSrc</td>
|
||||
<td class="col-sm-2">@item.ImageAlt</td>
|
||||
<td class="col-sm"><a asp-action="Edit" asp-route-id="@item.id">Edit</a></td>
|
||||
<td class="col-sm"><a asp-action="Delete" asp-route-id="@item.id" onclick="return item_deletion_confirmation();">Delete</a></td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</table>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h2>No products to show</h2>
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
@using pwt_0x01_ng.Areas.Admin.Controllers;
|
||||
@model Product
|
||||
@{
|
||||
IList<Product> products;
|
||||
IList<SimilarProduct> similar;
|
||||
products = (IList<Product>)ViewData["prods"];
|
||||
similar = new List<SimilarProduct>();
|
||||
if((!String.IsNullOrEmpty(ViewBag.Action))||(!String.IsNullOrWhiteSpace(ViewBag.Action)))
|
||||
{
|
||||
<div class="row">
|
||||
<form asp-action="@ViewBag.Action" enctype="multipart/form-data" method="post">
|
||||
<div class="form-group col-sm-4">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
@{
|
||||
if (@ViewBag.Action == nameof(ProductController.Edit)){
|
||||
<input type="hidden" asp-for="@Model.id" class="form-control">
|
||||
}
|
||||
}
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Name"></label>
|
||||
<input asp-for="@Model.Name" class="form-control" aria-describedby="product name" placeholder="product name">
|
||||
<span asp-validation-for="@Model.Name" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Price"></label>
|
||||
<input asp-for="@Model.Price" class="form-control" aria-describedby="product price" placeholder="price">
|
||||
<span asp-validation-for="@Model.Price" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Description"></label>
|
||||
<input asp-for="@Model.Description" class="form-control" aria-describedby="product description" placeholder="description">
|
||||
<span asp-validation-for="@Model.Description" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Image"></label>
|
||||
<input id="file" asp-for="@Model.Image" accept="image/*" class="form-inline" aria-describedby="product image">
|
||||
<span asp-validation-for="@Model.Image" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.ImageAlt"></label>
|
||||
<input asp-for="@Model.ImageAlt" class="form-control" aria-describedby="product image alt text" placeholder="Image alt">
|
||||
<span asp-validation-for="@Model.ImageAlt" class="text-danger"></span>
|
||||
</div>
|
||||
@{
|
||||
if(@Model != null && products != null && products.Count > 0){
|
||||
<div class="form-group form-check">
|
||||
<div>
|
||||
<label>similar products</label>
|
||||
</div>
|
||||
@if(@Model.Similar != null){
|
||||
similar = @Model.Similar;
|
||||
}
|
||||
@for(int i = 0; i < products.Count; i++){
|
||||
@if(products.ElementAt(i).id != @Model.id){
|
||||
<label class="form-check-label checkbox-inline">@products.ElementAt(i).Name</label>
|
||||
@if(similar[i].Selected){
|
||||
<input asp-for="@Model.Similar[i].Selected" type="checkbox" checked>
|
||||
<input asp-for="@Model.Similar[i].id" type="hidden">
|
||||
} else {
|
||||
<input asp-for="@Model.Similar[i].Selected" type="checkbox">
|
||||
<input asp-for="@Model.Similar[i].id" type="hidden">
|
||||
}
|
||||
} else {
|
||||
<input asp-for="@Model.Similar[i].Selected" type="checkbox" hidden>
|
||||
<input asp-for="@Model.Similar[i].id" type="hidden">
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
else {
|
||||
<h2>Error: Action is not set</h2>
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.Identity.User
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Create";
|
||||
}
|
||||
|
||||
<h2>Create</h2>
|
||||
|
||||
<h4>User</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form asp-action="Create">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Name" class="control-label"></label>
|
||||
<input asp-for="Name" class="form-control" />
|
||||
<span asp-validation-for="Name" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="LastName" class="control-label"></label>
|
||||
<input asp-for="LastName" class="form-control" />
|
||||
<span asp-validation-for="LastName" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="UserName" class="control-label"></label>
|
||||
<input asp-for="UserName" class="form-control" />
|
||||
<span asp-validation-for="UserName" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="NormalizedUserName" class="control-label"></label>
|
||||
<input asp-for="NormalizedUserName" class="form-control" />
|
||||
<span asp-validation-for="NormalizedUserName" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Email" class="control-label"></label>
|
||||
<input asp-for="Email" class="form-control" />
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="NormalizedEmail" class="control-label"></label>
|
||||
<input asp-for="NormalizedEmail" class="form-control" />
|
||||
<span asp-validation-for="NormalizedEmail" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input asp-for="EmailConfirmed" /> @Html.DisplayNameFor(model => model.EmailConfirmed)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="PasswordHash" class="control-label"></label>
|
||||
<input asp-for="PasswordHash" class="form-control" />
|
||||
<span asp-validation-for="PasswordHash" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="SecurityStamp" class="control-label"></label>
|
||||
<input asp-for="SecurityStamp" class="form-control" />
|
||||
<span asp-validation-for="SecurityStamp" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="ConcurrencyStamp" class="control-label"></label>
|
||||
<input asp-for="ConcurrencyStamp" class="form-control" />
|
||||
<span asp-validation-for="ConcurrencyStamp" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input asp-for="TwoFactorEnabled" /> @Html.DisplayNameFor(model => model.TwoFactorEnabled)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="LockoutEnd" class="control-label"></label>
|
||||
<input asp-for="LockoutEnd" class="form-control" />
|
||||
<span asp-validation-for="LockoutEnd" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input asp-for="LockoutEnabled" /> @Html.DisplayNameFor(model => model.LockoutEnabled)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="AccessFailedCount" class="control-label"></label>
|
||||
<input asp-for="AccessFailedCount" class="form-control" />
|
||||
<span asp-validation-for="AccessFailedCount" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Create" class="btn btn-default" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.Identity.User
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Delete";
|
||||
}
|
||||
|
||||
<h2>Delete</h2>
|
||||
|
||||
<h3>Are you sure you want to delete this?</h3>
|
||||
<div>
|
||||
<h4>User</h4>
|
||||
<hr />
|
||||
<dl class="dl-horizontal">
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.Name)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.Name)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.LastName)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.LastName)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.UserName)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.UserName)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.NormalizedUserName)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.NormalizedUserName)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.Email)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.Email)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.NormalizedEmail)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.NormalizedEmail)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.EmailConfirmed)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.EmailConfirmed)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.PasswordHash)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.PasswordHash)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.SecurityStamp)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.SecurityStamp)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ConcurrencyStamp)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ConcurrencyStamp)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.TwoFactorEnabled)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.TwoFactorEnabled)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.LockoutEnd)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.LockoutEnd)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.LockoutEnabled)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.LockoutEnabled)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.AccessFailedCount)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.AccessFailedCount)
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<form asp-action="Delete">
|
||||
<input type="hidden" asp-for="Id" />
|
||||
<input type="submit" value="Delete" class="btn btn-default" /> |
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</form>
|
||||
</div>
|
|
@ -1,102 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.Identity.User
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Details";
|
||||
}
|
||||
|
||||
<h2>Details</h2>
|
||||
|
||||
<div>
|
||||
<h4>User</h4>
|
||||
<hr />
|
||||
<dl class="dl-horizontal">
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.Name)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.Name)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.LastName)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.LastName)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.UserName)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.UserName)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.NormalizedUserName)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.NormalizedUserName)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.Email)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.Email)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.NormalizedEmail)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.NormalizedEmail)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.EmailConfirmed)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.EmailConfirmed)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.PasswordHash)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.PasswordHash)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.SecurityStamp)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.SecurityStamp)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ConcurrencyStamp)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ConcurrencyStamp)
|
||||
</dd>>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.TwoFactorEnabled)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.TwoFactorEnabled)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.LockoutEnd)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.LockoutEnd)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.LockoutEnabled)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.LockoutEnabled)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.AccessFailedCount)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.AccessFailedCount)
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div>
|
||||
<a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
|
@ -1,117 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.Identity.User
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Edit";
|
||||
}
|
||||
|
||||
<h2>Edit</h2>
|
||||
|
||||
<h4>User</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form asp-action="Edit">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Name" class="control-label"></label>
|
||||
<input asp-for="Name" class="form-control" />
|
||||
<span asp-validation-for="Name" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="LastName" class="control-label"></label>
|
||||
<input asp-for="LastName" class="form-control" />
|
||||
<span asp-validation-for="LastName" class="text-danger"></span>
|
||||
</div>
|
||||
<input type="hidden" asp-for="Id" />
|
||||
<div class="form-group">
|
||||
<label asp-for="UserName" class="control-label"></label>
|
||||
<input asp-for="UserName" class="form-control" />
|
||||
<span asp-validation-for="UserName" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="NormalizedUserName" class="control-label"></label>
|
||||
<input asp-for="NormalizedUserName" class="form-control" />
|
||||
<span asp-validation-for="NormalizedUserName" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Email" class="control-label"></label>
|
||||
<input asp-for="Email" class="form-control" />
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="NormalizedEmail" class="control-label"></label>
|
||||
<input asp-for="NormalizedEmail" class="form-control" />
|
||||
<span asp-validation-for="NormalizedEmail" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input asp-for="EmailConfirmed" /> @Html.DisplayNameFor(model => model.EmailConfirmed)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="PasswordHash" class="control-label"></label>
|
||||
<input asp-for="PasswordHash" class="form-control" />
|
||||
<span asp-validation-for="PasswordHash" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="SecurityStamp" class="control-label"></label>
|
||||
<input asp-for="SecurityStamp" class="form-control" />
|
||||
<span asp-validation-for="SecurityStamp" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="ConcurrencyStamp" class="control-label"></label>
|
||||
<input asp-for="ConcurrencyStamp" class="form-control" />
|
||||
<span asp-validation-for="ConcurrencyStamp" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="PhoneNumber" class="control-label"></label>
|
||||
<input asp-for="PhoneNumber" class="form-control" />
|
||||
<span asp-validation-for="PhoneNumber" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input asp-for="PhoneNumberConfirmed" /> @Html.DisplayNameFor(model => model.PhoneNumberConfirmed)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input asp-for="TwoFactorEnabled" /> @Html.DisplayNameFor(model => model.TwoFactorEnabled)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="LockoutEnd" class="control-label"></label>
|
||||
<input asp-for="LockoutEnd" class="form-control" />
|
||||
<span asp-validation-for="LockoutEnd" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input asp-for="LockoutEnabled" /> @Html.DisplayNameFor(model => model.LockoutEnabled)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="AccessFailedCount" class="control-label"></label>
|
||||
<input asp-for="AccessFailedCount" class="form-control" />
|
||||
<span asp-validation-for="AccessFailedCount" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Save" class="btn btn-default" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
@model IEnumerable<pwt_0x01_ng.Models.Identity.User>
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Index";
|
||||
}
|
||||
|
||||
<h2>Index</h2>
|
||||
|
||||
<p>
|
||||
<a asp-action="Create">Create New</a>
|
||||
</p>
|
||||
<table class="table table-responsive table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Name)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.LastName)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.UserName)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.NormalizedUserName)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.Email)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.NormalizedEmail)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.EmailConfirmed)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.PasswordHash)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.SecurityStamp)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.ConcurrencyStamp)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.TwoFactorEnabled)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.LockoutEnd)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.LockoutEnabled)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.AccessFailedCount)
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model) {
|
||||
<tr>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Name)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.LastName)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.UserName)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.NormalizedUserName)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Email)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.NormalizedEmail)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.EmailConfirmed)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.PasswordHash)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.SecurityStamp)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.ConcurrencyStamp)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.TwoFactorEnabled)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.LockoutEnd)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.LockoutEnabled)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.AccessFailedCount)
|
||||
</td>
|
||||
<td>
|
||||
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
|
||||
<a asp-action="Details" asp-route-id="@item.Id">Details</a> |
|
||||
<a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
|
@ -1,3 +1,3 @@
|
|||
@{
|
||||
Layout = "_Layout";
|
||||
Layout = "_Layout";
|
||||
}
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
using pwt_0x01_ng.Controllers;
|
||||
using pwt_0x01_ng.Models;
|
||||
using pwt_0x01_ng.Models.ApplicationServices;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace pwt_0x01_ng.Areas.Customer.Controllers
|
||||
{
|
||||
[Area("Customer")]
|
||||
[Authorize(Roles = nameof(Roles.Customer))]
|
||||
public class CustomerOrderNotCartController : Controller
|
||||
{
|
||||
const string s_price_total = "Price_total";
|
||||
const string s_order_items = "OrderItems";
|
||||
|
||||
ISecurityApplicationService isas;
|
||||
DBContext ctx;
|
||||
public CustomerOrderNotCartController(ISecurityApplicationService isas, DBContext ctx)
|
||||
{
|
||||
this.isas = isas;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public int AddOrderItemsToSession(int? Product_id)
|
||||
{
|
||||
int price_total = 0;
|
||||
if (HttpContext.Session.IsAvailable)
|
||||
{
|
||||
price_total = HttpContext.Session.GetInt32(s_price_total).GetValueOrDefault();
|
||||
}
|
||||
|
||||
Product product = ctx.Product.Where(prod => prod.id == Product_id).FirstOrDefault();
|
||||
|
||||
if (product != null)
|
||||
{
|
||||
OrderItem order_item = new OrderItem()
|
||||
{
|
||||
Product_id = product.id,
|
||||
Product = product,
|
||||
Amount = 1,
|
||||
Price = product.Price
|
||||
};
|
||||
|
||||
if (HttpContext.Session.IsAvailable)
|
||||
{
|
||||
List<OrderItem> orderItems = HttpContext.Session.GetObject<List<OrderItem>>(s_order_items);
|
||||
OrderItem orderItemInSession = null;
|
||||
if (orderItems != null){
|
||||
orderItemInSession = orderItems.Find(oi => oi.Product_id == order_item.Product_id);
|
||||
}
|
||||
else
|
||||
orderItems = new List<OrderItem>();
|
||||
|
||||
if (orderItemInSession != null)
|
||||
{
|
||||
++orderItemInSession.Amount;
|
||||
orderItemInSession.Price += order_item.Product.Price;
|
||||
}
|
||||
else
|
||||
{
|
||||
orderItems.Add(order_item);
|
||||
}
|
||||
|
||||
HttpContext.Session.SetObject(s_order_items, orderItems);
|
||||
|
||||
price_total += order_item.Product.Price;
|
||||
HttpContext.Session.SetInt32(s_price_total, price_total);
|
||||
}
|
||||
}
|
||||
return price_total;
|
||||
}
|
||||
public async Task<IActionResult> ApproveOrderInSession()
|
||||
{
|
||||
if (HttpContext.Session.IsAvailable)
|
||||
{
|
||||
|
||||
int price_total = 0;
|
||||
List<OrderItem> order_items = HttpContext.Session.GetObject<List<OrderItem>>(s_order_items);
|
||||
if (order_items != null)
|
||||
{
|
||||
foreach (OrderItem order_item in order_items)
|
||||
{
|
||||
price_total += order_item.Product.Price * order_item.Amount;
|
||||
order_item.Product = null;
|
||||
}
|
||||
|
||||
User currentUser = await isas.gimme_current_user(User);
|
||||
|
||||
Order order = new Order()
|
||||
{
|
||||
Order_Number = Convert.ToBase64String(Guid.NewGuid().ToByteArray()),
|
||||
Price_total = price_total,
|
||||
OrderItems = order_items,
|
||||
User_id = currentUser.Id
|
||||
};
|
||||
|
||||
await ctx.AddAsync(order);
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
HttpContext.Session.Remove(s_order_items);
|
||||
HttpContext.Session.Remove(s_price_total);
|
||||
|
||||
return RedirectToAction(nameof(CustomerOrdersController.Index), nameof(CustomerOrdersController).Replace("Controller", ""), new { Area = nameof(Customer) });
|
||||
}
|
||||
}
|
||||
|
||||
return RedirectToAction(nameof(HomeController.Index), nameof(HomeController).Replace("Controller", ""), new { Area = "" });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
using pwt_0x01_ng.Models;
|
||||
using pwt_0x01_ng.Models.ApplicationServices;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace pwt_0x01_ng.Areas.Customer.Controllers
|
||||
{
|
||||
[Area("Customer")]
|
||||
[Authorize(Roles = nameof(Roles.Customer))]
|
||||
public class CustomerOrdersController : Controller
|
||||
{
|
||||
|
||||
ISecurityApplicationService isas;
|
||||
DBContext ctx;
|
||||
|
||||
public CustomerOrdersController(ISecurityApplicationService isas, DBContext ctx)
|
||||
{
|
||||
this.isas = isas;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
if (User.Identity.IsAuthenticated)
|
||||
{
|
||||
User currentUser = await isas.gimme_current_user(User);
|
||||
if (currentUser != null)
|
||||
{
|
||||
IList<Order> userOrders = await this.ctx.Order
|
||||
.Where(or => or.User_id == currentUser.Id)
|
||||
.Include(o => o.OrderItems)
|
||||
.ThenInclude(oi => oi.Product)
|
||||
.ToListAsync();
|
||||
string uname = currentUser.username;
|
||||
ViewData["uname"] = uname;
|
||||
return View(userOrders);
|
||||
}
|
||||
}
|
||||
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
@model IList<Order>;
|
||||
@{
|
||||
ViewData["Title"] = "My Orders";
|
||||
}
|
||||
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
@{
|
||||
if (Model != null && Model != null && Model.Count > 0)
|
||||
{
|
||||
foreach (var item in Model)
|
||||
{
|
||||
<table id="myorders_table" class="table table-responsive table-striped table-bordered">
|
||||
<tr>
|
||||
<th class="col-sm-1">@nameof(Order.id)</th>
|
||||
<th class="col-sm-2">@nameof(Order.Order_Number)</th>
|
||||
<th class="col-sm-2">@nameof(Order.Price_total)</th>
|
||||
<th class="col-sm-2">@nameof(Order.Created)</th>
|
||||
<th class="col-sm-2">@nameof(Order.Updated)</th>
|
||||
<th class="col-sm-3">username</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-sm-1">@item.id</td>
|
||||
<td class="col-sm-2">@item.Order_Number</td>
|
||||
<td class="col-sm-2">@item.Price_total</td>
|
||||
<td class="col-sm-2">@item.Created</td>
|
||||
<td class="col-sm-2">@item.Updated</td>
|
||||
<td class="col-sm-3">@ViewData["uname"]</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<details id="details_summary">
|
||||
<summary class="btn-link">View Details</summary>
|
||||
<div>
|
||||
<h4>Order Items</h4>
|
||||
<table id="order_details_table" class="table table-responsive table-bordered">
|
||||
<tr>
|
||||
<th class="col-sm-3">@nameof(Product.Name)</th>
|
||||
<th class="col-sm-1">@nameof(OrderItem.Amount)</th>
|
||||
<th class="col-sm-1">@nameof(OrderItem.Price)</th>
|
||||
</tr>
|
||||
@{
|
||||
foreach (var order_items_item in item.OrderItems)
|
||||
{
|
||||
<tr>
|
||||
<td class="col-sm-3">@order_items_item.Product.Name</td>
|
||||
<td class="col-sm-1">@order_items_item.Amount</td>
|
||||
<td class="col-sm-1">@order_items_item.Price</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
</details>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<h2>Orders are empty!</h2>
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
@using pwt_0x01_ng
|
||||
@using pwt_0x01_ng.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
|
@ -1,3 +0,0 @@
|
|||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using pwt_0x01_ng.Models.ApplicationServices;
|
||||
using pwt_0x01_ng.Controllers;
|
||||
using pwt_0x01_ng.Models;
|
||||
|
||||
namespace pwt_0x01_ng.Areas.Security.Controllers
|
||||
{
|
||||
[Area("Security")]
|
||||
[AllowAnonymous]
|
||||
public class AccountController : Controller
|
||||
{
|
||||
private ISecurityApplicationService isas;
|
||||
|
||||
public AccountController(ISecurityApplicationService isas){
|
||||
this.isas = isas;
|
||||
}
|
||||
|
||||
public IActionResult Login()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Login(LoginViewModel lvm)
|
||||
{
|
||||
lvm.login_failed = false;
|
||||
if(ModelState.IsValid){
|
||||
bool login_success = await isas.login(lvm);
|
||||
if(login_success){
|
||||
return RedirectToAction(nameof(HomeController.Index), nameof(HomeController).Replace("Controller", String.Empty), new {area = ""});
|
||||
} else {
|
||||
lvm.login_failed = true;
|
||||
}
|
||||
}
|
||||
return View(lvm);
|
||||
}
|
||||
|
||||
public IActionResult Logout()
|
||||
{
|
||||
isas.logout();
|
||||
return RedirectToRoute(new { action = nameof(HomeController.Index), controller = nameof(HomeController).Replace("Controller", String.Empty), area="" });
|
||||
}
|
||||
|
||||
public IActionResult Register()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Register(RegisterViewModel rvm)
|
||||
{
|
||||
string[] errors = null;
|
||||
if(ModelState.IsValid){
|
||||
errors = await isas.register(rvm, Models.Identity.Roles.Customer);
|
||||
if(errors == null){
|
||||
var lvm = new LoginViewModel(){username = rvm.username, password = rvm.password, login_failed = false};
|
||||
return await Login(lvm);
|
||||
}
|
||||
Console.WriteLine("error registering user {" + rvm.username + "," + rvm.email + "," + rvm.password + "}.");
|
||||
}
|
||||
string err = "";
|
||||
for (int i = 0; i < ModelState.Values.Count(); i++){
|
||||
for (int j = 0; j < ModelState.Values.ElementAt(i).Errors.Count(); j++){
|
||||
err += "\n " + ModelState.Values.ElementAt(i).Errors.ElementAt(j).ToString();
|
||||
}
|
||||
}
|
||||
Console.WriteLine("ModelState errors: " + err);
|
||||
ViewData["Message"] = "error registering an account => \n" + err;
|
||||
return View();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
@using pwt_0x01_ng.Areas.Admin.Controllers;
|
||||
@model LoginViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Login";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<div class="container">
|
||||
<div class="login">
|
||||
<h3>Login or <a href="/Security/Account/Register">Sign up</a></h3>
|
||||
<div class="row row-xs-offset-1 row-sm-offset-2">
|
||||
<div class="col-xs-2 col-sm-2">
|
||||
<a href="#" class="btn btn-lg btn-block btn-facebook" data-toggle="tooltip" data-placement="top" title="Facebook">
|
||||
<i class="fa fa-facebook fa-1x"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-xs-2 col-sm-2">
|
||||
<a href="#" class="btn btn-lg btn-block btn-twitter" data-toggle="tooltip" data-placement="top" title="Twitter">
|
||||
<i class="fa fa-twitter fa-1x"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-xs-2 col-sm-2">
|
||||
<a href="#" class="btn btn-lg btn-block btn-github" data-toggle="tooltip" data-placement="top" title="GitHub">
|
||||
<i class="fa fa-github fa-1x"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row row-sm-offset-3">
|
||||
<div class="col-xs-12 col-sm-6"><hr></div>
|
||||
</div>
|
||||
<div class="row row-sm-offset-3">
|
||||
<div class="form-group col-xs-12 col-sm-6">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<form class="loginForm" action="" enctype="multipart/form-data" method="post">
|
||||
<span asp-validation-for="@Model.username" class="text-danger"></span>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><span class="fa fa-user"></span></span>
|
||||
<input asp-for="@Model.username" type="text" class="form-control" name="username" placeholder="Username">
|
||||
</div>
|
||||
<br>
|
||||
<span asp-validation-for="@Model.password" class="text-danger"></span>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><span class="fa fa-key"></span></span>
|
||||
<input asp-for="@Model.password" type="password" class="form-control" name="password" placeholder="Password">
|
||||
</div>
|
||||
<hr>
|
||||
<button class="btn btn-lg btn-outline-primary" type="submit"><i class="fa fa-sign-in"></i> Login</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
@using pwt_0x01_ng.Areas.Admin.Controllers;
|
||||
@model RegisterViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Register";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<br>
|
||||
<div class="row row-sm-offset-3">
|
||||
<div class="form-group col-xs-12 col-sm-6">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<form class="signupForm" action="" enctype="multipart/form-data" method="post">
|
||||
<span asp-validation-for="@Model.username" class="text-danger"></span>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><span class="fa fa-user"></span></span>
|
||||
<input asp-for="@Model.username" type="text" class="form-control" name="username" placeholder="Username">
|
||||
</div>
|
||||
<br>
|
||||
<span asp-validation-for="@Model.email" class="text-danger"></span>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><span class="fa fa-envelope"></span></span>
|
||||
<input asp-for="@Model.email" type="text" class="form-control" name="email" placeholder="Email">
|
||||
</div>
|
||||
<hr>
|
||||
<span asp-validation-for="@Model.password" class="text-danger"></span>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><span class="fa fa-key"></span></span>
|
||||
<input asp-for="@Model.password" type="password" class="form-control" name="password" placeholder="Password">
|
||||
</div>
|
||||
<br>
|
||||
<span asp-validation-for="@Model.repeated_password" class="text-danger"></span>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><span class="fa fa-key"></span></span>
|
||||
<input asp-for="@Model.repeated_password" type="password" class="form-control" name="repeated_password" placeholder="Repeated password">
|
||||
</div>
|
||||
<hr>
|
||||
<button class="btn btn-lg btn-outline-primary" type="submit"><i class="fa fa-sign-in"></i> Register</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
@using pwt_0x01_ng
|
||||
@using pwt_0x01_ng.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
|
@ -1,3 +0,0 @@
|
|||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
|
@ -1,73 +1,48 @@
|
|||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using pwt_0x01_ng.Models;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
using pwt_0x01_ng.Models.Dbfake;
|
||||
|
||||
namespace pwt_0x01_ng.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
readonly DBContext dbctx;
|
||||
readonly ILogger<HomeController> logger;
|
||||
public HomeController(DBContext dbctx, ILogger<HomeController> logger){
|
||||
this.dbctx = dbctx;
|
||||
this.logger = logger;
|
||||
}
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private IList<Carousel> carousels = Dbfake.Carousels;
|
||||
|
||||
public async Task <IActionResult> Index()
|
||||
{
|
||||
UltimateViewModel uvm = new UltimateViewModel();
|
||||
uvm.Carousels = await dbctx.Carousel.ToListAsync();
|
||||
uvm.Products = await dbctx.Product.ToListAsync();
|
||||
return View(uvm);
|
||||
}
|
||||
public IActionResult Index()
|
||||
{
|
||||
CarouselViewModel carousel = new CarouselViewModel();
|
||||
carousel.Carousels = carousels;
|
||||
return View(carousel);
|
||||
}
|
||||
|
||||
public IActionResult About()
|
||||
{
|
||||
ViewData["Message"] = "Best project ever";
|
||||
public IActionResult About()
|
||||
{
|
||||
ViewData["Message"] = "Your application description page.";
|
||||
|
||||
return View();
|
||||
}
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Contact()
|
||||
{
|
||||
ViewData["Message"] = "Where you can find us";
|
||||
logger.LogInformation("yay - somebody looking for our contact info");
|
||||
public IActionResult Contact()
|
||||
{
|
||||
ViewData["Message"] = "Your contact page.";
|
||||
|
||||
return View();
|
||||
}
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Privacy()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
public IActionResult Privacy()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel {RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier});
|
||||
}
|
||||
|
||||
[Route("/Home/HandleError/{code:int}")]
|
||||
public IActionResult HandleError(int code)
|
||||
{
|
||||
ViewData["ErrorMessage"] = $"Error {code}";
|
||||
switch(code) {
|
||||
case 403:
|
||||
return View("~/Views/Shared/403.cshtml");
|
||||
|
||||
case 404:
|
||||
return View("~/Views/Shared/404.cshtml");
|
||||
|
||||
case 500:
|
||||
return View("~/Views/Shared/500.cshtml");
|
||||
|
||||
default:
|
||||
return View("~/Views/Shared/unhandled_err_code.cshtml");
|
||||
}
|
||||
}
|
||||
}
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel {RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using pwt_0x01_ng.Models;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
|
||||
namespace pwt_0x01_ng.Controllers
|
||||
{
|
||||
public class ProductsController : Controller
|
||||
{
|
||||
readonly DBContext dbctx;
|
||||
|
||||
public ProductsController(DBContext dbctx){
|
||||
this.dbctx = dbctx;
|
||||
}
|
||||
public async Task<IActionResult> Detail(int id){
|
||||
Product p = await dbctx.Product.Where(p_item => p_item.id == id).FirstOrDefaultAsync();
|
||||
if (p == null) return NotFound();
|
||||
|
||||
IList<Similar> s = await dbctx.Similar.Where(p_item => p_item.prod_id == id).ToListAsync();
|
||||
IList<Product> similar = new List<Product>();
|
||||
if (s != null) {
|
||||
foreach (var s_item in s) {
|
||||
var prod = await dbctx.Product.Where(p_item => p_item.id == s_item.similar_prod_id).FirstOrDefaultAsync();
|
||||
if (prod != null) {
|
||||
similar.Add(prod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (similar.Count > 0) {
|
||||
ViewData["similar"] = similar;
|
||||
}
|
||||
return View(p);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
upstream pwt {
|
||||
server 127.0.0.1:8001;
|
||||
}
|
||||
|
||||
server {
|
||||
return 301 https://pwt.dotya.ml$request_uri;
|
||||
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name pwt.dotya.ml;
|
||||
return 404;
|
||||
|
||||
add_header Referrer-Policy "no-referrer, origin-when-cross-origin";
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header X-Robots-Tag none;
|
||||
add_header X-Real-IP $remote_addr;
|
||||
add_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
add_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
server {
|
||||
server_name pwt.dotya.ml;
|
||||
|
||||
access_log /var/log/nginx/pwt.dotya.ml.access.log;
|
||||
error_log /var/log/nginx/pwt.dotya.ml.error.log;
|
||||
|
||||
expires $expires;
|
||||
etag on;
|
||||
brotli on;
|
||||
brotli_static on;
|
||||
brotli_types *;
|
||||
|
||||
if ($http_user_agent ~* SemrushBot|morfeus) {
|
||||
return 302 your-script-kiddie-box;
|
||||
}
|
||||
error_page 302 @blackhole;
|
||||
|
||||
location @blackhole {
|
||||
add_header MESSAGE "YOU ALL SUCK D*CK";
|
||||
add_header Retry-after "your script dies";
|
||||
return 200;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://pwt;
|
||||
}
|
||||
location = /robots.txt {
|
||||
allow all;
|
||||
add_header Content-Type "text/plain; charset=utf-8";
|
||||
add_header X-Robots-Tag "none";
|
||||
return 200 "User-agent: *\nDisallow: /";
|
||||
}
|
||||
|
||||
add_header Content-Security-Policy "default-src 'none'; manifest-src 'self'; font-src 'self' https: blob:; img-src 'self'; script-src 'self' https: 'sha256-BU6NaT/mFkOb6wlKw9aAUV4i5MFr/Z/IFLIYAVFkmxQ=' 'sha256-V1j096ud9m6h5KncKkiAplx22jz14i0avalMtHLMFPs=' 'sha256-ggCJb9MSbkFha0PX0DCP2JxSZ4Vyz95IZKhP9nHXES8='; style-src 'self' https:; object-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';";
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
|
||||
add_header Feature-Policy "geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'self'; payment 'none';";
|
||||
add_header Referrer-Policy "no-referrer, strict-origin-when-cross-origin";
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header X-Robots-Tag none;
|
||||
add_header X-Real-IP $remote_addr;
|
||||
add_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
add_header X-Forwarded-Proto $scheme;
|
||||
|
||||
listen [::]:443 ssl http2;
|
||||
listen 443 ssl http2;
|
||||
ssl_certificate /etc/letsencrypt/live/pwt.dotya.ml/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/pwt.dotya.ml/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
}
|
||||
|
||||
server {
|
||||
if ($host = www.pwt.dotya.ml) {
|
||||
return 301 https://pwt.dotya.ml$request_uri;
|
||||
}
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name www.pwt.dotya.ml;
|
||||
return 404;
|
||||
|
||||
add_header Referrer-Policy "no-referrer, origin-when-cross-origin, strict-origin-when-cross-origin";
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header X-Robots-Tag none;
|
||||
add_header X-Real-IP $remote_addr;
|
||||
add_header X-Forwarded-For $remote_addr;
|
||||
|
||||
listen [::]:443 ssl http2;
|
||||
listen 443 ssl http2;
|
||||
ssl_certificate /etc/letsencrypt/live/pwt.dotya.ml/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/pwt.dotya.ml/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
[Unit]
|
||||
Description=pwt
|
||||
After=nginx.service docker.service
|
||||
|
||||
[Service]
|
||||
Restart=on-failure
|
||||
ExecStart=/usr/bin/docker-compose -f /etc/pwt/pwt-0x01-ng/docker-compose.prod.yml up --remove-orphans --build --scale netcoreultimateapp-prod=2
|
||||
ExecStop=/usr/bin/docker-compose -f /etc/pwt/pwt-0x01-ng/docker-compose.prod.yml stop
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
22
Dockerfile
22
Dockerfile
|
@ -1,17 +1,17 @@
|
|||
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine AS base
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:2.1-alpine
|
||||
|
||||
COPY . /src
|
||||
WORKDIR /src
|
||||
|
||||
COPY *.csproj ./
|
||||
RUN dotnet --version && dotnet --info
|
||||
RUN dotnet restore
|
||||
RUN dotnet clean
|
||||
RUN dotnet build -c Release
|
||||
|
||||
COPY . ./
|
||||
RUN dotnet publish -c Release -o bin/out
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:2.1
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:3.1-alpine
|
||||
# debug drone
|
||||
RUN pwd
|
||||
COPY --from=0 /src/bin/Release/netcoreapp2.1/publish/ App/
|
||||
WORKDIR /App
|
||||
COPY --from=base /src/bin/out/ .
|
||||
RUN chown -R nobody:nobody ./
|
||||
USER nobody
|
||||
ENV ASPNETCORE_ENVIRONMENT Production
|
||||
ENV ASPNETCORE_URLS http://*:8081
|
||||
ENV ASPNETCORE_ENVIRONMENT=Release
|
||||
ENTRYPOINT ["dotnet", "pwt-0x01-ng.dll"]
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine
|
||||
ENV UID 1000
|
||||
ENV GID 1000
|
||||
ENV UNAME unpriv
|
||||
RUN adduser -D -u ${UID} -g ${GID} -H ${UNAME} -h /src
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:2.1-alpine
|
||||
|
||||
COPY . /src
|
||||
WORKDIR /src
|
||||
|
||||
COPY *.csproj ./
|
||||
RUN dotnet --version && dotnet --info
|
||||
RUN dotnet restore
|
||||
RUN dotnet clean
|
||||
|
||||
COPY . ./
|
||||
RUN dotnet build -c Debug -o bin/out
|
||||
RUN chown -R "${UID}":"${GID}" ./ /root/
|
||||
USER ${UNAME}
|
||||
RUN dotnet build -c Debug
|
||||
|
||||
ENV ASPNETCORE_ENVIRONMENT=Development
|
||||
|
||||
|
|
67
Makefile
67
Makefile
|
@ -1,32 +1,13 @@
|
|||
dc = docker-compose
|
||||
dccmd = COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose
|
||||
dtag = netcoreultimateapp-prod
|
||||
dtag = netcoreultimapp
|
||||
dtagdev = netcoreultimapp-dev
|
||||
dfile = Dockerfile
|
||||
dfiledev = $(dfile).dev
|
||||
lport = 8000
|
||||
lportdev = 8001
|
||||
CC = dotnet
|
||||
dcmd = DOCKER_BUILDKIT=1 docker
|
||||
pruneargs = system prune -af
|
||||
dcmdrun = $(dcmd) run --rm
|
||||
wdir = /src
|
||||
kanikoimg = gcr.io/kaniko-project/executor@sha256:6ecc43ae139ad8cfa11604b592aaedddcabff8cef469eda303f1fb5afe5e3034
|
||||
dargskaniko = -w=$(wdir) -v $$(pwd):$(wdir):z $(kanikoimg)
|
||||
kanikoargs = -c=$(wdir) --use-new-run --snapshotMode=redo --no-push
|
||||
krelease = $(dcmdrun) $(dargskaniko) -f=$(dfile) $(kanikoargs)
|
||||
kdebug = $(dcmdrun) $(dargskaniko) -f=$(dfiledev) $(kanikoargs)
|
||||
postkanikochown = sudo chown -R $$USER:$$USER ./
|
||||
pgdbcapdrop = --cap-drop NET_ADMIN --cap-drop SYS_ADMIN
|
||||
pgdbenv = -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=679968312e029a806c1905c40ec331aa199a1eb86bd0b9eb04057933e449bdc9ef8ef292a39b68cafa5689c901a17266 -e POSTGRES_INITDB_ARGS="--data-checksums"
|
||||
pgdbname = pgdb
|
||||
pgdbports = -p 127.0.0.1:5433:5432
|
||||
pgdbvol = -v pgdbdata:/var/lib/postgresql/data
|
||||
pgdbargs = run -d $(pgdbcapdrop) $(pgdbenv) --name $(pgdbname) $(pgdbports) $(pgdbvol) --restart unless-stopped
|
||||
pgdbimg = postgres:13.1-alpine
|
||||
zenv = DB_CONNECTION_STRING=$$(cat appsettings.Development.json | jq .db.Postgres | sed -e 's/5432/5433/' -e 's/=db/=localhost/' -e 's/"//g')
|
||||
|
||||
.PHONY: dev dockerbuild dockerdevbuild dockerrun dockerdevrun dockertest dockerdev kaniko clean prune pgdba pgdbz test dcdevb dcprodbuild dcdevup dcprodup
|
||||
krelease = docker run --rm -it -w=$(wdir) -v $$PWD:$(wdir) gcr.io/kaniko-project/executor -f=$(dfile) -c=$(wdir) --use-new-run --snapshotMode=redo --no-push
|
||||
kdebug = docker run --rm -it -w=$(wdir) -v $$PWD:$(wdir) gcr.io/kaniko-project/executor -f=$(dfiledev) -c=$(wdir) --use-new-run --snapshotMode=redo --no-push
|
||||
|
||||
dev: restore build run
|
||||
|
||||
|
@ -37,70 +18,42 @@ build:
|
|||
$(CC) build .
|
||||
|
||||
run:
|
||||
$(zenv) $(CC) watch run .
|
||||
$(CC) run .
|
||||
|
||||
releasebuild: restore clean
|
||||
$(CC) publish -c Release
|
||||
|
||||
dockerbuild:
|
||||
$(dcmd) build \
|
||||
@docker build \
|
||||
--build-arg VCS_REF=`git rev-parse --short HEAD` \
|
||||
--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
|
||||
-t $(dtag) -f $(dfile) --no-cache .
|
||||
-t $(dtag) -f $(dfile) .
|
||||
|
||||
dockerdevbuild:
|
||||
$(dcmd) build \
|
||||
@docker build \
|
||||
--build-arg VCS_REF=`git rev-parse --short HEAD` \
|
||||
--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
|
||||
-t $(dtagdev) -f $(dfiledev) --no-cache .
|
||||
-t $(dtagdev) -f $(dfiledev) .
|
||||
|
||||
dockerrun:
|
||||
@echo ======================
|
||||
@echo local port: $(lport)
|
||||
@echo ======================
|
||||
$(dcmdrun) -p $(lport):80 $(dtag)
|
||||
docker run --rm -p $(lport):80 $(dtag)
|
||||
|
||||
dockerdevrun:
|
||||
@echo ======================
|
||||
@echo local dev port: $(lportdev)
|
||||
@echo ======================
|
||||
$(dcmdrun) -p $(lportdev):5000 $(dtagdev)
|
||||
|
||||
dcdevb:
|
||||
$(dccmd) -f $(dc).yml build --no-cache --pull --progress tty
|
||||
|
||||
dcprodbuild:
|
||||
$(dccmd) -f $(dc).prod.yml build --no-cache --pull --progress tty
|
||||
|
||||
dcdevup:
|
||||
@echo ======================
|
||||
@echo local dev port: $(lportdev)
|
||||
@echo ======================
|
||||
$(dccmd) -f $(dc).yml up --remove-orphans
|
||||
|
||||
dcprodup:
|
||||
$(dccmd) -f $(dc).prod.yml up --remove-orphans --scale netcoreultimateapp-prod=2
|
||||
docker run --rm -p $(lportdev):5000 $(dtagdev)
|
||||
|
||||
kaniko:
|
||||
$(krelease)
|
||||
$(postkanikochown)
|
||||
$(kdebug)
|
||||
$(postkanikochown)
|
||||
|
||||
dockerdev: dockerdevbuild dockerdevrun
|
||||
|
||||
dockertest: dockerdevbuild dockerbuild
|
||||
|
||||
test: releasebuild build dockertest kaniko
|
||||
|
||||
clean:
|
||||
$(CC) clean
|
||||
|
||||
prune:
|
||||
$(dcmd) $(pruneargs)
|
||||
|
||||
pgdba:
|
||||
$(dcmd) $(pgdbargs) $(pgdbimg)
|
||||
|
||||
pgdbz:
|
||||
$(dcmd) stop $(pgdbname)
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
|
||||
namespace pwt_0x01_ng.Models.ApplicationServices
|
||||
{
|
||||
public interface ISecurityApplicationService
|
||||
{
|
||||
Task<string[]> register(RegisterViewModel rvm, Roles role);
|
||||
Task<bool> login(LoginViewModel lvm);
|
||||
Task logout();
|
||||
Task<User> find_user_by_username(string username);
|
||||
Task<IList<string>> gimme_user_roles(User usr);
|
||||
Task<User> gimme_current_user(ClaimsPrincipal claims);
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
|
||||
namespace pwt_0x01_ng.Models.ApplicationServices
|
||||
{
|
||||
public class SecurityIdentityApplicationService : ISecurityApplicationService
|
||||
{
|
||||
UserManager<User> um;
|
||||
SignInManager<User> sim;
|
||||
|
||||
public SecurityIdentityApplicationService(UserManager<User> um, SignInManager<User> sim){
|
||||
this.um = um;
|
||||
this.sim = sim;
|
||||
}
|
||||
|
||||
public async Task<string[]> register(RegisterViewModel rvm, Roles role){
|
||||
User usr = new User(){username = rvm.username, UserName = rvm.username, Name = rvm.username, LastName = "", password = rvm.password, Email = rvm.email, EmailConfirmed = true};
|
||||
|
||||
string[] errors = null;
|
||||
var res = await um.CreateAsync(usr, rvm.password);
|
||||
|
||||
if(res.Succeeded){
|
||||
var roleres = await um.AddToRoleAsync(usr, role.ToString());
|
||||
if(!roleres.Succeeded){
|
||||
int c = 0;
|
||||
foreach (var err in res.Errors)
|
||||
{
|
||||
res.Errors.Append(res.Errors.ElementAt(c));
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(res.Errors != null && res.Errors.Count() > 0){
|
||||
errors = new string[res.Errors.Count()];
|
||||
int c = 0;
|
||||
foreach (var err in res.Errors)
|
||||
{
|
||||
errors[c] = res.Errors.ElementAt(c).Description;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
public async Task<bool> login(LoginViewModel lvm){
|
||||
var result = await sim.PasswordSignInAsync(lvm.username, lvm.password, config.remember_me_feature, config.lockout_on_failure);
|
||||
return result.Succeeded;
|
||||
}
|
||||
public Task logout(){
|
||||
return sim.SignOutAsync();
|
||||
}
|
||||
public Task<User> find_user_by_username(string username){
|
||||
return um.FindByNameAsync(username);
|
||||
}
|
||||
public Task<IList<string>> gimme_user_roles(User usr){
|
||||
return um.GetRolesAsync(usr);
|
||||
}
|
||||
public Task<User> gimme_current_user(ClaimsPrincipal claims){
|
||||
return um.GetUserAsync(claims);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +1,14 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using pwt_0x01_ng.Models.Validation;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
[Table("Carousel")]
|
||||
public class Carousel : Entity
|
||||
{
|
||||
[Required]
|
||||
public string DataTarget { get; set; }
|
||||
[NotMapped]
|
||||
[FileTypeAttr("image")]
|
||||
public IFormFile Image { get; set; }
|
||||
[StringLength(255)]
|
||||
public string ImageSrc { get; set; }
|
||||
[Required]
|
||||
[StringLength(50, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 1)]
|
||||
public string ImageAlt { get; set; }
|
||||
[Required]
|
||||
public string CarouselContent { get; set; }
|
||||
}
|
||||
public class Carousel
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string DataTarget { get; set; }
|
||||
public IFormFile Image { get; set; }
|
||||
public string ImageSrc { get; set; }
|
||||
public string ImageAlt { get; set; }
|
||||
public string CarouselContent { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ using System.Collections.Generic;
|
|||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class CarouselViewModel
|
||||
{
|
||||
public IList<Carousel> Carousels { get; set; }
|
||||
}
|
||||
public class CarouselViewModel
|
||||
{
|
||||
public IList<Carousel> Carousels { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class CustomerOrderViewModel
|
||||
{
|
||||
IList<Order> Orders { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Database
|
||||
{
|
||||
public static class CarouselHelper
|
||||
{
|
||||
public static IList<Carousel> GenerateCarousel()
|
||||
{
|
||||
IList<Carousel> carousels = new List<Carousel>()
|
||||
{
|
||||
new Carousel() { DataTarget = "#myCarousel", ImageSrc = "/images/banner1.svg", ImageAlt = "ASP.NET", CarouselContent = "Learn how to build ASP.NET apps that can run anywhere.<a class=\"btn btn-default\" href=\"https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409\">Learn More</a>"},
|
||||
new Carousel() { DataTarget = "#myCarousel", ImageSrc = "/images/banner2.svg", ImageAlt = "ASP.NET", CarouselContent = "There are powerful new features in Visual Studio for building modern web apps.<a class=\"btn btn-default\" href=\"https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409\">Learn More</a>"},
|
||||
new Carousel() { DataTarget = "#myCarousel", ImageSrc = "/images/banner3.svg", ImageAlt = "ASP.NET", CarouselContent = "Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.<a class=\"btn btn-default\" href=\"https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409\">Learn More</a>"},
|
||||
new Carousel() { DataTarget = "#myCarousel", ImageSrc = "/images/ms_loves_linux.jpeg", ImageAlt = "msloveslinux", CarouselContent = "ms loves linux"}
|
||||
};
|
||||
return carousels;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Database.Conf
|
||||
{
|
||||
public class CarouselConf : IEntityTypeConfiguration<Carousel>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Carousel> builder)
|
||||
{
|
||||
builder.Property(nameof(Carousel.Created)).ValueGeneratedOnAdd().HasDefaultValueSql("NOW()");
|
||||
builder.Property(nameof(Carousel.Updated)).ValueGeneratedOnAddOrUpdate().HasDefaultValueSql("NOW()");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Database.Conf
|
||||
{
|
||||
public class OrderConf : IEntityTypeConfiguration<Order>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Order> builder)
|
||||
{
|
||||
builder.HasMany(order => order.OrderItems).WithOne(item => item.Order).IsRequired().HasForeignKey(item => item.Order_id).OnDelete(DeleteBehavior.Restrict);
|
||||
builder.Property(nameof(Order.Created)).ValueGeneratedOnAdd().HasDefaultValueSql("NOW()");
|
||||
builder.Property(nameof(Order.Updated)).ValueGeneratedOnAddOrUpdate().HasDefaultValueSql("NOW()");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Database.Conf
|
||||
{
|
||||
public class OrderItemConf : IEntityTypeConfiguration<OrderItem>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<OrderItem> builder)
|
||||
{
|
||||
builder.Property(nameof(OrderItem.Created)).ValueGeneratedOnAdd().HasDefaultValueSql("NOW()");
|
||||
builder.Property(nameof(OrderItem.Updated)).ValueGeneratedOnAddOrUpdate().HasDefaultValueSql("NOW()");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Database.Conf
|
||||
{
|
||||
public class ProductConf : IEntityTypeConfiguration<Product>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Product> builder)
|
||||
{
|
||||
builder.Property(nameof(Product.Created)).ValueGeneratedOnAdd().HasDefaultValueSql("NOW()");
|
||||
builder.Property(nameof(Product.Updated)).ValueGeneratedOnAddOrUpdate().HasDefaultValueSql("NOW()");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
using pwt_0x01_ng.Models.Database.Conf;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Database
|
||||
{
|
||||
public class DBContext : IdentityDbContext<User, Role, int>
|
||||
{
|
||||
public DBContext(DbContextOptions<DBContext> options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DbSet<Carousel> Carousel { get; set; }
|
||||
public DbSet<Product> Product { get; set; }
|
||||
public DbSet<Order> Order { get; set; }
|
||||
public DbSet<OrderItem> OrderItem { get; set; }
|
||||
public DbSet<Similar> Similar { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder model_builder)
|
||||
{
|
||||
|
||||
base.OnModelCreating(model_builder);
|
||||
this.ApplyConfiguration(model_builder);
|
||||
|
||||
foreach(var entity_type in model_builder.Model.GetEntityTypes()){
|
||||
entity_type.SetTableName(entity_type.GetTableName().Replace("AspNet", string.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void ApplyConfiguration(ModelBuilder model_builder)
|
||||
{
|
||||
model_builder.ApplyConfiguration(new CarouselConf());
|
||||
model_builder.ApplyConfiguration(new ProductConf());
|
||||
model_builder.ApplyConfiguration(new OrderConf());
|
||||
model_builder.ApplyConfiguration(new OrderItemConf());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Database
|
||||
{
|
||||
public static class DBInit
|
||||
{
|
||||
|
||||
public static void Init(DBContext dbContext)
|
||||
{
|
||||
dbContext.Database.EnsureCreated();
|
||||
if(dbContext.Carousel.Count() == 0){
|
||||
IList<Carousel> carousels = CarouselHelper.GenerateCarousel();
|
||||
foreach (var c in carousels)
|
||||
{
|
||||
dbContext.Carousel.Add(c);
|
||||
}
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
if(dbContext.Product.Count() == 0){
|
||||
IList<Product> products = ProductHelper.GenerateProduct();
|
||||
foreach (var p in products)
|
||||
{
|
||||
dbContext.Product.Add(p);
|
||||
}
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task EnsureRolesCreated(IServiceProvider sp){
|
||||
using (var services = sp.CreateScope()){
|
||||
RoleManager<Role> role_manager = services.ServiceProvider.GetRequiredService<RoleManager<Role>>();
|
||||
|
||||
string[] rolespls = Enum.GetNames(typeof(Roles));
|
||||
foreach (var role in rolespls){
|
||||
Console.WriteLine(role + " => " + role.GetType());
|
||||
await role_manager.CreateAsync(new Role(role));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task EnsureManagerCreated(IServiceProvider sp){
|
||||
using (var services = sp.CreateScope()){
|
||||
UserManager<User> usr_manager = services.ServiceProvider.GetRequiredService<UserManager<User>>();
|
||||
|
||||
User manager = new User(){
|
||||
UserName = "manager",
|
||||
Email = "manager@manager.com",
|
||||
Name = "manager",
|
||||
LastName = "",
|
||||
EmailConfirmed = true
|
||||
};
|
||||
|
||||
var super_secure_password = "123"; /* TODO - rm this */
|
||||
User manager_in_db = await usr_manager.FindByNameAsync(manager.UserName);
|
||||
|
||||
if (manager_in_db == null){
|
||||
IdentityResult ir = new IdentityResult();
|
||||
try {
|
||||
ir = await usr_manager.CreateAsync(manager, super_secure_password);
|
||||
} catch (Exception e){
|
||||
Debug.WriteLine(e);
|
||||
}
|
||||
if(ir.Succeeded){
|
||||
string[] rolespls = Enum.GetNames(typeof(Roles));
|
||||
foreach (var role in rolespls){
|
||||
if(role != Roles.Admin.ToString()){
|
||||
await usr_manager.AddToRoleAsync(manager, role);
|
||||
}
|
||||
}
|
||||
} else if (ir.Errors != null && ir.Errors.Count() >0){
|
||||
foreach (var err in ir.Errors){
|
||||
Debug.WriteLine("Error during manager role creation" + err.Code + " => " + err.Description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static async Task EnsureAdminCreated(IServiceProvider sp){
|
||||
using (var services = sp.CreateScope()){
|
||||
UserManager<User> usr_manager = services.ServiceProvider.GetRequiredService<UserManager<User>>();
|
||||
|
||||
User admin = new User(){
|
||||
UserName = "admin",
|
||||
Email = "admin@admin.com",
|
||||
Name = "admin",
|
||||
LastName = "",
|
||||
EmailConfirmed = true
|
||||
};
|
||||
|
||||
var super_secure_password = "123"; /* TODO - rm this */
|
||||
User admin_in_db = await usr_manager.FindByNameAsync(admin.UserName);
|
||||
|
||||
if (admin_in_db == null){
|
||||
IdentityResult ir = new IdentityResult();
|
||||
try {
|
||||
ir = await usr_manager.CreateAsync(admin, super_secure_password);
|
||||
} catch (Exception e){
|
||||
Debug.WriteLine(e);
|
||||
}
|
||||
if(ir.Succeeded){
|
||||
string[] rolespls = Enum.GetNames(typeof(Roles));
|
||||
foreach (var role in rolespls){
|
||||
await usr_manager.AddToRoleAsync(admin, role);
|
||||
}
|
||||
} else if (ir.Errors != null && ir.Errors.Count() >0){
|
||||
foreach (var err in ir.Errors){
|
||||
Debug.WriteLine("Error during admin role creation" + err.Code + " => " + err.Description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Database
|
||||
{
|
||||
public static class ProductHelper
|
||||
{
|
||||
public static IList<Product> GenerateProduct()
|
||||
{
|
||||
IList<Product> products = new List<Product>()
|
||||
{
|
||||
new Product() { Name="a", Price=0, Description="aaaa", ImageSrc = "/images/banner1.svg", ImageAlt = "ASP.NET", Similar = {}},
|
||||
new Product() { Name="b", Price=1, Description="bbbb", ImageSrc = "/images/banner2.svg", ImageAlt = "ASP.NET", Similar = {}},
|
||||
new Product() { Name="c", Price=2, Description="cccc", ImageSrc = "/images/banner3.svg", ImageAlt = "ASP.NET", Similar = {}},
|
||||
new Product() { Name="d", Price=3, Description="dddd", ImageSrc = "/images/ms_loves_linux.jpeg", ImageAlt = "msloveslinux", Similar = {}}
|
||||
};
|
||||
return products;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Dbfake
|
||||
{
|
||||
public static class CarouselHelper
|
||||
{
|
||||
public static IList<Carousel> GenerateCarousel()
|
||||
{
|
||||
IList<Carousel> carousels = new List<Carousel>()
|
||||
{
|
||||
new Carousel() { id = 0, DataTarget = "#myCarousel", ImageSrc = "/images/banner1.svg", ImageAlt = "ASP.NET", CarouselContent = "Learn how to build ASP.NET apps that can run anywhere.<a class=\"btn btn-default\" href=\"https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409\">Learn More</a>"},
|
||||
new Carousel() { id = 1, DataTarget = "#myCarousel", ImageSrc = "/images/banner2.svg", ImageAlt = "ASP.NET", CarouselContent = "There are powerful new features in Visual Studio for building modern web apps.<a class=\"btn btn-default\" href=\"https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409\">Learn More</a>"},
|
||||
new Carousel() { id = 2, DataTarget = "#myCarousel", ImageSrc = "/images/banner3.svg", ImageAlt = "ASP.NET", CarouselContent = "Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.<a class=\"btn btn-default\" href=\"https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409\">Learn More</a>"},
|
||||
new Carousel() { id = 3, DataTarget = "#myCarousel", ImageSrc = "/images/ms_loves_linux.jpeg", ImageAlt = "msloveslinux", CarouselContent = "ms loves linux"}
|
||||
};
|
||||
return carousels;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Dbfake
|
||||
{
|
||||
public static class Dbfake
|
||||
{
|
||||
/* singe db table simulation*/
|
||||
public static IList<Carousel> Carousels { get; set; }
|
||||
|
||||
static Dbfake()
|
||||
{
|
||||
Carousels = CarouselHelper.GenerateCarousel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public abstract class Entity
|
||||
{
|
||||
[Key]
|
||||
[Required]
|
||||
public int id { get; set; }
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
|
||||
public DateTime Created { get; }
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
|
||||
public DateTime Updated { get; }
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Identity
|
||||
{
|
||||
public class Role : IdentityRole<int>
|
||||
{
|
||||
public Role(string name) : base(name){}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
namespace pwt_0x01_ng.Models.Identity
|
||||
{
|
||||
public enum Roles
|
||||
{
|
||||
Admin,
|
||||
Manager,
|
||||
Customer
|
||||
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Identity
|
||||
{
|
||||
public class User : IdentityUser<int>
|
||||
{
|
||||
public virtual string username {get;set;}
|
||||
public virtual string password {get;set;}
|
||||
public virtual string Name {get; set;}
|
||||
public virtual string LastName {get; set;}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using pwt_0x01_ng.Models.Validation;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class LoginViewModel
|
||||
{
|
||||
[Required]
|
||||
public string username {get; set;}
|
||||
[Required]
|
||||
[UniqueCharsAttr]
|
||||
public string password {get; set;}
|
||||
public bool login_failed {get; set;}
|
||||
}
|
||||
}
|
|
@ -1,40 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class MegaUpload
|
||||
{
|
||||
string webroot_path;
|
||||
string folder_name;
|
||||
string file_type;
|
||||
public class MegaUpload
|
||||
{
|
||||
IHostingEnvironment hosting_env;
|
||||
|
||||
public MegaUpload(string webroot_path, string folder_name, string file_type){
|
||||
this.webroot_path = webroot_path;
|
||||
this.folder_name = folder_name;
|
||||
this.file_type = file_type;
|
||||
}
|
||||
public async Task<string> DoMegaUpload(IFormFile iformfile)
|
||||
{
|
||||
string return_file_path = String.Empty;
|
||||
var img = iformfile;
|
||||
if(img != null && img.ContentType.ToLower().Contains(file_type) && img.Length > 0 && img.Length < 2000000){
|
||||
var fname = Path.GetFileNameWithoutExtension(img.FileName);
|
||||
var fext = Path.GetExtension(img.FileName);
|
||||
/* in case such file already exists - wip */
|
||||
/* var fname_rand = Path.GetRandomFileName()+Path.GetFileNameWithoutExtension(img.FileName); */
|
||||
var f_relative = Path.Combine("images",folder_name, fname + fext);
|
||||
var file_path = Path.Combine(webroot_path, f_relative);
|
||||
public MegaUpload(IHostingEnvironment hosting_env){
|
||||
this.hosting_env = hosting_env;
|
||||
}
|
||||
public async Task<bool> DoMegaUpload(Carousel carousel)
|
||||
{
|
||||
bool great_success = false;
|
||||
var img = carousel.Image;
|
||||
if(img != null && img.ContentType.ToLower().Contains("image") && img.Length > 0 && img.Length < 2000000){
|
||||
var fname = Path.GetFileNameWithoutExtension(img.FileName);
|
||||
var fext = Path.GetExtension(img.FileName);
|
||||
/* in case such file already exists - wip */
|
||||
/* var fname_rand = Path.GetRandomFileName()+Path.GetFileNameWithoutExtension(img.FileName); */
|
||||
var f_relative = Path.Combine("images","carousels", fname + fext);
|
||||
var file_path = Path.Combine(hosting_env.WebRootPath, f_relative);
|
||||
|
||||
using (var stream = new FileStream(file_path, FileMode.Create)){
|
||||
await img.CopyToAsync(stream);
|
||||
}
|
||||
return_file_path = $"/{f_relative}";
|
||||
/* great_success = true; */
|
||||
}
|
||||
return return_file_path;
|
||||
}
|
||||
}
|
||||
using (var stream = new FileStream(file_path, FileMode.Create)){
|
||||
await img.CopyToAsync(stream);
|
||||
}
|
||||
carousel.ImageSrc = $"/{f_relative}";
|
||||
great_success = true;
|
||||
}
|
||||
return great_success;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
[Table(nameof(Order))]
|
||||
public class Order : Entity
|
||||
{
|
||||
[Required]
|
||||
public string Order_Number { get; set; }
|
||||
public IList<OrderItem> OrderItems { get; set; }
|
||||
[ForeignKey(nameof(Identity.User))]
|
||||
[Required]
|
||||
public int User_id { get; set; }
|
||||
[NotMapped]
|
||||
public User usr { get; set; }
|
||||
[Required]
|
||||
public decimal Price_total { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
[Table(nameof(OrderItem))]
|
||||
public class OrderItem : Entity
|
||||
{
|
||||
[ForeignKey(nameof(Order))]
|
||||
[Required]
|
||||
public int Order_id { get; set; }
|
||||
[ForeignKey(nameof(Product))]
|
||||
[Required]
|
||||
public int Product_id { get; set; }
|
||||
[Required]
|
||||
public int Amount { get; set; }
|
||||
[Required]
|
||||
public decimal Price { get; set; }
|
||||
public Order Order { get; set; }
|
||||
public Product Product {get; set; }
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using pwt_0x01_ng.Models.Validation;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
[Table("Product")]
|
||||
public class Product : Entity
|
||||
{
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
public int Price { get; set; }
|
||||
[Required]
|
||||
public string Description { get; set; }
|
||||
[FileTypeAttr("image")]
|
||||
[NotMapped]
|
||||
public IFormFile Image { get; set; }
|
||||
[StringLength(255)]
|
||||
public string ImageSrc { get; set; }
|
||||
[Required]
|
||||
[StringLength(50, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 1)]
|
||||
public string ImageAlt { get; set; }
|
||||
[NotMapped]
|
||||
public IList<SimilarProduct> Similar { get; set; }
|
||||
[NotMapped]
|
||||
public bool Selected { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class ProductViewModel
|
||||
{
|
||||
public IList<Product> Products { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using pwt_0x01_ng.Models.Validation;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class RegisterViewModel
|
||||
{
|
||||
[Required]
|
||||
public string username {get; set;}
|
||||
[Required]
|
||||
[UniqueCharsAttr]
|
||||
[RegularExpression(@"^.{2,}$", ErrorMessage = "Minimum password length is 2 characters.")]
|
||||
public string password {get; set;}
|
||||
[Required]
|
||||
[Compare(nameof(password), ErrorMessage = "Passwords don't match.")]
|
||||
public string repeated_password {get; set;}
|
||||
[Required]
|
||||
public string email {get; set;}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
public static class SessionExtensions
|
||||
{
|
||||
public static T GetObject<T>(this ISession session, string key)
|
||||
{
|
||||
var data = session.GetString(key);
|
||||
if (data == null)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
return JsonConvert.DeserializeObject<T>(data);
|
||||
}
|
||||
|
||||
public static void SetObject(this ISession session, string key, object value)
|
||||
{
|
||||
session.SetString(key, JsonConvert.SerializeObject(value));
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
[Table(nameof(Similar))]
|
||||
public class Similar
|
||||
{
|
||||
[Required]
|
||||
[Key]
|
||||
public int id { get; set; }
|
||||
[Required]
|
||||
public int prod_id { get; set; }
|
||||
[ForeignKey(nameof(Product))]
|
||||
[Required]
|
||||
public int similar_prod_id { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class SimilarProduct
|
||||
{
|
||||
public int id { get; set; }
|
||||
public bool Selected { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class SimilarViewModel
|
||||
{
|
||||
public IList<Similar> Similar { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class UltimateViewModel
|
||||
{
|
||||
public IList<Carousel> Carousels { get; set; }
|
||||
public IList<Product> Products { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Validation
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false)]
|
||||
public class FileTypeAttr : ValidationAttribute, IClientModelValidator
|
||||
{
|
||||
private readonly string type;
|
||||
public FileTypeAttr(string type){
|
||||
this.type = type.ToLower();
|
||||
}
|
||||
|
||||
protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
|
||||
if (value == null) {
|
||||
/* img is optional as of now */
|
||||
return ValidationResult.Success;
|
||||
} else if (value is IFormFile iff) {
|
||||
if(iff.ContentType.ToLower().Contains(type)) {
|
||||
return ValidationResult.Success;
|
||||
} else {
|
||||
return new ValidationResult(GetErrorMessage(validationContext.MemberName), new List<string> { validationContext.MemberName });
|
||||
}
|
||||
}
|
||||
throw new NotImplementedException($"Attribute {nameof(FileTypeAttr)} not implemented for object {value.GetType()}.");
|
||||
}
|
||||
|
||||
protected string GetErrorMessage(string member_name) => $"make sure the {member_name} you picked really is of type <code>{type}/*</code>. <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\" title=\"help\" target=\"_blank\" rel=\"noopener noreferer\"><em>help</em></a>";
|
||||
|
||||
public void AddValidation(ClientModelValidationContext ctx){
|
||||
MergeAttribute(ctx.Attributes, "data-val", "true");
|
||||
MergeAttribute(ctx.Attributes, "data-val-content", GetErrorMessage("file"));
|
||||
MergeAttribute(ctx.Attributes, "data-val-content-type", type);
|
||||
}
|
||||
|
||||
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value){
|
||||
if (attributes.ContainsKey(key)){
|
||||
return false;
|
||||
}
|
||||
|
||||
attributes.Add(key, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
|
||||
namespace pwt_0x01_ng.Models.Validation
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false)]
|
||||
public class UniqueCharsAttr : ValidationAttribute, IClientModelValidator
|
||||
{
|
||||
public UniqueCharsAttr(){
|
||||
}
|
||||
|
||||
protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
|
||||
if(value == null){return new ValidationResult(GetErrorMessage(), new List<string> { validationContext.MemberName });}
|
||||
if (value is string phrase) {
|
||||
int count = phrase.Distinct().Count();
|
||||
if(count >= config.min_passwd_unique_chars) {
|
||||
return ValidationResult.Success;
|
||||
} else {
|
||||
return new ValidationResult(GetErrorMessage(count, validationContext.MemberName), new List<string> { validationContext.MemberName });
|
||||
}
|
||||
}
|
||||
throw new NotImplementedException($"Attribute {nameof(UniqueCharsAttr)} not implemented for object {value.GetType()}.");
|
||||
}
|
||||
|
||||
protected string GetErrorMessage(int chars, string member_name) => $"not enough unique characters - provided: {chars}, wanted: {config.min_passwd_unique_chars}, problematic field: {member_name}";
|
||||
protected string GetErrorMessage() => $"not enough unique characters. wanted: {config.min_passwd_unique_chars}";
|
||||
|
||||
public void AddValidation(ClientModelValidationContext ctx){
|
||||
MergeAttribute(ctx.Attributes, "data-val", "true");
|
||||
MergeAttribute(ctx.Attributes, "data-val-uniquechars", GetErrorMessage());
|
||||
}
|
||||
|
||||
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value){
|
||||
if (attributes.ContainsKey(key)){
|
||||
return false;
|
||||
}
|
||||
|
||||
attributes.Add(key, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
47
Program.cs
47
Program.cs
|
@ -1,39 +1,24 @@
|
|||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
|
||||
namespace pwt_0x01_ng
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
IWebHost webHost = CreateWebHostBuilder(args).Build();
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateWebHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
using (var scope = webHost.Services.CreateScope())
|
||||
{
|
||||
var serviceProvider = scope.ServiceProvider;
|
||||
var dbctx = serviceProvider.GetRequiredService<DBContext>();
|
||||
DBInit.Init(dbctx);
|
||||
await DBInit.EnsureRolesCreated(serviceProvider);
|
||||
await DBInit.EnsureAdminCreated(serviceProvider);
|
||||
await DBInit.EnsureManagerCreated(serviceProvider);
|
||||
}
|
||||
|
||||
webHost.Run();
|
||||
}
|
||||
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseStartup<Startup>()
|
||||
.ConfigureLogging((ctx, logging) => {
|
||||
logging.ClearProviders();
|
||||
logging.AddConsole();
|
||||
logging.AddDebug();
|
||||
logging.AddEventSourceLogger();
|
||||
});
|
||||
}
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseStartup<Startup>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
"launchBrowser": false,
|
||||
"applicationUrl": "http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation",
|
||||
"DB_CONNECTION_STRING": "User ID=postgres;Password=679968312e029a806c1905c40ec331aa199a1eb86bd0b9eb04057933e449bdc9ef8ef292a39b68cafa5689c901a17266;Server=localhost;Port=5433;Database=pwt;Integrated Security=true;Pooling=true;"
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
18
README.md
18
README.md
|
@ -3,23 +3,7 @@
|
|||
this repo holds *sawce* for PWT .netcore mvc project 0x01-ng
|
||||
|
||||
### how to run this
|
||||
- Makefile (you need `make` for this) --> see the [[Makefile]]
|
||||
- direct `dotnet` (and/or `docker`) commands
|
||||
|
||||
#### useful Makefile targets
|
||||
- `restore` --> runs `dotnet restore .`
|
||||
- `clean` --> clean builds the project
|
||||
- `build` --> builds the project
|
||||
- `dockerdevbuild` --> clean-builds a container image from [[Dockerfile.dev]] (have a look in there for details)
|
||||
- `dcdevb` --> compose clean build of a debug (dev) version, pulling db
|
||||
- `dcdevup` --> runs the above (see [[docker-compose.yml]])
|
||||
> you need to have created a db beforehand to run these
|
||||
- `run` --> runs `$CURRENT_ENV dotnet watch run .`
|
||||
- `dev` --> runs `restore build run` - this is kind of a convenience target
|
||||
|
||||
#### run using dotnet
|
||||
> run the `dotnet` commands from the solution folder
|
||||
> note that a preconfigured db is required for any kind of running the project (consider taking a look at [useful makefile targets](#useful-makefile-targets))
|
||||
> run the following commands from the solution folder
|
||||
|
||||
on the first run, restore stuff
|
||||
```sh
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
DROP TRIGGER IF EXISTS trigger_updated ON "Order";
|
||||
CREATE OR REPLACE FUNCTION updatedattr() RETURNS trigger
|
||||
AS $func$
|
||||
BEGIN
|
||||
NEW."Updated" := now();
|
||||
NEW."Created" := OLD."Created";
|
||||
RAISE NOTICE 'Order updated ''%'' on %', OLD."Order_Number", NEW."Updated";
|
||||
RETURN NEW;
|
||||
END;
|
||||
$func$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER trigger_updated
|
||||
BEFORE UPDATE ON "Order"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE updatedattr();
|
||||
|
||||
DROP TRIGGER IF EXISTS trigger_updated ON "Product";
|
||||
CREATE OR REPLACE FUNCTION updatedattr() RETURNS trigger
|
||||
AS $func$
|
||||
BEGIN
|
||||
NEW."Updated" := now();
|
||||
NEW."Created" := OLD."Created";
|
||||
RAISE NOTICE 'Product updated ''%'' on %', OLD."id", NEW."Updated";
|
||||
RETURN NEW;
|
||||
END;
|
||||
$func$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER trigger_updated
|
||||
BEFORE UPDATE ON "Product"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE updatedattr();
|
||||
|
||||
DROP TRIGGER IF EXISTS trigger_updated ON "OrderItem";
|
||||
CREATE OR REPLACE FUNCTION updatedattr() RETURNS trigger
|
||||
AS $func$
|
||||
BEGIN
|
||||
NEW."Updated" := now();
|
||||
NEW."Created" := OLD."Created";
|
||||
RAISE NOTICE 'OrderItem updated ''%'' on %', OLD."id", NEW."Updated";
|
||||
RETURN NEW;
|
||||
END;
|
||||
$func$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER trigger_updated
|
||||
BEFORE UPDATE ON "OrderItem"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE updatedattr();
|
||||
|
||||
DROP TRIGGER IF EXISTS trigger_updated ON "Carousel";
|
||||
CREATE OR REPLACE FUNCTION updatedattr() RETURNS trigger
|
||||
AS $func$
|
||||
BEGIN
|
||||
NEW."Updated" := now();
|
||||
NEW."Created" := OLD."Created";
|
||||
RAISE NOTICE 'Carousel updated ''%'' on %', OLD."id", NEW."Updated";
|
||||
RETURN NEW;
|
||||
END;
|
||||
$func$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER trigger_updated
|
||||
BEFORE UPDATE ON "Carousel"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE updatedattr();
|
163
Startup.cs
163
Startup.cs
|
@ -1,133 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.CookiePolicy;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.HttpsPolicy;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using pwt_0x01_ng.Models.Identity;
|
||||
using pwt_0x01_ng.Models.Database;
|
||||
using pwt_0x01_ng.Models.ApplicationServices;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace pwt_0x01_ng
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddHealthChecks();
|
||||
services.Configure<CookiePolicyOptions>(options =>
|
||||
{
|
||||
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
|
||||
options.CheckConsentNeeded = context => false;
|
||||
options.MinimumSameSitePolicy = SameSiteMode.Lax;
|
||||
options.HttpOnly = HttpOnlyPolicy.Always;
|
||||
options.Secure = CookieSecurePolicy.Always;
|
||||
});
|
||||
|
||||
services.AddControllersWithViews();
|
||||
IMvcBuilder builder = services.AddRazorPages();
|
||||
#if DEBUG
|
||||
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT").Equals("Development")){
|
||||
builder.AddRazorRuntimeCompilation();
|
||||
}
|
||||
#endif
|
||||
|
||||
var connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING");
|
||||
services.AddDbContext<DBContext>(options =>
|
||||
options.UseNpgsql(
|
||||
connectionString
|
||||
)
|
||||
);
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.Configure<CookiePolicyOptions>(options =>
|
||||
{
|
||||
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
|
||||
options.CheckConsentNeeded = context => true;
|
||||
options.MinimumSameSitePolicy = SameSiteMode.Lax;
|
||||
options.HttpOnly = HttpOnlyPolicy.Always;
|
||||
options.Secure = CookieSecurePolicy.Always;
|
||||
});
|
||||
|
||||
|
||||
services.AddIdentity<User, Role>().AddEntityFrameworkStores<DBContext>().AddDefaultTokenProviders();
|
||||
services.Configure<IdentityOptions>(o =>
|
||||
{
|
||||
/* dev fun settings */
|
||||
o.Password.RequireDigit = false;
|
||||
o.Password.RequireUppercase = false;
|
||||
o.Password.RequireLowercase = false;
|
||||
o.Password.RequireNonAlphanumeric = false;
|
||||
o.Password.RequiredLength = config.min_passwd_length;
|
||||
o.Password.RequiredUniqueChars = 1;
|
||||
o.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(1);
|
||||
o.Lockout.MaxFailedAccessAttempts = 3;
|
||||
o.Lockout.AllowedForNewUsers = false;
|
||||
o.User.RequireUniqueEmail = true;
|
||||
/* FIXME
|
||||
* o.Password.RequireDigit = true;
|
||||
* o.Password.RequiredLength = 18;
|
||||
* o.Password.RequiredUniqueChars = 10;
|
||||
* o.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
|
||||
* o.Lockout.MaxFailedAccessAttempts = 3;
|
||||
* o.Lockout.AllowedForNewUsers = true;
|
||||
* o.User.RequireUniqueEmail = true;
|
||||
*/
|
||||
});
|
||||
services.ConfigureApplicationCookie(o => {
|
||||
o.Cookie.HttpOnly = true;
|
||||
o.ExpireTimeSpan = TimeSpan.FromDays(2);
|
||||
o.SlidingExpiration = true;
|
||||
o.LoginPath = "/Security/Account/Login";
|
||||
o.LogoutPath = "/Security/Account/Logout";
|
||||
});
|
||||
services.AddScoped<ISecurityApplicationService, SecurityIdentityApplicationService>();
|
||||
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
|
||||
services.AddResponseCompression();
|
||||
services.AddSession();
|
||||
}
|
||||
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.EnvironmentName.Equals("Development"))
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
}
|
||||
app.UseStatusCodePages();
|
||||
app.UseStatusCodePagesWithReExecute("/Home/HandleError/{0}");
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
}
|
||||
|
||||
app.UseRouting();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.UseSession();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapRazorPages();
|
||||
endpoints.MapControllerRoute(
|
||||
name: "areas",
|
||||
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
|
||||
);
|
||||
endpoints.MapControllerRoute(
|
||||
name: "default",
|
||||
pattern: "{controller=Home}/{action=Index}/{id?}"
|
||||
);
|
||||
endpoints.MapControllerRoute(
|
||||
name: "default",
|
||||
pattern: "{controller=Products}/{action=Details}/{id?}"
|
||||
);
|
||||
endpoints.MapHealthChecks("/health");
|
||||
});
|
||||
app.UseStaticFiles();
|
||||
app.UseCookiePolicy();
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseCookiePolicy();
|
||||
|
||||
}
|
||||
}
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "areas",
|
||||
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
|
||||
);
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@{
|
||||
ViewData["Title"] = "About";
|
||||
ViewData["Title"] = "About";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<p>not much here now</p>
|
||||
<p>Use this area to provide additional information.</p>
|
|
@ -1,9 +1,17 @@
|
|||
@{
|
||||
ViewData["Title"] = "Contact";
|
||||
ViewData["Title"] = "Contact";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h4>@ViewData["Message"]</h4>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<address>
|
||||
Earth 🌍
|
||||
One Microsoft Way<br/>
|
||||
Redmond, WA 98052-6399<br/>
|
||||
<abbr title="Phone">P:</abbr>
|
||||
425.555.0100
|
||||
</address>
|
||||
|
||||
<address>
|
||||
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br/>
|
||||
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
|
||||
</address>
|
|
@ -1,68 +1,107 @@
|
|||
@model UltimateViewModel
|
||||
@model CarouselViewModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
@section Styles {
|
||||
<environment include="Development">
|
||||
<link rel="stylesheet" href="~/css/products.css"/>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<link rel="stylesheet" href="~/css/products.css"/>
|
||||
</environment>
|
||||
<link rel="stylesheet" href="~/css/Stylezbro.css"/>
|
||||
}
|
||||
|
||||
<div id="carouselpls">
|
||||
<div class="row">
|
||||
@{
|
||||
if (Model != null && Model.Carousels.Count > 0)
|
||||
{
|
||||
<div id="@Model.Carousels[0].DataTarget.Substring(1, Model.Carousels[0].DataTarget.Length - 1)" class="carousel slide" data-ride="carousel" data-interval="6000">
|
||||
<ol class="carousel-indicators">
|
||||
@{
|
||||
for (int i = 0; i < Model.Carousels.Count; i++)
|
||||
{
|
||||
string classli = String.Empty;
|
||||
if (i == 0)
|
||||
{
|
||||
classli = "class=\"active\"";
|
||||
}
|
||||
<li data-target="@Model.Carousels[i].DataTarget" data-slide-to="@i" @Html.Raw(classli)></li>
|
||||
}
|
||||
}
|
||||
</ol>
|
||||
<div class="carousel-inner " role="listbox">
|
||||
@{
|
||||
for (int i = 0; i < Model.Carousels.Count; i++)
|
||||
{
|
||||
string classitem = "item";
|
||||
if (i == 0)
|
||||
{
|
||||
classitem = "item active";
|
||||
}
|
||||
<div class="@classitem maxHeightCarousel">
|
||||
<img src="@Model.Carousels[i].ImageSrc" alt="@Model.Carousels[i].ImageAlt" class="img-responsive"/>
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
@Html.Raw(Model.Carousels[i].CarouselContent)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
|
||||
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
|
||||
<span class="sr-only">Previous</span>
|
||||
</a>
|
||||
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
|
||||
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
|
||||
<span class="sr-only">Next</span>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<partial name="../Products/_partial_Products.cshtml"/>
|
||||
@{
|
||||
if (Model != null && Model.Carousels.Count > 0)
|
||||
{
|
||||
<div id="@Model.Carousels[0].DataTarget.Substring(1, Model.Carousels[0].DataTarget.Length - 1)" class="carousel slide" data-ride="carousel" data-interval="6000">
|
||||
<ol class="carousel-indicators">
|
||||
@{
|
||||
for (int i = 0; i < Model.Carousels.Count; i++)
|
||||
{
|
||||
string classli = String.Empty;
|
||||
if (i == 0)
|
||||
{
|
||||
classli = "class=\"active\"";
|
||||
}
|
||||
<li data-target="@Model.Carousels[i].DataTarget" data-slide-to="@i" @Html.Raw(classli)></li>
|
||||
}
|
||||
}
|
||||
</ol>
|
||||
<div class="carousel-inner " role="listbox">
|
||||
@{
|
||||
for (int i = 0; i < Model.Carousels.Count; i++)
|
||||
{
|
||||
string classitem = "item";
|
||||
if (i == 0)
|
||||
{
|
||||
classitem = "item active";
|
||||
}
|
||||
<div class="@classitem maxHeightCarousel">
|
||||
<img src="@Model.Carousels[i].ImageSrc" alt="@Model.Carousels[i].ImageAlt" class="img-responsive"/>
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
@Html.Raw(Model.Carousels[i].CarouselContent)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
|
||||
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
|
||||
<span class="sr-only">Previous</span>
|
||||
</a>
|
||||
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
|
||||
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
|
||||
<span class="sr-only">Next</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<h2>Application uses</h2>
|
||||
<ul>
|
||||
<li>Sample pages using ASP.NET Core MVC</li>
|
||||
<li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>How to</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>Overview</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>Run & Deploy</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@{
|
||||
ViewData["Title"] = "Privacy Policy";
|
||||
ViewData["Title"] = "Privacy Policy";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.Product
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Detail - " + @Model.Name;
|
||||
}
|
||||
<h2>Detail</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<h1 class="my-4">@Model.Name</h1>
|
||||
<div class="list-group">
|
||||
<a href="#" class="list-group-item active">Category 1</a>
|
||||
<a href="#" class="list-group-item">Category 2</a>
|
||||
<a href="#" class="list-group-item">Category 3</a>
|
||||
</div>
|
||||
</div><!-- /.col-lg-3 -->
|
||||
|
||||
<div class="col-lg-9">
|
||||
<div class="card mt-4">
|
||||
<img class="card-img-top img-fluid img-responsive" src="@Model.ImageSrc" alt="@Model.ImageAlt">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">@Model.Name</h3>
|
||||
<h4>@Model.Price €</h4>
|
||||
<p class="card-text">@Model.Description</p>
|
||||
</div>
|
||||
</div><!-- /.card -->
|
||||
|
||||
<div class="card card-outline-secondary my-4">
|
||||
<div class="card-body">
|
||||
<hr>
|
||||
<input type="button" id="add_to_order" class="btn btn-primary" value="Add to order" onclick="Buy(@Model.id,'@Url.Action("AddOrderItemsToSession", "CustomerOrderNotCart", new { Area = "Customer" })', '#price_total', '@System.Globalization.CultureInfo.CurrentCulture.Name')" />
|
||||
</div>
|
||||
</div><!-- /.card -->
|
||||
<partial name="_partial_SimilarProducts"/>
|
||||
</div><!-- /.col-lg-9 -->
|
||||
</div>
|
||||
</div>
|
|
@ -1,40 +0,0 @@
|
|||
<!-- Page Content -->
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<h1 class="my-4">Products</h1>
|
||||
<div class="list-group">
|
||||
<a href="#" class="list-group-item">Category 1</a>
|
||||
<a href="#" class="list-group-item">Category 2</a>
|
||||
<a href="#" class="list-group-item">Category 3</a>
|
||||
</div>
|
||||
</div><!-- /.col-lg-3 -->
|
||||
<div class="col-lg-9">
|
||||
<div class="row">
|
||||
@{
|
||||
if (Model != null && Model.Products.Count > 0){
|
||||
for(int i = 0; i < Model.Products.Count; i++){
|
||||
<div id="prod_card" class="col-lg-4 col-md-6 mb-4">
|
||||
<div class="card h-100">
|
||||
<a asp-area="" asp-controller="Products" asp-action="Detail" asp-route-id="@Model.Products[i].id"><img class="card-img-top img-responsive" id="prod_list_img" src="@Model.Products[i].ImageSrc" alt="@Model.Products[i].ImageAlt"></a>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">
|
||||
<a asp-area="" asp-controller="Products" asp-action="Detail" asp-route-id="@Model.Products[i].id">@Model.Products[i].Name</a>
|
||||
</h4>
|
||||
<h5>@Model.Products[i].Price €</h5>
|
||||
<p class="card-text">@Model.Products[i].Description</p>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<small class="text-muted">★ ★ ★ ★ ★</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
} else {
|
||||
<h3 class="text-info"><code>we apologise, no products are available at the moment.</code></h3>
|
||||
}
|
||||
}
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.col-lg-9 -->
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.container -->
|
|
@ -1,35 +0,0 @@
|
|||
@model pwt_0x01_ng.Models.Product
|
||||
@{
|
||||
IList<Product> similar;
|
||||
similar = (IList<Product>) ViewData["similar"];
|
||||
}
|
||||
<div class="container">
|
||||
<div class="col-lg-9">
|
||||
<div class="row">
|
||||
@if (similar != null && similar.Count > 0) {
|
||||
<div class="col-lg-12 col-md-12">
|
||||
<div class="col-lg-4 col-md-4">
|
||||
<hr>
|
||||
<label>Similar products</label>
|
||||
</div>
|
||||
</div>
|
||||
int count_till = 3;
|
||||
if (similar.Count < 3) count_till = similar.Count;
|
||||
@for (int i = 0; i < count_till; i++) {
|
||||
<div id="prod_card" class="col-lg-4 col-md-6 mb-4">
|
||||
<div class="card h-100">
|
||||
<a asp-area="" asp-controller="Products" asp-action="Detail" asp-route-id="@similar[i].id"><img class="card-img-top img-responsive" id="prod_list_img" src="@similar[i].ImageSrc" alt="@similar[i].ImageAlt"></a>
|
||||
<div class="card-body">
|
||||
<label><a asp-area="" asp-controller="Products" asp-action="Detail" asp-route-id="@similar[i].id">@similar[i].Name</a></label>
|
||||
<div class="card-text">@similar[i].Description</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="text-muted">@similar[i].Price €</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,7 +0,0 @@
|
|||
@{
|
||||
ViewData["Title"] = "403 Forbidden";
|
||||
}
|
||||
|
||||
<partial name="_errdivtop_part"/>
|
||||
<h2 class="text-secondary">You are not authorized to access the resource.</h2>
|
||||
<partial name="_errdivbottom_part"/>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue