Add office location map dialogs
This commit is contained in:
1
assets/icons/arrow_outward.svg
Normal file
1
assets/icons/arrow_outward.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24" fill="#ffffff"><path d="m256-240-56-56 384-384H240v-80h480v480h-80v-344L256-240Z"/></svg>
|
||||
|
After Width: | Height: | Size: 178 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="000"><path d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#ffffff"><path d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 179 B |
1
assets/icons/location_on.svg
Normal file
1
assets/icons/location_on.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24" fill="#ffffff"><path d="M536.5-503.5Q560-527 560-560t-23.5-56.5Q513-640 480-640t-56.5 23.5Q400-593 400-560t23.5 56.5Q447-480 480-480t56.5-23.5ZM480-186q122-112 181-203.5T720-552q0-109-69.5-178.5T480-800q-101 0-170.5 69.5T240-552q0 71 59 162.5T480-186Zm0 106Q319-217 239.5-334.5T160-552q0-150 96.5-239T480-880q127 0 223.5 89T800-552q0 100-79.5 217.5T480-80Zm0-480Z"/></svg>
|
||||
|
After Width: | Height: | Size: 461 B |
40
contact.html
40
contact.html
@@ -44,15 +44,39 @@
|
||||
|
||||
<section class="contact-layout">
|
||||
<div class="office-list">
|
||||
<article>
|
||||
<span>Head Office</span>
|
||||
<h2>대구 본사</h2>
|
||||
<p>대구광역시 북구 경대로17길 47, 8층 803호<br />(복현동, IT융합산업빌딩)</p>
|
||||
<article class="office-location">
|
||||
<div>
|
||||
<span>Head Office</span>
|
||||
<h2>대구 본사</h2>
|
||||
<p>대구광역시 북구 경대로17길 47, 8층 803호<br />(복현동, IT융합산업빌딩)</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="office-map-button"
|
||||
data-map-title="대구 본사"
|
||||
data-map-address="대구광역시 북구 경대로17길 47 IT융합산업빌딩"
|
||||
aria-label="대구 본사 지도 보기"
|
||||
title="지도 보기"
|
||||
>
|
||||
<img src="assets/icons/location_on.svg" alt="" />
|
||||
</button>
|
||||
</article>
|
||||
<article>
|
||||
<span>Seoul Office</span>
|
||||
<h2>서울 사무소</h2>
|
||||
<p>서울특별시 강남구 논현로 416<br />운기빌딩 6층</p>
|
||||
<article class="office-location">
|
||||
<div>
|
||||
<span>Seoul Office</span>
|
||||
<h2>서울 사무소</h2>
|
||||
<p>서울특별시 강남구 논현로 416<br />운기빌딩 6층</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="office-map-button"
|
||||
data-map-title="서울 사무소"
|
||||
data-map-address="서울특별시 강남구 논현로 416 운기빌딩"
|
||||
aria-label="서울 사무소 지도 보기"
|
||||
title="지도 보기"
|
||||
>
|
||||
<img src="assets/icons/location_on.svg" alt="" />
|
||||
</button>
|
||||
</article>
|
||||
<article>
|
||||
<span>Office Hour</span>
|
||||
|
||||
@@ -1579,6 +1579,39 @@ code {
|
||||
border: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.office-location {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 40px;
|
||||
gap: 18px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.office-map-button {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
color: var(--text);
|
||||
border: 1px solid var(--line-strong);
|
||||
border-radius: 4px;
|
||||
background: rgba(255, 255, 255, .05);
|
||||
cursor: pointer;
|
||||
transition: border-color .2s var(--ease), background .2s var(--ease), transform .2s var(--ease);
|
||||
}
|
||||
|
||||
.office-map-button img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.office-map-button:hover,
|
||||
.office-map-button:focus-visible {
|
||||
border-color: var(--accent);
|
||||
background: rgba(158, 233, 255, .12);
|
||||
transform: translateX(2px);
|
||||
}
|
||||
|
||||
.office-list h2 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@@ -1948,6 +1981,50 @@ html.has-site-dialog,
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.location-dialog {
|
||||
width: min(960px, calc(100% - 32px));
|
||||
}
|
||||
|
||||
.location-map-content {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.location-map-frame {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: min(58dvh, 560px);
|
||||
min-height: 360px;
|
||||
border: 0;
|
||||
background: #0b1013;
|
||||
}
|
||||
|
||||
.location-map-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
padding: 16px 24px;
|
||||
border-top: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.location-map-meta p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.location-map-meta a {
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-weight: 750;
|
||||
}
|
||||
|
||||
.location-map-meta img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.sitemap-groups {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
@@ -1977,6 +2054,22 @@ html.has-site-dialog,
|
||||
.site-dialog-content {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.location-map-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.location-map-frame {
|
||||
height: 52dvh;
|
||||
min-height: 280px;
|
||||
}
|
||||
|
||||
.location-map-meta {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
padding: 14px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.contact-body button:disabled {
|
||||
|
||||
72
js/main.js
72
js/main.js
@@ -276,6 +276,20 @@
|
||||
</nav>`,
|
||||
},
|
||||
};
|
||||
|
||||
function prepareDialog(dialog) {
|
||||
dialog.querySelector(".dialog-close")?.addEventListener("click", () => dialog.close());
|
||||
dialog.addEventListener("click", (event) => {
|
||||
const rect = dialog.getBoundingClientRect();
|
||||
const clickedOutside = event.target === dialog && (
|
||||
event.clientX < rect.left || event.clientX > rect.right ||
|
||||
event.clientY < rect.top || event.clientY > rect.bottom
|
||||
);
|
||||
if (clickedOutside) dialog.close();
|
||||
});
|
||||
dialog.addEventListener("close", () => document.documentElement.classList.remove("has-site-dialog"));
|
||||
}
|
||||
|
||||
Object.entries(modalContent).forEach(([key, content]) => {
|
||||
const dialog = document.createElement("dialog");
|
||||
dialog.className = "site-dialog";
|
||||
@@ -288,19 +302,10 @@
|
||||
</header>
|
||||
<div class="site-dialog-content">${content.body}</div>`;
|
||||
document.body.appendChild(dialog);
|
||||
dialog.querySelector(".dialog-close").addEventListener("click", () => dialog.close());
|
||||
dialog.addEventListener("click", (event) => {
|
||||
const rect = dialog.getBoundingClientRect();
|
||||
const clickedOutside = event.target === dialog && (
|
||||
event.clientX < rect.left || event.clientX > rect.right ||
|
||||
event.clientY < rect.top || event.clientY > rect.bottom
|
||||
);
|
||||
if (clickedOutside) dialog.close();
|
||||
});
|
||||
prepareDialog(dialog);
|
||||
dialog.querySelectorAll(".sitemap-groups a").forEach((link) => {
|
||||
link.addEventListener("click", () => dialog.close());
|
||||
});
|
||||
dialog.addEventListener("close", () => document.documentElement.classList.remove("has-site-dialog"));
|
||||
document.querySelectorAll(`[data-site-modal="${key}"]`).forEach((trigger) => {
|
||||
trigger.setAttribute("aria-haspopup", "dialog");
|
||||
trigger.setAttribute("aria-controls", dialog.id);
|
||||
@@ -312,6 +317,53 @@
|
||||
});
|
||||
});
|
||||
|
||||
const mapTriggers = document.querySelectorAll("[data-map-address]");
|
||||
if (mapTriggers.length) {
|
||||
const dialog = document.createElement("dialog");
|
||||
dialog.className = "site-dialog location-dialog";
|
||||
dialog.id = "office-map-dialog";
|
||||
dialog.setAttribute("aria-labelledby", "office-map-title");
|
||||
dialog.innerHTML = `
|
||||
<header class="site-dialog-header">
|
||||
<h2 id="office-map-title">오시는 길</h2>
|
||||
<button type="button" class="dialog-close" aria-label="닫기" title="닫기">×</button>
|
||||
</header>
|
||||
<div class="site-dialog-content location-map-content">
|
||||
<iframe class="location-map-frame" title="회사 위치 지도" loading="lazy" referrerpolicy="no-referrer-when-downgrade" allowfullscreen></iframe>
|
||||
<div class="location-map-meta">
|
||||
<p data-location-address></p>
|
||||
<a data-location-link href="https://www.google.com/maps" target="_blank" rel="noopener noreferrer">
|
||||
Google 지도에서 크게 보기
|
||||
<img src="assets/icons/arrow_outward.svg" alt="" />
|
||||
</a>
|
||||
</div>
|
||||
</div>`;
|
||||
document.body.appendChild(dialog);
|
||||
prepareDialog(dialog);
|
||||
|
||||
const title = dialog.querySelector("#office-map-title");
|
||||
const frame = dialog.querySelector(".location-map-frame");
|
||||
const addressLabel = dialog.querySelector("[data-location-address]");
|
||||
const mapLink = dialog.querySelector("[data-location-link]");
|
||||
mapTriggers.forEach((trigger) => {
|
||||
trigger.setAttribute("aria-haspopup", "dialog");
|
||||
trigger.setAttribute("aria-controls", dialog.id);
|
||||
trigger.addEventListener("click", () => {
|
||||
const office = trigger.dataset.mapTitle;
|
||||
const address = trigger.dataset.mapAddress;
|
||||
const query = encodeURIComponent(address);
|
||||
title.textContent = `${office} 오시는 길`;
|
||||
frame.title = `${office} 위치 지도`;
|
||||
frame.src = `https://maps.google.com/maps?q=${query}&z=16&output=embed`;
|
||||
addressLabel.textContent = address;
|
||||
mapLink.href = `https://www.google.com/maps/search/?api=1&query=${query}`;
|
||||
dialog.showModal();
|
||||
document.documentElement.classList.add("has-site-dialog");
|
||||
});
|
||||
});
|
||||
dialog.addEventListener("close", () => frame.removeAttribute("src"));
|
||||
}
|
||||
|
||||
// 문의하기: PocketBase에 문의와 첨부파일을 저장.
|
||||
const form = document.querySelector("[data-contact-form]");
|
||||
if (form) {
|
||||
|
||||
Reference in New Issue
Block a user