ui 개선 완료
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<header class="bg-white/95 backdrop-blur-md border-b border-slate-200/80 sticky top-0 z-40 w-full transition-all">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between">
|
||||
<NuxtLink to="/" class="flex items-center gap-3 no-underline">
|
||||
<div class="w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white font-extrabold text-base shadow-sm">
|
||||
{{ logoLetter }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-extrabold text-lg sm:text-xl tracking-tight text-slate-900">{{ currentSiteName }}</span>
|
||||
<span class="hidden sm:inline-flex items-center text-[11px] font-semibold text-blue-700 bg-blue-50 px-2.5 py-0.5 rounded-full border border-blue-100">
|
||||
교육청 등록 협력
|
||||
</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="tel:010-5961-5807" class="hidden sm:flex items-center gap-1.5 text-sm font-semibold text-slate-600 hover:text-blue-600 transition no-underline">
|
||||
<i class="fa-solid fa-phone text-blue-600 text-xs"></i>
|
||||
<span>010-5961-5807</span>
|
||||
</a>
|
||||
<a href="#consult-section" class="bg-blue-600 hover:bg-blue-700 text-white text-xs sm:text-sm font-bold px-4 sm:px-5 py-2.5 rounded-xl transition shadow-sm hover:shadow flex items-center gap-1.5 no-underline">
|
||||
<span>무료 시범수업 신청</span>
|
||||
<i class="fa-solid fa-arrow-right text-[11px]"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
siteName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const currentSiteName = computed(() => {
|
||||
return props.siteName || config.public?.siteName || '1:1 맞춤과외'
|
||||
})
|
||||
|
||||
const logoLetter = computed(() => {
|
||||
const name = currentSiteName.value.trim()
|
||||
return name.charAt(0) || 'T'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
font-family: inherit;
|
||||
}
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@
|
||||
<!-- 신뢰 보증 뱃지 -->
|
||||
<div class="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full text-xs font-semibold bg-slate-50 border border-slate-200 text-slate-700 shadow-xs mb-5">
|
||||
<span class="w-2 h-2 rounded-full bg-blue-600"></span>
|
||||
<span>{{ region.dong }} 학군 전담 | 서울대·부산대 및 베테랑 강사진 100% 신원 보증</span>
|
||||
<span>{{ region.dong }} 학군 전담 | 서울대·연고대 및 베테랑 강사진 100% 신원 보증</span>
|
||||
</div>
|
||||
|
||||
<!-- SEO 메인 H1 (사용자 지정 롱테일 조합형: [지역] + [학년] + [과목]과외 + 검증된 전문 선생님 100% 매칭) -->
|
||||
@@ -46,7 +46,7 @@
|
||||
<i class="fa-solid fa-circle-check text-blue-600 text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-slate-900">과외 비용 투명 시세</strong>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">부산 표준 시세 가이드</span>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">동네 표준 시세 가이드</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -74,12 +74,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 실시간 접수 롤링 바 -->
|
||||
<div class="inline-flex items-center gap-2.5 bg-slate-100/90 border border-slate-200/80 rounded-full px-4 py-1.5 text-xs text-slate-600 shadow-xs mb-6">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span class="font-bold text-slate-700">실시간 매칭</span>
|
||||
<span class="text-slate-300">|</span>
|
||||
<span class="truncate max-w-[260px] sm:max-w-md font-medium text-slate-600">{{ currentNotice }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 태그 목록 -->
|
||||
<div class="flex justify-center flex-wrap gap-1.5">
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}{{ subjectName }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ grade }}내신대비</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#부산해운대과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#과외비용시세</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#1대1무료시범수업</span>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +96,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -109,6 +117,33 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const noticeIdx = ref(0)
|
||||
let timer = null
|
||||
|
||||
const notices = computed(() => {
|
||||
const d = props.region?.dong || '관내'
|
||||
const sub = props.subjectName || '과목'
|
||||
const grd = props.grade || '중학생'
|
||||
return [
|
||||
`${d} ${grd} ${sub} 1:1 맞춤 전담 선생님 매칭 완료`,
|
||||
`${d} 내신 1등급 도약 무료 시범수업 신청 접수 중`,
|
||||
`${d} 학교별 3개년 기출 족보 분석 자료 배부 완료`,
|
||||
`${d} 취약 단원 집중 클리닉 및 모의수업 예약 마감 임박`
|
||||
]
|
||||
})
|
||||
|
||||
const currentNotice = computed(() => notices.value[noticeIdx.value % notices.value.length])
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
noticeIdx.value = (noticeIdx.value + 1) % notices.value.length
|
||||
}, 3500)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
const displayRegionName = computed(() => {
|
||||
if (props.shortRegionName) return props.shortRegionName
|
||||
if (props.region) {
|
||||
@@ -116,9 +151,9 @@ const displayRegionName = computed(() => {
|
||||
const dong = props.region.dong || ''
|
||||
if (sido && dong) {
|
||||
let shortSido = sido.slice(0, 2)
|
||||
if (sido.includes('부산')) shortSido = '부산'
|
||||
else if (sido.includes('서울')) shortSido = '서울'
|
||||
if (sido.includes('서울')) shortSido = '서울'
|
||||
else if (sido.includes('대구')) shortSido = '대구'
|
||||
else if (sido.includes('부산')) shortSido = '부산'
|
||||
else if (sido.includes('인천')) shortSido = '인천'
|
||||
else if (sido.includes('광주')) shortSido = '광주'
|
||||
else if (sido.includes('대전')) shortSido = '대전'
|
||||
|
||||
+27
-38
@@ -1,13 +1,28 @@
|
||||
<template>
|
||||
<div class="landing-page-wrap">
|
||||
<!-- 1. 광고 랜딩 전용 지역 식별 바 (외부 이탈 링크 없음) -->
|
||||
<div class="ad-location-bar">
|
||||
<span class="loc-badge-tag">[지역센터]</span>
|
||||
<span class="loc-text">{{ parsed.shortRegionName }} ({{ parsed.sigungu }}) 관내 초·중·고 전담</span>
|
||||
<span class="loc-tag">1:1 맞춤 배정 센터</span>
|
||||
<template>
|
||||
<div class="landing-page-wrap bg-[#F8FAFC] min-h-screen text-slate-800 antialiased">
|
||||
<!-- 1. 클린 미니멀 프리미엄 네비게이션 헤더 (기본 홈과 동일) -->
|
||||
<AppHeader :siteName="siteName" />
|
||||
|
||||
<!-- 2. 세련된 지역 센터 식별 서브 바 (모던 칩 배너) -->
|
||||
<div class="bg-blue-50/70 border-b border-blue-100/70 py-2.5 px-4">
|
||||
<div class="max-w-4xl mx-auto flex items-center justify-between flex-wrap gap-2 text-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 font-bold text-blue-700 bg-white px-2.5 py-0.5 rounded-full border border-blue-200/80 shadow-xs">
|
||||
<i class="fa-solid fa-location-dot text-blue-600 text-[10px]"></i>
|
||||
{{ parsed.shortRegionName }} 센터
|
||||
</span>
|
||||
<span class="text-slate-600 font-medium">
|
||||
{{ parsed.dong }} ({{ parsed.sigungu }}) 관내 초·중·고 1:1 맞춤 전담
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden sm:flex items-center gap-1 text-slate-500 font-medium">
|
||||
<i class="fa-solid fa-shield-check text-emerald-600 text-xs"></i>
|
||||
<span>검증된 전문 선생님 100% 매칭</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 상단 히어로 배너 (Header 제거, H1 태그 포함) -->
|
||||
<!-- 3. 상단 히어로 배너 (H1 태그 포함) -->
|
||||
<HeroBanner
|
||||
:region="parsed.region"
|
||||
:shortRegionName="parsed.shortRegionName"
|
||||
@@ -82,6 +97,9 @@
|
||||
:defaultGrade="parsed.grade"
|
||||
:defaultSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 14. 클린 사이트 푸터 -->
|
||||
<AppFooter />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -92,6 +110,7 @@ import { generateSeoMeta } from '~/utils/seoHelper'
|
||||
|
||||
const route = useRoute()
|
||||
const config = useRuntimeConfig()
|
||||
const siteName = config.public?.siteName || '공부짝꿍'
|
||||
|
||||
// URL 파라미터 파싱
|
||||
const slug = route.params.slug
|
||||
@@ -122,34 +141,4 @@ useHead({
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ad-location-bar {
|
||||
max-width: 1080px;
|
||||
margin: 10px auto;
|
||||
padding: 8px 16px;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
color: #334155;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.loc-pin {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.loc-text {
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
}
|
||||
|
||||
.loc-tag {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 800;
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<header class="bg-white/95 backdrop-blur-md border-b border-slate-200/80 sticky top-0 z-40 w-full transition-all">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between">
|
||||
<NuxtLink to="/" class="flex items-center gap-3 no-underline">
|
||||
<div class="w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white font-extrabold text-base shadow-sm">
|
||||
{{ logoLetter }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-extrabold text-lg sm:text-xl tracking-tight text-slate-900">{{ currentSiteName }}</span>
|
||||
<span class="hidden sm:inline-flex items-center text-[11px] font-semibold text-blue-700 bg-blue-50 px-2.5 py-0.5 rounded-full border border-blue-100">
|
||||
교육청 등록 협력
|
||||
</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="tel:010-5961-5807" class="hidden sm:flex items-center gap-1.5 text-sm font-semibold text-slate-600 hover:text-blue-600 transition no-underline">
|
||||
<i class="fa-solid fa-phone text-blue-600 text-xs"></i>
|
||||
<span>010-5961-5807</span>
|
||||
</a>
|
||||
<a href="#consult-section" class="bg-blue-600 hover:bg-blue-700 text-white text-xs sm:text-sm font-bold px-4 sm:px-5 py-2.5 rounded-xl transition shadow-sm hover:shadow flex items-center gap-1.5 no-underline">
|
||||
<span>무료 시범수업 신청</span>
|
||||
<i class="fa-solid fa-arrow-right text-[11px]"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
siteName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const currentSiteName = computed(() => {
|
||||
return props.siteName || config.public?.siteName || '1:1 맞춤과외'
|
||||
})
|
||||
|
||||
const logoLetter = computed(() => {
|
||||
const name = currentSiteName.value.trim()
|
||||
return name.charAt(0) || 'T'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
font-family: inherit;
|
||||
}
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@
|
||||
<!-- 신뢰 보증 뱃지 -->
|
||||
<div class="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full text-xs font-semibold bg-slate-50 border border-slate-200 text-slate-700 shadow-xs mb-5">
|
||||
<span class="w-2 h-2 rounded-full bg-blue-600"></span>
|
||||
<span>{{ region.dong }} 학군 전담 | 서울대·경북대 및 베테랑 강사진 100% 신원 보증</span>
|
||||
<span>{{ region.dong }} 학군 전담 | 서울대·연고대 및 베테랑 강사진 100% 신원 보증</span>
|
||||
</div>
|
||||
|
||||
<!-- SEO 메인 H1 (사용자 지정 롱테일 조합형: [지역] + [학년] + [과목]과외 + 검증된 전문 선생님 100% 매칭) -->
|
||||
@@ -46,7 +46,7 @@
|
||||
<i class="fa-solid fa-circle-check text-blue-600 text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-slate-900">과외 비용 투명 시세</strong>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">대구 표준 시세 가이드</span>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">동네 표준 시세 가이드</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -74,12 +74,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 실시간 접수 롤링 바 -->
|
||||
<div class="inline-flex items-center gap-2.5 bg-slate-100/90 border border-slate-200/80 rounded-full px-4 py-1.5 text-xs text-slate-600 shadow-xs mb-6">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span class="font-bold text-slate-700">실시간 매칭</span>
|
||||
<span class="text-slate-300">|</span>
|
||||
<span class="truncate max-w-[260px] sm:max-w-md font-medium text-slate-600">{{ currentNotice }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 태그 목록 -->
|
||||
<div class="flex justify-center flex-wrap gap-1.5">
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}{{ subjectName }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ grade }}내신대비</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#대구수성구과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#과외비용시세</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#1대1무료시범수업</span>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +96,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -109,6 +117,33 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const noticeIdx = ref(0)
|
||||
let timer = null
|
||||
|
||||
const notices = computed(() => {
|
||||
const d = props.region?.dong || '관내'
|
||||
const sub = props.subjectName || '과목'
|
||||
const grd = props.grade || '중학생'
|
||||
return [
|
||||
`${d} ${grd} ${sub} 1:1 맞춤 전담 선생님 매칭 완료`,
|
||||
`${d} 내신 1등급 도약 무료 시범수업 신청 접수 중`,
|
||||
`${d} 학교별 3개년 기출 족보 분석 자료 배부 완료`,
|
||||
`${d} 취약 단원 집중 클리닉 및 모의수업 예약 마감 임박`
|
||||
]
|
||||
})
|
||||
|
||||
const currentNotice = computed(() => notices.value[noticeIdx.value % notices.value.length])
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
noticeIdx.value = (noticeIdx.value + 1) % notices.value.length
|
||||
}, 3500)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
const displayRegionName = computed(() => {
|
||||
if (props.shortRegionName) return props.shortRegionName
|
||||
if (props.region) {
|
||||
@@ -116,8 +151,8 @@ const displayRegionName = computed(() => {
|
||||
const dong = props.region.dong || ''
|
||||
if (sido && dong) {
|
||||
let shortSido = sido.slice(0, 2)
|
||||
if (sido.includes('대구')) shortSido = '대구'
|
||||
else if (sido.includes('서울')) shortSido = '서울'
|
||||
if (sido.includes('서울')) shortSido = '서울'
|
||||
else if (sido.includes('대구')) shortSido = '대구'
|
||||
else if (sido.includes('부산')) shortSido = '부산'
|
||||
else if (sido.includes('인천')) shortSido = '인천'
|
||||
else if (sido.includes('광주')) shortSido = '광주'
|
||||
|
||||
+27
-38
@@ -1,13 +1,28 @@
|
||||
<template>
|
||||
<div class="landing-page-wrap">
|
||||
<!-- 1. 광고 랜딩 전용 지역 식별 바 (외부 이탈 링크 없음) -->
|
||||
<div class="ad-location-bar">
|
||||
<span class="loc-badge-tag">[지역센터]</span>
|
||||
<span class="loc-text">{{ parsed.shortRegionName }} ({{ parsed.sigungu }}) 관내 초·중·고 전담</span>
|
||||
<span class="loc-tag">1:1 맞춤 배정 센터</span>
|
||||
<template>
|
||||
<div class="landing-page-wrap bg-[#F8FAFC] min-h-screen text-slate-800 antialiased">
|
||||
<!-- 1. 클린 미니멀 프리미엄 네비게이션 헤더 (기본 홈과 동일) -->
|
||||
<AppHeader :siteName="siteName" />
|
||||
|
||||
<!-- 2. 세련된 지역 센터 식별 서브 바 (모던 칩 배너) -->
|
||||
<div class="bg-blue-50/70 border-b border-blue-100/70 py-2.5 px-4">
|
||||
<div class="max-w-4xl mx-auto flex items-center justify-between flex-wrap gap-2 text-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 font-bold text-blue-700 bg-white px-2.5 py-0.5 rounded-full border border-blue-200/80 shadow-xs">
|
||||
<i class="fa-solid fa-location-dot text-blue-600 text-[10px]"></i>
|
||||
{{ parsed.shortRegionName }} 센터
|
||||
</span>
|
||||
<span class="text-slate-600 font-medium">
|
||||
{{ parsed.dong }} ({{ parsed.sigungu }}) 관내 초·중·고 1:1 맞춤 전담
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden sm:flex items-center gap-1 text-slate-500 font-medium">
|
||||
<i class="fa-solid fa-shield-check text-emerald-600 text-xs"></i>
|
||||
<span>검증된 전문 선생님 100% 매칭</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 상단 히어로 배너 (Header 제거, H1 태그 포함) -->
|
||||
<!-- 3. 상단 히어로 배너 (H1 태그 포함) -->
|
||||
<HeroBanner
|
||||
:region="parsed.region"
|
||||
:shortRegionName="parsed.shortRegionName"
|
||||
@@ -82,6 +97,9 @@
|
||||
:defaultGrade="parsed.grade"
|
||||
:defaultSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 14. 클린 사이트 푸터 -->
|
||||
<AppFooter />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -92,6 +110,7 @@ import { generateSeoMeta } from '~/utils/seoHelper'
|
||||
|
||||
const route = useRoute()
|
||||
const config = useRuntimeConfig()
|
||||
const siteName = config.public?.siteName || '티처브릿지'
|
||||
|
||||
// URL 파라미터 파싱
|
||||
const slug = route.params.slug
|
||||
@@ -122,34 +141,4 @@ useHead({
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ad-location-bar {
|
||||
max-width: 1080px;
|
||||
margin: 10px auto;
|
||||
padding: 8px 16px;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
color: #334155;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.loc-pin {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.loc-text {
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
}
|
||||
|
||||
.loc-tag {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 800;
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<header class="bg-white/95 backdrop-blur-md border-b border-slate-200/80 sticky top-0 z-40 w-full transition-all">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between">
|
||||
<NuxtLink to="/" class="flex items-center gap-3 no-underline">
|
||||
<div class="w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white font-extrabold text-base shadow-sm">
|
||||
{{ logoLetter }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-extrabold text-lg sm:text-xl tracking-tight text-slate-900">{{ currentSiteName }}</span>
|
||||
<span class="hidden sm:inline-flex items-center text-[11px] font-semibold text-blue-700 bg-blue-50 px-2.5 py-0.5 rounded-full border border-blue-100">
|
||||
교육청 등록 협력
|
||||
</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="tel:010-5961-5807" class="hidden sm:flex items-center gap-1.5 text-sm font-semibold text-slate-600 hover:text-blue-600 transition no-underline">
|
||||
<i class="fa-solid fa-phone text-blue-600 text-xs"></i>
|
||||
<span>010-5961-5807</span>
|
||||
</a>
|
||||
<a href="#consult-section" class="bg-blue-600 hover:bg-blue-700 text-white text-xs sm:text-sm font-bold px-4 sm:px-5 py-2.5 rounded-xl transition shadow-sm hover:shadow flex items-center gap-1.5 no-underline">
|
||||
<span>무료 시범수업 신청</span>
|
||||
<i class="fa-solid fa-arrow-right text-[11px]"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
siteName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const currentSiteName = computed(() => {
|
||||
return props.siteName || config.public?.siteName || '1:1 맞춤과외'
|
||||
})
|
||||
|
||||
const logoLetter = computed(() => {
|
||||
const name = currentSiteName.value.trim()
|
||||
return name.charAt(0) || 'T'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
font-family: inherit;
|
||||
}
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@
|
||||
<!-- 신뢰 보증 뱃지 -->
|
||||
<div class="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full text-xs font-semibold bg-slate-50 border border-slate-200 text-slate-700 shadow-xs mb-5">
|
||||
<span class="w-2 h-2 rounded-full bg-blue-600"></span>
|
||||
<span>{{ region.dong }} 학군 전담 | 서울대·전남대 및 베테랑 강사진 100% 신원 보증</span>
|
||||
<span>{{ region.dong }} 학군 전담 | 서울대·연고대 및 베테랑 강사진 100% 신원 보증</span>
|
||||
</div>
|
||||
|
||||
<!-- SEO 메인 H1 (사용자 지정 롱테일 조합형: [지역] + [학년] + [과목]과외 + 검증된 전문 선생님 100% 매칭) -->
|
||||
@@ -46,7 +46,7 @@
|
||||
<i class="fa-solid fa-circle-check text-blue-600 text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-slate-900">과외 비용 투명 시세</strong>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">광주 표준 시세 가이드</span>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">동네 표준 시세 가이드</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -74,12 +74,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 실시간 접수 롤링 바 -->
|
||||
<div class="inline-flex items-center gap-2.5 bg-slate-100/90 border border-slate-200/80 rounded-full px-4 py-1.5 text-xs text-slate-600 shadow-xs mb-6">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span class="font-bold text-slate-700">실시간 매칭</span>
|
||||
<span class="text-slate-300">|</span>
|
||||
<span class="truncate max-w-[260px] sm:max-w-md font-medium text-slate-600">{{ currentNotice }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 태그 목록 -->
|
||||
<div class="flex justify-center flex-wrap gap-1.5">
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}{{ subjectName }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ grade }}내신대비</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#광주봉선동과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#과외비용시세</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#1대1무료시범수업</span>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +96,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -109,6 +117,33 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const noticeIdx = ref(0)
|
||||
let timer = null
|
||||
|
||||
const notices = computed(() => {
|
||||
const d = props.region?.dong || '관내'
|
||||
const sub = props.subjectName || '과목'
|
||||
const grd = props.grade || '중학생'
|
||||
return [
|
||||
`${d} ${grd} ${sub} 1:1 맞춤 전담 선생님 매칭 완료`,
|
||||
`${d} 내신 1등급 도약 무료 시범수업 신청 접수 중`,
|
||||
`${d} 학교별 3개년 기출 족보 분석 자료 배부 완료`,
|
||||
`${d} 취약 단원 집중 클리닉 및 모의수업 예약 마감 임박`
|
||||
]
|
||||
})
|
||||
|
||||
const currentNotice = computed(() => notices.value[noticeIdx.value % notices.value.length])
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
noticeIdx.value = (noticeIdx.value + 1) % notices.value.length
|
||||
}, 3500)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
const displayRegionName = computed(() => {
|
||||
if (props.shortRegionName) return props.shortRegionName
|
||||
if (props.region) {
|
||||
@@ -116,9 +151,9 @@ const displayRegionName = computed(() => {
|
||||
const dong = props.region.dong || ''
|
||||
if (sido && dong) {
|
||||
let shortSido = sido.slice(0, 2)
|
||||
if (sido.includes('부산')) shortSido = '부산'
|
||||
else if (sido.includes('서울')) shortSido = '서울'
|
||||
if (sido.includes('서울')) shortSido = '서울'
|
||||
else if (sido.includes('대구')) shortSido = '대구'
|
||||
else if (sido.includes('부산')) shortSido = '부산'
|
||||
else if (sido.includes('인천')) shortSido = '인천'
|
||||
else if (sido.includes('광주')) shortSido = '광주'
|
||||
else if (sido.includes('대전')) shortSido = '대전'
|
||||
|
||||
+27
-45
@@ -1,13 +1,28 @@
|
||||
<template>
|
||||
<div class="landing-page-wrap">
|
||||
<!-- 1. 광고 랜딩 전용 지역 식별 바 (외부 이탈 링크 없음) -->
|
||||
<div class="ad-location-bar">
|
||||
<span class="loc-badge-tag">[지역센터]</span>
|
||||
<span class="loc-text">{{ parsed.shortRegionName }} ({{ parsed.sigungu }}) 관내 초·중·고 전담</span>
|
||||
<span class="loc-tag">1:1 맞춤 배정 센터</span>
|
||||
<template>
|
||||
<div class="landing-page-wrap bg-[#F8FAFC] min-h-screen text-slate-800 antialiased">
|
||||
<!-- 1. 클린 미니멀 프리미엄 네비게이션 헤더 (기본 홈과 동일) -->
|
||||
<AppHeader :siteName="siteName" />
|
||||
|
||||
<!-- 2. 세련된 지역 센터 식별 서브 바 (모던 칩 배너) -->
|
||||
<div class="bg-blue-50/70 border-b border-blue-100/70 py-2.5 px-4">
|
||||
<div class="max-w-4xl mx-auto flex items-center justify-between flex-wrap gap-2 text-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 font-bold text-blue-700 bg-white px-2.5 py-0.5 rounded-full border border-blue-200/80 shadow-xs">
|
||||
<i class="fa-solid fa-location-dot text-blue-600 text-[10px]"></i>
|
||||
{{ parsed.shortRegionName }} 센터
|
||||
</span>
|
||||
<span class="text-slate-600 font-medium">
|
||||
{{ parsed.dong }} ({{ parsed.sigungu }}) 관내 초·중·고 1:1 맞춤 전담
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden sm:flex items-center gap-1 text-slate-500 font-medium">
|
||||
<i class="fa-solid fa-shield-check text-emerald-600 text-xs"></i>
|
||||
<span>검증된 전문 선생님 100% 매칭</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 상단 히어로 배너 (Header 제거, H1 태그 포함) -->
|
||||
<!-- 3. 상단 히어로 배너 (H1 태그 포함) -->
|
||||
<HeroBanner
|
||||
:region="parsed.region"
|
||||
:shortRegionName="parsed.shortRegionName"
|
||||
@@ -76,19 +91,15 @@
|
||||
:subjectName="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 12. 과목별 1타 강사진 갤러리 캐러셀 (클릭 시 페이지 모달 확대 및 상담 연동) -->
|
||||
<SubjectCarousel
|
||||
:regionDong="parsed.dong"
|
||||
:grade="parsed.grade"
|
||||
:currentSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 웹 광고 단일 목적: 해당 학년과 과목이 기본 선택된 무료 상담 신청 폼 -->
|
||||
<ConsultForm
|
||||
:regionName="parsed.shortRegionName"
|
||||
:defaultGrade="parsed.grade"
|
||||
:defaultSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 14. 클린 사이트 푸터 -->
|
||||
<AppFooter />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -99,6 +110,7 @@ import { generateSeoMeta } from '~/utils/seoHelper'
|
||||
|
||||
const route = useRoute()
|
||||
const config = useRuntimeConfig()
|
||||
const siteName = config.public?.siteName || '클래스픽'
|
||||
|
||||
// URL 파라미터 파싱
|
||||
const slug = route.params.slug
|
||||
@@ -129,34 +141,4 @@ useHead({
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ad-location-bar {
|
||||
max-width: 1080px;
|
||||
margin: 10px auto;
|
||||
padding: 8px 16px;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
color: #334155;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.loc-pin {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.loc-text {
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
}
|
||||
|
||||
.loc-tag {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 800;
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<header class="bg-white/95 backdrop-blur-md border-b border-slate-200/80 sticky top-0 z-40 w-full transition-all">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between">
|
||||
<NuxtLink to="/" class="flex items-center gap-3 no-underline">
|
||||
<div class="w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white font-extrabold text-base shadow-sm">
|
||||
{{ logoLetter }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-extrabold text-lg sm:text-xl tracking-tight text-slate-900">{{ currentSiteName }}</span>
|
||||
<span class="hidden sm:inline-flex items-center text-[11px] font-semibold text-blue-700 bg-blue-50 px-2.5 py-0.5 rounded-full border border-blue-100">
|
||||
교육청 등록 협력
|
||||
</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="tel:010-5961-5807" class="hidden sm:flex items-center gap-1.5 text-sm font-semibold text-slate-600 hover:text-blue-600 transition no-underline">
|
||||
<i class="fa-solid fa-phone text-blue-600 text-xs"></i>
|
||||
<span>010-5961-5807</span>
|
||||
</a>
|
||||
<a href="#consult-section" class="bg-blue-600 hover:bg-blue-700 text-white text-xs sm:text-sm font-bold px-4 sm:px-5 py-2.5 rounded-xl transition shadow-sm hover:shadow flex items-center gap-1.5 no-underline">
|
||||
<span>무료 시범수업 신청</span>
|
||||
<i class="fa-solid fa-arrow-right text-[11px]"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
siteName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const currentSiteName = computed(() => {
|
||||
return props.siteName || config.public?.siteName || '1:1 맞춤과외'
|
||||
})
|
||||
|
||||
const logoLetter = computed(() => {
|
||||
const name = currentSiteName.value.trim()
|
||||
return name.charAt(0) || 'T'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
font-family: inherit;
|
||||
}
|
||||
</style>
|
||||
@@ -74,6 +74,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 실시간 접수 롤링 바 -->
|
||||
<div class="inline-flex items-center gap-2.5 bg-slate-100/90 border border-slate-200/80 rounded-full px-4 py-1.5 text-xs text-slate-600 shadow-xs mb-6">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span class="font-bold text-slate-700">실시간 매칭</span>
|
||||
<span class="text-slate-300">|</span>
|
||||
<span class="truncate max-w-[260px] sm:max-w-md font-medium text-slate-600">{{ currentNotice }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 태그 목록 -->
|
||||
<div class="flex justify-center flex-wrap gap-1.5">
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}과외</span>
|
||||
@@ -88,7 +96,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -109,6 +117,33 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const noticeIdx = ref(0)
|
||||
let timer = null
|
||||
|
||||
const notices = computed(() => {
|
||||
const d = props.region?.dong || '관내'
|
||||
const sub = props.subjectName || '과목'
|
||||
const grd = props.grade || '중학생'
|
||||
return [
|
||||
`${d} ${grd} ${sub} 1:1 맞춤 전담 선생님 매칭 완료`,
|
||||
`${d} 내신 1등급 도약 무료 시범수업 신청 접수 중`,
|
||||
`${d} 학교별 3개년 기출 족보 분석 자료 배부 완료`,
|
||||
`${d} 취약 단원 집중 클리닉 및 모의수업 예약 마감 임박`
|
||||
]
|
||||
})
|
||||
|
||||
const currentNotice = computed(() => notices.value[noticeIdx.value % notices.value.length])
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
noticeIdx.value = (noticeIdx.value + 1) % notices.value.length
|
||||
}, 3500)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
const displayRegionName = computed(() => {
|
||||
if (props.shortRegionName) return props.shortRegionName
|
||||
if (props.region) {
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
<template>
|
||||
<div class="landing-page-wrap">
|
||||
<!-- 1. 광고 랜딩 전용 지역 식별 바 (외부 이탈 링크 없음) -->
|
||||
<div class="ad-location-bar">
|
||||
<span class="loc-badge-tag">[지역센터]</span>
|
||||
<span class="loc-text">{{ parsed.shortRegionName }} ({{ parsed.sigungu }}) 관내 초·중·고 전담</span>
|
||||
<span class="loc-tag">1:1 맞춤 배정 센터</span>
|
||||
<template>
|
||||
<div class="landing-page-wrap bg-[#F8FAFC] min-h-screen text-slate-800 antialiased">
|
||||
<!-- 1. 클린 미니멀 프리미엄 네비게이션 헤더 (기본 홈과 동일) -->
|
||||
<AppHeader :siteName="siteName" />
|
||||
|
||||
<!-- 2. 세련된 지역 센터 식별 서브 바 (모던 칩 배너) -->
|
||||
<div class="bg-blue-50/70 border-b border-blue-100/70 py-2.5 px-4">
|
||||
<div class="max-w-4xl mx-auto flex items-center justify-between flex-wrap gap-2 text-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 font-bold text-blue-700 bg-white px-2.5 py-0.5 rounded-full border border-blue-200/80 shadow-xs">
|
||||
<i class="fa-solid fa-location-dot text-blue-600 text-[10px]"></i>
|
||||
{{ parsed.shortRegionName }} 센터
|
||||
</span>
|
||||
<span class="text-slate-600 font-medium">
|
||||
{{ parsed.dong }} ({{ parsed.sigungu }}) 관내 초·중·고 1:1 맞춤 전담
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden sm:flex items-center gap-1 text-slate-500 font-medium">
|
||||
<i class="fa-solid fa-shield-check text-emerald-600 text-xs"></i>
|
||||
<span>검증된 전문 선생님 100% 매칭</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 상단 히어로 배너 (Header 제거, H1 태그 포함) -->
|
||||
<!-- 3. 상단 히어로 배너 (H1 태그 포함) -->
|
||||
<HeroBanner
|
||||
:region="parsed.region"
|
||||
:shortRegionName="parsed.shortRegionName"
|
||||
@@ -76,19 +91,15 @@
|
||||
:subjectName="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 12. 과목별 1타 강사진 갤러리 캐러셀 (클릭 시 페이지 모달 확대 및 상담 연동) -->
|
||||
<SubjectCarousel
|
||||
:regionDong="parsed.dong"
|
||||
:grade="parsed.grade"
|
||||
:currentSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 웹 광고 단일 목적: 해당 학년과 과목이 기본 선택된 무료 상담 신청 폼 -->
|
||||
<ConsultForm
|
||||
:regionName="parsed.shortRegionName"
|
||||
:defaultGrade="parsed.grade"
|
||||
:defaultSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 14. 클린 사이트 푸터 -->
|
||||
<AppFooter />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -99,6 +110,7 @@ import { generateSeoMeta } from '~/utils/seoHelper'
|
||||
|
||||
const route = useRoute()
|
||||
const config = useRuntimeConfig()
|
||||
const siteName = config.public?.siteName || '새솔 1:1 맞춤과외'
|
||||
|
||||
// URL 파라미터 파싱
|
||||
const slug = route.params.slug
|
||||
@@ -129,34 +141,4 @@ useHead({
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ad-location-bar {
|
||||
max-width: 1080px;
|
||||
margin: 10px auto;
|
||||
padding: 8px 16px;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
color: #334155;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.loc-pin {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.loc-text {
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
}
|
||||
|
||||
.loc-tag {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 800;
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<header class="bg-white/95 backdrop-blur-md border-b border-slate-200/80 sticky top-0 z-40 w-full transition-all">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between">
|
||||
<NuxtLink to="/" class="flex items-center gap-3 no-underline">
|
||||
<div class="w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white font-extrabold text-base shadow-sm">
|
||||
{{ logoLetter }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-extrabold text-lg sm:text-xl tracking-tight text-slate-900">{{ currentSiteName }}</span>
|
||||
<span class="hidden sm:inline-flex items-center text-[11px] font-semibold text-blue-700 bg-blue-50 px-2.5 py-0.5 rounded-full border border-blue-100">
|
||||
교육청 등록 협력
|
||||
</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="tel:010-5961-5807" class="hidden sm:flex items-center gap-1.5 text-sm font-semibold text-slate-600 hover:text-blue-600 transition no-underline">
|
||||
<i class="fa-solid fa-phone text-blue-600 text-xs"></i>
|
||||
<span>010-5961-5807</span>
|
||||
</a>
|
||||
<a href="#consult-section" class="bg-blue-600 hover:bg-blue-700 text-white text-xs sm:text-sm font-bold px-4 sm:px-5 py-2.5 rounded-xl transition shadow-sm hover:shadow flex items-center gap-1.5 no-underline">
|
||||
<span>무료 시범수업 신청</span>
|
||||
<i class="fa-solid fa-arrow-right text-[11px]"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
siteName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const currentSiteName = computed(() => {
|
||||
return props.siteName || config.public?.siteName || '1:1 맞춤과외'
|
||||
})
|
||||
|
||||
const logoLetter = computed(() => {
|
||||
const name = currentSiteName.value.trim()
|
||||
return name.charAt(0) || 'T'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
font-family: inherit;
|
||||
}
|
||||
</style>
|
||||
@@ -74,6 +74,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 실시간 접수 롤링 바 -->
|
||||
<div class="inline-flex items-center gap-2.5 bg-slate-100/90 border border-slate-200/80 rounded-full px-4 py-1.5 text-xs text-slate-600 shadow-xs mb-6">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span class="font-bold text-slate-700">실시간 매칭</span>
|
||||
<span class="text-slate-300">|</span>
|
||||
<span class="truncate max-w-[260px] sm:max-w-md font-medium text-slate-600">{{ currentNotice }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 태그 목록 -->
|
||||
<div class="flex justify-center flex-wrap gap-1.5">
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}과외</span>
|
||||
@@ -88,7 +96,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -109,6 +117,33 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const noticeIdx = ref(0)
|
||||
let timer = null
|
||||
|
||||
const notices = computed(() => {
|
||||
const d = props.region?.dong || '관내'
|
||||
const sub = props.subjectName || '과목'
|
||||
const grd = props.grade || '중학생'
|
||||
return [
|
||||
`${d} ${grd} ${sub} 1:1 맞춤 전담 선생님 매칭 완료`,
|
||||
`${d} 내신 1등급 도약 무료 시범수업 신청 접수 중`,
|
||||
`${d} 학교별 3개년 기출 족보 분석 자료 배부 완료`,
|
||||
`${d} 취약 단원 집중 클리닉 및 모의수업 예약 마감 임박`
|
||||
]
|
||||
})
|
||||
|
||||
const currentNotice = computed(() => notices.value[noticeIdx.value % notices.value.length])
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
noticeIdx.value = (noticeIdx.value + 1) % notices.value.length
|
||||
}, 3500)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
const displayRegionName = computed(() => {
|
||||
if (props.shortRegionName) return props.shortRegionName
|
||||
if (props.region) {
|
||||
|
||||
+27
-45
@@ -1,13 +1,28 @@
|
||||
<template>
|
||||
<div class="landing-page-wrap">
|
||||
<!-- 1. 광고 랜딩 전용 지역 식별 바 (외부 이탈 링크 없음) -->
|
||||
<div class="ad-location-bar">
|
||||
<span class="loc-badge-tag">[지역센터]</span>
|
||||
<span class="loc-text">{{ parsed.shortRegionName }} ({{ parsed.sigungu }}) 관내 초·중·고 전담</span>
|
||||
<span class="loc-tag">1:1 맞춤 배정 센터</span>
|
||||
<template>
|
||||
<div class="landing-page-wrap bg-[#F8FAFC] min-h-screen text-slate-800 antialiased">
|
||||
<!-- 1. 클린 미니멀 프리미엄 네비게이션 헤더 (기본 홈과 동일) -->
|
||||
<AppHeader :siteName="siteName" />
|
||||
|
||||
<!-- 2. 세련된 지역 센터 식별 서브 바 (모던 칩 배너) -->
|
||||
<div class="bg-blue-50/70 border-b border-blue-100/70 py-2.5 px-4">
|
||||
<div class="max-w-4xl mx-auto flex items-center justify-between flex-wrap gap-2 text-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 font-bold text-blue-700 bg-white px-2.5 py-0.5 rounded-full border border-blue-200/80 shadow-xs">
|
||||
<i class="fa-solid fa-location-dot text-blue-600 text-[10px]"></i>
|
||||
{{ parsed.shortRegionName }} 센터
|
||||
</span>
|
||||
<span class="text-slate-600 font-medium">
|
||||
{{ parsed.dong }} ({{ parsed.sigungu }}) 관내 초·중·고 1:1 맞춤 전담
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden sm:flex items-center gap-1 text-slate-500 font-medium">
|
||||
<i class="fa-solid fa-shield-check text-emerald-600 text-xs"></i>
|
||||
<span>검증된 전문 선생님 100% 매칭</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 상단 히어로 배너 (Header 제거, H1 태그 포함) -->
|
||||
<!-- 3. 상단 히어로 배너 (H1 태그 포함) -->
|
||||
<HeroBanner
|
||||
:region="parsed.region"
|
||||
:shortRegionName="parsed.shortRegionName"
|
||||
@@ -76,19 +91,15 @@
|
||||
:subjectName="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 12. 과목별 1타 강사진 갤러리 캐러셀 (클릭 시 페이지 모달 확대 및 상담 연동) -->
|
||||
<SubjectCarousel
|
||||
:regionDong="parsed.dong"
|
||||
:grade="parsed.grade"
|
||||
:currentSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 웹 광고 단일 목적: 해당 학년과 과목이 기본 선택된 무료 상담 신청 폼 -->
|
||||
<ConsultForm
|
||||
:regionName="parsed.shortRegionName"
|
||||
:defaultGrade="parsed.grade"
|
||||
:defaultSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 14. 클린 사이트 푸터 -->
|
||||
<AppFooter />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -99,6 +110,7 @@ import { generateSeoMeta } from '~/utils/seoHelper'
|
||||
|
||||
const route = useRoute()
|
||||
const config = useRuntimeConfig()
|
||||
const siteName = config.public?.siteName || '튜터온'
|
||||
|
||||
// URL 파라미터 파싱
|
||||
const slug = route.params.slug
|
||||
@@ -129,34 +141,4 @@ useHead({
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ad-location-bar {
|
||||
max-width: 1080px;
|
||||
margin: 10px auto;
|
||||
padding: 8px 16px;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
color: #334155;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.loc-pin {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.loc-text {
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
}
|
||||
|
||||
.loc-tag {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 800;
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<header class="bg-white/95 backdrop-blur-md border-b border-slate-200/80 sticky top-0 z-40 w-full transition-all">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between">
|
||||
<NuxtLink to="/" class="flex items-center gap-3 no-underline">
|
||||
<div class="w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white font-extrabold text-base shadow-sm">
|
||||
{{ logoLetter }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-extrabold text-lg sm:text-xl tracking-tight text-slate-900">{{ currentSiteName }}</span>
|
||||
<span class="hidden sm:inline-flex items-center text-[11px] font-semibold text-blue-700 bg-blue-50 px-2.5 py-0.5 rounded-full border border-blue-100">
|
||||
교육청 등록 협력
|
||||
</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="tel:010-5961-5807" class="hidden sm:flex items-center gap-1.5 text-sm font-semibold text-slate-600 hover:text-blue-600 transition no-underline">
|
||||
<i class="fa-solid fa-phone text-blue-600 text-xs"></i>
|
||||
<span>010-5961-5807</span>
|
||||
</a>
|
||||
<a href="#consult-section" class="bg-blue-600 hover:bg-blue-700 text-white text-xs sm:text-sm font-bold px-4 sm:px-5 py-2.5 rounded-xl transition shadow-sm hover:shadow flex items-center gap-1.5 no-underline">
|
||||
<span>무료 시범수업 신청</span>
|
||||
<i class="fa-solid fa-arrow-right text-[11px]"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
siteName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const currentSiteName = computed(() => {
|
||||
return props.siteName || config.public?.siteName || '1:1 맞춤과외'
|
||||
})
|
||||
|
||||
const logoLetter = computed(() => {
|
||||
const name = currentSiteName.value.trim()
|
||||
return name.charAt(0) || 'T'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
font-family: inherit;
|
||||
}
|
||||
</style>
|
||||
@@ -74,6 +74,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 실시간 접수 롤링 바 -->
|
||||
<div class="inline-flex items-center gap-2.5 bg-slate-100/90 border border-slate-200/80 rounded-full px-4 py-1.5 text-xs text-slate-600 shadow-xs mb-6">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span class="font-bold text-slate-700">실시간 매칭</span>
|
||||
<span class="text-slate-300">|</span>
|
||||
<span class="truncate max-w-[260px] sm:max-w-md font-medium text-slate-600">{{ currentNotice }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 태그 목록 -->
|
||||
<div class="flex justify-center flex-wrap gap-1.5">
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}과외</span>
|
||||
@@ -88,7 +96,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -109,6 +117,33 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const noticeIdx = ref(0)
|
||||
let timer = null
|
||||
|
||||
const notices = computed(() => {
|
||||
const d = props.region?.dong || '관내'
|
||||
const sub = props.subjectName || '과목'
|
||||
const grd = props.grade || '중학생'
|
||||
return [
|
||||
`${d} ${grd} ${sub} 1:1 맞춤 전담 선생님 매칭 완료`,
|
||||
`${d} 내신 1등급 도약 무료 시범수업 신청 접수 중`,
|
||||
`${d} 학교별 3개년 기출 족보 분석 자료 배부 완료`,
|
||||
`${d} 취약 단원 집중 클리닉 및 모의수업 예약 마감 임박`
|
||||
]
|
||||
})
|
||||
|
||||
const currentNotice = computed(() => notices.value[noticeIdx.value % notices.value.length])
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
noticeIdx.value = (noticeIdx.value + 1) % notices.value.length
|
||||
}, 3500)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
const displayRegionName = computed(() => {
|
||||
if (props.shortRegionName) return props.shortRegionName
|
||||
if (props.region) {
|
||||
|
||||
+26
-37
@@ -1,13 +1,28 @@
|
||||
<template>
|
||||
<div class="landing-page-wrap">
|
||||
<!-- 1. 광고 랜딩 전용 지역 식별 바 (외부 이탈 링크 없음) -->
|
||||
<div class="ad-location-bar">
|
||||
<span class="loc-badge-tag">[지역센터]</span>
|
||||
<span class="loc-text">{{ parsed.shortRegionName }} ({{ parsed.sigungu }}) 관내 초·중·고 전담</span>
|
||||
<span class="loc-tag">1:1 맞춤 배정 센터</span>
|
||||
<div class="landing-page-wrap bg-[#F8FAFC] min-h-screen text-slate-800 antialiased">
|
||||
<!-- 1. 클린 미니멀 프리미엄 네비게이션 헤더 (기본 홈과 동일) -->
|
||||
<AppHeader :siteName="siteName" />
|
||||
|
||||
<!-- 2. 세련된 지역 센터 식별 서브 바 (모던 칩 배너) -->
|
||||
<div class="bg-blue-50/70 border-b border-blue-100/70 py-2.5 px-4">
|
||||
<div class="max-w-4xl mx-auto flex items-center justify-between flex-wrap gap-2 text-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 font-bold text-blue-700 bg-white px-2.5 py-0.5 rounded-full border border-blue-200/80 shadow-xs">
|
||||
<i class="fa-solid fa-location-dot text-blue-600 text-[10px]"></i>
|
||||
{{ parsed.shortRegionName }} 센터
|
||||
</span>
|
||||
<span class="text-slate-600 font-medium">
|
||||
{{ parsed.dong }} ({{ parsed.sigungu }}) 관내 초·중·고 1:1 맞춤 전담
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden sm:flex items-center gap-1 text-slate-500 font-medium">
|
||||
<i class="fa-solid fa-shield-check text-emerald-600 text-xs"></i>
|
||||
<span>검증된 전문 선생님 100% 매칭</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 상단 히어로 배너 (Header 제거, H1 태그 포함) -->
|
||||
<!-- 3. 상단 히어로 배너 (H1 태그 포함) -->
|
||||
<HeroBanner
|
||||
:region="parsed.region"
|
||||
:shortRegionName="parsed.shortRegionName"
|
||||
@@ -82,6 +97,9 @@
|
||||
:defaultGrade="parsed.grade"
|
||||
:defaultSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 14. 클린 사이트 푸터 -->
|
||||
<AppFooter />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -92,6 +110,7 @@ import { generateSeoMeta } from '~/utils/seoHelper'
|
||||
|
||||
const route = useRoute()
|
||||
const config = useRuntimeConfig()
|
||||
const siteName = config.public?.siteName || '로열클래스 1:1 과외'
|
||||
|
||||
// URL 파라미터 파싱
|
||||
const slug = route.params.slug
|
||||
@@ -122,34 +141,4 @@ useHead({
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ad-location-bar {
|
||||
max-width: 1080px;
|
||||
margin: 10px auto;
|
||||
padding: 8px 16px;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
color: #334155;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.loc-pin {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.loc-text {
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
}
|
||||
|
||||
.loc-tag {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 800;
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<header class="bg-white/95 backdrop-blur-md border-b border-slate-200/80 sticky top-0 z-40 w-full transition-all">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between">
|
||||
<NuxtLink to="/" class="flex items-center gap-3 no-underline">
|
||||
<div class="w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white font-extrabold text-base shadow-sm">
|
||||
{{ logoLetter }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-extrabold text-lg sm:text-xl tracking-tight text-slate-900">{{ currentSiteName }}</span>
|
||||
<span class="hidden sm:inline-flex items-center text-[11px] font-semibold text-blue-700 bg-blue-50 px-2.5 py-0.5 rounded-full border border-blue-100">
|
||||
교육청 등록 협력
|
||||
</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="tel:010-5961-5807" class="hidden sm:flex items-center gap-1.5 text-sm font-semibold text-slate-600 hover:text-blue-600 transition no-underline">
|
||||
<i class="fa-solid fa-phone text-blue-600 text-xs"></i>
|
||||
<span>010-5961-5807</span>
|
||||
</a>
|
||||
<a href="#consult-section" class="bg-blue-600 hover:bg-blue-700 text-white text-xs sm:text-sm font-bold px-4 sm:px-5 py-2.5 rounded-xl transition shadow-sm hover:shadow flex items-center gap-1.5 no-underline">
|
||||
<span>무료 시범수업 신청</span>
|
||||
<i class="fa-solid fa-arrow-right text-[11px]"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
siteName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const currentSiteName = computed(() => {
|
||||
return props.siteName || config.public?.siteName || '1:1 맞춤과외'
|
||||
})
|
||||
|
||||
const logoLetter = computed(() => {
|
||||
const name = currentSiteName.value.trim()
|
||||
return name.charAt(0) || 'T'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
font-family: inherit;
|
||||
}
|
||||
</style>
|
||||
@@ -74,6 +74,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 실시간 접수 롤링 바 -->
|
||||
<div class="inline-flex items-center gap-2.5 bg-slate-100/90 border border-slate-200/80 rounded-full px-4 py-1.5 text-xs text-slate-600 shadow-xs mb-6">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span class="font-bold text-slate-700">실시간 매칭</span>
|
||||
<span class="text-slate-300">|</span>
|
||||
<span class="truncate max-w-[260px] sm:max-w-md font-medium text-slate-600">{{ currentNotice }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 태그 목록 -->
|
||||
<div class="flex justify-center flex-wrap gap-1.5">
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}과외</span>
|
||||
@@ -88,7 +96,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -109,6 +117,33 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const noticeIdx = ref(0)
|
||||
let timer = null
|
||||
|
||||
const notices = computed(() => {
|
||||
const d = props.region?.dong || '관내'
|
||||
const sub = props.subjectName || '과목'
|
||||
const grd = props.grade || '중학생'
|
||||
return [
|
||||
`${d} ${grd} ${sub} 1:1 맞춤 전담 선생님 매칭 완료`,
|
||||
`${d} 내신 1등급 도약 무료 시범수업 신청 접수 중`,
|
||||
`${d} 학교별 3개년 기출 족보 분석 자료 배부 완료`,
|
||||
`${d} 취약 단원 집중 클리닉 및 모의수업 예약 마감 임박`
|
||||
]
|
||||
})
|
||||
|
||||
const currentNotice = computed(() => notices.value[noticeIdx.value % notices.value.length])
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
noticeIdx.value = (noticeIdx.value + 1) % notices.value.length
|
||||
}, 3500)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
const displayRegionName = computed(() => {
|
||||
if (props.shortRegionName) return props.shortRegionName
|
||||
if (props.region) {
|
||||
|
||||
+27
-38
@@ -1,13 +1,28 @@
|
||||
<template>
|
||||
<div class="landing-page-wrap">
|
||||
<!-- 1. 광고 랜딩 전용 지역 식별 바 (외부 이탈 링크 없음) -->
|
||||
<div class="ad-location-bar">
|
||||
<span class="loc-badge-tag">[지역센터]</span>
|
||||
<span class="loc-text">{{ parsed.shortRegionName }} ({{ parsed.sigungu }}) 관내 초·중·고 전담</span>
|
||||
<span class="loc-tag">1:1 맞춤 배정 센터</span>
|
||||
<template>
|
||||
<div class="landing-page-wrap bg-[#F8FAFC] min-h-screen text-slate-800 antialiased">
|
||||
<!-- 1. 클린 미니멀 프리미엄 네비게이션 헤더 (기본 홈과 동일) -->
|
||||
<AppHeader :siteName="siteName" />
|
||||
|
||||
<!-- 2. 세련된 지역 센터 식별 서브 바 (모던 칩 배너) -->
|
||||
<div class="bg-blue-50/70 border-b border-blue-100/70 py-2.5 px-4">
|
||||
<div class="max-w-4xl mx-auto flex items-center justify-between flex-wrap gap-2 text-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 font-bold text-blue-700 bg-white px-2.5 py-0.5 rounded-full border border-blue-200/80 shadow-xs">
|
||||
<i class="fa-solid fa-location-dot text-blue-600 text-[10px]"></i>
|
||||
{{ parsed.shortRegionName }} 센터
|
||||
</span>
|
||||
<span class="text-slate-600 font-medium">
|
||||
{{ parsed.dong }} ({{ parsed.sigungu }}) 관내 초·중·고 1:1 맞춤 전담
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden sm:flex items-center gap-1 text-slate-500 font-medium">
|
||||
<i class="fa-solid fa-shield-check text-emerald-600 text-xs"></i>
|
||||
<span>검증된 전문 선생님 100% 매칭</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 상단 히어로 배너 (Header 제거, H1 태그 포함) -->
|
||||
<!-- 3. 상단 히어로 배너 (H1 태그 포함) -->
|
||||
<HeroBanner
|
||||
:region="parsed.region"
|
||||
:shortRegionName="parsed.shortRegionName"
|
||||
@@ -82,6 +97,9 @@
|
||||
:defaultGrade="parsed.grade"
|
||||
:defaultSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 14. 클린 사이트 푸터 -->
|
||||
<AppFooter />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -92,6 +110,7 @@ import { generateSeoMeta } from '~/utils/seoHelper'
|
||||
|
||||
const route = useRoute()
|
||||
const config = useRuntimeConfig()
|
||||
const siteName = config.public?.siteName || '로열클래스 1:1 과외'
|
||||
|
||||
// URL 파라미터 파싱
|
||||
const slug = route.params.slug
|
||||
@@ -122,34 +141,4 @@ useHead({
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ad-location-bar {
|
||||
max-width: 1080px;
|
||||
margin: 10px auto;
|
||||
padding: 8px 16px;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
color: #334155;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.loc-pin {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.loc-text {
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
}
|
||||
|
||||
.loc-tag {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 800;
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<header class="bg-white/95 backdrop-blur-md border-b border-slate-200/80 sticky top-0 z-40 w-full transition-all">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between">
|
||||
<NuxtLink to="/" class="flex items-center gap-3 no-underline">
|
||||
<div class="w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white font-extrabold text-base shadow-sm">
|
||||
{{ logoLetter }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-extrabold text-lg sm:text-xl tracking-tight text-slate-900">{{ currentSiteName }}</span>
|
||||
<span class="hidden sm:inline-flex items-center text-[11px] font-semibold text-blue-700 bg-blue-50 px-2.5 py-0.5 rounded-full border border-blue-100">
|
||||
교육청 등록 협력
|
||||
</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="tel:010-5961-5807" class="hidden sm:flex items-center gap-1.5 text-sm font-semibold text-slate-600 hover:text-blue-600 transition no-underline">
|
||||
<i class="fa-solid fa-phone text-blue-600 text-xs"></i>
|
||||
<span>010-5961-5807</span>
|
||||
</a>
|
||||
<a href="#consult-section" class="bg-blue-600 hover:bg-blue-700 text-white text-xs sm:text-sm font-bold px-4 sm:px-5 py-2.5 rounded-xl transition shadow-sm hover:shadow flex items-center gap-1.5 no-underline">
|
||||
<span>무료 시범수업 신청</span>
|
||||
<i class="fa-solid fa-arrow-right text-[11px]"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
siteName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const currentSiteName = computed(() => {
|
||||
return props.siteName || config.public?.siteName || '1:1 맞춤과외'
|
||||
})
|
||||
|
||||
const logoLetter = computed(() => {
|
||||
const name = currentSiteName.value.trim()
|
||||
return name.charAt(0) || 'T'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
font-family: inherit;
|
||||
}
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@
|
||||
<!-- 신뢰 보증 뱃지 -->
|
||||
<div class="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full text-xs font-semibold bg-slate-50 border border-slate-200 text-slate-700 shadow-xs mb-5">
|
||||
<span class="w-2 h-2 rounded-full bg-blue-600"></span>
|
||||
<span>{{ region.dong }} 학군 전담 | 서울대·UNIST 및 베테랑 강사진 100% 신원 보증</span>
|
||||
<span>{{ region.dong }} 학군 전담 | 서울대·연고대 및 베테랑 강사진 100% 신원 보증</span>
|
||||
</div>
|
||||
|
||||
<!-- SEO 메인 H1 (사용자 지정 롱테일 조합형: [지역] + [학년] + [과목]과외 + 검증된 전문 선생님 100% 매칭) -->
|
||||
@@ -46,7 +46,7 @@
|
||||
<i class="fa-solid fa-circle-check text-blue-600 text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-slate-900">과외 비용 투명 시세</strong>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">울산 표준 시세 가이드</span>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">동네 표준 시세 가이드</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -74,12 +74,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 실시간 접수 롤링 바 -->
|
||||
<div class="inline-flex items-center gap-2.5 bg-slate-100/90 border border-slate-200/80 rounded-full px-4 py-1.5 text-xs text-slate-600 shadow-xs mb-6">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span class="font-bold text-slate-700">실시간 매칭</span>
|
||||
<span class="text-slate-300">|</span>
|
||||
<span class="truncate max-w-[260px] sm:max-w-md font-medium text-slate-600">{{ currentNotice }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 태그 목록 -->
|
||||
<div class="flex justify-center flex-wrap gap-1.5">
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}{{ subjectName }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ grade }}내신대비</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#울산옥동과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#과외비용시세</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#1대1무료시범수업</span>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +96,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -109,6 +117,33 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const noticeIdx = ref(0)
|
||||
let timer = null
|
||||
|
||||
const notices = computed(() => {
|
||||
const d = props.region?.dong || '관내'
|
||||
const sub = props.subjectName || '과목'
|
||||
const grd = props.grade || '중학생'
|
||||
return [
|
||||
`${d} ${grd} ${sub} 1:1 맞춤 전담 선생님 매칭 완료`,
|
||||
`${d} 내신 1등급 도약 무료 시범수업 신청 접수 중`,
|
||||
`${d} 학교별 3개년 기출 족보 분석 자료 배부 완료`,
|
||||
`${d} 취약 단원 집중 클리닉 및 모의수업 예약 마감 임박`
|
||||
]
|
||||
})
|
||||
|
||||
const currentNotice = computed(() => notices.value[noticeIdx.value % notices.value.length])
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
noticeIdx.value = (noticeIdx.value + 1) % notices.value.length
|
||||
}, 3500)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
const displayRegionName = computed(() => {
|
||||
if (props.shortRegionName) return props.shortRegionName
|
||||
if (props.region) {
|
||||
@@ -116,9 +151,9 @@ const displayRegionName = computed(() => {
|
||||
const dong = props.region.dong || ''
|
||||
if (sido && dong) {
|
||||
let shortSido = sido.slice(0, 2)
|
||||
if (sido.includes('부산')) shortSido = '부산'
|
||||
else if (sido.includes('서울')) shortSido = '서울'
|
||||
if (sido.includes('서울')) shortSido = '서울'
|
||||
else if (sido.includes('대구')) shortSido = '대구'
|
||||
else if (sido.includes('부산')) shortSido = '부산'
|
||||
else if (sido.includes('인천')) shortSido = '인천'
|
||||
else if (sido.includes('광주')) shortSido = '광주'
|
||||
else if (sido.includes('대전')) shortSido = '대전'
|
||||
|
||||
+27
-38
@@ -1,13 +1,28 @@
|
||||
<template>
|
||||
<div class="landing-page-wrap">
|
||||
<!-- 1. 광고 랜딩 전용 지역 식별 바 (외부 이탈 링크 없음) -->
|
||||
<div class="ad-location-bar">
|
||||
<span class="loc-badge-tag">[지역센터]</span>
|
||||
<span class="loc-text">{{ parsed.shortRegionName }} ({{ parsed.sigungu }}) 관내 초·중·고 전담</span>
|
||||
<span class="loc-tag">1:1 맞춤 배정 센터</span>
|
||||
<template>
|
||||
<div class="landing-page-wrap bg-[#F8FAFC] min-h-screen text-slate-800 antialiased">
|
||||
<!-- 1. 클린 미니멀 프리미엄 네비게이션 헤더 (기본 홈과 동일) -->
|
||||
<AppHeader :siteName="siteName" />
|
||||
|
||||
<!-- 2. 세련된 지역 센터 식별 서브 바 (모던 칩 배너) -->
|
||||
<div class="bg-blue-50/70 border-b border-blue-100/70 py-2.5 px-4">
|
||||
<div class="max-w-4xl mx-auto flex items-center justify-between flex-wrap gap-2 text-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 font-bold text-blue-700 bg-white px-2.5 py-0.5 rounded-full border border-blue-200/80 shadow-xs">
|
||||
<i class="fa-solid fa-location-dot text-blue-600 text-[10px]"></i>
|
||||
{{ parsed.shortRegionName }} 센터
|
||||
</span>
|
||||
<span class="text-slate-600 font-medium">
|
||||
{{ parsed.dong }} ({{ parsed.sigungu }}) 관내 초·중·고 1:1 맞춤 전담
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden sm:flex items-center gap-1 text-slate-500 font-medium">
|
||||
<i class="fa-solid fa-shield-check text-emerald-600 text-xs"></i>
|
||||
<span>검증된 전문 선생님 100% 매칭</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 상단 히어로 배너 (Header 제거, H1 태그 포함) -->
|
||||
<!-- 3. 상단 히어로 배너 (H1 태그 포함) -->
|
||||
<HeroBanner
|
||||
:region="parsed.region"
|
||||
:shortRegionName="parsed.shortRegionName"
|
||||
@@ -82,6 +97,9 @@
|
||||
:defaultGrade="parsed.grade"
|
||||
:defaultSubject="parsed.subjectName"
|
||||
/>
|
||||
|
||||
<!-- 14. 클린 사이트 푸터 -->
|
||||
<AppFooter />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -92,6 +110,7 @@ import { generateSeoMeta } from '~/utils/seoHelper'
|
||||
|
||||
const route = useRoute()
|
||||
const config = useRuntimeConfig()
|
||||
const siteName = config.public?.siteName || '쌤인증'
|
||||
|
||||
// URL 파라미터 파싱
|
||||
const slug = route.params.slug
|
||||
@@ -122,34 +141,4 @@ useHead({
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ad-location-bar {
|
||||
max-width: 1080px;
|
||||
margin: 10px auto;
|
||||
padding: 8px 16px;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
color: #334155;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.loc-pin {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.loc-text {
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
}
|
||||
|
||||
.loc-tag {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 800;
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user