mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
added missing source files
This commit is contained in:
parent
809689a614
commit
6a551b47e4
53
src/Components/Map/Popup.tsx
Normal file
53
src/Components/Map/Popup.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import * as React from 'react'
|
||||
import { Popup as LeafletPopup} from 'react-leaflet'
|
||||
import { Item, Tag } from '../../types'
|
||||
import { replaceURLs } from '../../Utils/ReplaceURLs'
|
||||
|
||||
export interface UtopiaPopupProps {
|
||||
item: Item,
|
||||
tags: Tag[]
|
||||
}
|
||||
|
||||
const Popup = (props: UtopiaPopupProps) => {
|
||||
const item: Item = props.item;
|
||||
const tags: Tag[] = props.tags;
|
||||
|
||||
return (
|
||||
<LeafletPopup maxHeight={320} minWidth={275} maxWidth={275} autoPanPadding={[30, 30]}>
|
||||
<b className="text-xl font-bold">{item.name}</b>
|
||||
{item.start && item.end &&
|
||||
<div className="flex flex-row">
|
||||
<div className="basis-2/5">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||
</svg>
|
||||
<span className='align-middle'>{new Date(item.start).toISOString().substring(0, 10) || ""}</span>
|
||||
</div>
|
||||
<div className="basis-1/5 place-content-center">
|
||||
<span>-</span>
|
||||
</div>
|
||||
<div className="basis-2/5">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||
</svg>
|
||||
<span className='align-middle leading-6'>{new Date(item.end).toISOString().substring(0, 10) || ""}</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<p style={{ whiteSpace: "pre-wrap" }} dangerouslySetInnerHTML={{ __html: replaceURLs(item.text) }} />
|
||||
<p>
|
||||
|
||||
{item.tags &&
|
||||
tags.map((tag: Tag) => (
|
||||
<span className="" style={{ fontWeight: "bold", display: "inline-block", color: "#fff", padding: ".3rem", borderRadius: ".5rem", backgroundColor: tag.color, margin: '.2rem', fontSize: "100%" }} key={tag.id}>#{tag.name}</span>
|
||||
))
|
||||
}
|
||||
</p>
|
||||
</LeafletPopup>
|
||||
)
|
||||
}
|
||||
|
||||
export {Popup};
|
||||
|
||||
|
||||
92
src/Components/Map/UtopiaMap.tsx
Normal file
92
src/Components/Map/UtopiaMap.tsx
Normal file
@ -0,0 +1,92 @@
|
||||
import { TileLayer, MapContainer, Marker } from "react-leaflet";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
import * as React from "react";
|
||||
import MarkerIconFactory from '../../Utils/MarkerIconFactory';
|
||||
import {Popup} from "./Popup";
|
||||
import { Item, Tag } from "../../types"
|
||||
import "../../index.css"
|
||||
import { LatLng } from "leaflet";
|
||||
import MarkerClusterGroup from 'react-leaflet-cluster'
|
||||
|
||||
export interface MapProps {
|
||||
height: string,
|
||||
width: string,
|
||||
center: LatLng,
|
||||
zoom: number,
|
||||
places?: Item[],
|
||||
events?: Item[],
|
||||
tags?: Tag[],
|
||||
}
|
||||
|
||||
const UtopiaMap = (props: MapProps) => {
|
||||
let center: LatLng = new LatLng(50.6, 9.5);
|
||||
if (props.center) center = props.center;
|
||||
let zoom: number = 10;
|
||||
if (props.zoom) zoom = props.zoom;
|
||||
let height: string = "400px";
|
||||
if (props.height) height = props.height;
|
||||
let width: string = "100vw";
|
||||
if (props.width) width = props.width;
|
||||
|
||||
let tagMap = new Map(props.tags?.map(key => [key.id, key]));
|
||||
|
||||
const getTags = (item: Item) => {
|
||||
let tags: Tag[] = [];
|
||||
item.tags && item.tags.forEach(element => {
|
||||
if (tagMap.has(element)) { tags.push(tagMap.get(element)!) };
|
||||
});
|
||||
return tags;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<MapContainer style={{ height: height, width: width }} center={center} zoom={zoom} >
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
||||
<MarkerClusterGroup showCoverageOnHover chunkedLoading maxClusterRadius={50}>
|
||||
{props.places &&
|
||||
props.places.map((place: Item) => {
|
||||
let tags = getTags(place);
|
||||
let color1 = "#666";
|
||||
let color2 = "RGBA(35, 31, 32, 0.2)";
|
||||
if (tags[0]) {
|
||||
color1 = tags[0].color;
|
||||
}
|
||||
if (tags[1]) {
|
||||
color2 = tags[1].color;
|
||||
}
|
||||
return (
|
||||
<Marker icon={MarkerIconFactory('circle', color1, color2, 'circle-solid')} key={place.id} position={[place.position.coordinates[1], place.position.coordinates[0]]}>
|
||||
<Popup item={place} tags={tags} />
|
||||
</Marker>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{props.events &&
|
||||
props.events.map((event: Item) => {
|
||||
let tags = getTags(event);
|
||||
let color1 = "#666";
|
||||
let color2 = "RGBA(35, 31, 32, 0.2)";
|
||||
if (tags[0]) {
|
||||
color1 = tags[0].color;
|
||||
}
|
||||
if (tags[1]) {
|
||||
color2 = tags[1].color;
|
||||
}
|
||||
return (
|
||||
<Marker icon={MarkerIconFactory('square', color1, color2, 'calendar-days-solid')} key={event.id} position={[event.position.coordinates[1], event.position.coordinates[0]]}>
|
||||
<Popup item={event} tags={tags} />
|
||||
</Marker>
|
||||
)
|
||||
})
|
||||
}
|
||||
</MarkerClusterGroup>
|
||||
</MapContainer>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
export { UtopiaMap, Item, Tag };
|
||||
|
||||
19
src/Utils/ReplaceURLs.ts
Normal file
19
src/Utils/ReplaceURLs.ts
Normal file
@ -0,0 +1,19 @@
|
||||
export function replaceURLs(message: string): string {
|
||||
if (!message) return "";
|
||||
|
||||
var urlRegex = /(^| )(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,10}(:[0-9]{1,10})?(\/.*)?$/gm;
|
||||
message = message.replace(urlRegex, function (url) {
|
||||
var hyperlink = url.replace(' ', '');
|
||||
if (!hyperlink.match('^https?:\/\/')) {
|
||||
hyperlink = 'http://' + hyperlink;
|
||||
}
|
||||
return '<a href="' + hyperlink + '" target="_blank" rel="noopener noreferrer">' + url + '</a>'
|
||||
});
|
||||
|
||||
var mailRegex = /([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)/gi;
|
||||
message = message.replace(mailRegex, function (mail) {
|
||||
return '<a href="mailto:' + mail + '">' + mail + '</a>'
|
||||
});
|
||||
|
||||
return message;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user