Commit bcc91c4a authored by xuchentao's avatar xuchentao

fix: 适配咨询入口的桌面端联系方式弹窗

parent 85a3e149
Pipeline #443 passed with stage
in 15 seconds
---
import { site } from "../data/site";
import Icon from "./Icon.astro";
---
<dialog class="contact-dialog" data-contact-dialog aria-labelledby="contact-dialog-title">
<div class="contact-dialog__panel">
<button class="contact-dialog__close" type="button" data-contact-dialog-close aria-label="关闭联系方式弹窗">×</button>
<p class="eyebrow"><span></span>CONTACT US</p>
<h2 id="contact-dialog-title">联系我们</h2>
<p class="contact-dialog__intro">欢迎电话咨询或到店沟通,我们会结合你的实际情况介绍合适的服务方案。</p>
<dl class="contact-dialog__details">
<div>
<dt><Icon name="phone" size={21} />联系电话</dt>
<dd>{site.contact.phone}</dd>
</div>
<div>
<dt><Icon name="pin" size={21} />线下门店</dt>
<dd>{site.contact.address}</dd>
</div>
<div>
<dt><Icon name="clock" size={21} />服务时间</dt>
<dd>{site.contact.serviceHours}</dd>
</div>
</dl>
<div class="contact-dialog__actions">
<button class="button" type="button" data-copy-phone data-phone={site.contact.phone}>复制电话</button>
<a class="button button--secondary" href="/contact/">查看联系页面 <Icon name="arrow" size={17} /></a>
</div>
<p class="contact-dialog__status" data-copy-phone-status aria-live="polite"></p>
</div>
</dialog>
......@@ -2,6 +2,7 @@
import "../styles/global.css";
import logo from "../../白底黑字绿LOGO.svg";
import { site } from "../data/site";
import ContactDialog from "../components/ContactDialog.astro";
interface Props {
title: string;
......@@ -67,6 +68,7 @@ const allLd = [organizationLd, ...pageLd.filter((item) => Object.keys(item).leng
<body>
<a class="skip-link" href="#main-content">跳到主要内容</a>
<slot />
<ContactDialog />
<script is:inline>
const header = document.querySelector('[data-header]');
const syncHeader = () => header?.classList.toggle('is-scrolled', window.scrollY > 12);
......@@ -84,6 +86,38 @@ const allLd = [organizationLd, ...pageLd.filter((item) => Object.keys(item).leng
document.querySelectorAll('[data-mobile-nav] a').forEach((link) => {
link.addEventListener('click', () => link.closest('details')?.removeAttribute('open'));
});
const contactDialog = document.querySelector('[data-contact-dialog]');
const mobileUserAgent = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
const isIPadOS = /Macintosh/i.test(navigator.userAgent) && navigator.maxTouchPoints > 1;
const isMobileDevice = navigator.userAgentData?.mobile === true || mobileUserAgent || isIPadOS;
if (!isMobileDevice && contactDialog instanceof HTMLDialogElement) {
document.querySelectorAll('a[href^="tel:"]').forEach((link) => {
link.addEventListener('click', (event) => {
event.preventDefault();
contactDialog.showModal();
});
});
contactDialog.querySelector('[data-contact-dialog-close]')?.addEventListener('click', () => contactDialog.close());
contactDialog.addEventListener('click', (event) => {
if (event.target === contactDialog) contactDialog.close();
});
const copyButton = contactDialog.querySelector('[data-copy-phone]');
const copyStatus = contactDialog.querySelector('[data-copy-phone-status]');
copyButton?.addEventListener('click', async () => {
const phone = copyButton.getAttribute('data-phone') || '';
try {
if (!navigator.clipboard) throw new Error('Clipboard API unavailable');
await navigator.clipboard.writeText(phone);
if (copyStatus) copyStatus.textContent = `电话 ${phone} 已复制`;
} catch {
if (copyStatus) copyStatus.textContent = `请手动记录电话:${phone}`;
}
});
}
</script>
</body>
</html>
......@@ -33,6 +33,21 @@ h3 { font-size: 21px; }
.skip-link { position: fixed; left: 18px; top: -80px; z-index: 1000; background: var(--ink); color: #fff; padding: 10px 16px; }
.skip-link:focus { top: 18px; }
.contact-dialog { width: min(620px, calc(100% - 32px)); max-width: none; padding: 0; color: var(--ink); background: transparent; border: 0; overflow: visible; }
.contact-dialog::backdrop { background: rgba(35, 25, 22, .62); backdrop-filter: blur(5px); }
.contact-dialog__panel { position: relative; padding: 42px; background: #fff; border-radius: 24px; box-shadow: 0 28px 80px rgba(35, 25, 22, .24); }
.contact-dialog__close { position: absolute; top: 18px; right: 18px; width: 38px; height: 38px; padding: 0; color: var(--muted); background: var(--background); border: 0; border-radius: 50%; font-size: 26px; line-height: 1; cursor: pointer; }
.contact-dialog__close:hover { color: var(--primary); background: var(--primary-light); }
.contact-dialog h2 { margin-bottom: 14px; font-size: 38px; }
.contact-dialog__intro { margin-bottom: 28px; color: var(--muted); font-size: 14px; }
.contact-dialog__details { display: grid; gap: 1px; margin: 0 0 28px; overflow: hidden; background: var(--border); border: 1px solid var(--border); border-radius: 14px; }
.contact-dialog__details > div { display: grid; grid-template-columns: 120px 1fr; gap: 20px; padding: 16px 18px; background: #fff; }
.contact-dialog__details dt { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12px; font-weight: 700; }
.contact-dialog__details dt svg { flex: none; color: var(--primary); }
.contact-dialog__details dd { margin: 0; font-size: 14px; font-weight: 700; text-align: right; }
.contact-dialog__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.contact-dialog__status { min-height: 24px; margin: 12px 0 -12px; color: var(--primary); font-size: 12px; }
.button { display: inline-flex; align-items: center; justify-content: center; gap: 9px; min-height: 52px; padding: 0 24px; border: 1px solid var(--primary); border-radius: 999px; color: #fff; background: var(--primary); font-size: 15px; font-weight: 700; transition: .24s ease; cursor: pointer; }
.button:hover { color: #fff; background: var(--primary-hover); border-color: var(--primary-hover); transform: translateY(-2px); box-shadow: 0 12px 24px rgba(255, 125, 65, .24); }
.button--secondary { color: var(--ink); background: #fff; border-color: #d8d3d0; }
......@@ -172,4 +187,5 @@ h3 { font-size: 21px; }
.stats-grid strong { font-size: 26px; }.stats-grid div { padding: 25px 18px; }.service-grid, .article-grid, .process-grid, .values-grid, .fit-grid, .certification-cards { grid-template-columns: 1fr; }.service-card { min-height: 285px; }.trust-proof { min-height: auto; padding: 36px 28px; }.faq-layout { gap: 16px; }.faq-list summary { min-height: 82px; }.faq-list details > p { padding-left: 48px; }
.page-hero { padding: 62px 0 72px; }.page-hero::after { display: none; }.breadcrumb { margin-bottom: 30px; }.service-detail-list { gap: 70px; }.about-story__facts, .service-detail__summary, .visit-panel { min-height: auto; padding: 36px 28px; }.join-hero { padding: 65px 0; }.join-card { padding: 28px; }.contact-hero { padding: 65px 0; }.contact-number a { font-size: 32px; }.visit-tips .container { grid-template-columns: 1fr; }.visit-tips .container > * { padding: 22px; }.article-card__body { padding: 24px; }.article-page > header { padding: 58px 0; }.article-layout { padding-top: 48px; padding-bottom: 80px; }.article-content { font-size: 15px; }.empty-state { padding: 55px 24px; }
.cta-section { padding-bottom: 68px; }.cta-panel { padding: 36px 26px; }.cta-actions { width: 100%; }.cta-actions .button { width: 100%; }.footer-grid { grid-template-columns: 1fr 1fr; }.footer-brand, .footer-contact { grid-column: 1 / -1; }.footer-bottom { flex-direction: column; gap: 8px; }.footer-logo { width: 170px; }
.contact-dialog__panel { padding: 34px 22px 26px; }.contact-dialog h2 { font-size: 32px; }.contact-dialog__details > div { grid-template-columns: 1fr; gap: 4px; }.contact-dialog__details dd { padding-left: 29px; text-align: left; }.contact-dialog__actions .button { width: 100%; }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment