Write.cshtml 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. @page
  2. @model Admin.Pages.Store.Coupon.WriteModel
  3. @using Domain.Entities.Store.ValueObject
  4. @{
  5. ViewData["Title"] = "쿠폰 등록";
  6. }
  7. <div class="container">
  8. <h3>@ViewData["Title"]</h3>
  9. <hr />
  10. <partial name="_StatusMessage" />
  11. <div class="alert alert-info">
  12. 쿠폰 등록 후 <strong>코드 풀</strong> 화면에서 CSV 파일로 실제 코드를 업로드해주세요.<br />
  13. 쿠폰 상품에만 쿠폰 발급 가능합니다.
  14. </div>
  15. <form name="f_admin_write" id="fAdminWrite" method="post" accept-charset="utf-8" autocomplete="off">
  16. <div class="row mb-2">
  17. <label asp-for="Input.GameID" class="col-sm-2 col-form-label"><span>*</span> 게임</label>
  18. <div class="col-sm-10">
  19. <select asp-for="Input.GameID" asp-items="Model.Games" id="couponGameID" class="form-select" required>
  20. <option value="">게임을 선택하세요</option>
  21. </select>
  22. <span asp-validation-for="Input.GameID" class="text-danger"></span>
  23. </div>
  24. </div>
  25. <div class="row mb-2">
  26. <label asp-for="Input.ProductID" class="col-sm-2 col-form-label"><span>*</span> 쿠폰 상품</label>
  27. <div class="col-sm-10">
  28. <select asp-for="Input.ProductID" id="couponProductID" class="form-select" required>
  29. <option value="">게임을 먼저 선택하세요</option>
  30. </select>
  31. <span asp-validation-for="Input.ProductID" class="text-danger"></span>
  32. </div>
  33. </div>
  34. <div class="row mb-2">
  35. <label asp-for="Input.Name" class="col-sm-2 col-form-label"><span>*</span> 쿠폰명</label>
  36. <div class="col-sm-10">
  37. <input asp-for="Input.Name" class="form-control" required maxlength="200" placeholder="예) LOL RP 충전 쿠폰 1만원권 (200자 이내)" />
  38. <span asp-validation-for="Input.Name" class="text-danger"></span>
  39. </div>
  40. </div>
  41. <hr />
  42. <div class="row mb-2">
  43. <label asp-for="Input.UsagePolicy" class="col-sm-2 col-form-label">사용 정책</label>
  44. <div class="col-sm-10 align-content-center">
  45. <div class="form-check-inline">
  46. <input asp-for="Input.UsagePolicy" type="radio" id="usageSingle" class="form-check-input" value="@CouponUsagePolicy.SingleUse" />
  47. <label class="form-check-label" for="usageSingle">1회 사용 후 소진</label>
  48. </div>
  49. <div class="form-check-inline">
  50. <input asp-for="Input.UsagePolicy" type="radio" id="usageReusable" class="form-check-input" value="@CouponUsagePolicy.Reusable" />
  51. <label class="form-check-label" for="usageReusable">재사용 가능</label>
  52. </div>
  53. </div>
  54. </div>
  55. <div class="row mb-2">
  56. <label asp-for="Input.ExpiresAt" class="col-sm-2 col-form-label">만료 일시</label>
  57. <div class="col-sm-10">
  58. <input asp-for="Input.ExpiresAt" class="form-control w-auto" type="datetime-local" />
  59. <small class="form-text text-muted">비워두면 만료 없음</small>
  60. </div>
  61. </div>
  62. <div class="row mb-2">
  63. <label asp-for="Input.LowStockThreshold" class="col-sm-2 col-form-label">재고 알림 임계치</label>
  64. <div class="col-sm-10">
  65. <div class="row">
  66. <div class="col col-md-auto">
  67. <div class="input-group">
  68. <input asp-for="Input.LowStockThreshold" class="form-control" type="number" min="0" />
  69. <span class="input-group-text">개</span>
  70. </div>
  71. </div>
  72. </div>
  73. <small class="form-text text-muted">잔여 코드 수가 이 값 미만이면 목록에서 빨간색 표시</small>
  74. <span asp-validation-for="Input.LowStockThreshold" class="text-danger"></span>
  75. </div>
  76. </div>
  77. <hr />
  78. <div class="d-grid gap-2 text-center d-md-block">
  79. <button type="submit" class="btn btn-success">등록</button>
  80. <a href="/Store/Coupon" class="btn btn-secondary">취소</a>
  81. </div>
  82. <br />
  83. </form>
  84. </div>
  85. @section Scripts {
  86. <partial name="_ValidationScriptsPartial" />
  87. <script>
  88. var allProducts = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.Products.Select(p => new { id = p.ID, gameID = p.GameID, name = p.Name })));
  89. function refreshProducts() {
  90. var gameID = parseInt(document.getElementById("couponGameID").value) || 0;
  91. var sel = document.getElementById("couponProductID");
  92. sel.innerHTML = "";
  93. if (gameID === 0) {
  94. sel.innerHTML = '<option value="">게임을 먼저 선택하세요</option>';
  95. return;
  96. }
  97. var filtered = allProducts.filter(function(p) { return p.gameID === gameID; });
  98. if (filtered.length === 0) {
  99. sel.innerHTML = '<option value="">해당 게임의 쿠폰 상품이 없습니다</option>';
  100. return;
  101. }
  102. sel.innerHTML = '<option value="">상품을 선택하세요</option>';
  103. filtered.forEach(function(p) {
  104. var opt = document.createElement("option");
  105. opt.value = p.id;
  106. opt.textContent = p.name;
  107. sel.appendChild(opt);
  108. });
  109. }
  110. document.getElementById("couponGameID").addEventListener("change", refreshProducts);
  111. refreshProducts();
  112. </script>
  113. }