dropdown
This commit is contained in:
12
superpage/src/components/Course/BuyDropdown.astro
Normal file
12
superpage/src/components/Course/BuyDropdown.astro
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<details class:list={["group relative group", Astro.props.class]}>
|
||||||
|
<summary
|
||||||
|
class="flex bg-black hover:bg-white hover:text-black group-open:text-black group-open:bg-white font-semibold py-2.5 px-3 rounded-md cursor-pointer transition"
|
||||||
|
>
|
||||||
|
<slot name="label" />
|
||||||
|
</summary>
|
||||||
|
<div
|
||||||
|
class="absolute right-0 top-full translate-y-1 bg-stone-900 p-2.5 border border-white/15 min-w-56 rounded-lg shadow drop-shadow"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
---
|
---
|
||||||
|
export type Props = {
|
||||||
|
trainer?: string;
|
||||||
|
};
|
||||||
|
|
||||||
import Clients from "../Clients.astro";
|
import Clients from "../Clients.astro";
|
||||||
import Modules from "./Modules.astro";
|
import Modules from "./Modules.astro";
|
||||||
import Features from "../Features.astro";
|
import Features from "../Features.astro";
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
import { Icon } from "astro-icon/components";
|
import { Icon } from "astro-icon/components";
|
||||||
import Container from "../Container.astro";
|
import Container from "../Container.astro";
|
||||||
|
import BuyDropdown from "./BuyDropdown.astro";
|
||||||
|
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
const courses = await getCollection(
|
const courses = await getCollection(
|
||||||
@@ -24,12 +25,12 @@ const { title } = Astro.props;
|
|||||||
<Icon name="chevron-down" aria-hidden="true" class="size-4 mt-1" />
|
<Icon name="chevron-down" aria-hidden="true" class="size-4 mt-1" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<BuyDropdown class="ml-auto">
|
||||||
type="button"
|
<Fragment slot="label">Contratar agora</Fragment>
|
||||||
class="bg-black hover:bg-white hover:text-black font-semibold py-2.5 px-3 rounded-md cursor-pointer ml-auto transition"
|
<ul>
|
||||||
>
|
<li>...</li>
|
||||||
Contratar agora
|
</ul>
|
||||||
</button>
|
</BuyDropdown>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
<dialog
|
<dialog
|
||||||
|
|||||||
155
superpage/src/components/Course/_bkp.astro
Normal file
155
superpage/src/components/Course/_bkp.astro
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
---
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
import Container from "../Container.astro";
|
||||||
|
|
||||||
|
import { getCollection } from "astro:content";
|
||||||
|
const courses = await getCollection(
|
||||||
|
"courses",
|
||||||
|
({ data }) => data.draft != true,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { title } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<nav
|
||||||
|
class="bg-lime-400 sticky top-0 z-10 py-3 drop-shadow shadow-sm"
|
||||||
|
x-data="{ open: false }"
|
||||||
|
x-on:keydown.esc.prevent.stop="open = false"
|
||||||
|
x-effect="document.body.classList.toggle('overflow-hidden', open)"
|
||||||
|
>
|
||||||
|
<Container class="flex items-center">
|
||||||
|
<button
|
||||||
|
class="text-black font-medium cursor-pointer lg:bg-white/15 hover:outline lg:border border-black lg:py-0.5 lg:px-2.5 rounded-lg transition"
|
||||||
|
x-bind:aria-expanded="open"
|
||||||
|
x-on:click="open = true"
|
||||||
|
aria-haspopup="true"
|
||||||
|
>
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<div class="truncate max-w-36 sm:max-w-72">
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
<Icon
|
||||||
|
name="chevron-down"
|
||||||
|
aria-hidden="true"
|
||||||
|
class="size-4 mt-1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="bg-black hover:bg-white hover:text-black font-semibold py-2.5 px-3 rounded-md cursor-pointer ml-auto transition"
|
||||||
|
>
|
||||||
|
Contratar agora
|
||||||
|
</button>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
{/* Dropdown Menu */}
|
||||||
|
<div
|
||||||
|
x-cloak
|
||||||
|
x-show="open"
|
||||||
|
role="menu"
|
||||||
|
class="absolute top-0 bg-lime-400 w-full py-6 2xl:py-24 rounded-b-2xl drop-shadow shadow-sm max-h-screen overflow-auto"
|
||||||
|
style="display: none;"
|
||||||
|
>
|
||||||
|
<Container class="text-black relative xl:w-10/12 2xl:w-5xl">
|
||||||
|
<button
|
||||||
|
class="absolute border border-black cursor-pointer rounded-full -top-3.5 2xl:-top-21.5 right-2.5"
|
||||||
|
aria-labelledby="Fechar"
|
||||||
|
x-on:click="open = false"
|
||||||
|
>
|
||||||
|
<Icon name="x-mark" class="size-4" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="border-b border-black pb-6 lg:pb-12 mb-6 lg:mb-12">
|
||||||
|
<span>Curso de formação</span>
|
||||||
|
<h1 class="text-xl lg:text-2xl">
|
||||||
|
{title}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex max-lg:flex-col gap-2.5 justify-between mb-3.5">
|
||||||
|
<h6 class="font-medium text-xl lg:text-2xl">
|
||||||
|
Conheça outros cursos da EDUSEG®
|
||||||
|
</h6>
|
||||||
|
|
||||||
|
<div class="flex max-lg:flex-col gap-0.5 lg:gap-4">
|
||||||
|
{/* Search */}
|
||||||
|
<label class="flex gap-1 items-center">
|
||||||
|
<span class="text-nowrap max-lg:w-2/5 text-right"
|
||||||
|
>Buscar por</span
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="flex items-center border rounded px-1.5 py-0.5 lg:px-2 lg:py-1 bg-white/20 focus-within:bg-white w-full"
|
||||||
|
>
|
||||||
|
<input class="outline-none w-full" />
|
||||||
|
<Icon name="magnifying-glass" class="size-5" />
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
{/* Search End */}
|
||||||
|
|
||||||
|
<!-- Filter -->
|
||||||
|
<label class="flex gap-1 items-center">
|
||||||
|
<span class="text-nowrap max-lg:w-2/5 text-right"
|
||||||
|
>Exibir apenas</span
|
||||||
|
>
|
||||||
|
<div class="relative w-full lg:w-30 bg-white/20">
|
||||||
|
<select
|
||||||
|
class="flex border items-center justify-between gap-0.5 border-black rounded px-1.5 py-0.5 lg:px-2 lg:py-1 appearance-none focus:outline-none w-full lowercase"
|
||||||
|
>
|
||||||
|
<option value="formacao">Formação</option>
|
||||||
|
<option value="reciclagem">Reciclagem</option>
|
||||||
|
</select>
|
||||||
|
<Icon
|
||||||
|
name="chevron-down"
|
||||||
|
class="absolute top-2.5 right-2.5 pointer-events-none size-3.5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<!-- Filder End -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div x-data="{ expanded: false }">
|
||||||
|
<div class="relative">
|
||||||
|
<div
|
||||||
|
x-show="! expanded"
|
||||||
|
class="absolute bottom-0 h-16 w-full bg-gradient-to-t from-lime-400 to-lime-400/30"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<ul
|
||||||
|
class="list-disc list-inside max-lg:[&_li]:truncate font-medium overflow-hidden"
|
||||||
|
:class="expanded ? 'h-none' : 'h-36'"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
courses.map(({ data: { title, slug } }) => {
|
||||||
|
return (
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href={`/${slug}`}
|
||||||
|
class=" hover:underline p-0.5"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
:aria-expanded="expanded"
|
||||||
|
x-on:click="expanded = ! expanded"
|
||||||
|
class="border border-black rounded-full px-5 py-1 cursor-pointer mt-2.5"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
x-text="expanded ? 'Ocultar' : 'Exibir todos os cursos'"
|
||||||
|
>
|
||||||
|
Exibir todos os cursos
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
{/* Dropdown Menu End */}
|
||||||
|
</nav>
|
||||||
4
superpage/src/icons/spinner.svg
Normal file
4
superpage/src/icons/spinner.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||||
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||||
|
<path class="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>
|
||||||
|
After Width: | Height: | Size: 349 B |
@@ -19,13 +19,13 @@ import Footer from "./_components/Footer.astro";
|
|||||||
</slot>
|
</slot>
|
||||||
|
|
||||||
<script
|
<script
|
||||||
data-category="analytics"
|
|
||||||
is:inline
|
is:inline
|
||||||
|
data-category="analytics"
|
||||||
type="text/partytown"
|
type="text/partytown"
|
||||||
src="https://www.googletagmanager.com/gtag/js?id=G-G2989LF493"
|
src="https://www.googletagmanager.com/gtag/js?id=G-G2989LF493"
|
||||||
></script>
|
></script>
|
||||||
|
|
||||||
<script data-category="analytics" is:inline type="text/partytown">
|
<script is:inline data-category="analytics" type="text/partytown">
|
||||||
window.dataLayer = window.dataLayer || [];
|
window.dataLayer = window.dataLayer || [];
|
||||||
function gtag() {
|
function gtag() {
|
||||||
dataLayer.push(arguments);
|
dataLayer.push(arguments);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Icon } from "astro-icon/components";
|
|||||||
import Layout from "~/layouts/Layout.astro";
|
import Layout from "~/layouts/Layout.astro";
|
||||||
import Container from "~/components/Container.astro";
|
import Container from "~/components/Container.astro";
|
||||||
import HeaderNav from "~/components/Course/HeaderNav.astro";
|
import HeaderNav from "~/components/Course/HeaderNav.astro";
|
||||||
|
import BuyButton from "./_components/BuyButton.astro";
|
||||||
|
|
||||||
import placeholder from "~/assets/placeholder.png";
|
import placeholder from "~/assets/placeholder.png";
|
||||||
|
|
||||||
@@ -120,17 +121,11 @@ const { Content } = await render(course);
|
|||||||
<div
|
<div
|
||||||
class="flex flex-col justify-center gap-2.5 max-lg:w-full"
|
class="flex flex-col justify-center gap-2.5 max-lg:w-full"
|
||||||
>
|
>
|
||||||
<a
|
<BuyButton
|
||||||
href="#"
|
id={data.id}
|
||||||
class="text-black font-semibold bg-lime-400 rounded p-2.5 max-lg:text-center hover:bg-white hover:text-black transition"
|
name={data.title}
|
||||||
>
|
unitPrice={data.course.unit_price}
|
||||||
Contratar {
|
/>
|
||||||
new Intl.NumberFormat("pt-BR", {
|
|
||||||
style: "currency",
|
|
||||||
currency: "BRL",
|
|
||||||
}).format(data.course.unit_price)
|
|
||||||
} p/ matrícula
|
|
||||||
</a>
|
|
||||||
<a
|
<a
|
||||||
href="#solutions"
|
href="#solutions"
|
||||||
class="text-blue-400 underline hover:no-underline text-center"
|
class="text-blue-400 underline hover:no-underline text-center"
|
||||||
|
|||||||
76
superpage/src/pages/_components/BuyButton.astro
Normal file
76
superpage/src/pages/_components/BuyButton.astro
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
unitPrice: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
const { id, name, unitPrice } = Astro.props;
|
||||||
|
const currency = new Intl.NumberFormat("pt-BR", {
|
||||||
|
style: "currency",
|
||||||
|
currency: "BRL",
|
||||||
|
}).format(unitPrice);
|
||||||
|
---
|
||||||
|
|
||||||
|
<button
|
||||||
|
data-toggle="buy"
|
||||||
|
data-id={id}
|
||||||
|
data-name={name}
|
||||||
|
data-unit_price={unitPrice}
|
||||||
|
class="text-black font-semibold bg-lime-400 rounded p-2.5 max-lg:text-center hover:bg-white hover:text-black transition cursor-pointer disabled:pointer-events-none relative overflow-hidden group"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="absolute bg-lime-400 inset-0 hidden group-disabled:flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<Icon name="spinner" class="size-5 animate-spin" />
|
||||||
|
</div>
|
||||||
|
Contratar {currency} p/ matrícula
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
type Item = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
quantity: number;
|
||||||
|
unit_price: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
async function checkout(item: Item): Promise<Response> {
|
||||||
|
const r = await fetch("https://api.saladeaula.digital/carts/", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ items: [item] }),
|
||||||
|
});
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
const button = document.querySelector(
|
||||||
|
"[data-toggle=buy]",
|
||||||
|
) as HTMLButtonElement;
|
||||||
|
|
||||||
|
button.addEventListener("click", async (e) => {
|
||||||
|
const target = e.target as HTMLButtonElement;
|
||||||
|
const { id, name, unit_price } = target.dataset as {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
unit_price: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const item: Item = {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
quantity: 1,
|
||||||
|
unit_price: parseFloat(unit_price),
|
||||||
|
};
|
||||||
|
|
||||||
|
target.disabled = true;
|
||||||
|
|
||||||
|
const r = await checkout(item);
|
||||||
|
const json = await r.json();
|
||||||
|
location.href = `https://checkout.betaeducacao.com.br/${json.id}`;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user