home修改
This commit is contained in:
parent
bbc9ad13fe
commit
860bd0161b
@ -104,6 +104,20 @@ const projectIndustryLabel = computed(() => {
|
|||||||
if (!target) return ''
|
if (!target) return ''
|
||||||
return getIndustryDisplayName(target, locale.value) || ''
|
return getIndustryDisplayName(target, locale.value) || ''
|
||||||
})
|
})
|
||||||
|
const heroBrandName = computed(() => t('home.cards.heroBrand'))
|
||||||
|
const heroBrandMessages = computed(() => [
|
||||||
|
t('home.cards.heroBrandMessage1'),
|
||||||
|
t('home.cards.heroBrandMessage2'),
|
||||||
|
t('home.cards.heroBrandMessage3'),
|
||||||
|
t('home.cards.heroBrandMessage4'),
|
||||||
|
t('home.cards.heroBrandMessage5')
|
||||||
|
].filter(Boolean))
|
||||||
|
const heroBrandMessageIndex = ref(0)
|
||||||
|
const activeHeroBrandMessage = computed(() => {
|
||||||
|
const options = heroBrandMessages.value
|
||||||
|
if (!options.length) return ''
|
||||||
|
return options[((heroBrandMessageIndex.value % options.length) + options.length) % options.length]
|
||||||
|
})
|
||||||
const localeBadge = computed(() => (locale.value === 'en-US' ? 'EN' : '中'))
|
const localeBadge = computed(() => (locale.value === 'en-US' ? 'EN' : '中'))
|
||||||
const toggleLocale = () => {
|
const toggleLocale = () => {
|
||||||
const next = locale.value === 'en-US' ? 'zh-CN' : 'en-US'
|
const next = locale.value === 'en-US' ? 'zh-CN' : 'en-US'
|
||||||
@ -393,10 +407,29 @@ const handleHomeVisibilityChange = () => {
|
|||||||
handleHomeWindowFocus()
|
handleHomeWindowFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let heroBrandMessageTimer: ReturnType<typeof setInterval> | null = null
|
||||||
|
|
||||||
|
const stopHeroBrandMessageRotation = () => {
|
||||||
|
if (heroBrandMessageTimer == null) return
|
||||||
|
clearInterval(heroBrandMessageTimer)
|
||||||
|
heroBrandMessageTimer = null
|
||||||
|
}
|
||||||
|
|
||||||
|
const startHeroBrandMessageRotation = () => {
|
||||||
|
stopHeroBrandMessageRotation()
|
||||||
|
if (heroBrandMessages.value.length <= 1) return
|
||||||
|
heroBrandMessageTimer = setInterval(() => {
|
||||||
|
const total = heroBrandMessages.value.length
|
||||||
|
if (total <= 1) return
|
||||||
|
heroBrandMessageIndex.value = (heroBrandMessageIndex.value + 1) % total
|
||||||
|
}, 2400)
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
void refreshExistingProjects()
|
void refreshExistingProjects()
|
||||||
void loadProjectDefaults()
|
void loadProjectDefaults()
|
||||||
void loadQuickDefaults()
|
void loadQuickDefaults()
|
||||||
|
startHeroBrandMessageRotation()
|
||||||
window.addEventListener('focus', handleHomeWindowFocus)
|
window.addEventListener('focus', handleHomeWindowFocus)
|
||||||
document.addEventListener('visibilitychange', handleHomeVisibilityChange)
|
document.addEventListener('visibilitychange', handleHomeVisibilityChange)
|
||||||
try {
|
try {
|
||||||
@ -421,6 +454,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
stopExistingProjectPolling()
|
stopExistingProjectPolling()
|
||||||
|
stopHeroBrandMessageRotation()
|
||||||
window.removeEventListener('focus', handleHomeWindowFocus)
|
window.removeEventListener('focus', handleHomeWindowFocus)
|
||||||
document.removeEventListener('visibilitychange', handleHomeVisibilityChange)
|
document.removeEventListener('visibilitychange', handleHomeVisibilityChange)
|
||||||
})
|
})
|
||||||
@ -467,6 +501,13 @@ onBeforeUnmount(() => {
|
|||||||
</div>
|
</div>
|
||||||
<h2 class="relative mt-8 text-2xl font-semibold leading-tight tracking-tight lg:text-3xl">{{ t('home.cards.heroTitle') }}</h2>
|
<h2 class="relative mt-8 text-2xl font-semibold leading-tight tracking-tight lg:text-3xl">{{ t('home.cards.heroTitle') }}</h2>
|
||||||
<p class="relative mt-2 text-sm text-red-200/90">{{ t('home.cards.heroSubTitle') }}</p>
|
<p class="relative mt-2 text-sm text-red-200/90">{{ t('home.cards.heroSubTitle') }}</p>
|
||||||
|
<div class="relative mt-4 inline-flex max-w-full items-center gap-3 rounded-full border border-white/15 bg-white/10 px-4 py-2 text-xs text-white/90 backdrop-blur-sm">
|
||||||
|
<span class="shrink-0 font-semibold tracking-[0.28em] text-white">{{ heroBrandName }}</span>
|
||||||
|
<span class="h-3.5 w-px shrink-0 bg-white/25" />
|
||||||
|
<Transition name="hero-brand-message" mode="out-in">
|
||||||
|
<span :key="`${locale}-${heroBrandMessageIndex}`" class="truncate text-white/90">{{ activeHeroBrandMessage }}</span>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
<div class="relative mt-6 h-px bg-white/20" />
|
<div class="relative mt-6 h-px bg-white/20" />
|
||||||
<p class="relative mt-4 text-xs leading-5 text-red-200/60">{{ t('home.cards.heroDesc') }}</p>
|
<p class="relative mt-4 text-xs leading-5 text-red-200/60">{{ t('home.cards.heroDesc') }}</p>
|
||||||
</div>
|
</div>
|
||||||
@ -582,6 +623,13 @@ onBeforeUnmount(() => {
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="home-slogan-row mt-5 flex items-center justify-center">
|
||||||
|
<div class="flex w-full flex-wrap items-center justify-center gap-x-4 gap-y-1 px-4 py-2 text-center">
|
||||||
|
<span class="text-lg font-semibold tracking-[0.18em] text-slate-900 sm:text-xl">{{ t('home.cards.heroFooterTitle') }}</span>
|
||||||
|
<span class="text-slate-300">|</span>
|
||||||
|
<span class="text-sm tracking-[0.08em] text-slate-500 sm:text-base">{{ t('home.cards.heroFooterSubTitle') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -738,6 +786,9 @@ onBeforeUnmount(() => {
|
|||||||
.home-entry-item {
|
.home-entry-item {
|
||||||
animation: fade-up 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
|
animation: fade-up 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
|
||||||
}
|
}
|
||||||
|
.home-slogan-row {
|
||||||
|
animation: fade-up 0.45s cubic-bezier(0.22, 1, 0.36, 1) 0.6s both;
|
||||||
|
}
|
||||||
.home-entry-item--1 { animation-delay: 0.2s; }
|
.home-entry-item--1 { animation-delay: 0.2s; }
|
||||||
.home-entry-item--2 { animation-delay: 0.3s; }
|
.home-entry-item--2 { animation-delay: 0.3s; }
|
||||||
.home-entry-item--3 { animation-delay: 0.4s; }
|
.home-entry-item--3 { animation-delay: 0.4s; }
|
||||||
@ -819,4 +870,13 @@ onBeforeUnmount(() => {
|
|||||||
from { opacity: 0; transform: translateY(16px); }
|
from { opacity: 0; transform: translateY(16px); }
|
||||||
to { opacity: 1; transform: translateY(0); }
|
to { opacity: 1; transform: translateY(0); }
|
||||||
}
|
}
|
||||||
|
.hero-brand-message-enter-active,
|
||||||
|
.hero-brand-message-leave-active {
|
||||||
|
transition: opacity 0.22s ease, transform 0.22s ease;
|
||||||
|
}
|
||||||
|
.hero-brand-message-enter-from,
|
||||||
|
.hero-brand-message-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(6px);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -26,6 +26,14 @@ export const enUS = {
|
|||||||
cards: {
|
cards: {
|
||||||
heroTitle: 'One-Click Smart Budget',
|
heroTitle: 'One-Click Smart Budget',
|
||||||
heroSubTitle: 'Accelerate standards adoption',
|
heroSubTitle: 'Accelerate standards adoption',
|
||||||
|
heroFooterTitle: 'Instant Cost Intelligence',
|
||||||
|
heroFooterSubTitle: 'Leave your time for creation',
|
||||||
|
heroBrand: 'Huizhongyi',
|
||||||
|
heroBrandMessage1: 'So easy',
|
||||||
|
heroBrandMessage2: 'Fee calc made easy',
|
||||||
|
heroBrandMessage3: 'No late nights for fees',
|
||||||
|
heroBrandMessage4: 'No heavy lifting for fees',
|
||||||
|
heroBrandMessage5: 'No late nights, no heavy lifting',
|
||||||
heroDesc: 'Cost consulting fee calculator for transport construction projects',
|
heroDesc: 'Cost consulting fee calculator for transport construction projects',
|
||||||
projectBudget: 'Project Budget',
|
projectBudget: 'Project Budget',
|
||||||
projectBudgetDesc: 'For full project-level calculation across multiple contracts with import/export support',
|
projectBudgetDesc: 'For full project-level calculation across multiple contracts with import/export support',
|
||||||
|
|||||||
@ -26,6 +26,14 @@ export const zhCN = {
|
|||||||
cards: {
|
cards: {
|
||||||
heroTitle: '智能预算一键生成',
|
heroTitle: '智能预算一键生成',
|
||||||
heroSubTitle: '助力《规范》高效落地',
|
heroSubTitle: '助力《规范》高效落地',
|
||||||
|
heroFooterTitle: '智算费用 即点即出',
|
||||||
|
heroFooterSubTitle: '您的时间留给创造',
|
||||||
|
heroBrand: '慧众易',
|
||||||
|
heroBrandMessage1: '真容易',
|
||||||
|
heroBrandMessage2: '算费真容易',
|
||||||
|
heroBrandMessage3: '算费不熬夜',
|
||||||
|
heroBrandMessage4: '算费不费力',
|
||||||
|
heroBrandMessage5: '不熬夜,不费力',
|
||||||
heroDesc: '交通建设项目工程造价咨询服务费计算',
|
heroDesc: '交通建设项目工程造价咨询服务费计算',
|
||||||
projectBudget: '项目预算',
|
projectBudget: '项目预算',
|
||||||
projectBudgetDesc: '适用于多合同段、项目级整体计算,支持导出/导入完整项目数据',
|
projectBudgetDesc: '适用于多合同段、项目级整体计算,支持导出/导入完整项目数据',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user