From 296083577a82e43f4227db3b6229b8c863036834 Mon Sep 17 00:00:00 2001 From: log101 Date: Fri, 5 Jul 2024 18:01:22 +0300 Subject: [PATCH] chore: change endpoint --- bun.lockb | Bin 263740 -> 263682 bytes src/components/LockedContent.tsx | 150 +++++++++++++++-------------- src/env.d.ts | 1 + src/pages/[id].astro | 10 +- src/pages/api/content/increment.ts | 39 -------- src/pages/api/content/index.ts | 141 --------------------------- src/pages/api/debug.ts | 11 --- src/pages/index.astro | 2 +- src/scripts/initMap.js | 2 +- 9 files changed, 89 insertions(+), 267 deletions(-) delete mode 100644 src/pages/api/content/increment.ts delete mode 100644 src/pages/api/content/index.ts delete mode 100644 src/pages/api/debug.ts diff --git a/bun.lockb b/bun.lockb index b363b797eeae55473720a313284b6977b35c0cde..c91bb72fdb8dfdeab0d6662bd48dabd588bbdeea 100755 GIT binary patch delta 5844 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 diff --git a/src/components/LockedContent.tsx b/src/components/LockedContent.tsx index 4569741..8be41ef 100644 --- a/src/components/LockedContent.tsx +++ b/src/components/LockedContent.tsx @@ -1,136 +1,146 @@ -import { Button } from "@/components/ui/button" -import { Card, CardContent } from "@/components/ui/card" +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; -import { LockClosedIcon, LockOpen1Icon } from "@radix-ui/react-icons" -import { useEffect, useState } from "react" +import { LockClosedIcon, LockOpen1Icon } from "@radix-ui/react-icons"; +import { useEffect, useState } from "react"; -import "../styles/locked-content.css" -import type { Generated } from "kysely" -import { onLocationError } from "@/lib/error" +import "../styles/locked-content.css"; +import type { Generated } from "kysely"; +import { onLocationError } from "@/lib/error"; const incrementCounter = async (id: string | Generated) => - await fetch(`${import.meta.env.PUBLIC_HOME_URL}/api/content/increment?id=${id}`) + await fetch(`http://localhost:3000/api/location/increment/${id}`, { + method: "PATCH", + }); const LocationButton = ({ contentId = "", imageUrl = "#", - location = "" + location = "", }: { - contentId?: string | Generated - imageUrl?: string - location?: string + contentId?: string | Generated; + imageUrl?: string; + location?: string; }) => { - const [atTarget, setAtTarget] = useState(false) - const [contentVisible, setContentVisible] = useState(false) - const [hasPermission, setHasPermission] = useState(false) - const [watchId, setWatchId] = useState() - const [distanceRemain, setDistanceRemain] = useState("") + const [atTarget, setAtTarget] = useState(false); + const [contentVisible, setContentVisible] = useState(false); + const [hasPermission, setHasPermission] = useState(false); + const [watchId, setWatchId] = useState(); + const [distanceRemain, setDistanceRemain] = useState(""); - const targetCoordinates = JSON.parse(location).coordinates + const targetCoordinates = JSON.parse(location); + + console.log("coor", targetCoordinates); const targetPos = { lat: targetCoordinates[0], - lng: targetCoordinates[1] - } + lng: targetCoordinates[1], + }; const startWatchingLocation = () => { - setHasPermission(true) + setHasPermission(true); if (!watchId) { const id = navigator.geolocation.watchPosition( (position: GeolocationPosition) => { const pos = { lat: position.coords.latitude, - lng: position.coords.longitude - } + lng: position.coords.longitude, + }; // @ts-expect-error 3rd party script - const targetLatLng = L.latLng(targetPos) + const targetLatLng = L.latLng(targetPos); // @ts-expect-error 3rd party script - const currentLatLng = L.latLng(pos) + const currentLatLng = L.latLng(pos); - const betweenMeters = currentLatLng.distanceTo(targetLatLng) + const betweenMeters = currentLatLng.distanceTo(targetLatLng); if (betweenMeters > 1000) { - setDistanceRemain(`${(betweenMeters / 1000).toFixed()} KM`) + setDistanceRemain(`${(betweenMeters / 1000).toFixed()} KM`); } else if (betweenMeters > 50) { - setDistanceRemain(`${betweenMeters.toFixed(0)} M`) + setDistanceRemain(`${betweenMeters.toFixed(0)} M`); } else { - setAtTarget(true) + setAtTarget(true); } }, - err => onLocationError(err), + (err) => onLocationError(err), { enableHighAccuracy: true, timeout: 27000, maximumAge: 10000 } - ) + ); - setWatchId(id) + setWatchId(id); } - } + }; const handleUnlock = async () => { - setContentVisible(true) - await incrementCounter(contentId) - } + setContentVisible(true); + await incrementCounter(contentId); + }; useEffect(() => { - navigator.permissions.query({ name: "geolocation" }).then(permissionStatus => { - if (permissionStatus.state === "granted") { - setHasPermission(true) - startWatchingLocation() - } - }) - }, []) + navigator.permissions + .query({ name: "geolocation" }) + .then((permissionStatus) => { + if (permissionStatus.state === "granted") { + setHasPermission(true); + startWatchingLocation(); + } + }); + }, []); if (contentVisible) { return ( -
+
- ) + ); } else { return ( -
+
{atTarget ? ( -
- +
+ -
+
- - İçeriği görmek için butona bas! + + + İçeriği görmek için butona bas! +
) : ( -
- -
- - + {hasPermission ? ( - +

İçeriği görmek için konuma gitmelisin!

{distanceRemain && `Kalan mesafe: ${distanceRemain}`}

) : ( -
- +
+ Ne kadar yaklaştığını görmek için aşağıdaki butona bas.
@@ -140,8 +150,8 @@ const LocationButton = ({
)}
- ) + ); } -} +}; -export default LocationButton +export default LocationButton; diff --git a/src/env.d.ts b/src/env.d.ts index 623fcd7..381873d 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -1,3 +1,4 @@ +/// /// /// /// diff --git a/src/pages/[id].astro b/src/pages/[id].astro index b1d6eab..bce0c68 100644 --- a/src/pages/[id].astro +++ b/src/pages/[id].astro @@ -19,16 +19,18 @@ import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import utc from 'dayjs/plugin/utc'; -type Content = Omit; +type Content = ContentTable; const { id } = Astro.params; const res = await fetch( - `${import.meta.env.PUBLIC_HOME_URL}/api/content?id=${id}` + `http://localhost:3000/api/location/${id}` ); const data: Content | null = res.status === 200 ? await res.json() : null; +console.log(data) + dayjs.extend(relativeTime); dayjs.extend(utc); @@ -68,8 +70,8 @@ const dateFromNow = dayjs.utc(data?.created_at).from(dayjs.utc()); diff --git a/src/pages/api/content/increment.ts b/src/pages/api/content/increment.ts deleted file mode 100644 index 3b5b7f8..0000000 --- a/src/pages/api/content/increment.ts +++ /dev/null @@ -1,39 +0,0 @@ -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({ 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" - }) - } -} diff --git a/src/pages/api/content/index.ts b/src/pages/api/content/index.ts deleted file mode 100644 index dbad08f..0000000 --- a/src/pages/api/content/index.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { createClient } from "@supabase/supabase-js" -import type { APIRoute } from "astro" -import { createKysely } from "@vercel/postgres-kysely" -import { customAlphabet } from "nanoid" -import sharpService from "astro/assets/services/sharp" - -import type { Database } from "@/lib/db" - -export const POST: APIRoute = async ({ request }) => { - const formData = await request.formData() - - const image = formData.get("selected-photo") as File - const author = formData.get("author") - const description = formData.get("description") - const geolocation = formData.get("geolocation") - - if (!image || !geolocation) { - return new Response(null, { - status: 400, - statusText: "Image and geolocation are required fields" - }) - } - - const pos = geolocation.toString().split(",") - - if (pos.length !== 2) { - return new Response(null, { - status: 400, - statusText: "Geolocation not correctly formatted" - }) - } - - const supabaseUrl = import.meta.env.SUPABASE_URL - const supabaseKey = import.meta.env.SUPABASE_KEY - const supabase = createClient(supabaseUrl, supabaseKey) - - const nanoid = customAlphabet("abcdefghijklmnoprstuvyz", 10) - - const randomImageId = nanoid() - - const imageName = `${image.name.replace(/\.[^/.]+$/, "")}${randomImageId}.webp` - - const imageBuf = await image.arrayBuffer() - - const { data, format } = await sharpService.transform( - new Uint8Array(imageBuf), - { src: imageName, format: "webp" }, - { domains: [], remotePatterns: [], service: { entrypoint: "", config: { limitInputPixels: false } } } - ) - - console.log(format) - - const { error } = await supabase.storage.from("images").upload(`public/${imageName}`, data, { - cacheControl: "3600", - upsert: false, - contentType: "image/webp" - }) - - if (error) { - console.error(error.message, imageName, error.cause) - return new Response(null, { - status: 400, - statusText: error.message - }) - } - - const imagePublicUrl = `https://sozfqjbdyppxfwhqktja.supabase.co/storage/v1/object/public/images/public/${imageName}` - - const db = createKysely({ connectionString: import.meta.env.POSTGRES_URL }) - - const newUrl = nanoid() - - const res = await db - .insertInto("contents") - .values({ - url: `${newUrl.slice(0, 3)}-${newUrl.slice(3, 7)}-${newUrl.slice(7)}`, - blob_url: imagePublicUrl, - author: author?.toString() ?? "", - description: description?.toString() ?? "", - loc: `SRID=4326;POINT(${pos[0]} ${pos[1]})` - }) - .returning("url") - .executeTakeFirst() - - if (res?.url) { - return new Response( - JSON.stringify({ - url: res.url - }) - ) - } else { - return new Response(null, { - status: 500, - statusText: "Error while saving data" - }) - } -} - -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({ connectionString: import.meta.env.POSTGRES_URL }) - - try { - const content = await db - .selectFrom("contents") - .select(({ fn }) => [ - "id", - "blob_url", - fn("ST_AsGeoJSON", ["loc"]).as("loc"), - "description", - "author", - "created_at", - "unlocked_counter" - ]) - .where("url", "=", contentId) - .executeTakeFirst() - - if (content) { - return new Response(JSON.stringify(content)) - } else { - return new Response(null, { - status: 404, - statusText: "Content not found" - }) - } - } catch (error) { - console.error("Error fetching content:", error) - return new Response(null, { - status: 500, - statusText: "Error while fetching content" - }) - } -} diff --git a/src/pages/api/debug.ts b/src/pages/api/debug.ts deleted file mode 100644 index 75c9874..0000000 --- a/src/pages/api/debug.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { APIRoute } from "astro" - -export const POST: APIRoute = async ({ request }) => { - const data = await request.json() - - console.log(data) - - return new Response(null, { - status: 200 - }) -} diff --git a/src/pages/index.astro b/src/pages/index.astro index 38c313e..063c8cd 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -195,7 +195,7 @@ import { Label } from '@/components/ui/label'; const formData = new FormData(e.target as HTMLFormElement); - const res = await fetch(`/api/content`, { + const res = await fetch(`http://127.0.0.1:3000/api/location`, { method: 'POST', body: formData, }); diff --git a/src/scripts/initMap.js b/src/scripts/initMap.js index 04dd7ab..b2a7b2e 100644 --- a/src/scripts/initMap.js +++ b/src/scripts/initMap.js @@ -1,6 +1,6 @@ const data = JSON.parse(document.getElementById('map').dataset.targetLocation) -const TARGET_LOCATION = data.coordinates +const TARGET_LOCATION = data function startWatchingLocation() { map.locate({ watch: true })