Changeset fa0fbaf for KernelRecordsMVC.Web/Views/Admin
- Timestamp:
- 09/01/26 06:11:34 (4 weeks ago)
- Branches:
- main
- Children:
- d2eccb3
- Parents:
- 08aefc6
- Location:
- KernelRecordsMVC.Web/Views/Admin
- Files:
-
- 1 added
- 4 edited
-
CreateProduct.cshtml (modified) (1 diff)
-
CreateRelease.cshtml (added)
-
EditProduct.cshtml (modified) (1 diff)
-
Index.cshtml (modified) (1 diff)
-
Products.cshtml (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
KernelRecordsMVC.Web/Views/Admin/CreateProduct.cshtml
r08aefc6 rfa0fbaf 1 1 @model KernelRecordsMVC.Application.ViewModels.CreateProductViewModel 2 2 3 <h1>New Product</h1> 4 5 <p class="text-muted"> 6 Add a physical product format for an existing release. 7 </p> 8 9 <form asp-action="CreateProduct" 10 method="post"> 11 12 @Html.AntiForgeryToken() 13 14 <div asp-validation-summary="ModelOnly" 15 class="text-danger mb-3"> 3 @{ 4 ViewData["Title"] = "New Product"; 5 } 6 7 <div class="admin-page admin-form-page"> 8 9 <!-- HEADER --> 10 11 <div class="admin-header"> 12 13 <div> 14 15 <a asp-action="Products" 16 class="admin-back-link"> 17 18 ← Products 19 20 </a> 21 22 <span class="admin-eyebrow"> 23 INVENTORY 24 </span> 25 26 <h1>New Product</h1> 27 28 <p> 29 Add a new physical format to an existing release. 30 </p> 31 32 </div> 33 16 34 </div> 17 35 18 36 19 <!-- RELEASE --> 20 21 <div class="mb-3"> 22 23 <label asp-for="ReleaseId" 24 class="form-label"> 25 </label> 26 27 <select asp-for="ReleaseId" 28 class="form-select"> 29 30 <option value=""> 31 -- Select Release -- 32 </option> 33 34 @foreach (var release in ViewBag.Releases) 35 { 36 <option value="@release.ReleaseId"> 37 38 @release.Title 39 (@release.ReleaseDate.ToString("yyyy")) 40 41 </option> 42 } 43 44 </select> 45 46 <span asp-validation-for="ReleaseId" 47 class="text-danger"> 48 </span> 37 <div class="admin-form-layout"> 38 39 40 <!-- ================================================= 41 FORM 42 ================================================= --> 43 44 <section class="admin-form-card"> 45 46 <div class="admin-form-card-header"> 47 48 <span class="admin-eyebrow"> 49 PRODUCT INFORMATION 50 </span> 51 52 <h2>Product Details</h2> 53 54 </div> 55 56 57 <form asp-action="CreateProduct" 58 method="post"> 59 60 @Html.AntiForgeryToken() 61 62 63 <div asp-validation-summary="ModelOnly" 64 class="admin-validation"> 65 </div> 66 67 68 <!-- RELEASE --> 69 70 <div class="admin-form-field"> 71 72 <label asp-for="ReleaseId"> 73 Release 74 </label> 75 76 <select asp-for="ReleaseId"> 77 78 <option value=""> 79 Select a release 80 </option> 81 82 @foreach (var release in ViewBag.Releases) 83 { 84 <option value="@release.ReleaseId"> 85 86 @release.Title 87 (@release.ReleaseDate.ToString("yyyy")) 88 89 </option> 90 } 91 92 </select> 93 94 <span asp-validation-for="ReleaseId" 95 class="admin-field-error"> 96 </span> 97 98 <small> 99 Select the release this physical 100 product belongs to. 101 </small> 102 103 </div> 104 105 106 <div class="admin-form-row"> 107 108 109 <!-- FORMAT --> 110 111 <div class="admin-form-field"> 112 113 <label asp-for="Format"> 114 Format 115 </label> 116 117 <select asp-for="Format" 118 asp-items="Html.GetEnumSelectList<KernelRecordsMVC.Domain.Enums.ProductFormat>()"> 119 120 <option value=""> 121 Select format 122 </option> 123 124 </select> 125 126 <span asp-validation-for="Format" 127 class="admin-field-error"> 128 </span> 129 130 </div> 131 132 133 <!-- PRICE --> 134 135 <div class="admin-form-field"> 136 137 <label asp-for="Price"> 138 Price 139 </label> 140 141 <div class="admin-input-prefix"> 142 143 <span>$</span> 144 145 <input asp-for="Price" 146 type="number" 147 min="0" 148 step="0.01" 149 placeholder="0.00" /> 150 151 </div> 152 153 <span asp-validation-for="Price" 154 class="admin-field-error"> 155 </span> 156 157 </div> 158 159 </div> 160 161 162 <!-- STOCK --> 163 164 <div class="admin-form-field"> 165 166 <label asp-for="Stock"> 167 Initial Stock 168 </label> 169 170 <input asp-for="Stock" 171 type="number" 172 min="0" 173 placeholder="0" /> 174 175 <span asp-validation-for="Stock" 176 class="admin-field-error"> 177 </span> 178 179 </div> 180 181 182 <!-- DESCRIPTION --> 183 184 <div class="admin-form-field"> 185 186 <label asp-for="ProductDescription"> 187 Product Description 188 </label> 189 190 <textarea asp-for="ProductDescription" 191 rows="5" 192 placeholder="Describe this physical edition..."></textarea> 193 194 <span asp-validation-for="ProductDescription" 195 class="admin-field-error"> 196 </span> 197 198 </div> 199 200 201 <!-- ACTIONS --> 202 203 <div class="admin-form-actions"> 204 205 <button type="submit" 206 class="admin-button primary"> 207 208 Create Product 209 210 </button> 211 212 213 <a asp-action="Products" 214 class="admin-button secondary"> 215 216 Cancel 217 218 </a> 219 220 </div> 221 222 </form> 223 224 </section> 225 226 227 <!-- ================================================= 228 SIDE INFO 229 ================================================= --> 230 231 <aside class="admin-help-card"> 232 233 <span class="admin-eyebrow"> 234 PRODUCT CREATION 235 </span> 236 237 <h3>Before you create</h3> 238 239 <div class="admin-help-item"> 240 241 <strong>01</strong> 242 243 <p> 244 A release can only have one product 245 for each physical format. 246 </p> 247 248 </div> 249 250 251 <div class="admin-help-item"> 252 253 <strong>02</strong> 254 255 <p> 256 Stock can be updated later from 257 Product Management. 258 </p> 259 260 </div> 261 262 263 <div class="admin-help-item"> 264 265 <strong>03</strong> 266 267 <p> 268 Creating the product will automatically 269 create a modification record. 270 </p> 271 272 </div> 273 274 </aside> 49 275 50 276 </div> 51 277 52 53 <!-- FORMAT --> 54 55 <div class="mb-3"> 56 57 <label asp-for="Format" 58 class="form-label"> 59 </label> 60 61 <select asp-for="Format" 62 asp-items="Html.GetEnumSelectList<KernelRecordsMVC.Domain.Enums.ProductFormat>()" 63 class="form-select"> 64 65 <option value=""> 66 -- Select Format -- 67 </option> 68 69 </select> 70 71 <span asp-validation-for="Format" 72 class="text-danger"> 73 </span> 74 75 </div> 76 77 78 <!-- PRICE --> 79 80 <div class="mb-3"> 81 82 <label asp-for="Price" 83 class="form-label"> 84 </label> 85 86 <div class="input-group"> 87 88 <span class="input-group-text"> 89 $ 90 </span> 91 92 <input asp-for="Price" 93 class="form-control" 94 step="0.01"/> 95 96 </div> 97 98 <span asp-validation-for="Price" 99 class="text-danger"> 100 </span> 101 102 </div> 103 104 105 <!-- DESCRIPTION --> 106 107 <div class="mb-3"> 108 109 <label asp-for="ProductDescription" 110 class="form-label"> 111 </label> 112 113 <textarea asp-for="ProductDescription" 114 class="form-control" 115 rows="4"> 116 </textarea> 117 118 <span asp-validation-for="ProductDescription" 119 class="text-danger"> 120 </span> 121 122 </div> 123 124 125 <!-- STOCK --> 126 127 <div class="mb-3"> 128 129 <label asp-for="Stock" 130 class="form-label"> 131 </label> 132 133 <input asp-for="Stock" 134 type="number" 135 min="0" 136 class="form-control"/> 137 138 <span asp-validation-for="Stock" 139 class="text-danger"> 140 </span> 141 142 </div> 143 144 145 <div class="d-flex gap-2"> 146 147 <button type="submit" 148 class="btn btn-success"> 149 150 Create Product 151 152 </button> 153 154 <a asp-action="Index" 155 class="btn btn-secondary"> 156 157 Cancel 158 159 </a> 160 161 </div> 162 163 </form> 278 </div> 279 164 280 165 281 @section Scripts 166 282 { 167 <partial name="_ValidationScriptsPartial" />283 <partial name="_ValidationScriptsPartial" /> 168 284 } -
KernelRecordsMVC.Web/Views/Admin/EditProduct.cshtml
r08aefc6 rfa0fbaf 1 1 @model KernelRecordsMVC.Application.ViewModels.EditProductViewModel 2 2 3 <h1>Modify Product</h1> 4 5 <div class="card mb-4"> 6 7 <div class="card-body"> 8 9 <h4>@Model.ReleaseTitle</h4> 10 11 <p class="text-muted mb-0"> 12 13 Format: 14 15 <strong> 16 @Model.Format 17 </strong> 18 19 </p> 3 @{ 4 ViewData["Title"] = "Modify Product"; 5 } 6 7 <div class="admin-page admin-form-page"> 8 9 <!-- HEADER --> 10 11 <div class="admin-header"> 12 13 <div> 14 15 <a asp-action="Products" 16 class="admin-back-link"> 17 18 ← Products 19 20 </a> 21 22 <span class="admin-eyebrow"> 23 PRODUCT MANAGEMENT 24 </span> 25 26 <h1>Modify Product</h1> 27 28 <p> 29 Update inventory information or apply a discount. 30 </p> 31 32 </div> 20 33 21 34 </div> 22 35 36 37 <!-- PRODUCT SUMMARY --> 38 39 <div class="admin-product-summary"> 40 41 <div> 42 43 <span class="admin-eyebrow"> 44 SELECTED PRODUCT 45 </span> 46 47 <h2> 48 @Model.ReleaseTitle 49 </h2> 50 51 </div> 52 53 <div class="admin-product-summary-meta"> 54 55 <div> 56 57 <span>FORMAT</span> 58 59 <strong> 60 @Model.Format 61 </strong> 62 63 </div> 64 65 <div> 66 67 <span>CURRENT PRICE</span> 68 69 <strong> 70 @Model.Price.ToString("C") 71 </strong> 72 73 </div> 74 75 <div> 76 77 <span>STOCK</span> 78 79 <strong> 80 @Model.Stock 81 </strong> 82 83 </div> 84 85 </div> 86 87 </div> 88 89 90 <section class="admin-form-card admin-edit-card"> 91 92 <form asp-action="EditProduct" 93 method="post" 94 id="productEditForm"> 95 96 @Html.AntiForgeryToken() 97 98 <input type="hidden" 99 asp-for="ProductId" /> 100 101 102 <div asp-validation-summary="ModelOnly" 103 class="admin-validation"> 104 </div> 105 106 107 <!-- ================================================= 108 MODIFICATION TYPE 109 ================================================= --> 110 111 <div class="admin-form-field"> 112 113 <label asp-for="ModificationType"> 114 What do you want to do? 115 </label> 116 117 <div class="admin-modification-options"> 118 119 <label class="admin-modification-option"> 120 121 <input type="radio" 122 asp-for="ModificationType" 123 value="UPDATE" 124 id="updateOption" /> 125 126 <span> 127 128 <strong> 129 Update Product 130 </strong> 131 132 <small> 133 Change price, description or stock. 134 </small> 135 136 </span> 137 138 </label> 139 140 141 <label class="admin-modification-option"> 142 143 <input type="radio" 144 asp-for="ModificationType" 145 value="DISCOUNT" 146 id="discountOption" /> 147 148 <span> 149 150 <strong> 151 Apply Discount 152 </strong> 153 154 <small> 155 Reduce the current selling price. 156 </small> 157 158 </span> 159 160 </label> 161 162 </div> 163 164 <span asp-validation-for="ModificationType" 165 class="admin-field-error"> 166 </span> 167 168 </div> 169 170 171 <!-- ================================================= 172 UPDATE FIELDS 173 ================================================= --> 174 175 <div id="updateFields" 176 class="admin-edit-section"> 177 178 <div class="admin-edit-section-heading"> 179 180 <span class="admin-eyebrow"> 181 PRODUCT UPDATE 182 </span> 183 184 <h3>Product Information</h3> 185 186 </div> 187 188 189 <div class="admin-form-row"> 190 191 <!-- PRICE --> 192 193 <div class="admin-form-field"> 194 195 <label asp-for="Price"> 196 Price 197 </label> 198 199 <div class="admin-input-prefix"> 200 201 <span>$</span> 202 203 <input asp-for="Price" 204 type="number" 205 min="0" 206 step="0.01" /> 207 208 </div> 209 210 <span asp-validation-for="Price" 211 class="admin-field-error"> 212 </span> 213 214 </div> 215 216 217 <!-- STOCK --> 218 219 <div class="admin-form-field"> 220 221 <label asp-for="Stock"> 222 Stock 223 </label> 224 225 <input asp-for="Stock" 226 type="number" 227 min="0" /> 228 229 <span asp-validation-for="Stock" 230 class="admin-field-error"> 231 </span> 232 233 </div> 234 235 </div> 236 237 238 <div class="admin-form-field"> 239 240 <label asp-for="ProductDescription"> 241 Description 242 </label> 243 244 <textarea asp-for="ProductDescription" 245 rows="5"></textarea> 246 247 <span asp-validation-for="ProductDescription" 248 class="admin-field-error"> 249 </span> 250 251 </div> 252 253 </div> 254 255 256 <!-- ================================================= 257 DISCOUNT 258 ================================================= --> 259 260 <div id="discountFields" 261 class="admin-edit-section"> 262 263 <div class="admin-edit-section-heading"> 264 265 <span class="admin-eyebrow"> 266 PROMOTION 267 </span> 268 269 <h3>Apply Discount</h3> 270 271 <p> 272 The percentage will be deducted 273 from the product's current price. 274 </p> 275 276 </div> 277 278 279 <div class="admin-form-field"> 280 281 <label asp-for="Discount"> 282 Discount Percentage 283 </label> 284 285 <div class="admin-input-suffix"> 286 287 <input asp-for="Discount" 288 type="number" 289 min="0.01" 290 max="99.99" 291 step="0.01" 292 placeholder="10" /> 293 294 <span>%</span> 295 296 </div> 297 298 <span asp-validation-for="Discount" 299 class="admin-field-error"> 300 </span> 301 302 </div> 303 304 305 <div class="admin-discount-preview"> 306 307 <span> 308 CURRENT PRICE 309 </span> 310 311 <strong id="currentPrice" 312 data-price="@Model.Price"> 313 @Model.Price.ToString("C") 314 </strong> 315 316 317 <span> 318 NEW PRICE 319 </span> 320 321 <strong id="discountedPrice"> 322 — 323 </strong> 324 325 </div> 326 327 </div> 328 329 330 <!-- ACTIONS --> 331 332 <div class="admin-form-actions"> 333 334 <button type="submit" 335 class="admin-button primary"> 336 337 Save Changes 338 339 </button> 340 341 <a asp-action="Products" 342 class="admin-button secondary"> 343 344 Cancel 345 346 </a> 347 348 </div> 349 350 </form> 351 352 </section> 353 23 354 </div> 24 355 25 26 <form asp-action="EditProduct"27 method="post">28 29 @Html.AntiForgeryToken()30 31 <input type="hidden"32 asp-for="ProductId" />33 34 <div asp-validation-summary="ModelOnly"35 class="text-danger mb-3">36 </div>37 38 39 <!-- MODIFICATION TYPE -->40 41 <div class="mb-3">42 43 <label asp-for="ModificationType"44 class="form-label">45 46 Modification Type47 48 </label>49 50 <select asp-for="ModificationType"51 class="form-select">52 53 <option value="UPDATE">54 Update Product55 </option>56 57 <option value="DISCOUNT">58 Apply Discount59 </option>60 61 </select>62 63 <span asp-validation-for="ModificationType"64 class="text-danger">65 </span>66 67 </div>68 69 70 <!-- PRICE -->71 72 <div class="mb-3">73 74 <label asp-for="Price"75 class="form-label">76 77 Price78 79 </label>80 81 <div class="input-group">82 83 <span class="input-group-text">84 $85 </span>86 87 <input asp-for="Price"88 class="form-control"89 step="0.01" />90 91 </div>92 93 <span asp-validation-for="Price"94 class="text-danger">95 </span>96 97 </div>98 99 100 <!-- DISCOUNT -->101 102 <div class="mb-3">103 104 <label asp-for="Discount"105 class="form-label">106 107 Discount Percentage108 109 </label>110 111 <div class="input-group">112 113 <input asp-for="Discount"114 class="form-control"115 type="number"116 min="0"117 max="100"118 step="0.01" />119 120 <span class="input-group-text">121 %122 </span>123 124 </div>125 126 <small class="text-muted">127 Only used when "Apply Discount" is selected.128 </small>129 130 <span asp-validation-for="Discount"131 class="text-danger">132 </span>133 134 </div>135 136 137 <!-- DESCRIPTION -->138 139 <div class="mb-3">140 141 <label asp-for="ProductDescription"142 class="form-label">143 144 Description145 146 </label>147 148 <textarea asp-for="ProductDescription"149 class="form-control"150 rows="4">151 </textarea>152 153 <span asp-validation-for="ProductDescription"154 class="text-danger">155 </span>156 157 </div>158 159 160 <!-- STOCK -->161 162 <div class="mb-3">163 164 <label asp-for="Stock"165 class="form-label">166 167 Stock168 169 </label>170 171 <input asp-for="Stock"172 class="form-control"173 type="number"174 min="0" />175 176 <span asp-validation-for="Stock"177 class="text-danger">178 </span>179 180 </div>181 182 183 <div class="d-flex gap-2">184 185 <button type="submit"186 class="btn btn-success">187 188 Save Changes189 190 </button>191 192 <a asp-action="Index"193 class="btn btn-secondary">194 195 Cancel196 197 </a>198 199 </div>200 201 </form>202 356 203 357 @section Scripts 204 358 { 205 <partial name="_ValidationScriptsPartial"/> 359 <partial name="_ValidationScriptsPartial" /> 360 361 <script> 362 363 document.addEventListener("DOMContentLoaded", function () 364 { 365 const updateOption = 366 document.getElementById("updateOption"); 367 368 const discountOption = 369 document.getElementById("discountOption"); 370 371 const updateFields = 372 document.getElementById("updateFields"); 373 374 const discountFields = 375 document.getElementById("discountFields"); 376 377 const discountInput = 378 document.getElementById("Discount"); 379 380 const currentPriceElement = 381 document.getElementById("currentPrice"); 382 383 const discountedPriceElement = 384 document.getElementById("discountedPrice"); 385 386 387 function updateMode() 388 { 389 const isDiscount = 390 discountOption.checked; 391 392 updateFields.style.display = 393 isDiscount ? "none" : "block"; 394 395 discountFields.style.display = 396 isDiscount ? "block" : "none"; 397 } 398 399 400 function updateDiscountPreview() 401 { 402 const currentPrice = 403 parseFloat( 404 currentPriceElement.dataset.price); 405 406 const discount = 407 parseFloat(discountInput.value); 408 409 410 if (isNaN(discount) || 411 discount <= 0 || 412 discount >= 100) 413 { 414 discountedPriceElement.textContent = 415 "—"; 416 417 return; 418 } 419 420 421 const newPrice = 422 currentPrice * 423 (1 - discount / 100); 424 425 426 discountedPriceElement.textContent = 427 "$" + newPrice.toFixed(2); 428 } 429 430 431 updateOption.addEventListener( 432 "change", 433 updateMode); 434 435 discountOption.addEventListener( 436 "change", 437 updateMode); 438 439 discountInput.addEventListener( 440 "input", 441 updateDiscountPreview); 442 443 444 updateMode(); 445 updateDiscountPreview(); 446 }); 447 448 </script> 206 449 } -
KernelRecordsMVC.Web/Views/Admin/Index.cshtml
r08aefc6 rfa0fbaf 3 3 } 4 4 5 <h1>Admin Dashboard</h1> 6 7 @if (TempData["Success"] != null) 8 { 9 <div class="alert alert-success"> 10 @TempData["Success"] 5 <div class="admin-page"> 6 7 <!-- ===================================================== 8 HEADER 9 ===================================================== --> 10 11 <div class="admin-header"> 12 13 <div> 14 15 <span class="admin-eyebrow"> 16 KERNEL RECORDS 17 </span> 18 19 <h1>Admin Dashboard</h1> 20 21 <p> 22 Manage catalog, inventory and store operations. 23 </p> 24 25 </div> 26 27 28 <div class="admin-header-actions"> 29 30 <a asp-action="CreateRelease" 31 class="admin-button secondary"> 32 33 <span>♪</span> 34 New Release 35 36 </a> 37 38 39 <a asp-action="CreateProduct" 40 class="admin-button primary"> 41 42 <span>+</span> 43 New Product 44 45 </a> 46 47 </div> 48 11 49 </div> 12 } 13 14 <div class="row mt-4"> 15 16 <div class="col-md-6 mb-3"> 17 18 <div class="card h-100"> 19 20 <div class="card-body"> 21 22 <h4>Products</h4> 50 51 52 @if (TempData["Success"] != null) 53 { 54 <div class="admin-alert success"> 55 56 <span>✓</span> 57 58 @TempData["Success"] 59 60 </div> 61 } 62 63 64 @if (TempData["Error"] != null) 65 { 66 <div class="admin-alert danger"> 67 68 <span>!</span> 69 70 @TempData["Error"] 71 72 </div> 73 } 74 75 76 <!-- ===================================================== 77 STATISTICS 78 ===================================================== --> 79 80 <div class="admin-stat-grid"> 81 82 <div class="admin-stat-card"> 83 84 <span class="admin-stat-label"> 85 PRODUCTS 86 </span> 87 88 <strong> 89 @ViewBag.ProductCount 90 </strong> 91 92 <p> 93 Physical products in the store 94 </p> 95 96 </div> 97 98 99 <div class="admin-stat-card"> 100 101 <span class="admin-stat-label"> 102 RELEASES 103 </span> 104 105 <strong> 106 @ViewBag.ReleaseCount 107 </strong> 108 109 <p> 110 Albums and singles in the catalog 111 </p> 112 113 </div> 114 115 116 <div class="admin-stat-card warning"> 117 118 <span class="admin-stat-label"> 119 LOW STOCK 120 </span> 121 122 <strong> 123 @ViewBag.LowStockCount 124 </strong> 125 126 <p> 127 Products with 5 or fewer remaining 128 </p> 129 130 </div> 131 132 133 <div class="admin-stat-card danger"> 134 135 <span class="admin-stat-label"> 136 OUT OF STOCK 137 </span> 138 139 <strong> 140 @ViewBag.OutOfStockCount 141 </strong> 142 143 <p> 144 Products requiring restocking 145 </p> 146 147 </div> 148 149 </div> 150 151 152 <!-- ===================================================== 153 CATALOG MANAGEMENT 154 ===================================================== --> 155 156 <section class="admin-section"> 157 158 <div class="admin-section-heading"> 159 160 <div> 161 162 <span class="admin-eyebrow"> 163 CATALOG MANAGEMENT 164 </span> 165 166 <h2>Releases & Products</h2> 23 167 24 168 <p> 25 Create and modify products available 26 in the music store. 169 Create music releases and manage their physical formats. 27 170 </p> 28 171 29 <a asp-action="Products" 30 class="btn btn-primary"> 31 32 Manage Products 33 34 </a> 35 36 <a asp-action="CreateProduct" 37 class="btn btn-success"> 38 39 New Product 40 41 </a> 42 43 </div> 44 45 </div> 46 47 </div> 172 </div> 173 174 </div> 175 176 177 <div class="admin-action-grid"> 178 179 <!-- CREATE RELEASE --> 180 181 <a asp-action="CreateRelease" 182 class="admin-action-card"> 183 184 <div class="admin-action-icon"> 185 ♪ 186 </div> 187 188 <div> 189 190 <h3>Create Release</h3> 191 192 <p> 193 Create an album or single, 194 assign artists and add album tracks. 195 </p> 196 197 </div> 198 199 <span class="admin-action-arrow"> 200 → 201 </span> 202 203 </a> 204 205 206 <!-- CREATE PRODUCT --> 207 208 <a asp-action="CreateProduct" 209 class="admin-action-card"> 210 211 <div class="admin-action-icon"> 212 + 213 </div> 214 215 <div> 216 217 <h3>Create Product</h3> 218 219 <p> 220 Add vinyl, CD or cassette 221 editions to an existing release. 222 </p> 223 224 </div> 225 226 <span class="admin-action-arrow"> 227 → 228 </span> 229 230 </a> 231 232 233 <!-- MANAGE PRODUCTS --> 234 235 <a asp-action="Products" 236 class="admin-action-card"> 237 238 <div class="admin-action-icon"> 239 ◫ 240 </div> 241 242 <div> 243 244 <h3>Manage Products</h3> 245 246 <p> 247 Update pricing, inventory, 248 descriptions and discounts. 249 </p> 250 251 </div> 252 253 <span class="admin-action-arrow"> 254 → 255 </span> 256 257 </a> 258 259 </div> 260 261 </section> 262 263 264 <!-- ===================================================== 265 WORKFLOW INFO 266 ===================================================== --> 267 268 <section class="admin-section"> 269 270 <div class="admin-section-heading"> 271 272 <div> 273 274 <span class="admin-eyebrow"> 275 ADMIN WORKFLOW 276 </span> 277 278 <h2>Catalog Process</h2> 279 280 </div> 281 282 </div> 283 284 285 <div class="admin-workflow-grid"> 286 287 <div class="admin-workflow-card"> 288 289 <span class="admin-workflow-number"> 290 01 291 </span> 292 293 <div> 294 295 <strong> 296 Create Release 297 </strong> 298 299 <p> 300 Add the album or single, 301 artists and track information. 302 </p> 303 304 </div> 305 306 </div> 307 308 309 <div class="admin-workflow-card"> 310 311 <span class="admin-workflow-number"> 312 02 313 </span> 314 315 <div> 316 317 <strong> 318 Create Product 319 </strong> 320 321 <p> 322 Add its vinyl, CD or cassette 323 store edition. 324 </p> 325 326 </div> 327 328 </div> 329 330 331 <div class="admin-workflow-card"> 332 333 <span class="admin-workflow-number"> 334 03 335 </span> 336 337 <div> 338 339 <strong> 340 Manage Inventory 341 </strong> 342 343 <p> 344 Change prices, stock, 345 descriptions or apply discounts. 346 </p> 347 348 </div> 349 350 </div> 351 352 </div> 353 354 </section> 48 355 49 356 </div> -
KernelRecordsMVC.Web/Views/Admin/Products.cshtml
r08aefc6 rfa0fbaf 1 1 @model IEnumerable<KernelRecordsMVC.Models.Product> 2 2 3 <div class="d-flex justify-content-between align-items-center mb-4"> 4 5 <div> 6 7 <h1>Product Management</h1> 8 9 <p class="text-muted"> 10 Create and modify products in the store. 11 </p> 3 @{ 4 ViewData["Title"] = "Product Management"; 5 } 6 7 <div class="admin-page"> 8 9 <!-- HEADER --> 10 11 <div class="admin-header"> 12 13 <div> 14 15 <a asp-action="Index" 16 class="admin-back-link"> 17 18 ← Dashboard 19 20 </a> 21 22 <span class="admin-eyebrow"> 23 INVENTORY 24 </span> 25 26 <h1>Product Management</h1> 27 28 <p> 29 Manage formats, prices and inventory. 30 </p> 31 32 </div> 33 34 35 <a asp-action="CreateProduct" 36 class="admin-button primary"> 37 38 <span>+</span> 39 New Product 40 41 </a> 12 42 13 43 </div> 14 44 15 45 16 <a asp-action="CreateProduct" 17 class="btn btn-success"> 18 19 + New Product 20 21 </a> 46 @if (TempData["Success"] != null) 47 { 48 <div class="admin-alert success"> 49 50 <span>✓</span> 51 52 @TempData["Success"] 53 54 </div> 55 } 56 57 58 <!-- SUMMARY --> 59 60 <div class="admin-list-summary"> 61 62 <span> 63 @Model.Count() products 64 </span> 65 66 <span> 67 @Model.Count(x => x.Stock <= 0) out of stock 68 </span> 69 70 </div> 71 72 73 <!-- TABLE --> 74 75 <div class="admin-table-wrapper"> 76 77 <table class="admin-table"> 78 79 <thead> 80 81 <tr> 82 83 <th>Release</th> 84 85 <th>Format</th> 86 87 <th>Price</th> 88 89 <th>Stock</th> 90 91 <th>Status</th> 92 93 <th></th> 94 95 </tr> 96 97 </thead> 98 99 100 <tbody> 101 102 @foreach (var product in Model) 103 { 104 <tr> 105 106 <!-- RELEASE --> 107 108 <td> 109 110 <div class="admin-product-release"> 111 112 <div class="admin-product-cover"> 113 114 @if (!string.IsNullOrWhiteSpace( 115 product.Release.CoverPhoto)) 116 { 117 <img src="@product.Release.CoverPhoto" 118 alt="@product.Release.Title" /> 119 } 120 else 121 { 122 <span>♪</span> 123 } 124 125 </div> 126 127 128 <div> 129 130 <strong> 131 @product.Release.Title 132 </strong> 133 134 <small> 135 Product #@product.ProductId 136 </small> 137 138 </div> 139 140 </div> 141 142 </td> 143 144 145 <!-- FORMAT --> 146 147 <td> 148 149 <span class="admin-format-badge"> 150 @product.Format 151 </span> 152 153 </td> 154 155 156 <!-- PRICE --> 157 158 <td class="admin-price"> 159 160 @product.Price.ToString("C") 161 162 </td> 163 164 165 <!-- STOCK --> 166 167 <td> 168 169 <strong> 170 @product.Stock 171 </strong> 172 173 </td> 174 175 176 <!-- STATUS --> 177 178 <td> 179 180 @if (product.Stock <= 0) 181 { 182 <span class="admin-stock danger"> 183 Out of stock 184 </span> 185 } 186 else if (product.Stock <= 5) 187 { 188 <span class="admin-stock warning"> 189 Low stock 190 </span> 191 } 192 else 193 { 194 <span class="admin-stock success"> 195 In stock 196 </span> 197 } 198 199 </td> 200 201 202 <!-- ACTION --> 203 204 <td class="admin-table-action"> 205 206 <a asp-action="EditProduct" 207 asp-route-id="@product.ProductId" 208 class="admin-button secondary small"> 209 210 Modify 211 212 </a> 213 214 </td> 215 216 </tr> 217 } 218 219 </tbody> 220 221 </table> 222 223 </div> 22 224 23 225 </div> 24 25 26 @if (TempData["Success"] != null)27 {28 <div class="alert alert-success">29 30 @TempData["Success"]31 32 </div>33 }34 35 36 <div class="table-responsive">37 38 <table class="table table-hover align-middle">39 40 <thead>41 42 <tr>43 44 <th>Release</th>45 46 <th>Format</th>47 48 <th>Price</th>49 50 <th>Stock</th>51 52 <th></th>53 54 </tr>55 56 </thead>57 58 59 <tbody>60 61 @foreach (var product in Model)62 {63 <tr>64 65 <td>66 67 <strong>68 @product.Release.Title69 </strong>70 71 </td>72 73 74 <td>75 76 <span class="badge bg-secondary">77 78 @product.Format79 80 </span>81 82 </td>83 84 85 <td>86 87 $@product.Price.ToString("0.00")88 89 </td>90 91 92 <td>93 94 @if (product.Stock > 0)95 {96 <span class="text-success">97 98 @product.Stock99 100 </span>101 }102 else103 {104 <span class="text-danger">105 Out of stock106 </span>107 }108 109 </td>110 111 112 <td>113 114 <a asp-action="EditProduct"115 asp-route-id="@product.ProductId"116 class="btn btn-outline-primary">117 118 Modify119 120 </a>121 122 </td>123 124 </tr>125 }126 127 </tbody>128 129 </table>130 131 </div>
Note:
See TracChangeset
for help on using the changeset viewer.
