create.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <template>
  2. <div class="admin--branch-form">
  3. <form @submit.prevent="handleSubmit" class="admin--form">
  4. <!-- 지점명 -->
  5. <div class="admin--form-group">
  6. <label class="admin--form-label"
  7. >딜러사 명 <span class="admin--required">*</span></label
  8. >
  9. <input
  10. v-model="formData.name"
  11. type="text"
  12. class="admin--form-input"
  13. placeholder="지점명을 입력하세요"
  14. required
  15. />
  16. </div>
  17. <!-- 대표번호 -->
  18. <!-- <div class="admin--form-group">
  19. <label class="admin--form-label">대표번호 <span class="admin--required">*</span></label>
  20. <input
  21. v-model="formData.phone"
  22. type="tel"
  23. class="admin--form-input"
  24. placeholder="02-1234-5678"
  25. required
  26. >
  27. </div> -->
  28. <!-- 주소 -->
  29. <!-- <div class="admin--form-group">
  30. <label class="admin--form-label">주소 <span class="admin--required">*</span></label>
  31. <input
  32. v-model="formData.address"
  33. type="text"
  34. class="admin--form-input"
  35. placeholder="주소를 입력하세요"
  36. required
  37. >
  38. </div> -->
  39. <!-- 상세주소 -->
  40. <!-- <div class="admin--form-group">
  41. <label class="admin--form-label">상세주소</label>
  42. <input
  43. v-model="formData.detail_address"
  44. type="text"
  45. class="admin--form-input"
  46. placeholder="상세주소를 입력하세요"
  47. >
  48. </div> -->
  49. <!-- 위도/경도 -->
  50. <!-- <div class="admin--form-group">
  51. <label class="admin--form-label">위치 좌표</label>
  52. <div class="admin--coordinate-group">
  53. <div class="admin--coordinate-item">
  54. <label>위도</label>
  55. <input
  56. v-model.number="formData.latitude"
  57. type="number"
  58. step="any"
  59. class="admin--form-input"
  60. placeholder="37.5665"
  61. >
  62. </div>
  63. <div class="admin--coordinate-item">
  64. <label>경도</label>
  65. <input
  66. v-model.number="formData.longitude"
  67. type="number"
  68. step="any"
  69. class="admin--form-input"
  70. placeholder="126.9780"
  71. >
  72. </div>
  73. </div>
  74. </div> -->
  75. <!-- 영업시간 -->
  76. <!-- <div class="admin--form-group">
  77. <label class="admin--form-label">영업시간</label>
  78. <textarea
  79. v-model="formData.business_hours"
  80. class="admin--form-textarea"
  81. rows="3"
  82. placeholder="평일: 09:00 - 18:00&#10;주말: 10:00 - 17:00"
  83. ></textarea>
  84. </div> -->
  85. <!-- 버튼 영역 -->
  86. <div class="admin--form-actions">
  87. <button type="submit" class="admin--btn admin--btn-primary" :disabled="isSaving">
  88. {{ isSaving ? "저장 중..." : "확인" }}
  89. </button>
  90. <button type="button" class="admin--btn admin--btn-secondary" @click="goToList">
  91. 목록
  92. </button>
  93. </div>
  94. <!-- 성공/에러 메시지 -->
  95. <div v-if="successMessage" class="admin--alert admin--alert-success">
  96. {{ successMessage }}
  97. </div>
  98. <div v-if="errorMessage" class="admin--alert admin--alert-error">
  99. {{ errorMessage }}
  100. </div>
  101. </form>
  102. </div>
  103. </template>
  104. <script setup>
  105. import { ref } from "vue";
  106. import { useRouter } from "vue-router";
  107. definePageMeta({
  108. layout: "admin",
  109. middleware: ["auth"],
  110. });
  111. const router = useRouter();
  112. const { post } = useApi();
  113. const isSaving = ref(false);
  114. const successMessage = ref("");
  115. const errorMessage = ref("");
  116. const formData = ref({
  117. name: "",
  118. // phone: "",
  119. // address: "",
  120. // detail_address: "",
  121. //latitude: null,
  122. //longitude: null,
  123. //business_hours: "",
  124. });
  125. // 폼 제출
  126. const handleSubmit = async () => {
  127. successMessage.value = "";
  128. errorMessage.value = "";
  129. // 유효성 검사
  130. if (!formData.value.name) {
  131. errorMessage.value = "딜러사 명을 입력하세요.";
  132. return;
  133. }
  134. // if (!formData.value.phone) {
  135. // errorMessage.value = "대표번호를 입력하세요.";
  136. // return;
  137. // }
  138. // if (!formData.value.address) {
  139. // errorMessage.value = "주소를 입력하세요.";
  140. // return;
  141. // }
  142. isSaving.value = true;
  143. try {
  144. const { data, error } = await post("/branch", formData.value);
  145. if (error || !data?.success) {
  146. errorMessage.value = error?.message || data?.message || "등록에 실패했습니다.";
  147. } else {
  148. successMessage.value = data.message || "지점이 등록되었습니다.";
  149. setTimeout(() => {
  150. router.push("/site-manager/branch/list");
  151. }, 1000);
  152. }
  153. } catch (error) {
  154. errorMessage.value = "서버 오류가 발생했습니다.";
  155. console.error("Save error:", error);
  156. } finally {
  157. isSaving.value = false;
  158. }
  159. };
  160. // 목록으로 이동
  161. const goToList = () => {
  162. router.push("/site-manager/branch/list");
  163. };
  164. </script>
  165. <style scoped>
  166. .admin--coordinate-group {
  167. display: flex;
  168. gap: 16px;
  169. }
  170. .admin--coordinate-item {
  171. flex: 1;
  172. }
  173. .admin--coordinate-item label {
  174. display: block;
  175. margin-bottom: 8px;
  176. font-size: 14px;
  177. color: #666;
  178. }
  179. </style>