chore: move index.astro script to a seperate file
feat: add custom validation for input elements
This commit is contained in:
parent
7cb50bd982
commit
318d1caa9e
|
@ -24,7 +24,6 @@
|
|||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"dayjs": "^1.11.11",
|
||||
"htmx.org": "^1.9.12",
|
||||
"leaflet": "^1.9.4",
|
||||
"lucide-react": "^0.309.0",
|
||||
"react": "^18.3.1",
|
||||
|
|
4
src/env.d.ts
vendored
4
src/env.d.ts
vendored
|
@ -4,10 +4,6 @@
|
|||
/// <reference types="@types/leaflet" />
|
||||
|
||||
export declare global {
|
||||
interface Window {
|
||||
htmx: any
|
||||
}
|
||||
|
||||
namespace astroHTML.JSX {
|
||||
interface HTMLAttributes {
|
||||
_?: any
|
||||
|
|
|
@ -38,11 +38,5 @@
|
|||
<body class='container my-8'>
|
||||
<slot />
|
||||
</body>
|
||||
|
||||
<script>
|
||||
import htmx from "htmx.org";
|
||||
|
||||
window.htmx = htmx;
|
||||
</script>
|
||||
</html>
|
||||
<style is:global></style>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
---
|
||||
export const prerender = true;
|
||||
export const prerender = true
|
||||
|
||||
import "@/styles/globals.css";
|
||||
import "../styles/locked-page.css";
|
||||
import "@/styles/globals.css"
|
||||
import "../styles/locked-page.css"
|
||||
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import Layout from "../layouts/Layout.astro"
|
||||
import { Loader2 } from "lucide-react"
|
||||
---
|
||||
|
||||
<Layout>
|
||||
|
@ -126,84 +127,15 @@ import Layout from "../layouts/Layout.astro";
|
|||
</div>
|
||||
|
||||
<button
|
||||
class='w-full text-lg bg-slate-900 text-white p-2 rounded-lg'
|
||||
class='w-full text-lg bg-slate-900 text-white p-2 rounded-lg inline-flex justify-center items-center gap-2'
|
||||
type='submit'
|
||||
id='submit-button'>
|
||||
<Loader2 id='submit-button-spinner' className='animate-spin hidden' />
|
||||
Bağlantıyı Oluştur
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<script src='../scripts/initSelectionMap.js'></script>
|
||||
<script src='../scripts/initSelectionMap.ts'></script>
|
||||
<script src='../scripts/index.ts'></script>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
import { toast } from "@/lib/utils";
|
||||
|
||||
const handleSubmit = async (e: SubmitEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
const locationSelected = document.getElementById(
|
||||
"location-selected-confirmation"
|
||||
)?.innerText;
|
||||
|
||||
if (!locationSelected) {
|
||||
const coordinatesText = document.getElementById("coordinates");
|
||||
|
||||
const mapDiv = document.getElementById("map");
|
||||
|
||||
mapDiv?.classList.add("border-slate-700");
|
||||
coordinatesText?.classList.add("drop-shadow-xl");
|
||||
|
||||
setTimeout(() => {
|
||||
mapDiv?.classList.remove("border-slate-700");
|
||||
coordinatesText?.classList.remove("drop-shadow-xl");
|
||||
}, 500);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const inputEl = document.getElementById(
|
||||
"photo-selector"
|
||||
) as HTMLInputElement | null;
|
||||
|
||||
if (!inputEl) return;
|
||||
|
||||
const files = inputEl.files;
|
||||
|
||||
if (!files) return;
|
||||
|
||||
if (files.length > 0) {
|
||||
if (files[0].size > 4 * 1024 * 1024) {
|
||||
inputEl.setCustomValidity("Dosya boyutu 4 MB'den küçük olmalıdır.");
|
||||
inputEl.reportValidity();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const submitButton = document.getElementById(
|
||||
"submit-button"
|
||||
) as HTMLButtonElement;
|
||||
|
||||
submitButton.disabled = true;
|
||||
|
||||
const formData = new FormData(e.target as HTMLFormElement);
|
||||
|
||||
const res = await fetch(`http://127.0.0.1:3000/api/location`, {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
});
|
||||
|
||||
submitButton.disabled = false;
|
||||
|
||||
if (res.status === 200) {
|
||||
const data = await res.json();
|
||||
|
||||
if (data.url) location.assign("/" + data.url);
|
||||
} else {
|
||||
toast("Konulu konum oluşturulamadı, lütfen tekrar deneyin.");
|
||||
}
|
||||
};
|
||||
|
||||
document.getElementById("sample-form")!.onsubmit = handleSubmit;
|
||||
</script>
|
||||
</Layout>
|
||||
|
|
99
src/scripts/index.ts
Normal file
99
src/scripts/index.ts
Normal file
|
@ -0,0 +1,99 @@
|
|||
import { addClasses, removeClasses } from "@/components/LockedContent/domUtils"
|
||||
import { toast } from "@/lib/utils"
|
||||
|
||||
export function toggleMap() {
|
||||
const coordinatesText = document.getElementById("coordinates")
|
||||
|
||||
const mapDiv = document.getElementById("map")
|
||||
|
||||
mapDiv?.classList.add("border-slate-900")
|
||||
coordinatesText?.classList.add("drop-shadow-2xl")
|
||||
|
||||
setTimeout(() => {
|
||||
mapDiv?.classList.remove("border-slate-900")
|
||||
coordinatesText?.classList.remove("drop-shadow-2xl")
|
||||
}, 800)
|
||||
}
|
||||
|
||||
export function validateFileInput(el: HTMLInputElement) {
|
||||
const files = el.files
|
||||
|
||||
if (!files) return
|
||||
|
||||
if (files.length > 0) {
|
||||
if (files[0].size > 4 * 1024 * 1024) {
|
||||
el.setCustomValidity("Dosya boyutu 4 MB'den küçük olmalıdır.")
|
||||
el.reportValidity()
|
||||
} else {
|
||||
el.setCustomValidity("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleButton(elemId: string, spinnerId: string) {
|
||||
const elem = document.getElementById(elemId) as HTMLButtonElement | null
|
||||
const spinner = document.getElementById(spinnerId)
|
||||
|
||||
if (!elem) {
|
||||
throw new Error("Element could not be found!")
|
||||
} else if (elem.disabled) {
|
||||
spinner?.classList.add("hidden")
|
||||
removeClasses(elemId, "bg-slate-500")
|
||||
addClasses(elemId, "bg-slate-900")
|
||||
elem.disabled = false
|
||||
} else {
|
||||
spinner?.classList.remove("hidden")
|
||||
removeClasses(elemId, "bg-slate-900")
|
||||
addClasses(elemId, "bg-slate-500")
|
||||
elem.disabled = true
|
||||
setTimeout(() => toggleButton(elemId, spinnerId), 1000)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async (e: SubmitEvent) => {
|
||||
e.preventDefault()
|
||||
toggleButton("submit-button", "submit-button-spinner")
|
||||
const locationSelected = document.getElementById(
|
||||
"geolocation-input"
|
||||
) as HTMLInputElement | null
|
||||
|
||||
if (!locationSelected) {
|
||||
throw new Error("Element could not be found!")
|
||||
}
|
||||
|
||||
if (!locationSelected.value) {
|
||||
const map = document.getElementById("map")
|
||||
map?.scrollIntoView({ behavior: "smooth", block: "center" })
|
||||
return toggleMap()
|
||||
}
|
||||
|
||||
const inputEl = document.getElementById(
|
||||
"photo-selector"
|
||||
) as HTMLInputElement | null
|
||||
|
||||
if (!inputEl) {
|
||||
throw new Error("Element could not be found!")
|
||||
}
|
||||
|
||||
validateFileInput(inputEl)
|
||||
|
||||
const formData = new FormData(e.target as HTMLFormElement)
|
||||
|
||||
const res = await fetch(`http://127.0.0.1:3000/api/location`, {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
})
|
||||
|
||||
if (res.status === 200) {
|
||||
const data = await res.json()
|
||||
|
||||
if (data.url) location.assign("/" + data.url)
|
||||
} else {
|
||||
toast("Konulu konum oluşturulamadı, lütfen tekrar deneyin.")
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("sample-form")!.onsubmit = handleSubmit
|
||||
|
||||
document.getElementById("photo-selector")!.oninput = (ev) =>
|
||||
validateFileInput(ev.target as HTMLInputElement)
|
|
@ -1,3 +1,7 @@
|
|||
import {
|
||||
currentLocationIcon,
|
||||
targetLocationIcon,
|
||||
} from "@/components/Leaflet/icons"
|
||||
import { toast } from "@/lib/utils"
|
||||
import L from "leaflet"
|
||||
|
||||
|
@ -5,16 +9,6 @@ type TargetLocation = [lat: number, lng: number] | null
|
|||
|
||||
const mapEl = document.getElementById("map")
|
||||
|
||||
var targetLocationIcon = L.icon({
|
||||
iconUrl: "goal.svg",
|
||||
iconSize: [32, 32],
|
||||
})
|
||||
|
||||
var currentLocationIcon = L.icon({
|
||||
iconUrl: "blue-dot.png",
|
||||
iconSize: [32, 32],
|
||||
})
|
||||
|
||||
const targetLocation = mapEl?.dataset.targetLocation
|
||||
|
||||
const data = targetLocation ? JSON.parse(targetLocation) : null
|
||||
|
@ -108,10 +102,6 @@ function addTargetLocationMarker(target: TargetLocation) {
|
|||
}
|
||||
}
|
||||
|
||||
function initLocationControls() {
|
||||
addTargetLocationMarker(TARGET_LOCATION)
|
||||
targetLocationControl.addTo(map)
|
||||
goToCurrentLocationControl.addTo(map)
|
||||
}
|
||||
|
||||
addTargetLocationMarker(TARGET_LOCATION)
|
||||
initLocationControls()
|
||||
|
|
|
@ -54,7 +54,6 @@ const CurrentLocationControl = L.Control.extend({
|
|||
locationButton.id = "current-location-control"
|
||||
|
||||
locationButton.addEventListener("click", (ev) => {
|
||||
console.log(currentLocationMarker)
|
||||
if (currentLocationMarker) {
|
||||
map.setView(currentLocationMarker.getLatLng(), 12)
|
||||
} else {
|
||||
|
@ -116,10 +115,18 @@ map.on("click", (e) => {
|
|||
}
|
||||
|
||||
const pos = targetLocationMarker.getLatLng()
|
||||
updateText("coordinates", `${pos.lat}. Enlem, ${pos.lng}. Boylam`)
|
||||
updateInputValue("geolocation-input", `${pos.lat},${pos.lng}`)
|
||||
updateText("coordinates", `${pos.lat}. Enlem, ${pos.lng}. Boylam`)
|
||||
updateText(
|
||||
"location-selected-confirmation",
|
||||
"Konum seçildi, bir sonraki adıma geçebilirsiniz."
|
||||
)
|
||||
})
|
||||
|
||||
const geolocationInputEl = document.getElementById(
|
||||
"geolocation-input"
|
||||
) as HTMLInputElement | null
|
||||
|
||||
if (geolocationInputEl?.value) {
|
||||
geolocationInputEl.value = ""
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user