diff --git a/README.md b/README.md deleted file mode 100644 index fd5a8f3..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# ZG \ No newline at end of file diff --git a/app/.deploy/settings.sample.json b/app/.deploy/settings.sample.json index e69de29..8b13789 100644 --- a/app/.deploy/settings.sample.json +++ b/app/.deploy/settings.sample.json @@ -0,0 +1 @@ + diff --git a/app/.meteor/packages b/app/.meteor/packages index 4a965dd..a9b4cd2 100644 --- a/app/.meteor/packages +++ b/app/.meteor/packages @@ -44,3 +44,4 @@ hot-module-replacement@0.5.3 dev-error-overlay@0.1.2 http ostrio:files +webapp diff --git a/app/client/main.js b/app/client/main.js index 93627c8..76519f7 100644 --- a/app/client/main.js +++ b/app/client/main.js @@ -1,3 +1,5 @@ import '../imports/startup/client/Startup'; import 'bootstrap/dist/css/bootstrap.min.css'; import './style.css'; + + diff --git a/app/client/style.css b/app/client/style.css index fd9b974..d124fe6 100644 --- a/app/client/style.css +++ b/app/client/style.css @@ -6,4 +6,4 @@ .landing-white-background img { margin-bottom: 50px; -} +} \ No newline at end of file diff --git a/app/imports/api/modcard/modcard.js b/app/imports/api/modcard/modcard.js new file mode 100644 index 0000000..81a4e8a --- /dev/null +++ b/app/imports/api/modcard/modcard.js @@ -0,0 +1,22 @@ +import { Mongo } from 'meteor/mongo'; +import SimpleSchema from 'simpl-schema'; + +class ModCardsCollection { + constructor() { + this.name = 'ModCardsCollection'; + this.collection = new Mongo.Collection(this.name); + this.schema = new SimpleSchema({ + type: String, + image: { type: String, optional: true }, + cost: String, + detail: String, + address: String, + createdAt: Date, + owner: String, + }); + this.collection.attachSchema(this.schema); + this.userPublicationName = `${this.name}.publication.user`; + } +} + +export const ModCards = new ModCardsCollection(); diff --git a/app/imports/startup/server/Method.js b/app/imports/startup/server/Method.js index add56b2..8f94ed4 100644 --- a/app/imports/startup/server/Method.js +++ b/app/imports/startup/server/Method.js @@ -2,12 +2,6 @@ import { Meteor } from 'meteor/meteor'; import { HTTP } from 'meteor/http'; import cloudinary from 'cloudinary'; -cloudinary.config({ - cloud_name: 'you-own-key', - api_key: 'you-own-key', - api_secret: 'you-own-key', -}); - Meteor.methods({ // eslint-disable-next-line meteor/audit-argument-checks async generateImage(prompt) { @@ -15,7 +9,7 @@ Meteor.methods({ const response = await HTTP.call('POST', 'https://api.openai.com/v1/images/generations', { headers: { 'Content-Type': 'application/json', - Authorization: `Bearer ${'you-own-key'}`, + Authorization: `Bearer ${'your key'}`, }, data: { model: 'dall-e-3', diff --git a/app/imports/startup/server/Mongo.js b/app/imports/startup/server/Mongo.js index f4f2d25..640f24b 100644 --- a/app/imports/startup/server/Mongo.js +++ b/app/imports/startup/server/Mongo.js @@ -4,6 +4,7 @@ import { Posts } from '../../api/post/post'; import { Comments } from '../../api/comment/comment'; import { Surveys } from '../../api/survey/survey'; import { Votes } from '../../api/vote/vote'; +import { ModCards } from '../../api/modcard/modcard'; const addProfile = (profile) => { console.log(` Adding: ${profile.firstName} (${profile.owner})`); @@ -64,3 +65,15 @@ if (Comments.collection.find().count() === 0) { Meteor.settings.defaultComments.forEach(data => addComment(data)); } } + +const addModCard = (modcard) => { + console.log(` Adding: ${modcard.address}`); + ModCards.collection.insert(modcard); +}; + +if (ModCards.collection.find().count() === 0) { + if (Meteor.settings.defaultModCards) { + console.log('Creating default modcards.'); + Meteor.settings.defaultModCards.forEach(data => addModCard(data)); + } +} diff --git a/app/imports/startup/server/Publications.js b/app/imports/startup/server/Publications.js index b67482b..2f24a71 100644 --- a/app/imports/startup/server/Publications.js +++ b/app/imports/startup/server/Publications.js @@ -4,6 +4,7 @@ import { Posts } from '../../api/post/post'; import { Comments } from '../../api/comment/comment'; import { Surveys } from '../../api/survey/survey'; import { Votes } from '../../api/vote/vote'; +import { ModCards } from '../../api/modcard/modcard'; Meteor.publish(Comments.userPublicationName, function () { if (this.userId) { @@ -32,6 +33,13 @@ Meteor.publish(Votes.userPublicationName, function () { return this.ready(); }); +Meteor.publish(ModCards.userPublicationName, function () { + if (this.userId) { + return ModCards.collection.find(); + } + return this.ready(); +}); + Meteor.publish(Surveys.userPublicationName, function () { if (this.userId) { return Surveys.collection.find(); diff --git a/app/imports/ui/components/ModCard.jsx b/app/imports/ui/components/ModCard.jsx new file mode 100644 index 0000000..83e978a --- /dev/null +++ b/app/imports/ui/components/ModCard.jsx @@ -0,0 +1,74 @@ +import React, { useState } from 'react'; +import { Button, Card, Col, ListGroup, OverlayTrigger, Popover } from 'react-bootstrap'; +import PropTypes from 'prop-types'; + +const ModCard = ({ modCard, onImageClick }) => { + const [show, setShow] = useState(false); + const detailLengthLimit = 55; + + const renderPopover = ( + + + {modCard.detail} + + + ); + + const detailDisplay = modCard.detail.length > detailLengthLimit + ? `${modCard.detail.substring(0, detailLengthLimit)}...` + : modCard.detail; + + return ( + + + + {modCard.type} + + + Cost: {modCard.cost} + {modCard.image && ( + + )} + + Details: { /* space */} + {modCard.detail.length > detailLengthLimit ? ( + setShow(nextShow)} + > + + {detailDisplay} + + + ) : ( + detailDisplay + )} +

+ {modCard.owner} @ {modCard.createdAt.toLocaleDateString('en-US')} +

+
+
+
+ + ); +}; + +ModCard.propTypes = { + modCard: PropTypes.shape({ + type: PropTypes.string.isRequired, + cost: PropTypes.string.isRequired, + image: PropTypes.string, + detail: PropTypes.string.isRequired, + createdAt: PropTypes.instanceOf(Date).isRequired, + owner: PropTypes.string.isRequired, + _id: PropTypes.string.isRequired, + }).isRequired, + onImageClick: PropTypes.func.isRequired, +}; + +export default ModCard; diff --git a/app/imports/ui/components/NavBar.jsx b/app/imports/ui/components/NavBar.jsx index ce2f984..97fbc42 100644 --- a/app/imports/ui/components/NavBar.jsx +++ b/app/imports/ui/components/NavBar.jsx @@ -36,15 +36,15 @@ const NavBar = () => { ) : ''} {currentUser ? ( + + Model + Dall-E3 Gis-Map - - Data (Coming Soon) - External diff --git a/app/imports/ui/layouts/App.jsx b/app/imports/ui/layouts/App.jsx index f975c0c..7ee9e02 100644 --- a/app/imports/ui/layouts/App.jsx +++ b/app/imports/ui/layouts/App.jsx @@ -23,7 +23,8 @@ import AddPost from '../pages/AddPost'; import Survey from '../pages/SurveyPage'; import AddSurvey from '../pages/AddSurvey'; import Mapping from '../pages/Mapping'; -import Data from '../pages/Data'; +import Model from '../pages/Model'; +import AddModCard from '../pages/AddModCard'; const App = () => { const { ready } = useTracker(() => { @@ -51,7 +52,8 @@ const App = () => { } /> } /> } /> - } /> + } /> + } /> } /> } /> } /> diff --git a/app/imports/ui/pages/AddModCard.jsx b/app/imports/ui/pages/AddModCard.jsx new file mode 100644 index 0000000..79678e4 --- /dev/null +++ b/app/imports/ui/pages/AddModCard.jsx @@ -0,0 +1,89 @@ +import React, { useState } from 'react'; +import { useLocation } from 'react-router-dom'; +import { Meteor } from 'meteor/meteor'; +import { Container, Row, Col, Card } from 'react-bootstrap'; +import { AutoForm, TextField, LongTextField, SubmitField, ErrorsField, HiddenField } from 'uniforms-bootstrap5'; +import swal from 'sweetalert'; +import SimpleSchema2Bridge from 'uniforms-bridge-simple-schema-2'; +import { ModCards } from '../../api/modcard/modcard'; +import FileField from '../components/FileField'; + +const bridge = new SimpleSchema2Bridge(ModCards.schema); + +const AddModCard = () => { + const [imageFile, setImageFile] = useState(null); + let fRef = null; + const user = Meteor.user(); + + const location = useLocation(); + const currentAddress = location.state?.formattedAddress || ''; + + const handleImageChange = (file) => { + setImageFile(file); + }; + + const submit = (data) => { + const { image, ...modCardData } = data; + modCardData.address = currentAddress; + + // eslint-disable-next-line no-shadow + const insertModCard = (modCardData) => { + ModCards.collection.insert(modCardData, (error) => { + if (error) { + swal('Error', error.message, 'error'); + } else { + swal('Success', 'ModCard added successfully', 'success'); + fRef.reset(); + } + }); + }; + + if (imageFile) { + const reader = new FileReader(); + reader.onloadend = function () { + const fileData = reader.result; + + Meteor.call('uploadImage', fileData, (error, imageUrl) => { + if (error) { + swal('Error', 'Failed to upload image.', 'error'); + } else { + modCardData.image = imageUrl; + insertModCard(modCardData); + } + }); + }; + reader.readAsDataURL(imageFile); + } else { + insertModCard(modCardData); + } + }; + + return ( + + + +

Add ModCard

+ { fRef = ref; }} schema={bridge} onSubmit={submit}> + + + +
+ +
+ + + + + + + {user ? : null} +
+
+
+ +
+
+ ); +}; + +export default AddModCard; diff --git a/app/imports/ui/pages/Data.jsx b/app/imports/ui/pages/Data.jsx deleted file mode 100644 index e97555a..0000000 --- a/app/imports/ui/pages/Data.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { Carousel, Image } from 'react-bootstrap'; - -const Data = () => ( - - - fire-map - - - lahaina-sale - - -); - -export default Data; diff --git a/app/imports/ui/pages/Landing.jsx b/app/imports/ui/pages/Landing.jsx index 7651292..3e1ee62 100644 --- a/app/imports/ui/pages/Landing.jsx +++ b/app/imports/ui/pages/Landing.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { Col, Container, Image, Row } from 'react-bootstrap'; +import { EmojiSmile } from 'react-bootstrap-icons'; const Landing = () => (
@@ -10,7 +11,8 @@ const Landing = () => ( ( (

Our Mission

-
{/* eslint-disable-next-line max-len */} -

We want to create a web portal that facilitates the civic engagement around how to rebuild Lahaina, Maui, including surveys, forums, sharing design concepts with visual and data models for economic, environmental, etc. analysis.

+

We want to create a web portal that facilitates the civic engagement around how to rebuild Lahaina, Maui, including surveys, forums, sharing design concepts with visual and mappinig models for economic, environmental, etc. analysis.

+ @@ -53,7 +55,8 @@ const Landing = () => ( ( { + const [mapOptions] = useState({ + center: center, + zoom: 16, + mapTypeId: 'satellite', + tilt: 0, + }); + + const [selectedPlace, setSelectedPlace] = useState(null); + const [infoWindowPosition, setInfoWindowPosition] = useState(null); + const [formattedAddress, setFormattedAddress] = useState(''); + const [locationPhotoUrl, setLocationPhotoUrl] = useState(''); + const [activeAccordionKey, setActiveAccordionKey] = useState(null); + const [currentPage, setCurrentPage] = useState(1); + const [isMapScriptLoaded, setIsMapScriptLoaded] = useState(false); + const modCardsPerPage = 2; + const navigate = useNavigate(); + const searchBoxRef = useRef(null); + + const handleImageClick = (imageUrl) => { + setLocationPhotoUrl(imageUrl); + }; + + const onMapClick = (e) => { + const lat = e.latLng.lat(); + const lng = e.latLng.lng(); + setInfoWindowPosition({ lat, lng }); + setLocationPhotoUrl(''); + + const geocoder = new window.google.maps.Geocoder(); + geocoder.geocode({ location: { lat, lng } }, (results, status) => { + if (status === 'OK' && results[0]) { + setFormattedAddress(results[0].formatted_address); + setSelectedPlace({ lat, lng }); + } + }); + }; + + const onLoadSearchBox = (ref) => { + searchBoxRef.current = ref; + }; + + const navigateToAddModCard = () => { + navigate('/addmodcard', { state: { formattedAddress } }); + }; + + const onPlacesChanged = () => { + const places = searchBoxRef.current.getPlaces(); + if (places && places.length > 0) { + const place = places[0]; + const latLng = place.geometry.location; + const lat = latLng.lat(); + const lng = latLng.lng(); + setInfoWindowPosition({ lat, lng }); + setLocationPhotoUrl(''); + setSelectedPlace({ lat, lng }); + setFormattedAddress(place.formatted_address || ''); + onMapClick({ latLng: new window.google.maps.LatLng(lat, lng) }); + } + }; + + const photoUrlToShow = locationPhotoUrl || '/images/example-photo.png'; + + const handleAccordionToggle = (key) => setActiveAccordionKey(activeAccordionKey === key ? null : key); + + const { ready, modcards } = useTracker(() => { + const subscription = Meteor.subscribe(ModCards.userPublicationName); + const allModCards = ModCards.collection.find({}).fetch(); + const filteredModCards = allModCards.filter(modCard => modCard.address === formattedAddress); + + return { + modcards: filteredModCards, + ready: subscription.ready(), + }; + }, [formattedAddress]); + + const indexOfLastModCard = currentPage * modCardsPerPage; + const indexOfFirstModCard = indexOfLastModCard - modCardsPerPage; + const currentModCards = modcards.slice(indexOfFirstModCard, indexOfLastModCard); + + const handlePageChange = (pageNumber) => setCurrentPage(pageNumber); + + return ready ? ( + + +
+ Location +
+ + + handleAccordionToggle('0')}>Information + +

Address: {formattedAddress}

+
+
+ + handleAccordionToggle('1')}>User Modeling + + + {currentModCards.map((modcard) => ( + + ))} + +
+ + {Array.from({ length: Math.ceil(modcards.length / modCardsPerPage) }, (_, i) => ( + handlePageChange(i + 1)}> + {i + 1} + + ))} + +
+ {formattedAddress && ( +
+ + + +
+ )} +
+
+
+ + + setIsMapScriptLoaded(true)} + > + {isMapScriptLoaded && ( +
{/* Search box container */} + + {/* eslint-disable-next-line max-len */} + + +
+ )} + + {selectedPlace && ( + setSelectedPlace(null)} + > +
+

Address

+

{formattedAddress}

+
+
+ )} +
+
+ +
+ ) : ; +}; + +export default Model; diff --git a/app/package-lock.json b/app/package-lock.json index ebea391..673a352 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1770,6 +1770,41 @@ "to-fast-properties": "^2.0.0" } }, + "@cesium/engine": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@cesium/engine/-/engine-6.1.0.tgz", + "integrity": "sha512-gufv2rfvbPVA3foYrMP+8RBOpH9z8zq6PaHqFOSCmNlRDPDsoAhsjGAog+sjFz1ybFiQ2/DY84YB/2cjs+DYxw==", + "requires": { + "@tweenjs/tween.js": "^21.0.0", + "@zip.js/zip.js": "2.4.x", + "autolinker": "^4.0.0", + "bitmap-sdf": "^1.0.3", + "dompurify": "^3.0.2", + "draco3d": "^1.5.1", + "earcut": "^2.2.4", + "grapheme-splitter": "^1.0.4", + "jsep": "^1.3.8", + "kdbush": "^4.0.1", + "ktx-parse": "^0.6.0", + "lerc": "^2.0.0", + "mersenne-twister": "^1.1.0", + "meshoptimizer": "^0.19.0", + "pako": "^2.0.4", + "protobufjs": "^7.1.0", + "rbush": "^3.0.1", + "topojson-client": "^3.1.0", + "urijs": "^1.19.7" + } + }, + "@cesium/widgets": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@cesium/widgets/-/widgets-4.3.0.tgz", + "integrity": "sha512-TZoJJJpv6Jp6bEl0t+nSQwGYvttp4RJbB6oYbtJPPqURz/JP/kYd+hAF+uV0DefRws3yl6waDDZ3Lrd09Ype4g==", + "requires": { + "@cesium/engine": "^6.1.0", + "nosleep.js": "^0.12.0" + } + }, "@devexpress/bin-v8-flags-filter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@devexpress/bin-v8-flags-filter/-/bin-v8-flags-filter-1.3.0.tgz", @@ -1914,6 +1949,23 @@ "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", "dev": true }, + "@googlemaps/js-api-loader": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz", + "integrity": "sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "@googlemaps/markerclusterer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.3.2.tgz", + "integrity": "sha512-zb9OQP8XscZp2Npt1uQUYnGKu1miuq4DPP28JyDuFd6HV17HCEcjV9MtBi4muG/iVRXXvuHW9bRCnHbao9ITfw==", + "requires": { + "fast-deep-equal": "^3.1.3", + "supercluster": "^8.0.1" + } + }, "@humanwhocodes/config-array": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", @@ -2016,6 +2068,60 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "@react-aria/ssr": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.7.0.tgz", @@ -2024,6 +2130,29 @@ "@swc/helpers": "^0.5.0" } }, + "@react-google-maps/api": { + "version": "2.19.2", + "resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.19.2.tgz", + "integrity": "sha512-Vt57XWzCKfsUjKOmFUl2erVVfOePkPK5OigF/f+q7UuV/Nm9KDDy1PMFBx+wNahEqOd6a32BxfsykEhBnbU9wQ==", + "requires": { + "@googlemaps/js-api-loader": "1.16.2", + "@googlemaps/markerclusterer": "2.3.2", + "@react-google-maps/infobox": "2.19.2", + "@react-google-maps/marker-clusterer": "2.19.2", + "@types/google.maps": "3.53.5", + "invariant": "2.2.4" + } + }, + "@react-google-maps/infobox": { + "version": "2.19.2", + "resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.19.2.tgz", + "integrity": "sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg==" + }, + "@react-google-maps/marker-clusterer": { + "version": "2.19.2", + "resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz", + "integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw==" + }, "@remix-run/router": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.7.1.tgz", @@ -2068,6 +2197,11 @@ "tslib": "^2.4.0" } }, + "@tweenjs/tween.js": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-21.0.0.tgz", + "integrity": "sha512-qVfOiFh0U8ZSkLgA6tf7kj2MciqRbSCWaJZRwftVO7UbtVDNsZAXpWXqvCDtIefvjC83UJB+vHTDOGm5ibXjEA==" + }, "@types/estree": { "version": "0.0.46", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.46.tgz", @@ -2084,6 +2218,11 @@ "@types/node": "*" } }, + "@types/google.maps": { + "version": "3.53.5", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.53.5.tgz", + "integrity": "sha512-HoRq4Te8J6krH7hj+TfdYepqegoKZCj3kkaK5gf+ySFSHLvyqYkDvkrtbcVJXQ6QBphQ0h1TF7p4J6sOh4r/zg==" + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -2149,6 +2288,11 @@ "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==" }, + "@zip.js/zip.js": { + "version": "2.4.26", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.4.26.tgz", + "integrity": "sha512-I9HBO3BHIxEMQmltmHM3iqUW6IHqi3gsL9wTSXvHTRpOrA6q2OxtR58EDSaOGjHhDVJ+wIOAxZyKq2x00AVmqw==" + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -2823,6 +2967,14 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "autolinker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-4.0.0.tgz", + "integrity": "sha512-fl5Kh6BmEEZx+IWBfEirnRUU5+cOiV0OK7PEt0RBKvJMJ8GaRseIOeDU3FKf4j3CE5HVefcjHmhYPOcaVt0bZw==", + "requires": { + "tslib": "^2.3.0" + } + }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -2937,6 +3089,11 @@ "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" }, + "bitmap-sdf": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bitmap-sdf/-/bitmap-sdf-1.0.4.tgz", + "integrity": "sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg==" + }, "bootstrap": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.0.tgz", @@ -3013,6 +3170,15 @@ "integrity": "sha512-HWJnhnID+0YMtGlzcp3T9drmBJUVDchPJ08tpUGFLs9CYlwWPH2uLgpHn8fND5pCgXVtnGS3H4QR9XLMHVNkHw==", "dev": true }, + "cesium": { + "version": "1.111.0", + "resolved": "https://registry.npmjs.org/cesium/-/cesium-1.111.0.tgz", + "integrity": "sha512-wWtBa1KIMIJZR39U4Tv+CkJUeCfi83eVjCLxblYilD9zd4gb7vm3V9ytmJ0+v0sqk9RQws5JOg7Hobbs9ODTxQ==", + "requires": { + "@cesium/engine": "^6.1.0", + "@cesium/widgets": "^4.3.0" + } + }, "chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", @@ -3715,11 +3881,26 @@ "csstype": "^3.0.2" } }, + "dompurify": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.6.tgz", + "integrity": "sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w==" + }, "dotenv": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" }, + "draco3d": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.6.tgz", + "integrity": "sha512-+3NaRjWktb5r61ZFoDejlykPEFKT5N/LkbXsaddlw6xNSXBanUYpFc2AXXpbJDilPHazcSreU/DpQIaxfX0NfQ==" + }, + "earcut": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" + }, "electron-to-chromium": { "version": "1.4.526", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.526.tgz", @@ -4606,8 +4787,7 @@ "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { "version": "3.3.1", @@ -4971,6 +5151,11 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -5626,6 +5811,11 @@ "argparse": "^2.0.1" } }, + "jsep": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.8.tgz", + "integrity": "sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ==" + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -5697,12 +5887,22 @@ } } }, + "kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==" + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, + "ktx-parse": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.6.0.tgz", + "integrity": "sha512-hYOJUI86N9+YPm0M3t8hVzW9t5FnFFibRalZCrqHs/qM2eNziqQzBtAaF0ErgkXm8F+5uE8CjPUYr32vWlXLkQ==" + }, "language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", @@ -5718,6 +5918,11 @@ "language-subtag-registry": "~0.3.2" } }, + "lerc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lerc/-/lerc-2.0.0.tgz", + "integrity": "sha512-7qo1Mq8ZNmaR4USHHm615nEW2lPeeWJ3bTyoqFbd35DLx0LUH7C6ptt5FDCTAlbIzs3+WKrk5SkJvw8AFDE2hg==" + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5814,6 +6019,11 @@ } } }, + "long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", @@ -5885,6 +6095,16 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "mersenne-twister": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mersenne-twister/-/mersenne-twister-1.1.0.tgz", + "integrity": "sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==" + }, + "meshoptimizer": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.19.0.tgz", + "integrity": "sha512-58qz5Qc/6Geu8Ib3bBWERE5R7pM5ErrJVo16fAtu6ryxVaE3VAtM/u2vurDxaq8AGZ3yWxuM/DnylTga5a4XCQ==" + }, "message-box": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/message-box/-/message-box-0.2.7.tgz", @@ -6794,6 +7014,11 @@ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, + "nosleep.js": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/nosleep.js/-/nosleep.js-0.12.0.tgz", + "integrity": "sha512-9d1HbpKLh3sdWlhXMhU6MMH+wQzKkrgfRkYV0EBdvt99YJfj0ilCJrWRDYG2130Tm4GXbEoTCx5b34JSaP+HhA==" + }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -7343,6 +7568,11 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7564,6 +7794,35 @@ "warning": "^4.0.0" } }, + "protobufjs": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", + "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "dependencies": { + "@types/node": { + "version": "20.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", + "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", + "requires": { + "undici-types": "~5.26.4" + } + } + } + }, "psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -7609,6 +7868,19 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + }, + "rbush": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", + "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==", + "requires": { + "quickselect": "^2.0.0" + } + }, "react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -7831,6 +8103,11 @@ "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==", "dev": true }, + "resium": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/resium/-/resium-1.17.2.tgz", + "integrity": "sha512-yV9nv+czwgSqT2FbTnzS1H+xs0DRLmrkmu3h/sQuyFhQjq7PEq0576UsS8k3/LtmsaJ7jubmHjyYBnE/TnOT9g==" + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -8305,6 +8582,14 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "requires": { + "kdbush": "^4.0.2" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -8884,6 +9169,21 @@ "is-number": "^7.0.0" } }, + "topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "requires": { + "commander": "2" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } + } + }, "tough-cookie": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", @@ -9143,6 +9443,11 @@ "punycode": "^2.1.0" } }, + "urijs": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" + }, "url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", diff --git a/app/package.json b/app/package.json index bf68dda..baabac5 100644 --- a/app/package.json +++ b/app/package.json @@ -3,7 +3,9 @@ "private": true, "dependencies": { "@babel/runtime": "^7.22.6", + "@react-google-maps/api": "^2.19.2", "bootstrap": "^5.3.0", + "cesium": "^1.111.0", "classnames": "^2.3.2", "cloudinary": "^1.41.0", "core-js": "^3.31.1", @@ -19,6 +21,7 @@ "react-dom": "^18.2.0", "react-router": "^6.14.1", "react-router-dom": "^6.14.1", + "resium": "^1.17.2", "simpl-schema": "^3.4.1", "sweetalert": "^2.1.2", "uniforms": "^4.0.0-alpha.5", diff --git a/app/public/favicon.ico b/app/public/favicon.ico deleted file mode 100644 index 0202f35..0000000 Binary files a/app/public/favicon.ico and /dev/null differ diff --git a/app/public/images/example-photo.png b/app/public/images/example-photo.png new file mode 100644 index 0000000..4bda6b9 Binary files /dev/null and b/app/public/images/example-photo.png differ