parent
03da0ef24d
commit
228aea0b1a
5 changed files with 198 additions and 0 deletions
@ -0,0 +1,47 @@ |
||||
--- |
||||
import Popup from "./Popup/Popup.astro"; |
||||
--- |
||||
|
||||
<Popup |
||||
id="download-popup" |
||||
title="Download Roadmap" |
||||
subtitle="Enter your email below to receive the download link." |
||||
> |
||||
<form |
||||
action="https://newsletter.roadmap.sh/subscribe" |
||||
method="POST" |
||||
accept-charset="utf-8" |
||||
target="_blank" |
||||
class="validate-captcha-form" |
||||
> |
||||
<input |
||||
type="email" |
||||
name="email" |
||||
id="email" |
||||
required |
||||
autofocus |
||||
class="w-full rounded-md border text-md py-2.5 px-3 mb-2" |
||||
placeholder="Enter your Email" |
||||
/> |
||||
|
||||
<!-- {# Captcha Form Start #} --> |
||||
<div class="recaptcha-field mb-2"></div> |
||||
<input |
||||
type="hidden" |
||||
name="g-recaptcha-response" |
||||
class="recaptcha-response" |
||||
/> |
||||
<!-- {# Captcha Form End #} --> |
||||
|
||||
<input type="hidden" name="list" value="tTqz1w7nexY3cWDpLnI88Q" /> |
||||
<input type="hidden" name="subform" value="yes" /> |
||||
|
||||
<button |
||||
type="submit" |
||||
name="submit" |
||||
class="text-white bg-gradient-to-r from-amber-700 to-blue-800 hover:from-amber-800 hover:to-blue-900 font-regular rounded-md text-md px-5 py-2.5 w-full text-center mr-2" |
||||
> |
||||
Send Link |
||||
</button> |
||||
</form> |
||||
</Popup> |
@ -0,0 +1,36 @@ |
||||
--- |
||||
import Icon from '../Icon.astro'; |
||||
|
||||
export interface Props { |
||||
id: string; |
||||
title: string; |
||||
subtitle: string; |
||||
} |
||||
|
||||
const { id, title, subtitle } = Astro.props; |
||||
--- |
||||
|
||||
<script src="./popup.js"></script> |
||||
|
||||
<div id={id} tabindex="-1" class="hidden bg-black/50 overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 h-full flex items-center justify-center modal"> |
||||
<div class="relative p-4 w-full max-w-md h-full md:h-auto"> |
||||
<div class="relative bg-white rounded-lg shadow modal-body"> |
||||
<button type="button" class="absolute top-3 right-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center" onclick='this.closest(".modal").classList.add("hidden")'> |
||||
<Icon icon="close" /> |
||||
<span class="sr-only">Close modal</span> |
||||
</button> |
||||
<div class="p-5"> |
||||
<h3 class='text-2xl mb-0.5 font-medium'> |
||||
{ title } |
||||
</h3> |
||||
<p class="mb-4 text-sm font-normal text-gray-800"> |
||||
{ subtitle } |
||||
</p> |
||||
|
||||
<slot /> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
@ -0,0 +1,65 @@ |
||||
export class Modal { |
||||
constructor() { |
||||
this.triggerModal = this.triggerModal.bind(this); |
||||
this.onDOMLoaded = this.onDOMLoaded.bind(this); |
||||
this.handleCloseModal = this.handleCloseModal.bind(this); |
||||
this.handleKeydown = this.handleKeydown.bind(this); |
||||
} |
||||
|
||||
/** |
||||
* Triggers the modal on target elements |
||||
* @param {Event} e |
||||
*/ |
||||
triggerModal(e) { |
||||
const modalToShow = e?.target?.closest('[data-modal]')?.dataset?.modal || 'unknown-modal'; |
||||
const modalEl = document.querySelector(`#${modalToShow}`); |
||||
|
||||
if (!modalEl) { |
||||
return; |
||||
} |
||||
|
||||
modalEl.classList.remove('hidden'); |
||||
const focusEl = modalEl.querySelector('[autofocus]'); |
||||
if (focusEl) { |
||||
focusEl.focus(); |
||||
} |
||||
} |
||||
|
||||
handleCloseModal(e) { |
||||
const target = e.target; |
||||
const modalBody = target.closest('.modal-body'); |
||||
const closestModal = target.closest('.modal'); |
||||
|
||||
if (modalBody) { |
||||
return; |
||||
} |
||||
|
||||
if (closestModal) { |
||||
closestModal.classList.add('hidden'); |
||||
} |
||||
} |
||||
|
||||
handleKeydown(e) { |
||||
if (e.key !== 'Escape') { |
||||
return; |
||||
} |
||||
|
||||
const modal = document.querySelector('.modal:not(.hidden)'); |
||||
if (modal) { |
||||
modal.classList.add('hidden'); |
||||
} |
||||
} |
||||
|
||||
onDOMLoaded() { |
||||
document.addEventListener('click', this.triggerModal); |
||||
document.addEventListener('click', this.handleCloseModal); |
||||
document.addEventListener('keydown', this.handleKeydown); |
||||
} |
||||
|
||||
init() { |
||||
window.addEventListener('DOMContentLoaded', this.onDOMLoaded); |
||||
} |
||||
} |
||||
|
||||
const modalRef = new Modal(); |
||||
modalRef.init();
|
@ -0,0 +1,46 @@ |
||||
--- |
||||
import Popup from "./Popup/Popup.astro"; |
||||
--- |
||||
|
||||
<Popup |
||||
id="subscribe-popup" |
||||
title="Subscribe" |
||||
subtitle="Enter your email below to receive updates." |
||||
> |
||||
<form |
||||
action="https://newsletter.roadmap.sh/subscribe" |
||||
method="POST" |
||||
accept-charset="utf-8" |
||||
target="_blank" |
||||
class="validate-captcha-form" |
||||
> |
||||
<input |
||||
type="email" |
||||
name="email" |
||||
required |
||||
autofocus |
||||
class="w-full rounded-md border text-md py-2.5 px-3 mb-2" |
||||
placeholder="Enter your Email" |
||||
/> |
||||
|
||||
<!-- Captcha Form Start --> |
||||
<div class="recaptcha-field mb-2"></div> |
||||
<input |
||||
type="hidden" |
||||
name="g-recaptcha-response" |
||||
class="recaptcha-response" |
||||
/> |
||||
<!-- Captcha Form End --> |
||||
|
||||
<input type="hidden" name="list" value="tTqz1w7nexY3cWDpLnI88Q" /> |
||||
<input type="hidden" name="subform" value="yes" /> |
||||
|
||||
<button |
||||
type="submit" |
||||
name="submit" |
||||
class="text-white bg-gradient-to-r from-amber-700 to-blue-800 hover:from-amber-800 hover:to-blue-900 font-regular rounded-md text-md px-5 py-2.5 w-full text-center mr-2" |
||||
> |
||||
Subscribe |
||||
</button> |
||||
</form> |
||||
</Popup> |
Loading…
Reference in new issue