feat: add templates for buttons
This commit is contained in:
parent
68750ad964
commit
5821818618
|
@ -26,6 +26,7 @@
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.0",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
|
"htmx.org": "^1.9.12",
|
||||||
"kysely": "^0.26.0",
|
"kysely": "^0.26.0",
|
||||||
"lucide-react": "^0.309.0",
|
"lucide-react": "^0.309.0",
|
||||||
"nanoid": "^5.0.4",
|
"nanoid": "^5.0.4",
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
---
|
---
|
||||||
|
import { LockClosedIcon } from "@radix-ui/react-icons";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
contentId?: string;
|
contentId?: string;
|
||||||
imageUrl: string;
|
imageUrl: string;
|
||||||
|
@ -9,8 +11,47 @@ const { contentId = "", imageUrl = "#", location = "" } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<template id="locked-content-template">
|
<template id="locked-content-template">
|
||||||
<link rel="stylesheet" href="css/tailwind.css" />
|
<div
|
||||||
|
class="w-full h-[475px] overflow-hidden border border-zinc-200 shadow-sm p-4 rounded"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col justify-center items-center image-wrapper">
|
||||||
|
<img id="content" src="#" class="blur-2xl h-[450px]" />
|
||||||
|
|
||||||
|
<div class="flex flex-col justify-center gap-4 overlay">
|
||||||
|
<template id="unlock-content-button-template">
|
||||||
|
<button
|
||||||
|
id="unlock-content-button"
|
||||||
|
class="inline-flex items-center justify-center whitespace-nowrap font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 text-primary-foreground h-11 rounded-md text-lg p-6 animate-pulse bg-indigo-600 hover:bg-indigo-700 hover:animate-none border-2 border-indigo-800"
|
||||||
|
>
|
||||||
|
İçeriğin Kilidi Açıldı
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="unlock-content-button-template-locked">
|
||||||
|
<button
|
||||||
|
class="inline-flex items-center justify-center whitespace-nowrap font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-11 rounded-md px-8 text-md"
|
||||||
|
>
|
||||||
|
<LockClosedIcon className="mr-2 h-4 w-4" /> İçerik Kilitli
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<slot name="locked-content-button" />
|
||||||
|
<unlock-content-button></unlock-content-button>
|
||||||
|
|
||||||
|
<slot name="locked-content-description">
|
||||||
|
<div
|
||||||
|
class="rounded-lg border bg-card text-card-foreground shadow-sm p-2"
|
||||||
|
>
|
||||||
|
<div class="pb-0 px-4 text-center">
|
||||||
|
İçeriği görmek için butona bas!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
@import url("css/tailwind.css");
|
||||||
.image-wrapper {
|
.image-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
@ -26,69 +67,9 @@ const { contentId = "", imageUrl = "#", location = "" } = Astro.props;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div
|
|
||||||
class="w-full h-[475px] overflow-hidden border border-zinc-200 shadow-sm p-4 rounded"
|
|
||||||
>
|
|
||||||
<div class="flex flex-col justify-center items-center image-wrapper">
|
|
||||||
<img src={imageUrl} class="blur-2xl h-[450px]" />
|
|
||||||
|
|
||||||
<div class="flex flex-col justify-center gap-4 overlay">
|
|
||||||
<button
|
|
||||||
id="unlock-content-button"
|
|
||||||
class="inline-flex items-center justify-center whitespace-nowrap font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 text-primary-foreground h-11 rounded-md text-lg p-6 animate-pulse bg-indigo-600 hover:bg-indigo-700 hover:animate-none border-2 border-indigo-800"
|
|
||||||
>
|
|
||||||
İçeriğin Kilidi Açıldı
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="rounded-lg border bg-card text-card-foreground shadow-sm p-2"
|
|
||||||
>
|
|
||||||
<div class="pb-0 text-center">İçeriği görmek için butona bas!</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<locked-content contentId={contentId}></locked-content>
|
<locked-content contentId={contentId} imageURL={imageUrl} id="locked-content"
|
||||||
|
></locked-content>
|
||||||
|
|
||||||
<script>
|
<script src="../components/locked-content.ts"></script>
|
||||||
customElements.define(
|
|
||||||
"locked-content",
|
|
||||||
class extends HTMLElement {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
// Clone the template
|
|
||||||
let template = document.getElementById(
|
|
||||||
"locked-content-template"
|
|
||||||
) as HTMLTemplateElement;
|
|
||||||
let templateContent = template.content;
|
|
||||||
|
|
||||||
// Get attributes
|
|
||||||
const contentId = this.getAttribute("contentId");
|
|
||||||
|
|
||||||
// Attach cloned template to DOM
|
|
||||||
const shadowRoot = this.attachShadow({ mode: "open" });
|
|
||||||
shadowRoot.appendChild(templateContent.cloneNode(true));
|
|
||||||
|
|
||||||
// Add onclick listener to unlock content button
|
|
||||||
const unlockContentButton = shadowRoot.getElementById(
|
|
||||||
"unlock-content-button"
|
|
||||||
);
|
|
||||||
const incrementCounter = async (id: string) =>
|
|
||||||
await fetch(`http://localhost:3000/api/location/increment/${id}`, {
|
|
||||||
method: "PATCH",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (unlockContentButton) {
|
|
||||||
unlockContentButton.addEventListener("click", () => {
|
|
||||||
if (contentId) {
|
|
||||||
incrementCounter(contentId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
62
src/components/locked-content.ts
Normal file
62
src/components/locked-content.ts
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
class LockedContent extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Clone the template
|
||||||
|
let template = document.getElementById(
|
||||||
|
"locked-content-template"
|
||||||
|
) as HTMLTemplateElement;
|
||||||
|
let templateContent = template.content;
|
||||||
|
|
||||||
|
// Get attributes
|
||||||
|
const contentId = this.getAttribute("contentId");
|
||||||
|
const imageURL = this.getAttribute("imageURL") ?? "#";
|
||||||
|
|
||||||
|
// Fetch functions
|
||||||
|
const incrementCounter = async (id: string) =>
|
||||||
|
await fetch(`http://localhost:3000/api/location/increment/${id}`, {
|
||||||
|
method: "PATCH",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Attach cloned template to DOM
|
||||||
|
const shadowRoot = this.attachShadow({ mode: "open" });
|
||||||
|
shadowRoot.appendChild(templateContent.cloneNode(true));
|
||||||
|
|
||||||
|
// Set image source URL
|
||||||
|
const content = shadowRoot.getElementById("content") as HTMLImageElement;
|
||||||
|
content.src = imageURL;
|
||||||
|
|
||||||
|
// Add onclick listener to unlock content button
|
||||||
|
const unlockContentButton = shadowRoot.getElementById(
|
||||||
|
"unlock-content-button"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (unlockContentButton) {
|
||||||
|
unlockContentButton.addEventListener("click", () => {
|
||||||
|
if (contentId) {
|
||||||
|
incrementCounter(contentId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnlockContentButton extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
const host = document.getElementById("locked-content");
|
||||||
|
|
||||||
|
if (host) {
|
||||||
|
let template = host.shadowRoot?.getElementById(
|
||||||
|
"unlock-content-button-template"
|
||||||
|
) as HTMLTemplateElement;
|
||||||
|
let templateContent = template.content;
|
||||||
|
|
||||||
|
this.appendChild(templateContent.cloneNode(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("locked-content", LockedContent);
|
||||||
|
customElements.define("unlock-content-button", UnlockContentButton);
|
6
src/env.d.ts
vendored
6
src/env.d.ts
vendored
|
@ -2,3 +2,9 @@
|
||||||
/// <reference types="astro/client" />
|
/// <reference types="astro/client" />
|
||||||
/// <reference types="@types/google.maps" />
|
/// <reference types="@types/google.maps" />
|
||||||
/// <reference types="@types/leaflet" />
|
/// <reference types="@types/leaflet" />
|
||||||
|
|
||||||
|
export declare global {
|
||||||
|
interface Window {
|
||||||
|
htmx: any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -38,5 +38,11 @@
|
||||||
<body class="container my-8">
|
<body class="container my-8">
|
||||||
<slot />
|
<slot />
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import htmx from "htmx.org";
|
||||||
|
|
||||||
|
window.htmx = htmx;
|
||||||
|
</script>
|
||||||
</html>
|
</html>
|
||||||
<style is:global></style>
|
<style is:global></style>
|
||||||
|
|
|
@ -67,6 +67,12 @@ const dateFromNow = dayjs.utc(data?.created_at).from(dayjs.utc());
|
||||||
<p>{dateFromNow}</p>
|
<p>{dateFromNow}</p>
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
<WebComponentWrapper
|
||||||
|
contentId={data?.url}
|
||||||
|
imageUrl={`http://localhost:3000/images/${data?.blob_url}`}
|
||||||
|
location={data?.loc}
|
||||||
|
/>
|
||||||
<LockedContent
|
<LockedContent
|
||||||
contentId={data?.url}
|
contentId={data?.url}
|
||||||
imageUrl={`http://localhost:3000/images/${data?.blob_url}`}
|
imageUrl={`http://localhost:3000/images/${data?.blob_url}`}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user