Skip to content

Commit

Permalink
Merge pull request #3 from SmartCityFlensburg/feature/implement-map
Browse files Browse the repository at this point in the history
feat: add leaflet map
  • Loading branch information
choffmann authored Jul 6, 2024
2 parents 76eff98 + 17486fb commit 4e1a782
Show file tree
Hide file tree
Showing 13 changed files with 309 additions and 16 deletions.
4 changes: 2 additions & 2 deletions components.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "app/globals.css",
"css": "src/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
Expand All @@ -14,4 +14,4 @@
"components": "@/components",
"utils": "@/lib/utils"
}
}
}
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@
"preview": "vite preview"
},
"dependencies": {
"@radix-ui/react-slot": "^1.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"leaflet": "^1.9.4",
"lucide-react": "^0.400.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-leaflet": "^4.2.1",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@types/leaflet": "^1.9.12",
"@types/node": "^20.14.10",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
Expand Down
13 changes: 8 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
function App() {
import MapHeader from "@/components/MapHeader";
import Map from "@/components/Map";

function App() {
return (
<div>
Hello World
<div className="w-screen h-screen">
<MapHeader />
<Map />
</div>
)
);
}

export default App
export default App;
47 changes: 47 additions & 0 deletions src/components/Map.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { MapContainer, TileLayer } from "react-leaflet";
import L from "leaflet";

export interface MapProps {
width?: string;
height?: string;
}

const markerHtmlStyles = (color: string) => `
background-color: ${color};
width: 2rem;
height: 2rem;
display: block;
left: -1rem;
top: -1rem;
position: relative;
border-radius: 3rem 3rem 0;
transform: rotate(45deg);
border: 1px solid #FFFFFF
`;

export const TreeIcon = (color: string) =>
L.divIcon({
iconAnchor: [0, 24],
popupAnchor: [0, -36],
html: `<span style="${markerHtmlStyles(color)}" />`,
});

const Map = ({ width = "100%", height = "100vh" }: MapProps) => {
return (
<MapContainer
className="z-0"
zoomControl={false}
style={{ width, height }}
center={[54.792277136221905, 9.43580607453268]}
zoom={13}
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{/* treeMarkers */}
</MapContainer>
);
};

export default Map;
42 changes: 42 additions & 0 deletions src/components/MapHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Menu } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";

export interface HeaderProps { }

const MapHeader = ({ }: HeaderProps) => {
const handleToggleMenu = () => {
console.log("Toggle menu");
};

return (
<Card className="z-50 absolute top-4 left-4 w-[350px] h-12 bg-white rounded shadow-lg">
<div className="flex justify-between items-center h-full mx-2">
<div className="flex items-center">
<Button
variant="ghost"
size="icon"
onClick={() => handleToggleMenu()}
>
<Menu className="w-6 h-6" />
</Button>
</div>
<div className="flex items-center gap-2">
<PlaceholderIcon />
<PlaceholderIcon />
<PlaceholderIcon />
</div>
</div>
</Card>
);
};

export const PlaceholderIcon = () => {
return (
<div className="flex items-center">
<div className="h-8 w-8 bg-gray-200 rounded-xl"></div>
</div>
);
};

export default MapHeader;
56 changes: 56 additions & 0 deletions src/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"

import { cn } from "@/lib/utils"

const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"

export { Button, buttonVariants }
79 changes: 79 additions & 0 deletions src/components/ui/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import * as React from "react"

import { cn } from "@/lib/utils"

const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-lg border bg-card text-card-foreground shadow-sm",
className
)}
{...props}
/>
))
Card.displayName = "Card"

const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
))
CardHeader.displayName = "CardHeader"

const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn(
"text-2xl font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
))
CardTitle.displayName = "CardTitle"

const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
CardDescription.displayName = "CardDescription"

const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"

const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
))
CardFooter.displayName = "CardFooter"

export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
File renamed without changes.
3 changes: 2 additions & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import '../app/globals.css'
import './globals.css'
import "leaflet/dist/leaflet.css";

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
Expand Down
20 changes: 15 additions & 5 deletions tsconfig.app.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"lib": [
"ES2020",
"DOM",
"DOM.Iterable"
],
"module": "ESNext",
"skipLibCheck": true,

/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
Expand All @@ -16,12 +19,19 @@
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",

/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
]
}
},
"include": ["src"]
"include": [
"src"
]
}
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
"@/*": [
"./src/*"
]
}
},
"references": [
Expand Down
12 changes: 10 additions & 2 deletions tsconfig.node.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"strict": true,
"noEmit": true
"noEmit": true,
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
]
}
},
"include": ["vite.config.ts"]
"include": [
"vite.config.ts"
]
}
Loading

0 comments on commit 4e1a782

Please sign in to comment.