app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit a42901b0ade3c06c3f5d999b710044561e6e5b5e
parent 8d15fd0ffcec2d9266eb8d72433e47acd8580462
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Mon,  9 Dec 2024 01:42:41 +0000

Edit `/farm/land/add` add submit handler, edit page handlers. Edit `/farm/land` add display column for models. Add map point display component. Add/edit utils.

Diffstat:
Asrc/lib/components/map_point_display.svelte | 23+++++++++++++++++++++++
Msrc/lib/util/client.ts | 22++++++++++++++++++++--
Rsrc/lib/util/models.ts -> src/lib/util/models-location-gcs.ts | 0
Msrc/routes/(app)/farm/land/+page.svelte | 101++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/routes/(app)/farm/land/add/+page.svelte | 48++++++++++++++++++++++++++++++++----------------
Msrc/routes/(app)/models/trade-product/add/+page.svelte | 4++--
6 files changed, 172 insertions(+), 26 deletions(-)

diff --git a/src/lib/components/map_point_display.svelte b/src/lib/components/map_point_display.svelte @@ -0,0 +1,23 @@ +<script lang="ts"> + import { cfg } from "$lib/conf"; + import { app_thc } from "@radroots/svelte-lib"; + import { MapLibre, Marker } from "@radroots/svelte-maplibre"; + import type { GeolocationCoordinatesPoint } from "@radroots/utils"; + import MapMarkerDot from "./map_marker_dot.svelte"; + + export let basis: { + point: GeolocationCoordinatesPoint; + }; +</script> + +<MapLibre + center={basis.point} + zoom={4} + class={`h-full w-full`} + style={cfg.map.styles.base[$app_thc]} + attributionControl={false} +> + <Marker bind:lngLat={basis.point} draggable={false}> + <MapMarkerDot /> + </Marker> +</MapLibre> diff --git a/src/lib/util/client.ts b/src/lib/util/client.ts @@ -1,5 +1,5 @@ -import { db, keystore } from "$lib/client"; -import { app_notify, catch_err, el_id, route, sleep, type NavigationRoute } from "@radroots/svelte-lib"; +import { db, dialog, keystore } from "$lib/client"; +import { app_notify, catch_err, el_id, route, sleep, type CallbackPromise, type NavigationRoute } from "@radroots/svelte-lib"; import type { ThemeLayer } from "@radroots/theme"; import type { ErrorMessage } from "@radroots/utils"; @@ -13,6 +13,24 @@ export const keystore_reset = async (): Promise<ErrorMessage<string> | undefined } }; +export const callback_alert = async (message: string, callback: CallbackPromise): Promise<void> => { + try { + dialog.alert(message); + await callback(); + } catch (e) { + await catch_err(e, `cb_alert`); + } +}; + +export const page_reload = async (message?: string): Promise<void> => { + try { + if (message) dialog.alert(message); + location.reload(); + } catch (e) { + await catch_err(e, `page_reload`); + } +}; + export const restart = async (opts?: { notify_message?: string; route?: NavigationRoute; diff --git a/src/lib/util/models.ts b/src/lib/util/models-location-gcs.ts diff --git a/src/routes/(app)/farm/land/+page.svelte b/src/routes/(app)/farm/land/+page.svelte @@ -1,14 +1,18 @@ <script lang="ts"> import { db } from "$lib/client"; + import MapPointDisplay from "$lib/components/map_point_display.svelte"; import type { LocationGcs } from "@radroots/models"; import { - Fill, + ButtonGlyphSimple, + Fade, LayoutView, NavToolbar, PageHeader, TabsFloat, app_notify, catch_err, + fmt_geol_latitude, + fmt_geol_longitude, ls, route, } from "@radroots/svelte-lib"; @@ -43,13 +47,100 @@ await catch_err(e, `load_data`); } }; + + $: { + console.log(JSON.stringify(ld, null, 4), `ld`); + } </script> <LayoutView> <NavToolbar /> - <PageHeader basis={{ label: `${$ls(`common.farm_land`)}` }} /> + <PageHeader basis={{ label: `${$ls(`common.farm_land`)}` }}> + <div slot="option" class={`flex flex-row justify-start items-center`}> + {#if ld && ld.location_gcss.length} + <Fade> + <ButtonGlyphSimple + basis={{ + label: `${$ls(`common.add`)}`, + callback: async () => { + await route(`/farm/land/add`); + }, + }} + /> + </Fade> + {/if} + </div> + </PageHeader> <div class={`flex flex-col w-full px-4 justify-start items-center`}> - <button + {#if ld && ld.location_gcss.length} + {#each ld.location_gcss.filter((i) => i.kind === `farm_land`) as li} + <button + class={`group flex flex-row h-[5rem] w-full px-8 gap-8 justify-start items-center bg-layer-1-surface layer-1-active-surface round-36 el-re`} + on:click={async () => { + await route(`/farm/land/add`); + }} + > + <div + class={`flex flex-col h-[4rem] w-[4rem] justify-start items-center bg-layer-2-surface round-24`} + > + <MapPointDisplay + basis={{ + point: { + lat: li.lat, + lng: li.lng, + }, + }} + /> + </div> + <div + class={`flex flex-col flex-grow h-[3.25rem] justify-between items-start`} + > + <div + class={`flex flex-row w-full justify-start items-center`} + > + <p + class={`font-sans font-[500] text-layer-0-glyph`} + > + {`${ + li.label || + `${fmt_geol_latitude( + li.lat, + `d`, + 4, + )}, ${fmt_geol_longitude(li.lng, `d`, 4)}` + }`} + </p> + </div> + <div + class={`flex flex-row w-full gap-2 justify-start items-center`} + > + {#if li.kind === `farm_land`} + <div + class={`flex flex-row h-5 px-2 justify-center items-center bg-layer-2-surface rounded-md`} + > + <p + class={`font-sans font-[700] text-[0.8rem] text-white`} + > + {`${$ls(`common.farm`)}`} + </p> + </div> + {/if} + <p + class={`font-sansd font-[500] text-layer-0-glyph`} + > + {`${li.gc_name}, ${li.gc_admin1_id}, ${li.gc_country_id}`} + </p> + </div> + </div> + </button> + {/each} + {/if} + </div> +</LayoutView> +<TabsFloat /> + +<!-- +<button class={`group flex flex-row h-[7rem] w-full px-8 justify-start items-center bg-layer-1-surface layer-1-active-surface round-36 el-re`} on:click={async () => { await route(`/farm/land/add`); @@ -68,6 +159,4 @@ </p> </div> </button> - </div> -</LayoutView> -<TabsFloat /> + --> diff --git a/src/routes/(app)/farm/land/add/+page.svelte b/src/routes/(app)/farm/land/add/+page.svelte @@ -1,11 +1,13 @@ <script lang="ts"> import { dialog, geol } from "$lib/client"; import MapPointSelect from "$lib/components/map_point_select.svelte"; + import { callback_alert } from "$lib/util/client"; import { kv_init_page } from "$lib/util/kv"; + import { model_location_gcs_add_geocode } from "$lib/util/models-location-gcs"; import type { IClientGeolocationPosition } from "@radroots/client"; import type { GeocoderReverseResult } from "@radroots/geocoder"; import { - ButtonGlyphPrimary, + ButtonGlyphSimple, carousel_dec, carousel_inc, carousel_index, @@ -24,7 +26,7 @@ PageHeader, SelectMenu, } from "@radroots/svelte-lib"; - import { num_str, regex } from "@radroots/utils"; + import { regex } from "@radroots/utils"; import { onMount } from "svelte"; let view_init: View = `c_1`; @@ -41,11 +43,6 @@ let lgcs_elevation_unit = `m`; let lgcs_climate = ``; - $: lgcs_elevation = - typeof geol_pos?.altitude === `number` - ? num_str(geol_pos.altitude) - : lgcs_elevation; - onMount(async () => { try { await init_page(); @@ -57,7 +54,7 @@ const init_page = async (): Promise<void> => { try { await kv_init_page(); - carousel_init(1); + await carousel_init(view, 1); const geolc = await geol.current(); if (`err` in geolc) { await dialog.alert( @@ -86,6 +83,25 @@ await catch_err(e, `handle_dec`); } }; + + const submit = async (): Promise<void> => { + try { + if (!geol_pos || !geol_c) + return await callback_alert( + `${$ls(`error.geolocation.result_missing`)}`, + async () => await init_page(), + ); + + const location_gcs = await model_location_gcs_add_geocode({ + geo_code: geol_c, + point: geol_pos, + kind: `farm_land`, + }); + console.log(JSON.stringify(location_gcs, null, 4), `location_gcs`); + } catch (e) { + await catch_err(e, `submit`); + } + }; </script> <LayoutView> @@ -103,7 +119,7 @@ <div slot="option" class={`flex flex-row justify-start items-center`}> {#if $carousel_index > 0} <Fade> - <ButtonGlyphPrimary + <ButtonGlyphSimple basis={{ label: `${$ls(`common.back`)}`, callback: async () => { @@ -142,7 +158,7 @@ <div class={`flex flex-col w-full pt-2 justify-center items-center`} > - <ButtonGlyphPrimary + <ButtonGlyphSimple basis={{ label: `${$ls(`icu.add_*`, { value: `${$ls(`common.location`)}` })}`, callback: async () => { @@ -248,7 +264,7 @@ sync: true, layer: 0, classes: `h-10 placeholder:text-[1.1rem]`, - placeholder: `Name of farm or estate`, + placeholder: `${$ls(`common.name_of_farm_or_estate`)}`, field: { charset: regex.description, validate: regex.description_ch, @@ -312,7 +328,7 @@ sync: true, layer: 0, classes: `h-10 placeholder:text-[1.1rem]`, - placeholder: `Land area`, + placeholder: `${$ls(`common.land_area`)}`, field: { charset: regex.num, validate: regex.num, @@ -372,7 +388,7 @@ sync: true, layer: 0, classes: `h-10 placeholder:text-[1.1rem]`, - placeholder: `Elevation`, + placeholder: `${$ls(`common.elevation`)}`, field: { charset: regex.num, validate: regex.num, @@ -404,7 +420,7 @@ sync: true, layer: 0, classes: `h-10 placeholder:text-[1.1rem]`, - placeholder: `Local climate`, + placeholder: `${$ls(`common.climate`)}`, field: { charset: regex.description, validate: regex.description_ch, @@ -417,11 +433,11 @@ <div class={`flex flex-row w-full pt-2 justify-center items-center`} > - <ButtonGlyphPrimary + <ButtonGlyphSimple basis={{ label: `${$ls(`icu.add_*`, { value: `${$ls(`common.location`)}` })}`, callback: async () => { - if (geol_c) await handle_inc(); + await submit(); }, }} /> diff --git a/src/routes/(app)/models/trade-product/add/+page.svelte b/src/routes/(app)/models/trade-product/add/+page.svelte @@ -8,7 +8,7 @@ import { el_focus } from "$lib/util/client"; import { location_gcs_to_geoc } from "$lib/util/geocode"; import { kv_init_page, kv_sync } from "$lib/util/kv"; - import { model_location_gcs_add_geocode } from "$lib/util/models"; + import { model_location_gcs_add_geocode } from "$lib/util/models-location-gcs"; import { model_media_upload_add_list } from "$lib/util/models-media-upload"; import { trade_product_fields_validate, @@ -471,7 +471,7 @@ await model_location_gcs_add_geocode({ geo_code: tradepr_lgc_map_geoc, point: tradepr_lgc_map_point, - kind: `trade_product`, + kind: `trade_product`, //@todo }); if ( `err` in location_gcs_add_geocode ||