Added order image and description upload

This commit is contained in:
2025-11-30 10:48:08 +01:00
parent b005975c81
commit 1bce61267a
13 changed files with 974 additions and 2 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
bin
obj
*.db*
wwwroot/uploads

View File

@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using OneForMe.Data;
using OneForMe.Models;
using System.IO;
namespace OneForMe.Controllers;
@@ -24,7 +25,7 @@ public class OrderController : Controller
// POST: Order/Create
[HttpPost]
public async Task<IActionResult> Create(Order order, string[] itemNames, string[] itemPrices)
public async Task<IActionResult> Create(Order order, string[] itemNames, string[] itemPrices, IFormFile? ImageFile)
{
if (!ModelState.IsValid)
return View();
@@ -32,6 +33,34 @@ public class OrderController : Controller
order.OrderCode = GenerateOrderCode();
order.CreatorName = User.Identity?.Name ?? "Unknown";
// Handle image upload
if (ImageFile != null && ImageFile.Length > 0)
{
try
{
var uploadsFolder = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "uploads", "orders");
if (!Directory.Exists(uploadsFolder))
{
Directory.CreateDirectory(uploadsFolder);
}
var uniqueFileName = $"{order.OrderCode}_{Guid.NewGuid()}_{Path.GetFileName(ImageFile.FileName)}";
var filePath = Path.Combine(uploadsFolder, uniqueFileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await ImageFile.CopyToAsync(fileStream);
}
order.ImagePath = $"/uploads/orders/{uniqueFileName}";
}
catch (Exception ex)
{
ModelState.AddModelError("ImageFile", $"Error uploading file: {ex.Message}");
return View();
}
}
_context.Orders.Add(order);
await _context.SaveChangesAsync();

View File

@@ -0,0 +1,408 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using OneForMe.Data;
#nullable disable
namespace OneForMe.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20251130093329_AddAdditionalInfoAndImagePath")]
partial class AddAdditionalInfoAndImagePath
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "10.0.0-rc.2.25502.107");
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("ProviderKey")
.HasColumnType("TEXT");
b.Property<string>("ProviderDisplayName")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.HasColumnType("TEXT");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("OneForMe.Models.MenuItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OrderId")
.HasColumnType("INTEGER");
b.Property<decimal>("Price")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("MenuItems");
});
modelBuilder.Entity("OneForMe.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AdditionalInfo")
.HasColumnType("TEXT");
b.Property<DateTime?>("ClosedAt")
.HasColumnType("TEXT");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("CreatorName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ImagePath")
.HasColumnType("TEXT");
b.Property<bool>("IsClosed")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OrderCode")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("OrderCode")
.IsUnique();
b.ToTable("Orders");
});
modelBuilder.Entity("OneForMe.Models.OrderItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("MenuItemId")
.HasColumnType("INTEGER");
b.Property<int>("OrderId")
.HasColumnType("INTEGER");
b.Property<DateTime>("OrderedAt")
.HasColumnType("TEXT");
b.Property<string>("ParticipantEmail")
.HasColumnType("TEXT");
b.Property<string>("ParticipantName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("Quantity")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("MenuItemId");
b.HasIndex("OrderId");
b.ToTable("OrderItems");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("OneForMe.Models.MenuItem", b =>
{
b.HasOne("OneForMe.Models.Order", "Order")
.WithMany("MenuItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Order");
});
modelBuilder.Entity("OneForMe.Models.OrderItem", b =>
{
b.HasOne("OneForMe.Models.MenuItem", "MenuItem")
.WithMany("OrderItems")
.HasForeignKey("MenuItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("OneForMe.Models.Order", "Order")
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("MenuItem");
b.Navigation("Order");
});
modelBuilder.Entity("OneForMe.Models.MenuItem", b =>
{
b.Navigation("OrderItems");
});
modelBuilder.Entity("OneForMe.Models.Order", b =>
{
b.Navigation("MenuItems");
b.Navigation("OrderItems");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace OneForMe.Migrations
{
/// <inheritdoc />
public partial class AddAdditionalInfoAndImagePath : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "AdditionalInfo",
table: "Orders",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "ImagePath",
table: "Orders",
type: "TEXT",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "AdditionalInfo",
table: "Orders");
migrationBuilder.DropColumn(
name: "ImagePath",
table: "Orders");
}
}
}

View File

@@ -0,0 +1,408 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using OneForMe.Data;
#nullable disable
namespace OneForMe.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20251130093404_AddAdditionalInfoAndImageToOrder")]
partial class AddAdditionalInfoAndImageToOrder
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "10.0.0-rc.2.25502.107");
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("ProviderKey")
.HasColumnType("TEXT");
b.Property<string>("ProviderDisplayName")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.HasColumnType("TEXT");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("OneForMe.Models.MenuItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OrderId")
.HasColumnType("INTEGER");
b.Property<decimal>("Price")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("MenuItems");
});
modelBuilder.Entity("OneForMe.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AdditionalInfo")
.HasColumnType("TEXT");
b.Property<DateTime?>("ClosedAt")
.HasColumnType("TEXT");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("CreatorName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ImagePath")
.HasColumnType("TEXT");
b.Property<bool>("IsClosed")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OrderCode")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("OrderCode")
.IsUnique();
b.ToTable("Orders");
});
modelBuilder.Entity("OneForMe.Models.OrderItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("MenuItemId")
.HasColumnType("INTEGER");
b.Property<int>("OrderId")
.HasColumnType("INTEGER");
b.Property<DateTime>("OrderedAt")
.HasColumnType("TEXT");
b.Property<string>("ParticipantEmail")
.HasColumnType("TEXT");
b.Property<string>("ParticipantName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("Quantity")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("MenuItemId");
b.HasIndex("OrderId");
b.ToTable("OrderItems");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("OneForMe.Models.MenuItem", b =>
{
b.HasOne("OneForMe.Models.Order", "Order")
.WithMany("MenuItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Order");
});
modelBuilder.Entity("OneForMe.Models.OrderItem", b =>
{
b.HasOne("OneForMe.Models.MenuItem", "MenuItem")
.WithMany("OrderItems")
.HasForeignKey("MenuItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("OneForMe.Models.Order", "Order")
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("MenuItem");
b.Navigation("Order");
});
modelBuilder.Entity("OneForMe.Models.MenuItem", b =>
{
b.Navigation("OrderItems");
});
modelBuilder.Entity("OneForMe.Models.Order", b =>
{
b.Navigation("MenuItems");
b.Navigation("OrderItems");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace OneForMe.Migrations
{
/// <inheritdoc />
public partial class AddAdditionalInfoAndImageToOrder : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@@ -238,6 +238,9 @@ namespace OneForMe.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AdditionalInfo")
.HasColumnType("TEXT");
b.Property<DateTime?>("ClosedAt")
.HasColumnType("TEXT");
@@ -248,6 +251,9 @@ namespace OneForMe.Migrations
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ImagePath")
.HasColumnType("TEXT");
b.Property<bool>("IsClosed")
.HasColumnType("INTEGER");

View File

@@ -6,6 +6,8 @@ public class Order
public string OrderCode { get; set; } = string.Empty;
public string CreatorName { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string? AdditionalInfo { get; set; }
public string? ImagePath { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? ClosedAt { get; set; }
public bool IsClosed { get; set; } = false;

View File

@@ -279,4 +279,19 @@
<data name="Currency" xml:space="preserve">
<value>{0} €</value>
</data>
<data name="AdditionalInfo" xml:space="preserve">
<value>Zusätzliche Informationen</value>
</data>
<data name="EnterAdditionalInfo" xml:space="preserve">
<value>Zusätzliche Informationen eingeben (optional)</value>
</data>
<data name="UploadImage" xml:space="preserve">
<value>Bild hochladen</value>
</data>
<data name="CreatedBy" xml:space="preserve">
<value>Erstellt von</value>
</data>
<data name="CreatedOn" xml:space="preserve">
<value>Erstellt am</value>
</data>
</root>

View File

@@ -279,4 +279,16 @@
<data name="Currency" xml:space="preserve">
<value>${0}</value>
</data>
<data name="AdditionalInfo" xml:space="preserve">
<value>Additional Information</value>
</data>
<data name="EnterAdditionalInfo" xml:space="preserve">
<value>Enter additional information (optional)</value>
</data>
<data name="UploadImage" xml:space="preserve">
<value>Upload Image</value>
</data>
<data name="CreatedOn" xml:space="preserve">
<value>Created on</value>
</data>
</root>

View File

@@ -12,13 +12,25 @@
<div class="card-body p-5">
<h2 class="mb-4">@Localizer["CreateNewOrder"]</h2>
<form method="post" id="createOrderForm">
<form method="post" id="createOrderForm" enctype="multipart/form-data">
<div class="mb-3">
<label for="Name" class="form-label">@Localizer["OrderName"]</label>
<input type="text" class="form-control" id="Name" name="Name" required>
<small class="text-muted">@Localizer["GiveOrderName"]</small>
</div>
<div class="mb-3">
<label for="AdditionalInfo" class="form-label">Additional Information</label>
<textarea class="form-control" id="AdditionalInfo" name="AdditionalInfo" rows="3" placeholder="Enter any additional details about this order..."></textarea>
<small class="text-muted">Optional: Add notes, special instructions, or other details</small>
</div>
<div class="mb-3">
<label for="ImageFile" class="form-label">Order Image</label>
<input type="file" class="form-control" id="ImageFile" name="ImageFile" accept="image/*">
<small class="text-muted">Optional: Upload an image for this order (JPG, PNG, etc.)</small>
</div>
<hr>
<h5 class="mb-3">@Localizer["MenuItems"]</h5>

View File

@@ -15,6 +15,15 @@
<h2>@Model.Name</h2>
<p class="text-muted">@Localizer.Get("Code"): <strong>@Model.OrderCode</strong></p>
<p>@Localizer.Get("CreatedBy"): <strong>@Model.CreatorName</strong></p>
<p>@Localizer.Get("CreatedOn"): @Model.CreatedAt.ToString("g")</p>
@if (!string.IsNullOrEmpty(Model.ImagePath))
{
<img src="@Model.ImagePath" alt="Order Image" class="img-fluid mb-3" style="max-height: 300px; object-fit: cover;">
}
@if (!string.IsNullOrEmpty(Model.AdditionalInfo))
{
<p class="border rounded p-3" style="white-space: pre-wrap;">@Model.AdditionalInfo</p>
}
<p>@Localizer.Get("Status"): <span class="badge @(Model.IsClosed ? "bg-danger" : "bg-success")">@(Model.IsClosed ? Localizer.Get("Closed") : Localizer.Get("Open"))</span></p>
</div>
</div>

View File

@@ -15,6 +15,16 @@
<h2>@Model.Name</h2>
<p class="text-muted">@Localizer["Code"]: <strong>@Model.OrderCode</strong></p>
<p>@Localizer["CreatedBy"]: <strong>@Model.CreatorName</strong></p>
@if (!string.IsNullOrEmpty(Model.ImagePath))
{
<img src="@Model.ImagePath" alt="Order Image" class="img-fluid mb-3" style="max-height: 300px; object-fit: cover;">
}
@if (!string.IsNullOrEmpty(Model.AdditionalInfo))
{
<p class="border rounded p-3" style="white-space: pre-wrap;">@Model.AdditionalInfo</p>
}
</div>
</div>