Skip to content

Commit

Permalink
Add a hook to receive markers (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
umonkey authored Mar 18, 2024
1 parent 6db6cc9 commit cc003e6
Show file tree
Hide file tree
Showing 17 changed files with 212 additions and 10 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
lint:
make -C backend lint
make -C frontend lint
16 changes: 16 additions & 0 deletions backend/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
name = "treemap"
version = "0.1.0"
edition = "2021"
rust-version = "1.75"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-cors = "0.7.0"
actix-web = "4.5.1"
async-sqlite = "0.2.2"
async-trait = "0.1.77"
Expand Down
3 changes: 3 additions & 0 deletions backend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ lint:
serve:
cargo run

sqlite:
sqlite3 database.sqlite

sqlite-schema:
sqlite3 database.sqlite < dev/schema-sqlite.sql

Expand Down
4 changes: 2 additions & 2 deletions backend/dev/seed-sqlite.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
-- Adds some sample data to test the API with.

INSERT INTO trees (id, lat, lon) VALUES (1, 37.7749, -122.4194);
INSERT INTO trees (id, lat, lon) VALUES (2, 37.7749, -122.4194);
INSERT INTO trees (id, lat, lon) VALUES (3, 37.7749, -122.4194);
INSERT INTO trees (id, lat, lon) VALUES (2, 38.7749, -123.4194);
INSERT INTO trees (id, lat, lon) VALUES (3, 39.7749, -124.4194);
3 changes: 3 additions & 0 deletions backend/src/actions/get_trees.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use actix_web::{get, web::Data, web::Json};
use log::debug;

use crate::Result;
use crate::objects::TreeList;
Expand All @@ -10,5 +11,7 @@ pub async fn get_trees(
) -> Result<Json<TreeList>> {
let trees = state.get_trees().await?;

debug!("Returning {} trees", trees.len());

Ok(Json(trees))
}
3 changes: 3 additions & 0 deletions backend/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod objects;
mod services;
mod utils;

use actix_cors::Cors;
use actix_web::{middleware::DefaultHeaders, App, HttpServer};
use log::{debug, info};
use std::time::Duration;
Expand Down Expand Up @@ -49,8 +50,10 @@ async fn main() -> std::io::Result<()> {
DefaultHeaders::new()
.add(("Cache-Control", "no-store"))
)
.wrap(Cors::permissive())
.data_factory(data_factory)
.service(get_trees)
.service(get_tree)
})
.bind((host_addr.as_str(), host_port))?
.workers(workers)
Expand Down
6 changes: 6 additions & 0 deletions backend/src/objects/tree_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@ use crate::objects::TreeInfo;
pub struct TreeList {
pub trees: Vec<TreeInfo>,
}

impl TreeList {
pub fn len(&self) -> usize {
self.trees.len()
}
}
3 changes: 3 additions & 0 deletions frontend/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
install:
npm install

lint:
npm run lint

serve:
npm run dev
91 changes: 91 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.6.8",
"leaflet": "^1.9.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useState } from 'react'

import { Map } from "./components/Map";

function App() {
Expand Down
20 changes: 14 additions & 6 deletions frontend/src/components/Map/Map.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";

import { useMarkers } from "./hooks";

import "./styles.css";

export const Map = () => {
const { center, markers } = useMarkers();

return (
<MapContainer center={[40.181389, 44.514444]} zoom={13} maxZoom={18} scrollWheelZoom={true} className="map">
<MapContainer center={center} zoom={13} maxZoom={18} scrollWheelZoom={true} className="map">
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={[51.505, -0.09]}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>

{markers.map((marker, index) => (
<Marker key={index} position={[marker.lat, marker.lon]}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
))}

</MapContainer>
);
};
30 changes: 30 additions & 0 deletions frontend/src/components/Map/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useState, useEffect } from "react";

import { ITreeInfo } from "./types";
import { treeMapService } from "../../services/api";

export const useMarkers = () => {
const center = [40.181389, 44.514444];
const [markers, setMarkers] = useState<ITreeInfo>([]);

useEffect(() => {
(async () => {
const res = await treeMapService.getMarkers();
console.debug("MARKERS", res);

setMarkers(res);
})();

// Fix markers multiplying on every re-render.
return () => {
setMarkers([]);
};
}, []);

console.debug(`Have ${markers.length} markers.`);

return {
center,
markers,
};
};
27 changes: 27 additions & 0 deletions frontend/src/services/api/TreeMapService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import axios, { AxiosResponse, AxiosInstance, AxiosRequestConfig } from "axios";

import { ITreeInfo } from "./types";

export class TreeMapService {
private readonly client: AxiosInstance;

public constructor() {
this.client = axios.create({
baseURL: "http://localhost:8000",
timeout: 10000,
responseType: "json",
headers: {
"Content-Type": "application/json",
},
});
}

public async getMarkers(): Promise<ITreeInfo[]> {
const res = await this.get("/v1/trees");
return res.data.trees;
}

private async get<T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {
return this.client.get<T>(url, config);
}
}
3 changes: 3 additions & 0 deletions frontend/src/services/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { TreeMapService } from "./TreeMapService";

export const treeMapService = new TreeMapService();
5 changes: 5 additions & 0 deletions frontend/src/services/api/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ITreeInfo {
id: number;
lat: number;
lon: number;
}

0 comments on commit cc003e6

Please sign in to comment.