| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * This component ties together all the steps that are needed to create a new point. | 
					
						
							|  |  |  |      * There are many subcomponents which help with that | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     import type {SpecialVisualizationState} from "../../SpecialVisualization"; | 
					
						
							|  |  |  |     import PresetList from "./PresetList.svelte"; | 
					
						
							|  |  |  |     import type PresetConfig from "../../../Models/ThemeConfig/PresetConfig"; | 
					
						
							|  |  |  |     import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"; | 
					
						
							|  |  |  |     import Tr from "../../Base/Tr.svelte"; | 
					
						
							|  |  |  |     import SubtleButton from "../../Base/SubtleButton.svelte"; | 
					
						
							|  |  |  |     import FromHtml from "../../Base/FromHtml.svelte"; | 
					
						
							|  |  |  |     import Translations from "../../i18n/Translations.js"; | 
					
						
							|  |  |  |     import TagHint from "../TagHint.svelte"; | 
					
						
							|  |  |  |     import {And} from "../../../Logic/Tags/And.js"; | 
					
						
							|  |  |  |     import LoginToggle from "../../Base/LoginToggle.svelte"; | 
					
						
							|  |  |  |     import Constants from "../../../Models/Constants.js"; | 
					
						
							|  |  |  |     import FilteredLayer from "../../../Models/FilteredLayer"; | 
					
						
							|  |  |  |     import {Store, UIEventSource} from "../../../Logic/UIEventSource"; | 
					
						
							|  |  |  |     import {EyeIcon, EyeOffIcon} from "@rgossiaux/svelte-heroicons/solid"; | 
					
						
							|  |  |  |     import LoginButton from "../../Base/LoginButton.svelte"; | 
					
						
							|  |  |  |     import NewPointLocationInput from "../../BigComponents/NewPointLocationInput.svelte"; | 
					
						
							|  |  |  |     import CreateNewNodeAction from "../../../Logic/Osm/Actions/CreateNewNodeAction"; | 
					
						
							|  |  |  |     import {OsmWay} from "../../../Logic/Osm/OsmObject"; | 
					
						
							|  |  |  |     import {Tag} from "../../../Logic/Tags/Tag"; | 
					
						
							|  |  |  |     import type {WayId} from "../../../Models/OsmFeature"; | 
					
						
							|  |  |  |     import Loading from "../../Base/Loading.svelte"; | 
					
						
							|  |  |  |     import type {GlobalFilter} from "../../../Models/GlobalFilter"; | 
					
						
							|  |  |  |     import {onDestroy} from "svelte"; | 
					
						
							|  |  |  |     import NextButton from "../../Base/NextButton.svelte"; | 
					
						
							|  |  |  |     import BackButton from "../../Base/BackButton.svelte"; | 
					
						
							| 
									
										
										
										
											2023-05-14 17:59:44 +02:00
										 |  |  |     import ToSvelte from "../../Base/ToSvelte.svelte"; | 
					
						
							|  |  |  |     import Svg from "../../../Svg"; | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     export let coordinate: { lon: number, lat: number }; | 
					
						
							|  |  |  |     export let state: SpecialVisualizationState; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let selectedPreset: { | 
					
						
							|  |  |  |         preset: PresetConfig, | 
					
						
							|  |  |  |         layer: LayerConfig, | 
					
						
							|  |  |  |         icon: string, | 
					
						
							|  |  |  |         tags: Record<string, string> | 
					
						
							|  |  |  |     } = undefined; | 
					
						
							|  |  |  |     let checkedOfGlobalFilters: number = 0 | 
					
						
							|  |  |  |     let confirmedCategory = false; | 
					
						
							|  |  |  |     $: if (selectedPreset === undefined) { | 
					
						
							|  |  |  |         confirmedCategory = false; | 
					
						
							|  |  |  |         creating = false; | 
					
						
							|  |  |  |         checkedOfGlobalFilters = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 03:58:31 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |     let flayer: FilteredLayer = undefined; | 
					
						
							|  |  |  |     let layerIsDisplayed: UIEventSource<boolean> | undefined = undefined; | 
					
						
							|  |  |  |     let layerHasFilters: Store<boolean> | undefined = undefined; | 
					
						
							|  |  |  |     let globalFilter: UIEventSource<GlobalFilter[]> = state.layerState.globalFilters; | 
					
						
							|  |  |  |     let _globalFilter: GlobalFilter[] = []; | 
					
						
							|  |  |  |     onDestroy(globalFilter.addCallbackAndRun(globalFilter => { | 
					
						
							|  |  |  |         console.log("Global filters are", globalFilter); | 
					
						
							|  |  |  |         _globalFilter = globalFilter ?? []; | 
					
						
							|  |  |  |     })); | 
					
						
							|  |  |  |     $:{ | 
					
						
							|  |  |  |         flayer = state.layerState.filteredLayers.get(selectedPreset?.layer?.id); | 
					
						
							|  |  |  |         layerIsDisplayed = flayer?.isDisplayed; | 
					
						
							|  |  |  |         layerHasFilters = flayer?.hasFilter; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const t = Translations.t.general.add; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const zoom = state.mapProperties.zoom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const isLoading = state.dataIsLoading; | 
					
						
							|  |  |  |     let preciseCoordinate: UIEventSource<{ lon: number, lat: number }> = new UIEventSource(undefined); | 
					
						
							|  |  |  |     let snappedToObject: UIEventSource<string> = new UIEventSource<string>(undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let creating = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Call when the user should restart the flow by clicking on the map, e.g. because they disabled filters. | 
					
						
							|  |  |  |      * Will delete the lastclick-location | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function abort() { | 
					
						
							|  |  |  |         state.selectedElement.setData(undefined); | 
					
						
							|  |  |  |         // When aborted, we force the contributors to place the pin _again_ | 
					
						
							|  |  |  |         // This is because there might be a nearby object that was disabled; this forces them to re-evaluate the map | 
					
						
							|  |  |  |         state.lastClickObject.features.setData([]); | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-06 02:20:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |     async function confirm() { | 
					
						
							|  |  |  |         creating = true; | 
					
						
							|  |  |  |         const location: { lon: number; lat: number } = preciseCoordinate.data; | 
					
						
							|  |  |  |         const snapTo: WayId | undefined = <WayId>snappedToObject.data; | 
					
						
							|  |  |  |         const tags: Tag[] = selectedPreset.preset.tags.concat(..._globalFilter.map(f => f?.onNewPoint?.tags ?? [])); | 
					
						
							|  |  |  |         console.log("Creating new point at", location, "snapped to", snapTo, "with tags", tags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let snapToWay: undefined | OsmWay = undefined; | 
					
						
							|  |  |  |         if (snapTo !== undefined) { | 
					
						
							|  |  |  |             const downloaded = await state.osmObjectDownloader.DownloadObjectAsync(snapTo, 0); | 
					
						
							|  |  |  |             if (downloaded !== "deleted") { | 
					
						
							|  |  |  |                 snapToWay = downloaded; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 theme: state.layout?.id ?? "unkown", | 
					
						
							|  |  |  |                 changeType: "create", | 
					
						
							|  |  |  |                 snapOnto: snapToWay | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         await state.changes.applyAction(newElementAction); | 
					
						
							|  |  |  |         state.newFeatures.features.ping(); | 
					
						
							|  |  |  |         // The 'changes' should have created a new point, which added this into the 'featureProperties' | 
					
						
							|  |  |  |         const newId = newElementAction.newElementId; | 
					
						
							|  |  |  |         console.log("Applied pending changes, fetching store for", newId); | 
					
						
							|  |  |  |         const tagsStore = state.featureProperties.getStore(newId); | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Set some metainfo | 
					
						
							|  |  |  |             const properties = tagsStore.data; | 
					
						
							|  |  |  |             if (snapTo) { | 
					
						
							|  |  |  |                 // metatags (starting with underscore) are not uploaded, so we can safely mark this | 
					
						
							|  |  |  |                 delete properties["_referencing_ways"]; | 
					
						
							|  |  |  |                 properties["_referencing_ways"] = `["${snapTo}"]`; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             properties["_backend"] = state.osmConnection.Backend(); | 
					
						
							|  |  |  |             properties["_last_edit:timestamp"] = new Date().toISOString(); | 
					
						
							|  |  |  |             const userdetails = state.osmConnection.userDetails.data; | 
					
						
							|  |  |  |             properties["_last_edit:contributor"] = userdetails.name; | 
					
						
							|  |  |  |             properties["_last_edit:uid"] = "" + userdetails.uid; | 
					
						
							|  |  |  |             tagsStore.ping(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const feature = state.indexedFeatures.featuresById.data.get(newId); | 
					
						
							|  |  |  |         abort(); | 
					
						
							|  |  |  |         state.selectedLayer.setData(selectedPreset.layer); | 
					
						
							|  |  |  |         state.selectedElement.setData(feature); | 
					
						
							|  |  |  |         tagsStore.ping(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <LoginToggle ignoreLoading={true} {state}> | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |     <!-- This component is basically one big if/then/else flow checking for many conditions and edge cases that (in some cases) have to be handled;
 | 
					
						
							|  |  |  |     1. the first (and outermost) is of course: are we logged in? | 
					
						
							|  |  |  |     2. What do we want to add? | 
					
						
							|  |  |  |     3. Are all elements of this category visible? (i.e. there are no filters possibly hiding this, is the data still loading, ...) --> | 
					
						
							|  |  |  |     <LoginButton osmConnection={state.osmConnection} slot="not-logged-in"> | 
					
						
							|  |  |  |         <Tr slot="message" t={Translations.t.general.add.pleaseLogin}/> | 
					
						
							|  |  |  |     </LoginButton> | 
					
						
							|  |  |  |     {#if $isLoading} | 
					
						
							|  |  |  |         <div class="alert"> | 
					
						
							|  |  |  |             <Loading> | 
					
						
							|  |  |  |                 <Tr t={Translations.t.general.add.stillLoading}/> | 
					
						
							|  |  |  |             </Loading> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |     {:else if $zoom < Constants.minZoomLevelToAddNewPoint} | 
					
						
							|  |  |  |         <div class="alert"> | 
					
						
							|  |  |  |             <Tr t={Translations.t.general.add.zoomInFurther}></Tr> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |     {:else if selectedPreset === undefined} | 
					
						
							|  |  |  |         <!-- First, select the correct preset --> | 
					
						
							|  |  |  |         <PresetList {state} on:select={event => {selectedPreset = event.detail}}></PresetList> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {:else if !$layerIsDisplayed} | 
					
						
							|  |  |  |         <!-- Check that the layer is enabled, so that we don't add a duplicate --> | 
					
						
							| 
									
										
										
										
											2023-05-14 17:59:44 +02:00
										 |  |  |         <div class="alert flex  justify-center items-center"> | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |             <EyeOffIcon class="w-8"/> | 
					
						
							|  |  |  |             <Tr t={Translations.t.general.add.layerNotEnabled | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |                     .Subs({ layer: selectedPreset.layer.name }) | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |                    }/> | 
					
						
							|  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 17:59:44 +02:00
										 |  |  |         <div class="flex flex-wrap-reverse md:flex-nowrap"> | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 17:59:44 +02:00
										 |  |  |             <button class="flex w-full gap-x-1" | 
					
						
							|  |  |  |                     on:click={() => {abort();state.guistate.openFilterView(selectedPreset.layer)}}> | 
					
						
							|  |  |  |                 <ToSvelte construct={Svg.layers_svg().SetClass("w-12")}/> | 
					
						
							|  |  |  |                 <Tr t={Translations.t.general.add.openLayerControl}/> | 
					
						
							|  |  |  |             </button> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             <button class="flex w-full gap-x-1 primary" on:click={() => {layerIsDisplayed.setData(true);abort()}}> | 
					
						
							|  |  |  |                 <EyeIcon class="w-12"/> | 
					
						
							|  |  |  |                 <Tr t={Translations.t.general.add.enableLayer.Subs({name: selectedPreset.layer.name})}/> | 
					
						
							|  |  |  |             </button> | 
					
						
							|  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |     {:else if $layerHasFilters} | 
					
						
							|  |  |  |         <!-- Some filters are enabled. The feature to add might already be mapped, but hidden --> | 
					
						
							|  |  |  |         <div class="alert flex justify-center items-center"> | 
					
						
							|  |  |  |             <EyeOffIcon class="w-8"/> | 
					
						
							|  |  |  |             <Tr t={Translations.t.general.add.disableFiltersExplanation}/> | 
					
						
							|  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2023-05-14 17:59:44 +02:00
										 |  |  |         <div class="flex flex-wrap-reverse md:flex-nowrap"> | 
					
						
							|  |  |  |             <button class="flex w-full gap-x-1 primary" | 
					
						
							|  |  |  |                     on:click={() => {abort(); state.layerState.filteredLayers.get(selectedPreset.layer.id).disableAllFilters()}    }> | 
					
						
							|  |  |  |                 <EyeOffIcon class="w-12"/> | 
					
						
							|  |  |  |                 <Tr t={Translations.t.general.add.disableFilters}/> | 
					
						
							|  |  |  |             </button> | 
					
						
							|  |  |  |             <button class="flex w-full gap-x-1" on:click={() => {abort();state.guistate.openFilterView(selectedPreset.layer)}}> | 
					
						
							|  |  |  |                 <ToSvelte construct={Svg.layers_svg().SetClass("w-12")}/> | 
					
						
							|  |  |  |                 <Tr t={Translations.t.general.add.openLayerControl}/> | 
					
						
							|  |  |  |             </button> | 
					
						
							|  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |     {:else if !confirmedCategory  } | 
					
						
							|  |  |  |         <!-- Second, confirm the category --> | 
					
						
							|  |  |  |         <h2> | 
					
						
							|  |  |  |             <Tr t={Translations.t.general.add.confirmTitle.Subs({title: selectedPreset.preset.title})}/> | 
					
						
							|  |  |  |         </h2> | 
					
						
							| 
									
										
										
										
											2023-05-14 17:59:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |         <Tr t={Translations.t.general.add.confirmIntro}/> | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |         {#if selectedPreset.preset.description} | 
					
						
							|  |  |  |             <Tr t={selectedPreset.preset.description}/> | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |         {/if} | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         {#if selectedPreset.preset.exampleImages} | 
					
						
							|  |  |  |             <h3> | 
					
						
							|  |  |  |                 {#if selectedPreset.preset.exampleImages.length === 1} | 
					
						
							|  |  |  |                     <Tr t={Translations.t.general.example}/> | 
					
						
							|  |  |  |                 {:else} | 
					
						
							|  |  |  |                     <Tr t={Translations.t.general.examples }/> | 
					
						
							|  |  |  |                 {/if} | 
					
						
							|  |  |  |             </h3> | 
					
						
							|  |  |  |             <span class="flex flex-wrap items-stretch"> | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |       {#each selectedPreset.preset.exampleImages as src} | 
					
						
							|  |  |  |         <img {src} class="h-64 m-1 w-auto rounded-lg"> | 
					
						
							|  |  |  |       {/each} | 
					
						
							|  |  |  |       </span> | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |         {/if} | 
					
						
							|  |  |  |         <TagHint embedIn={tags => t.presetInfo.Subs({tags})} {state} | 
					
						
							|  |  |  |                  tags={new And(selectedPreset.preset.tags)}></TagHint> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 17:59:44 +02:00
										 |  |  |         <div class="flex w-full flex-wrap-reverse md:flex-nowrap"> | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             <BackButton on:click={() => selectedPreset = undefined} clss="w-full"> | 
					
						
							|  |  |  |                 <Tr slot="message" t={t.backToSelect}/> | 
					
						
							|  |  |  |             </BackButton> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             <NextButton on:click={() => confirmedCategory = true} clss="primary w-full"> | 
					
						
							|  |  |  |                 <div slot="image" class="relative"> | 
					
						
							|  |  |  |                     <FromHtml src={selectedPreset.icon}></FromHtml> | 
					
						
							|  |  |  |                     <img class="absolute bottom-0 right-0 w-4 h-4" src="./assets/svg/confirm.svg"> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |                 <div class="w-full"> | 
					
						
							|  |  |  |                     <Tr t={selectedPreset.text}></Tr> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |             </NextButton> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {:else if _globalFilter?.length > 0 && _globalFilter?.length > checkedOfGlobalFilters} | 
					
						
							|  |  |  |         <Tr t={_globalFilter[checkedOfGlobalFilters].onNewPoint?.safetyCheck}/> | 
					
						
							|  |  |  |         <SubtleButton on:click={() => {checkedOfGlobalFilters = checkedOfGlobalFilters + 1}}> | 
					
						
							|  |  |  |             <img slot="image" src={_globalFilter[checkedOfGlobalFilters].onNewPoint?.icon ?? "./assets/svg/confirm.svg"} | 
					
						
							|  |  |  |                  class="w-12 h-12"> | 
					
						
							|  |  |  |             <Tr slot="message" | 
					
						
							|  |  |  |                 t={_globalFilter[checkedOfGlobalFilters].onNewPoint?.confirmAddNew.Subs({preset: selectedPreset.preset})}/> | 
					
						
							|  |  |  |         </SubtleButton> | 
					
						
							|  |  |  |         <SubtleButton on:click={() => {globalFilter.setData([]); abort()}}> | 
					
						
							|  |  |  |             <img slot="image" src="./assets/svg/close.svg" class="w-8 h-8"/> | 
					
						
							|  |  |  |             <Tr slot="message" t={Translations.t.general.cancel}/> | 
					
						
							|  |  |  |         </SubtleButton> | 
					
						
							|  |  |  |     {:else if !creating} | 
					
						
							| 
									
										
										
										
											2023-05-17 13:57:26 +02:00
										 |  |  |         <div class="w-full p-1"> | 
					
						
							|  |  |  |             <div class="w-full h-96 max-h-screen rounded-xl overflow-hidden"> | 
					
						
							|  |  |  |             <NewPointLocationInput value={preciseCoordinate} snappedTo={snappedToObject} {state} {coordinate} | 
					
						
							|  |  |  |                                    targetLayer={selectedPreset.layer} | 
					
						
							|  |  |  |                                    snapToLayers={selectedPreset.preset.preciseInput.snapToLayers}/> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2023-05-14 17:59:44 +02:00
										 |  |  |         <div class="flex flex-wrap-reverse md:flex-nowrap"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             <BackButton on:click={() => selectedPreset = undefined} clss="w-full"> | 
					
						
							|  |  |  |                 <Tr slot="message" t={t.backToSelect}/> | 
					
						
							|  |  |  |             </BackButton> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             <NextButton on:click={confirm} clss="primary w-full"> | 
					
						
							|  |  |  |                 <div class="w-full flex justify-end gap-x-2"> | 
					
						
							|  |  |  |                     <Tr t={Translations.t.general.add.confirmLocation}/> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |             </NextButton> | 
					
						
							| 
									
										
										
										
											2023-05-14 03:24:13 +02:00
										 |  |  |         </div> | 
					
						
							|  |  |  |     {:else} | 
					
						
							|  |  |  |         <Loading>Creating point...</Loading> | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |     {/if} | 
					
						
							|  |  |  | </LoginToggle> |