konulu-konum/src/components/LockedContent.tsx

148 lines
4.8 KiB
TypeScript
Raw Normal View History

2024-01-17 21:50:12 +00:00
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
2024-01-16 14:57:13 +00:00
2024-01-17 21:50:12 +00:00
import { LockClosedIcon, LockOpen1Icon } from "@radix-ui/react-icons"
import { useEffect, useState } from "react"
2024-01-16 14:57:13 +00:00
2024-01-17 21:50:12 +00:00
import "../styles/locked-content.css"
import type { Generated } from "kysely"
2024-01-16 14:57:13 +00:00
const incrementCounter = async (id: string | Generated<string>) =>
await fetch(`${import.meta.env.PUBLIC_HOME_URL}/api/content/increment?id=${id}`)
const LocationButton = ({
contentId = "",
imageUrl = "#",
location = ""
}: {
contentId?: string | Generated<string>
imageUrl?: string
location?: string
}) => {
2024-01-17 21:50:12 +00:00
const [atTarget, setAtTarget] = useState(false)
const [contentVisible, setContentVisible] = useState(false)
const [hasPermission, setHasPermission] = useState(false)
2024-01-18 17:39:47 +00:00
const [watchId, setWatchId] = useState<number>()
const [distanceRemain, setDistanceRemain] = useState<string>("")
const targetCoordinates = JSON.parse(location).coordinates
const targetPos = {
lat: targetCoordinates[0],
lng: targetCoordinates[1]
}
2024-01-17 21:50:12 +00:00
const startWatchingLocation = () => {
setHasPermission(true)
2024-01-18 17:39:47 +00:00
if (!watchId) {
const id = navigator.geolocation.watchPosition(
(position: GeolocationPosition) => {
const pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
}
// @ts-expect-error 3rd party script
const targetLatLng = L.latLng(targetPos)
// @ts-expect-error 3rd party script
const currentLatLng = L.latLng(pos)
const betweenMeters = currentLatLng.distanceTo(targetLatLng)
2024-01-18 17:39:47 +00:00
if (betweenMeters > 1000) {
setDistanceRemain(`${(betweenMeters / 1000).toFixed()} KM`)
} else if (betweenMeters > 50) {
setDistanceRemain(`${betweenMeters.toFixed(0)} M`)
} else {
2024-01-18 17:39:47 +00:00
setAtTarget(true)
}
},
() => null,
{ enableHighAccuracy: true, timeout: 27000, maximumAge: 10000 }
2024-01-18 17:39:47 +00:00
)
setWatchId(id)
}
2024-01-17 21:50:12 +00:00
}
2024-01-16 14:57:13 +00:00
const handleUnlock = async () => {
setContentVisible(true)
await incrementCounter(contentId)
}
useEffect(() => {
navigator.permissions.query({ name: "geolocation" }).then(permissionStatus => {
if (permissionStatus.state === "granted") {
setHasPermission(true)
startWatchingLocation()
}
})
}, [])
2024-01-17 21:50:12 +00:00
if (contentVisible) {
return (
<div className='w-full h-[475px] p-4 flex justify-center'>
<img src={imageUrl} />
</div>
)
2024-01-16 14:57:13 +00:00
} else {
return (
<div className='w-full h-[475px] p-4'>
2024-01-17 21:50:12 +00:00
{atTarget ? (
<div className='flex flex-col justify-center items-center image-wrapper'>
<img src={imageUrl} className='blur-lg h-[450px]' />
2024-01-27 15:23:27 +00:00
<div className='flex flex-col justify-center gap-4 overlay'>
<Button
size='lg'
className='text-lg p-6 animate-pulse bg-indigo-600 hover:bg-indigo-700 hover:animate-none border-2 border-indigo-800'
onClick={handleUnlock}
>
2024-01-17 21:50:12 +00:00
<LockOpen1Icon className='mr-2 h-4 w-4' />
2024-01-16 14:57:13 +00:00
İçeriğin Kilidi ıldı
2024-01-17 21:50:12 +00:00
</Button>
<Card className='p-2'>
<CardContent className='pb-0 text-center'>İçeriği görmek için butona bas!</CardContent>
</Card>
</div>
2024-01-16 14:57:13 +00:00
</div>
2024-01-17 21:50:12 +00:00
) : (
<div className='flex flex-col justify-center items-center image-wrapper'>
<img src={imageUrl} className='blur-lg h-[450px]' />
2024-01-27 15:23:27 +00:00
<div className='flex flex-col justify-center gap-4 overlay'>
<Button size='lg' className='text-md'>
<LockClosedIcon className='mr-2 h-4 w-4' /> İçerik Kilitli
</Button>
<Card className='p-2'>
{hasPermission ? (
<CardContent className='pb-0 text-center'>
<p>İçeriği görmek için konuma gitmelisin!</p>
<p>{distanceRemain && `Kalan mesafe: ${distanceRemain}`}</p>
</CardContent>
) : (
<div className='flex flex-col gap-2'>
<CardContent className='pb-0 text-center'>
Ne kadar yaklaştığını görmek için aşağıdaki butona bas.
</CardContent>
2024-01-16 14:57:13 +00:00
<Button
2024-01-27 15:23:27 +00:00
size='sm'
className='bg-green-700 hover:bg-green-600 text-md'
onClick={() => startWatchingLocation()}
>
Konum İzni Ver
</Button>
</div>
)}
</Card>
</div>
2024-01-17 21:50:12 +00:00
</div>
)}
2024-01-16 14:57:13 +00:00
</div>
2024-01-17 21:50:12 +00:00
)
2024-01-16 14:57:13 +00:00
}
2024-01-17 21:50:12 +00:00
}
2024-01-16 14:57:13 +00:00
2024-01-17 21:50:12 +00:00
export default LocationButton