feat: show counter at the bottom of the page

This commit is contained in:
log101 2024-01-30 20:06:23 +03:00
parent 3060afa59a
commit 75a403ddf2
5 changed files with 67 additions and 8 deletions

View File

@ -6,8 +6,18 @@ import { LockClosedIcon, LockOpen1Icon } from "@radix-ui/react-icons"
import { useEffect, useState } from "react"
import "../styles/locked-content.css"
import type { Generated } from "kysely"
const LocationButton = ({ imageUrl = "#" }: { imageUrl?: string }) => {
const incrementCounter = async (id: string | Generated<string>) =>
await fetch(`${import.meta.env.PUBLIC_HOME_URL}/api/content/increment?id=${id}`)
const LocationButton = ({
contentId = "",
imageUrl = "#"
}: {
contentId?: string | Generated<string>
imageUrl?: string
}) => {
const [atTarget, setAtTarget] = useState(false)
const [contentVisible, setContentVisible] = useState(false)
const [hasPermission, setHasPermission] = useState(false)
@ -37,6 +47,11 @@ const LocationButton = ({ imageUrl = "#" }: { imageUrl?: string }) => {
}
}
const handleUnlock = async () => {
setContentVisible(true)
await incrementCounter(contentId)
}
useEffect(() => {
navigator.permissions.query({ name: "geolocation" }).then(permissionStatus => {
if (permissionStatus.state === "granted") {
@ -60,7 +75,7 @@ const LocationButton = ({ imageUrl = "#" }: { imageUrl?: string }) => {
<img src={imageUrl} className='blur-lg h-[450px]' />
<div className='flex flex-col justify-center gap-4 overlay'>
<Button size='lg' className='text-md' onClick={() => setContentVisible(true)}>
<Button size='lg' className='text-md' onClick={handleUnlock}>
<LockOpen1Icon className='mr-2 h-4 w-4' />
İçeriğin Kilidi ıldı
</Button>

View File

@ -12,4 +12,5 @@ export interface ContentTable {
author: string
description: string
created_at: Generated<string>
unlocked_counter: Generated<number>
}

View File

@ -19,11 +19,13 @@ import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import localeTR from 'dayjs/locale/tr';
type Content = Omit<ContentTable, 'id' | 'url'>;
type Content = Omit<ContentTable, 'url'>;
const { id } = Astro.params;
const res = await fetch(`${import.meta.env.HOME_URL}/api/content?id=${id}`);
const res = await fetch(
`${import.meta.env.PUBLIC_HOME_URL}/api/content?id=${id}`
);
const data: Content | null = res.status === 200 ? await res.json() : null;
@ -65,7 +67,7 @@ const dateFromNow = dayjs(data?.created_at).fromNow();
</CardFooter>
</Card>
<LockedContent imageUrl={data?.blob_url} client:load />
<LockedContent contentId={data?.id} imageUrl={data?.blob_url} client:load />
<div
id="map"
@ -77,7 +79,7 @@ const dateFromNow = dayjs(data?.created_at).fromNow();
<Button className="w-full text-lg" size="lg">Paylaş</Button>
<div class="flex justify-center">
<p class="text-muted-foreground">
Fotoğrafın kilidi şu ana dek <b>2</b> kez açıldı
Fotoğrafın kilidi şu ana dek <b>{data?.unlocked_counter}</b> kez açıldı
</p>
</div>
</main>

View File

@ -0,0 +1,39 @@
import type { Database } from "@/lib/db"
import { createKysely } from "@vercel/postgres-kysely"
import type { APIRoute } from "astro"
export const GET: APIRoute = async ({ request }) => {
const contentId = new URL(request.url).searchParams.get("id")
if (!contentId) {
return new Response(null, {
status: 400,
statusText: "Content id is required"
})
}
const db = createKysely<Database>({ connectionString: import.meta.env.POSTGRES_URL })
try {
const result = await db
.updateTable("contents")
.set(eb => ({ unlocked_counter: eb("unlocked_counter", "+", 1) }))
.where("id", "=", contentId)
.executeTakeFirst()
if (result) {
return new Response(JSON.stringify({ counter: Number(result) }))
} else {
return new Response(null, {
status: 404,
statusText: "Could not increment the counter"
})
}
} catch (error) {
console.error("Error fetching content:", error)
return new Response(null, {
status: 500,
statusText: "Error while fetching content"
})
}
}

View File

@ -3,7 +3,7 @@ import type { APIRoute } from "astro"
import { createKysely } from "@vercel/postgres-kysely"
import { customAlphabet } from "nanoid"
import type { Database } from "../../lib/db"
import type { Database } from "@/lib/db"
export const POST: APIRoute = async ({ request }) => {
const data = await request.formData()
@ -79,11 +79,13 @@ export const GET: APIRoute = async ({ request }) => {
const content = await db
.selectFrom("contents")
.select(({ fn }) => [
"id",
"blob_url",
fn<string>("ST_AsGeoJSON", ["loc"]).as("loc"),
"description",
"author",
"created_at"
"created_at",
"unlocked_counter"
])
.where("url", "=", contentId)
.executeTakeFirst()