@@ -19,10 +19,7 @@ import styles from "../main.module.sass";
1919import { createCheckins , useRockdAPI , Image } from "../index" ;
2020import "./main.sass" ;
2121import "@macrostrat/style-system" ;
22- import { LngLatCoords } from "@macrostrat/map-interface" ;
23- import { set } from "react-datepicker/dist/date_utils" ;
24- import { configDefinitionsBuiltInGlobal } from "vike/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn" ;
25- import chroma from "chroma-js" ;
22+ import { MapPosition } from "@macrostrat/mapbox-utils" ;
2623
2724const h = hyper . styled ( styles ) ;
2825
@@ -145,6 +142,9 @@ function WeaverMap({
145142 const style = useMapStyle ( type , mapboxToken , showSatelite , showOverlay ) ;
146143 const [ selectedCheckin , setSelectedCheckin ] = useState ( null ) ;
147144 const [ showSettings , setSettings ] = useState ( false ) ;
145+ const [ showFilter , setFilter ] = useState ( false ) ;
146+ const [ filteredCheckins , setFilteredCheckins ] = useState ( false ) ;
147+ const [ filteredData , setFilteredData ] = useState ( null ) ;
148148
149149 // overlay
150150 const [ inspectPosition , setInspectPosition ] = useState < mapboxgl . LngLat | null > ( null ) ;
@@ -174,8 +174,11 @@ function WeaverMap({
174174 selectedCheckin ? `protected/checkins?checkin_id=${ selectedCheckin } ` : null
175175 ) ;
176176
177- const toolbar = h ( Toolbar , { showSettings, setSettings} ) ;
177+ const toolbar = h ( Toolbar , { showSettings, setSettings, showFilter , setFilter } ) ;
178178 const contextPanel = h ( ContextPanel , { showSettings, showSatelite, setSatelite, showOverlay, setOverlay} ) ;
179+ const autoComplete = h ( AutoComplete , { showFilter, setFilteredCheckins, setFilteredData} ) ;
180+
181+ const test = h ( createFilteredCheckins , { filteredData, setInspectPosition} ) ;
179182
180183 if ( selectedCheckin && checkinData ) {
181184 const clickedCheckins = h ( createSelectedCheckins , { data : checkinData ?. success . data , setInspectPosition} ) ;
@@ -198,6 +201,16 @@ function WeaverMap({
198201 } , "X" ) ,
199202 h ( "div.overlay-div" , clickedCheckins ) ,
200203 ] ) ;
204+ } else if ( filteredCheckins ) {
205+ overlay = h ( "div.sidebox" , [
206+ h ( 'div.sidebox-header' , [
207+ h ( 'div.title' , [
208+ toolbar ,
209+ h ( "h1" , "Filtered Checkins" ) ,
210+ ] ) ,
211+ ] ) ,
212+ h ( "div.overlay-div" , test ) ,
213+ ] ) ;
201214 } else {
202215 overlay = h ( "div.sidebox" , [
203216 h ( 'div.sidebox-header' , [
@@ -212,14 +225,28 @@ function WeaverMap({
212225
213226 if ( style == null ) return null ;
214227
228+ const sidePanel = h ( "div.side-panel" , [
229+ autoComplete ,
230+ contextPanel ,
231+ ] )
232+
233+
234+ const mapPosition : MapPosition = {
235+ camera : {
236+ lat : 0 ,
237+ lng : 0 ,
238+ altitude : 30000000 ,
239+ } ,
240+ } ;
241+
215242 return h (
216243 "div.map-container" ,
217244 [
218245 // The Map Area Container
219246 h (
220247 MapAreaContainer ,
221248 {
222- contextPanel : contextPanel ,
249+ contextPanel : sidePanel ,
223250 className : "map-area-container" ,
224251 style : { "padding-left" : "calc(30% + 14px)" , } ,
225252 } ,
@@ -324,31 +351,40 @@ function FeatureDetails({setInspectPosition}) {
324351 ] ) ;
325352}
326353
327- function Toolbar ( { showSettings, setSettings} ) {
354+ function Toolbar ( { showSettings, setSettings, showFilter , setFilter } ) {
328355 return h ( "div" , { className : "toolbar" , style : { padding : "0" } } , [
329356 h ( "div.toolbar-header" , [
330357 h ( "a" , { href : "/" } ,
331358 h ( Image , { className : "home-icon" , src : "favicon-32x32.png" } ) ,
332359 ) ,
360+ h ( Icon , { className : "settings-icon" , icon : "filter" , onClick : ( ) => {
361+ setFilter ( ! showFilter ) ;
362+ }
363+ } ) ,
333364 h ( Icon , { className : "settings-icon" , icon : "settings" , onClick : ( ) => {
334- setSettings ( ! showSettings ) ;
335- }
365+ setSettings ( ! showSettings ) ;
366+ }
336367 } ) ,
337368 ] ) ,
338369 ] ) ;
339370}
340371
341372function ContextPanel ( { showSettings, showSatelite, setSatelite, showOverlay, setOverlay} ) {
342373 return h ( PanelCard , { className : showSettings ? "settings-content" : "hide" } , [
374+ h ( "div" , { className : "settings-header" } , [
375+ h ( Icon , { className : "settings-icon" , icon : "settings" } ) ,
376+ h ( "h1" , "Settings" ) ,
377+ ] ) ,
378+ h ( Divider , { className : "settings-divider" } ) ,
343379 h ( "div" , { className : "settings" } , [
344380 h ( DarkModeButton , { className : "dark-btn" , showText : true } ) ,
345- h ( PanelCard , { className : "satellite-style" , onClick : ( ) => {
381+ h ( PanelCard , { className : showSatelite ? "selected satellite-style" : "satellite-style" , onClick : ( ) => {
346382 setSatelite ( ! showSatelite ) ;
347383 } } , [
348384 h ( Icon , { className : "satellite-icon" , icon : "satellite" } ) ,
349385 h ( "p" , "Satellite" ) ,
350386 ] ) ,
351- h ( PanelCard , { className : "map-style" , onClick : ( ) => {
387+ h ( PanelCard , { className : showOverlay ? "selected map-style" : "map-style" , onClick : ( ) => {
352388 setOverlay ( ! showOverlay ) ;
353389 } } , [
354390 h ( Icon , { className : "overlay-icon" , icon : "map" } ) ,
@@ -359,22 +395,6 @@ function ContextPanel({showSettings, showSatelite, setSatelite, showOverlay, set
359395 ] )
360396}
361397
362- function handleClusterClick ( ) {
363- const mapRef = useMapRef ( ) ;
364- const map = mapRef . current ;
365- // handle cluster click
366- map ?. on ( 'click' , 'clusters' , ( e ) => {
367- console . log ( "cluster click" ) ;
368- const features = map . queryRenderedFeatures ( e . point , {
369- layers : [ 'clusters' ]
370- } ) ;
371-
372- console . log ( "features" , features [ 0 ] . properties . expansion_zoom ) ;
373- } ) ;
374-
375- return null ;
376- }
377-
378398function ClickedCheckins ( { setSelectedCheckin} ) {
379399 const mapRef = useMapRef ( ) ;
380400 const map = mapRef . current ;
@@ -439,4 +459,193 @@ function createSelectedCheckins(result, setInspectPosition) {
439459 const mapRef = useMapRef ( ) ;
440460
441461 return createCheckins ( result . data , mapRef , setInspectPosition ) ;
462+ }
463+
464+ function createFilteredCheckins ( filteredData , setInspectPosition ) {
465+ const mapRef = useMapRef ( ) ;
466+
467+ return createCheckins ( filteredData ?. filteredData , mapRef , setInspectPosition ) ;
468+ }
469+
470+ function AutoComplete ( { showFilter, setFilteredCheckins, setFilteredData} ) {
471+ const mapRef = useMapRef ( ) ;
472+ const map = mapRef . current ;
473+ const [ filters , setFilters ] = useState ( [ ] ) ;
474+ const [ autocompleteOpen , setAutocompleteOpen ] = useState ( true ) ;
475+ const [ input , setInput ] = useState ( '' ) ;
476+ const [ close , setClose ] = useState ( false ) ;
477+
478+ const person_data = getPersonCheckins ( filters . length > 0 ? filters [ 0 ] . id : 0 ) ?. success . data ;
479+
480+ if ( person_data && person_data . length > 0 ) {
481+ setFilteredCheckins ( true ) ;
482+ setFilteredData ( person_data ) ;
483+ } else {
484+ setFilteredCheckins ( false ) ;
485+ }
486+
487+ // add markers for filtered checkins
488+ let coordinates = [ ] ;
489+ let lngs = [ ] ;
490+ let lats = [ ] ;
491+
492+ if ( person_data && person_data . length > 0 ) {
493+ person_data . forEach ( ( checkin ) => {
494+ coordinates . push ( [ checkin . lng , checkin . lat ] ) ;
495+ lngs . push ( checkin . lng ) ;
496+ lats . push ( checkin . lat ) ;
497+ } ) ;
498+
499+ let previous = document . querySelectorAll ( '.filtered_pin' ) ;
500+ previous . forEach ( ( marker ) => {
501+ marker . remove ( ) ;
502+ } ) ;
503+
504+ let previousFeatured = document . querySelectorAll ( '.marker_pin' ) ;
505+ previousFeatured . forEach ( ( marker ) => {
506+ marker . remove ( ) ;
507+ } ) ;
508+
509+ if ( ! close ) {
510+ let stop = 0 ;
511+ coordinates . forEach ( ( coord ) => {
512+ stop ++ ;
513+ // marker
514+ const el = document . createElement ( 'div' ) ;
515+ el . className = 'filtered_pin' ;
516+
517+ // Create marker
518+ new mapboxgl . Marker ( el )
519+ . setLngLat ( coord )
520+ . addTo ( map ) ;
521+ } ) ;
522+ }
523+
524+ map . fitBounds ( [
525+ [ Math . max ( ...lngs ) , Math . max ( ...lats ) ] ,
526+ [ Math . min ( ...lngs ) , Math . min ( ...lats ) ]
527+ ] , {
528+ maxZoom : 12 ,
529+ duration : 0 ,
530+ padding : 75
531+ } ) ;
532+ }
533+
534+ // rest
535+ const handleInputChange = ( event ) => {
536+ setAutocompleteOpen ( true ) ;
537+ setInput ( event . target . value ) ;
538+ setClose ( false ) ;
539+ } ;
540+
541+ let result = null ;
542+
543+ try {
544+ result = useRockdAPI ( "autocomplete/" + input ) ;
545+ } catch ( e ) {
546+ return null ;
547+ }
548+
549+ let searchBar = h ( 'div.search-bar' , [
550+ h ( 'input' , { type : "text" , placeholder : "Search name" , onChange : handleInputChange } ) ,
551+ h ( 'div.x-icon' , [
552+ h ( Icon , { icon : "cross" , onClick : ( ) => {
553+ let input = document . querySelector ( 'input' ) ;
554+ input . value = "" ;
555+ setAutocompleteOpen ( false ) ;
556+ setClose ( true ) ;
557+ setFilters ( [ ] ) ;
558+
559+ let previous = document . querySelectorAll ( '.filtered_pin' ) ;
560+ previous . forEach ( ( marker ) => {
561+ marker . remove ( ) ;
562+ } ) ;
563+ }
564+ } ) ,
565+ ] ) ,
566+ ] ) ;
567+
568+ let filterContainer = filters . length != 0 ? h ( "div.filter-container" , [
569+ h ( 'h2' , "Filters" ) ,
570+ h ( 'ul' , filters . map ( ( item ) => {
571+ return h ( "div.filter-item" , [
572+ h ( 'li' , item . name ) ,
573+ h ( Icon , { icon : "cross" , style : { color : "red" } , onClick : ( ) => {
574+ setFilters ( filters . filter ( ( filter ) => filter != item ) ) ;
575+ if ( filters . length == 1 ) {
576+ setClose ( true ) ;
577+
578+ let previous = document . querySelectorAll ( '.filtered_pin' ) ;
579+ previous . forEach ( ( marker ) => {
580+ marker . remove ( ) ;
581+ } ) ;
582+ }
583+ }
584+ } )
585+ ] )
586+ } ) ) ,
587+ ] ) : null ;
588+
589+ if ( ! result || close ) return h ( PanelCard , { className : showFilter ? "autocomplete" : "hide" } , [
590+ h ( "div" , { className : "search-header" } , [
591+ h ( Icon , { className : "search-icon" , icon : "filter" } ) ,
592+ h ( "h1" , "Filter Checkins" ) ,
593+ ] ) ,
594+ h ( Divider , { className : "filter-divider" } ) ,
595+ searchBar
596+ ] ) ;
597+ result = result . success . data ;
598+
599+ let taxa = result . taxa . length > 0 && autocompleteOpen ? h ( 'div.taxa' , [
600+ h ( 'h2' , "Taxa" ) ,
601+ h ( 'ul' , result . taxa . map ( ( item ) => {
602+ return h ( 'li' , {
603+ onClick : ( ) => {
604+ if ( ! filters . includes ( item ) ) {
605+ setAutocompleteOpen ( false ) ;
606+ setFilters ( filters . concat ( [ item ] ) ) ;
607+ console . log ( item . id )
608+ }
609+ }
610+ } , item . name ) ;
611+ } ) )
612+ ] ) : null ;
613+
614+ let people = result . people . length > 0 && autocompleteOpen ? h ( 'div.people' , [
615+ h ( 'h2' , "People" ) ,
616+ h ( 'ul' , result . people . map ( ( item ) => {
617+ return h ( 'li' , {
618+ onClick : ( ) => {
619+ if ( ! filters . includes ( item ) ) {
620+ setAutocompleteOpen ( false ) ;
621+ setFilters ( filters . concat ( [ item ] ) ) ;
622+ }
623+ }
624+ } , item . name ) ;
625+ } ) )
626+ ] ) : null ;
627+
628+ const results = h ( "div.results" , [
629+ taxa ,
630+ people ,
631+ ] ) ;
632+
633+ const wrapper = h ( 'div.autocomplete-wrapper' , [
634+ filterContainer ,
635+ results ,
636+ ] ) ;
637+
638+ return h ( PanelCard , { className : showFilter ? "autocomplete" : "hide" } , [
639+ h ( "div" , { className : "search-header" } , [
640+ h ( Icon , { className : "search-icon" , icon : "filter" } ) ,
641+ h ( "h1" , "Filter Checkins" ) ,
642+ ] ) ,
643+ h ( Divider , { className : "filter-divider" } ) ,
644+ searchBar ,
645+ wrapper
646+ ] ) ;
647+ }
648+
649+ function getPersonCheckins ( personId ) {
650+ return useRockdAPI ( "protected/checkins?person_id=" + personId ) ;
442651}
0 commit comments