feat: 대전(daejeon)을 울산(ulsan)으로 개편 및 전체 7개 광역 지역(seoul, gyeonggi, incheon, gwangju, busan, daegu, ulsan) 세팅 완료
This commit is contained in:
@@ -0,0 +1,443 @@
|
||||
<template>
|
||||
<section id="consult-section" class="consult-section">
|
||||
<div class="consult-card">
|
||||
<div class="consult-header">
|
||||
<h2 class="consult-title">상담은 무료입니다</h2>
|
||||
<p class="consult-desc">연락처만 남기시면 확인하는 대로 연락드리겠습니다.</p>
|
||||
</div>
|
||||
|
||||
<div v-if="submitted" class="success-box">
|
||||
<h3 class="success-title">상담 신청이 정상적으로 완료되었습니다!</h3>
|
||||
<p class="success-desc">
|
||||
남겨주신 부모님 연락처(<strong>{{ form.parentPhone }}</strong>)로 전문 상담 팀장이 확인하는 대로 빠른 시일 내에 연락드리겠습니다.
|
||||
</p>
|
||||
<button type="button" class="btn-reset" @click="resetForm">추가 문의하기</button>
|
||||
</div>
|
||||
|
||||
<form v-else class="consult-form" @submit.prevent="handleSubmit">
|
||||
<div class="form-grid">
|
||||
<!-- 1행 좌: 학생 이름 -->
|
||||
<div class="form-group">
|
||||
<label for="c-student-name" class="form-label">학생 이름</label>
|
||||
<input
|
||||
id="c-student-name"
|
||||
v-model="form.studentName"
|
||||
type="text"
|
||||
placeholder="홍길동"
|
||||
required
|
||||
class="form-input"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 1행 우: 부모님 연락처 -->
|
||||
<div class="form-group">
|
||||
<label for="c-parent-phone" class="form-label">부모님 연락처</label>
|
||||
<input
|
||||
id="c-parent-phone"
|
||||
v-model="form.parentPhone"
|
||||
type="tel"
|
||||
placeholder="010-0000-0000"
|
||||
required
|
||||
class="form-input"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 2행 좌: 다니는 학교 -->
|
||||
<div class="form-group">
|
||||
<label for="c-school" class="form-label">다니는 학교</label>
|
||||
<input
|
||||
id="c-school"
|
||||
v-model="form.schoolName"
|
||||
type="text"
|
||||
placeholder="OO고등학교"
|
||||
class="form-input"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 2행 우: 학년 -->
|
||||
<div class="form-group">
|
||||
<label for="c-grade" class="form-label">학년</label>
|
||||
<div class="select-wrap">
|
||||
<select id="c-grade" v-model="form.grade" class="form-select" required>
|
||||
<option value="초등">초등</option>
|
||||
<option value="중1">중1</option>
|
||||
<option value="중2">중2</option>
|
||||
<option value="중3">중3</option>
|
||||
<option value="고1">고1</option>
|
||||
<option value="고2">고2</option>
|
||||
<option value="고3">고3</option>
|
||||
<option value="N수">N수</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3행 전체: 사는 곳 -->
|
||||
<div class="form-group full-width">
|
||||
<label for="c-location" class="form-label">사는 곳</label>
|
||||
<input
|
||||
id="c-location"
|
||||
v-model="form.location"
|
||||
type="text"
|
||||
:placeholder="regionName || '행복시 행복동'"
|
||||
class="form-input"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 4행 전체: 상담문의 내용 (선택) -->
|
||||
<div class="form-group full-width">
|
||||
<label for="c-memo" class="form-label">상담문의 내용 (선택)</label>
|
||||
<textarea
|
||||
id="c-memo"
|
||||
v-model="form.memo"
|
||||
rows="4"
|
||||
placeholder="지금 등급, 어려운 과목, 원하는 시간대 같은 것을 적어 주시면 상담이 빨라집니다."
|
||||
class="form-textarea"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 개인정보 수집 동의 -->
|
||||
<div class="privacy-wrap">
|
||||
<label class="privacy-label">
|
||||
<input type="checkbox" v-model="form.agree" required class="privacy-checkbox" />
|
||||
<span>상담을 위해 학생 이름과 부모님 연락처를 받는 데 동의합니다. 받은 정보는 상담 외에 쓰지 않습니다.</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- 버튼 그룹 -->
|
||||
<div class="button-group">
|
||||
<button type="submit" class="btn-submit" :disabled="loading">
|
||||
<span v-if="loading">문의 전송 중...</span>
|
||||
<span v-else>문의 보내기</span>
|
||||
</button>
|
||||
<a href="tel:010-5961-5807" class="btn-call">
|
||||
전화로 바로 상담
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
regionName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
defaultGrade: {
|
||||
type: String,
|
||||
default: '고1'
|
||||
},
|
||||
defaultSubject: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
function resolveGrade(g) {
|
||||
if (!g) return '고1'
|
||||
if (g.includes('고1') || g.includes('고등학교 1')) return '고1'
|
||||
if (g.includes('고2') || g.includes('고등학교 2')) return '고2'
|
||||
if (g.includes('고3') || g.includes('고등학교 3')) return '고3'
|
||||
if (g.includes('중1') || g.includes('중학교 1')) return '중1'
|
||||
if (g.includes('중2') || g.includes('중학교 2')) return '중2'
|
||||
if (g.includes('중3') || g.includes('중학교 3')) return '중3'
|
||||
if (g.includes('초등')) return '초등'
|
||||
if (g.includes('고등')) return '고1'
|
||||
if (g.includes('중등') || g.includes('중학')) return '중2'
|
||||
return '고1'
|
||||
}
|
||||
|
||||
const form = ref({
|
||||
studentName: '',
|
||||
parentPhone: '',
|
||||
schoolName: '',
|
||||
grade: resolveGrade(props.defaultGrade),
|
||||
location: props.regionName || '',
|
||||
memo: '',
|
||||
agree: false
|
||||
})
|
||||
|
||||
watch(() => props.defaultGrade, (newVal) => {
|
||||
if (newVal) form.value.grade = resolveGrade(newVal)
|
||||
})
|
||||
|
||||
watch(() => props.regionName, (newVal) => {
|
||||
if (newVal && !form.value.location) form.value.location = newVal
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
const submitted = ref(false)
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!form.value.parentPhone) return
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
const currentUrl = typeof window !== 'undefined' ? window.location.href : ''
|
||||
await $fetch('/api/consult', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
studentName: form.value.studentName,
|
||||
parentPhone: form.value.parentPhone,
|
||||
schoolName: form.value.schoolName,
|
||||
grade: form.value.grade,
|
||||
location: form.value.location || props.regionName,
|
||||
memo: form.value.memo,
|
||||
url: currentUrl
|
||||
}
|
||||
})
|
||||
submitted.value = true
|
||||
} catch (err) {
|
||||
console.error('상담 신청 전송:', err)
|
||||
submitted.value = true
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
form.value = {
|
||||
studentName: '',
|
||||
parentPhone: '',
|
||||
schoolName: '',
|
||||
grade: resolveGrade(props.defaultGrade),
|
||||
location: props.regionName || '',
|
||||
memo: '',
|
||||
agree: false
|
||||
}
|
||||
submitted.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.consult-section {
|
||||
width: 100%;
|
||||
padding: clamp(35px, 6vw, 65px) 16px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.consult-card {
|
||||
width: 100%;
|
||||
max-width: 580px;
|
||||
background: #f7fdfd;
|
||||
border: 1px solid #99f6e4;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 10px 30px rgba(13, 148, 136, 0.1);
|
||||
padding: clamp(24px, 5vw, 40px) clamp(20px, 4vw, 36px);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.consult-header {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.consult-title {
|
||||
font-size: clamp(1.45rem, 3.5vw, 1.85rem);
|
||||
font-weight: 800;
|
||||
color: #0f766e;
|
||||
letter-spacing: -0.5px;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.consult-desc {
|
||||
font-size: clamp(0.88rem, 2.2vw, 0.98rem);
|
||||
color: #115e59;
|
||||
line-height: 1.5;
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.form-group.full-width {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
color: #134e4a;
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
|
||||
.form-input,
|
||||
.form-select,
|
||||
.form-textarea {
|
||||
width: 100%;
|
||||
padding: 12px 14px;
|
||||
font-size: 0.95rem;
|
||||
font-family: inherit;
|
||||
color: #1e293b;
|
||||
background: #ffffff;
|
||||
border: 1px solid #ccfbf1;
|
||||
border-radius: 12px;
|
||||
outline: none;
|
||||
transition: all 0.2s ease;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-input::placeholder,
|
||||
.form-textarea::placeholder {
|
||||
color: #94a3b8;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.form-input:focus,
|
||||
.form-select:focus,
|
||||
.form-textarea:focus {
|
||||
border-color: #0d9488;
|
||||
box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.2);
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.select-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 14px center;
|
||||
padding-right: 36px;
|
||||
}
|
||||
|
||||
.form-textarea {
|
||||
resize: vertical;
|
||||
min-height: 90px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.privacy-wrap {
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
|
||||
.privacy-label {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
font-size: 0.82rem;
|
||||
color: #0f766e;
|
||||
line-height: 1.45;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.privacy-checkbox {
|
||||
margin-top: 3px;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
accent-color: #0d9488;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
width: 100%;
|
||||
padding: 16px 20px;
|
||||
font-size: 1.08rem;
|
||||
font-weight: 800;
|
||||
color: #ffffff;
|
||||
background: #0d9488;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
letter-spacing: -0.3px;
|
||||
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.btn-submit:hover:not(:disabled) {
|
||||
background: #0f766e;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
|
||||
.btn-submit:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.btn-call {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 15px 20px;
|
||||
font-size: 1.02rem;
|
||||
font-weight: 800;
|
||||
text-align: center;
|
||||
color: #0f766e;
|
||||
background: #f0fdfa;
|
||||
border: 2px solid #0d9488;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
letter-spacing: -0.3px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.btn-call:hover {
|
||||
background: #ccfbf1;
|
||||
}
|
||||
|
||||
.success-box {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.success-title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 800;
|
||||
color: #0f766e;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.success-desc {
|
||||
font-size: 0.95rem;
|
||||
color: #475569;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.btn-reset {
|
||||
padding: 10px 24px;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 700;
|
||||
color: #0d9488;
|
||||
background: transparent;
|
||||
border: 1px solid #0d9488;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
.form-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user