open modal
This commit is contained in:
@@ -39,7 +39,7 @@ export const config: CookieConsentConfig = {
|
|||||||
// function gtag(...args: any[]) {
|
// function gtag(...args: any[]) {
|
||||||
// window.dataLayer.push(args);
|
// window.dataLayer.push(args);
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
// gtag("consent", "update", {
|
// gtag("consent", "update", {
|
||||||
// ad_storage: "granted",
|
// ad_storage: "granted",
|
||||||
// ad_user_data: "granted",
|
// ad_user_data: "granted",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createElement, useEffect } from "react";
|
import { createElement, useEffect, forwardRef } from "react";
|
||||||
import { Form, useForm } from "react-hook-form";
|
import { Form, useForm, Controller } from "react-hook-form";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { PatternFormat } from "react-number-format";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -20,6 +21,9 @@ const schema = z.object({
|
|||||||
export default function Contact({ url }) {
|
export default function Contact({ url }) {
|
||||||
const { register, formState, control, reset, setValue } = useForm({
|
const { register, formState, control, reset, setValue } = useForm({
|
||||||
resolver: zodResolver(schema),
|
resolver: zodResolver(schema),
|
||||||
|
defaultValues: {
|
||||||
|
telephone: "",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -70,10 +74,23 @@ export default function Contact({ url }) {
|
|||||||
</Control>
|
</Control>
|
||||||
|
|
||||||
<Control>
|
<Control>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="telephone"
|
||||||
|
defaultValue=""
|
||||||
|
render={({ field: { ref, ...props } }) => {
|
||||||
|
return (
|
||||||
<Input
|
<Input
|
||||||
aria-invalid={!!formState.errors?.name}
|
aria-invalid={!!formState.errors?.name}
|
||||||
|
as={PatternFormat}
|
||||||
placeholder="Telefone"
|
placeholder="Telefone"
|
||||||
{...register("telephone")}
|
format="+55 (##) ### ### ###"
|
||||||
|
getInputRef={ref}
|
||||||
|
mask="_"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<Error>{formState.errors.telephone?.message}</Error>
|
<Error>{formState.errors.telephone?.message}</Error>
|
||||||
</Control>
|
</Control>
|
||||||
@@ -100,15 +117,22 @@ export default function Contact({ url }) {
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="p-2.5 border border-lime-400 rounded-lg cursor-pointer"
|
className="p-2.5 border border-lime-400 rounded-lg cursor-pointer disabled:border-white/10 disabled:pointer-events-none relative overflow-hidden group"
|
||||||
|
disabled={formState.isSubmitting}
|
||||||
>
|
>
|
||||||
Enviar
|
<div className="absolute inset-0 hidden group-disabled:flex items-center justify-center bg-black">
|
||||||
|
<Spinner className="size-6 animate-spin" />
|
||||||
|
</div>
|
||||||
|
<>Enviar</>
|
||||||
</button>
|
</button>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Input({ as = "input", className, children, ...props }) {
|
export const Input = forwardRef(function Input(
|
||||||
|
{ as = "input", className, children, ...props },
|
||||||
|
ref,
|
||||||
|
) {
|
||||||
return createElement(
|
return createElement(
|
||||||
as,
|
as,
|
||||||
{
|
{
|
||||||
@@ -119,11 +143,12 @@ export function Input({ as = "input", className, children, ...props }) {
|
|||||||
"aria-invalid:border-red-600",
|
"aria-invalid:border-red-600",
|
||||||
className,
|
className,
|
||||||
),
|
),
|
||||||
|
ref,
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
children,
|
children,
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
function Control({ children, className }) {
|
function Control({ children, className }) {
|
||||||
return <label className={className}>{children}</label>;
|
return <label className={className}>{children}</label>;
|
||||||
@@ -138,3 +163,28 @@ function Error({ children, className }) {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Spinner(props) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<circle
|
||||||
|
className="opacity-25"
|
||||||
|
cx="12"
|
||||||
|
cy="12"
|
||||||
|
r="10"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="4"
|
||||||
|
></circle>
|
||||||
|
<path
|
||||||
|
className="opacity-75"
|
||||||
|
fill="currentColor"
|
||||||
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -9,15 +9,16 @@ const currency = new Intl.NumberFormat("pt-BR", {
|
|||||||
<buy-dropdown class:list={[Astro.props.class]}>
|
<buy-dropdown class:list={[Astro.props.class]}>
|
||||||
<details class="group/dropdown">
|
<details class="group/dropdown">
|
||||||
<summary
|
<summary
|
||||||
class="flex bg-black hover:bg-white hover:text-black font-semibold py-2.5 px-3 rounded-md cursor-pointer transition
|
class="flex bg-black hover:bg-white hover:text-black font-semibold
|
||||||
|
py-2.5 px-3 rounded-md cursor-pointer transition
|
||||||
group-open/dropdown:text-black group-open/dropdown:bg-white"
|
group-open/dropdown:text-black group-open/dropdown:bg-white"
|
||||||
>
|
>
|
||||||
Contratar agora
|
Contratar agora
|
||||||
</summary>
|
</summary>
|
||||||
<form
|
<form
|
||||||
class="absolute inset-x-2.5 translate-y-1.5
|
class="absolute inset-x-2.5 translate-y-1.5
|
||||||
md:inset-auto md:right-2.5 2xl:right-0
|
md:inset-auto md:right-2.5 md:min-w-96 2xl:right-0
|
||||||
md:min-w-96 bg-stone-900 border border-white/15 rounded-xl shadow-lg"
|
bg-stone-900 border border-white/15 rounded-xl shadow-lg"
|
||||||
>
|
>
|
||||||
<h6
|
<h6
|
||||||
class="p-2.5 lg:px-5 lg:py-3.5 font-semibold border-b border-white/10 bg-white/5"
|
class="p-2.5 lg:px-5 lg:py-3.5 font-semibold border-b border-white/10 bg-white/5"
|
||||||
@@ -33,15 +34,15 @@ const currency = new Intl.NumberFormat("pt-BR", {
|
|||||||
class="box-content size-1.5 border-5 border-black bg-black appearance-none rounded-full ring-1 ring-white/15 checked:border-lime-400 checked:ring-lime-400 mt-1.5"
|
class="box-content size-1.5 border-5 border-black bg-black appearance-none rounded-full ring-1 ring-white/15 checked:border-lime-400 checked:ring-lime-400 mt-1.5"
|
||||||
name="selected"
|
name="selected"
|
||||||
type="radio"
|
type="radio"
|
||||||
value={}
|
value="SINGLE"
|
||||||
checked
|
checked
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<p class="uppercase font-semibold">
|
<p class="uppercase font-semibold">
|
||||||
Matrícula única <span
|
Matrícula única
|
||||||
class="px-0.5 text-black bg-lime-400"
|
<span class="px-0.5 text-black bg-lime-400">
|
||||||
>{currency}</span
|
{currency}
|
||||||
>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="text-sm text-white/50">
|
<p class="text-sm text-white/50">
|
||||||
Contratação rápida e sem burocracia
|
Contratação rápida e sem burocracia
|
||||||
@@ -134,6 +135,35 @@ const currency = new Intl.NumberFormat("pt-BR", {
|
|||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
document.addEventListener("click", this.handleClickOutside);
|
document.addEventListener("click", this.handleClickOutside);
|
||||||
|
|
||||||
|
const form = this.querySelector("form") as HTMLFormElement;
|
||||||
|
form.addEventListener("submit", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const radio = form.querySelector(
|
||||||
|
"input[type=radio]:checked",
|
||||||
|
) as HTMLInputElement;
|
||||||
|
|
||||||
|
if (radio.value === "SINGLE") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatch a custom event with the selected solution,
|
||||||
|
// so a React component can listen to it using `window.addEventListener`.
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent("custom_event:react_form", {
|
||||||
|
detail: radio.value,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent("modal:open", {
|
||||||
|
detail: document.querySelector(
|
||||||
|
"#solutionmodal",
|
||||||
|
) as HTMLDialogElement,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
|
|||||||
@@ -1,17 +1,7 @@
|
|||||||
---
|
---
|
||||||
import Container from "~/components/Container.astro";
|
import Container from "~/components/Container.astro";
|
||||||
import Contact from "./Contact.jsx";
|
|
||||||
import Modal from "~/components/Modal.astro";
|
|
||||||
---
|
---
|
||||||
|
|
||||||
{/* Modal */}
|
|
||||||
<Modal id="planform">
|
|
||||||
<h1 class="text-2xl lg:text-4xl font-medium">
|
|
||||||
Preencha os dados da sua empresa
|
|
||||||
</h1>
|
|
||||||
<Contact url={Astro.request.url} client:load />
|
|
||||||
</Modal>
|
|
||||||
|
|
||||||
<Container {...Astro.props}>
|
<Container {...Astro.props}>
|
||||||
<section class="space-y-5 lg:space-y-10 xl:w-4/6 mx-auto">
|
<section class="space-y-5 lg:space-y-10 xl:w-4/6 mx-auto">
|
||||||
<h1 class="text-pretty text-4xl lg:text-6xl">
|
<h1 class="text-pretty text-4xl lg:text-6xl">
|
||||||
@@ -45,7 +35,7 @@ import Modal from "~/components/Modal.astro";
|
|||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
data-toggle="modal"
|
data-toggle="modal"
|
||||||
data-target="#planform"
|
data-target="#solutionmodal"
|
||||||
data-label="EDUSEG® FLEXÍVEL"
|
data-label="EDUSEG® FLEXÍVEL"
|
||||||
class="cursor-pointer font-semibold bg-lime-400 text-black hover:bg-white p-2.5 rounded-lg block text-center transition"
|
class="cursor-pointer font-semibold bg-lime-400 text-black hover:bg-white p-2.5 rounded-lg block text-center transition"
|
||||||
>
|
>
|
||||||
@@ -77,7 +67,7 @@ import Modal from "~/components/Modal.astro";
|
|||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
data-toggle="modal"
|
data-toggle="modal"
|
||||||
data-target="#planform"
|
data-target="#solutionmodal"
|
||||||
data-label="EDUSEG® IN-COMPANY"
|
data-label="EDUSEG® IN-COMPANY"
|
||||||
class="cursor-pointer font-semibold bg-lime-400 text-black hover:bg-white p-2.5 rounded-lg block text-center transition"
|
class="cursor-pointer font-semibold bg-lime-400 text-black hover:bg-white p-2.5 rounded-lg block text-center transition"
|
||||||
>
|
>
|
||||||
@@ -107,7 +97,7 @@ import Modal from "~/components/Modal.astro";
|
|||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
data-toggle="modal"
|
data-toggle="modal"
|
||||||
data-target="#planform"
|
data-target="#solutionmodal"
|
||||||
data-label="EDUSEG® CONTEÚDO"
|
data-label="EDUSEG® CONTEÚDO"
|
||||||
class="cursor-pointer font-semibold bg-lime-400 text-black hover:bg-white p-2.5 rounded-lg block text-center transition"
|
class="cursor-pointer font-semibold bg-lime-400 text-black hover:bg-white p-2.5 rounded-lg block text-center transition"
|
||||||
>
|
>
|
||||||
@@ -139,7 +129,7 @@ import Modal from "~/components/Modal.astro";
|
|||||||
buttons.forEach((e) => {
|
buttons.forEach((e) => {
|
||||||
e.addEventListener("click", (e) => {
|
e.addEventListener("click", (e) => {
|
||||||
const button = e.target as HTMLButtonElement;
|
const button = e.target as HTMLButtonElement;
|
||||||
// Dispatch a custom event with the selected solution label,
|
// Dispatch a custom event with the selected solution,
|
||||||
// so a React component can listen to it using `window.addEventListener`.
|
// so a React component can listen to it using `window.addEventListener`.
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent("custom_event:react_form", {
|
new CustomEvent("custom_event:react_form", {
|
||||||
|
|||||||
@@ -56,4 +56,13 @@ import { Icon } from "astro-icon/components";
|
|||||||
|
|
||||||
el.addEventListener("click", () => openModal(modal));
|
el.addEventListener("click", () => openModal(modal));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.addEventListener("modal:open", function (event: Event) {
|
||||||
|
const customEvent = event as CustomEvent<HTMLDialogElement>;
|
||||||
|
const modal = customEvent.detail;
|
||||||
|
|
||||||
|
if (modal instanceof HTMLDialogElement) {
|
||||||
|
openModal(modal);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import BaseHead, {
|
|||||||
} from "./_components/BaseHead.astro";
|
} from "./_components/BaseHead.astro";
|
||||||
import Header from "./_components/Header.astro";
|
import Header from "./_components/Header.astro";
|
||||||
import Footer from "./_components/Footer.astro";
|
import Footer from "./_components/Footer.astro";
|
||||||
|
import Contact from "~/components/Contact.jsx";
|
||||||
|
import Modal from "~/components/Modal.astro";
|
||||||
|
|
||||||
interface Props extends HeadProps {}
|
interface Props extends HeadProps {}
|
||||||
---
|
---
|
||||||
@@ -32,6 +34,7 @@ interface Props extends HeadProps {}
|
|||||||
dataLayer.push(arguments);
|
dataLayer.push(arguments);
|
||||||
}
|
}
|
||||||
gtag("js", new Date());
|
gtag("js", new Date());
|
||||||
|
|
||||||
// gtag("consent", "default", {
|
// gtag("consent", "default", {
|
||||||
// ad_storage: "denied",
|
// ad_storage: "denied",
|
||||||
// ad_user_data: "denied",
|
// ad_user_data: "denied",
|
||||||
@@ -44,6 +47,14 @@ interface Props extends HeadProps {}
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
{/* Modal */}
|
||||||
|
<Modal id="solutionmodal">
|
||||||
|
<h1 class="text-2xl lg:text-4xl font-medium">
|
||||||
|
Preencha os dados da sua empresa
|
||||||
|
</h1>
|
||||||
|
<Contact url={Astro.request.url} client:load />
|
||||||
|
</Modal>
|
||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
|
|
||||||
<slot name="nav" />
|
<slot name="nav" />
|
||||||
|
|||||||
@@ -86,23 +86,6 @@ const currency = new Intl.NumberFormat("pt-BR", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// window.dataLayer = window.dataLayer || [];
|
|
||||||
// function gtag(...args: any[]) {
|
|
||||||
// window.dataLayer.push(args);
|
|
||||||
// }
|
|
||||||
// gtag("event", "add_to_cart", {
|
|
||||||
// currency: "BRL",
|
|
||||||
// value: parseFloat(unit_price),
|
|
||||||
// items: [
|
|
||||||
// {
|
|
||||||
// item_id: id,
|
|
||||||
// item_name: name,
|
|
||||||
// price: parseFloat(unit_price),
|
|
||||||
// quantity: 1,
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// });
|
|
||||||
|
|
||||||
const r = await checkout(item);
|
const r = await checkout(item);
|
||||||
const json = await r.json();
|
const json = await r.json();
|
||||||
|
|
||||||
|
|||||||
@@ -145,15 +145,36 @@ import mulhercomepi from "~/assets/mulher-com-epi.png";
|
|||||||
<div
|
<div
|
||||||
class="flex flex-col justify-center items-center border-transparent"
|
class="flex flex-col justify-center items-center border-transparent"
|
||||||
>
|
>
|
||||||
<a
|
<button
|
||||||
href="#"
|
data-toggle="modal"
|
||||||
|
data-target="#solutionmodal"
|
||||||
|
data-label="EDUSEG® FLEXÍVEL"
|
||||||
class="font-semibold bg-lime-400 text-black hover:bg-white p-2.5 px-4 rounded-lg block text-center transition"
|
class="font-semibold bg-lime-400 text-black hover:bg-white p-2.5 px-4 rounded-lg block text-center transition"
|
||||||
>
|
>
|
||||||
Saiba mais
|
Saiba mais
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const buttons = document.querySelectorAll(
|
||||||
|
"[data-toggle=modal]",
|
||||||
|
) as NodeListOf<HTMLButtonElement>;
|
||||||
|
|
||||||
|
buttons.forEach((e) => {
|
||||||
|
e.addEventListener("click", (e) => {
|
||||||
|
const button = e.target as HTMLButtonElement;
|
||||||
|
// Dispatch a custom event with the selected solution label,
|
||||||
|
// so a React component can listen to it using `window.addEventListener`.
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent("custom_event:react_form", {
|
||||||
|
detail: button.dataset.label,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user