Skip to content

Commit

Permalink
feat: add highlighted state (#181)
Browse files Browse the repository at this point in the history
Co-authored-by: Dorien Grönwald <[email protected]>
  • Loading branch information
doriengr and Dorien Grönwald authored Oct 16, 2024
1 parent 90a472c commit c1e190e
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 25 deletions.
27 changes: 19 additions & 8 deletions frontend/src/components/map/MapMarker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,37 +70,48 @@ const markerClusterHtmlStyles = (color: string) => `
font-family: Nunito, sans-serif;
`;

const makerWrapperStyles = (isSelected: boolean) => `
background-color: ${isSelected ? 'white' : ''};
const makerWrapperStyles = (isSelected: boolean, isHighlighted: boolean) => `
background-color: ${isSelected || isHighlighted ? 'white' : ''};
width: 2.5rem;
height: 2.5rem;
border-radius: 3rem;
position: relative;
left: -1rem;
top: -1rem;
box-shadow: rgba(0, 0, 0, ${isSelected ? '0.35' : '0'}) 0px 5px 15px;
box-shadow: rgba(0, 0, 0, ${isSelected || isHighlighted ? '0.35' : '0'}) 0px 5px 15px;
`;

export const TreeMarkerIcon = (color: string, isSelected: boolean) =>
const makerClusterWrapperStyles = (isHighlighted: boolean) => `
background-color: ${isHighlighted ? 'white' : ''};
width: 2.75rem;
height: 2.75rem;
border-radius: 3rem;
position: relative;
left: -1.25rem;
top: -1.25rem;
box-shadow: rgba(0, 0, 0, ${isHighlighted ? '0.35' : '0'}) 0px 5px 15px;
`;

export const TreeMarkerIcon = (color: string, isSelected: boolean, isHighlighted: boolean) =>
L.divIcon({
iconAnchor: [0, 24],
popupAnchor: [0, -36],
html:
`<figure style="${makerWrapperStyles(isSelected)}">
`<figure style="${makerWrapperStyles(isSelected, isHighlighted)}">
<span style="${markerHtmlStyles(color)}">
${isSelected ? iconToSvg(Check) : iconToSvg(TreeIcon)}
</span>
</figure>`,
});

export const ClusterIcon = (color: string, isSelected: boolean, includedTrees: number) =>
export const ClusterIcon = (color: string, isHighlighted: boolean, includedTrees: number) =>
L.divIcon({
iconAnchor: [0, 24],
popupAnchor: [0, -36],
html:
`<figure style="${makerWrapperStyles(isSelected)}">
`<figure style="${makerClusterWrapperStyles(isHighlighted)}">
<span style="${markerClusterHtmlStyles(color)}">
${isSelected ? iconToSvg(Check) : includedTrees}
${includedTrees}
</span>
</figure>`,
});
Expand Down
32 changes: 20 additions & 12 deletions frontend/src/components/map/TreeMarker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ interface WithAllTreesProps {
onClick?: (tree: Tree) => void
selectedTrees?: number[]
trees: Tree[]
hasHighlightedTree?: number
}

export const WithAllTrees = ({
onClick,
selectedTrees = [],
trees,
hasHighlightedTree,
}: WithAllTreesProps) => {
const getStatusColor = (wateringStatus: EntitiesWateringStatus) => {
const statusDetails = getWateringStatusDetails(
Expand All @@ -30,9 +32,13 @@ export const WithAllTrees = ({
return selectedTrees.includes(treeId)
}

const isHighlighted = (treeId: number) => {
return hasHighlightedTree === treeId
}

return trees.map((tree) => (
<Marker
icon={TreeMarkerIcon(getStatusColor(tree.wateringStatus), isSelected(tree.id))}
icon={TreeMarkerIcon(getStatusColor(tree.wateringStatus), isSelected(tree.id), isHighlighted(tree.id))}
key={tree.id}
position={[tree.latitude, tree.longitude]}
eventHandlers={{
Expand All @@ -44,14 +50,14 @@ export const WithAllTrees = ({

interface WithAllClustersProps {
onClick?: (tree: TreeCluster) => void
selectedClusters?: number[]
clusters: TreeCluster[]
hasHighlightedCluster?: number,
}

export const WithAllClusters = ({
onClick,
selectedClusters = [],
clusters
clusters,
hasHighlightedCluster,
}: WithAllClustersProps) => {
const getStatusColor = (wateringStatus: EntitiesWateringStatus) => {
const statusDetails = getWateringStatusDetails(
Expand All @@ -60,13 +66,13 @@ export const WithAllClusters = ({
return statusDetails.colorHex
}

const isSelected = (treeId: number) => {
return selectedClusters.includes(treeId)
const isHighlighted = (clusterId: number) => {
return hasHighlightedCluster === clusterId
}

return clusters.map((cluster) => (
<Marker
icon={ClusterIcon(getStatusColor(cluster.wateringStatus), isSelected(cluster.id), cluster.trees.length)}
icon={ClusterIcon(getStatusColor(cluster.wateringStatus), isHighlighted(cluster.id), cluster.trees.length)}
key={cluster.id}
position={[cluster.latitude, cluster.longitude]}
eventHandlers={{
Expand All @@ -80,22 +86,24 @@ interface WithTreesAndClustersProps {
onClickTree?: (tree: Tree) => void
onClickCluster?: (cluster: TreeCluster) => void
selectedTrees?: number[]
selectedClusters?: number[]
trees: Tree[]
clusters: TreeCluster[]
zoomThreshold?: number
activeFilter?: boolean,
activeFilter?: boolean
hasHighlightedTree?: number,
hasHighlightedCluster?: number,
}

export const WithTreesAndClusters = ({
onClickTree,
onClickCluster,
selectedTrees = [],
selectedClusters = [],
trees,
clusters,
zoomThreshold = 17,
activeFilter = false,
hasHighlightedTree,
hasHighlightedCluster,
}: WithTreesAndClustersProps) => {
const { zoom } = useStore((state) => ({
zoom: state.map.zoom,
Expand All @@ -104,8 +112,8 @@ export const WithTreesAndClusters = ({
return (
<>
{zoom >= zoomThreshold || activeFilter
? <WithAllTrees trees={trees} onClick={onClickTree} selectedTrees={selectedTrees} />
: <WithAllClusters clusters={clusters} onClick={onClickCluster} selectedClusters={selectedClusters} />}
? <WithAllTrees trees={trees} onClick={onClickTree} selectedTrees={selectedTrees} hasHighlightedTree={hasHighlightedTree} />
: <WithAllClusters clusters={clusters} onClick={onClickCluster} hasHighlightedCluster={hasHighlightedCluster} />}

</>
)
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/tree/TreeDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const TreeDashboard = ({ treeId }: TreeDashboardProps) => {
{tree.description && <p>{tree.description}</p>}
<div className="flex mt-4 flex-wrap gap-x-10">
<GeneralLink
url={`/map?lat=${tree.latitude}&lng=${tree.longitude}&zoom=18`}
url={`/map?lat=${tree.latitude}&lng=${tree.longitude}&zoom=18&tree=${tree.id}`}
label="Auf der Karte anzeigen"
/>
{tree.treeClusterId && (
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/components/treecluster/TreeClusterDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ButtonLink from '@/components/general/links/ButtonLink'
import { Pencil } from 'lucide-react'
import { getWateringStatusDetails } from '@/hooks/useDetailsForWateringStatus'
import { Link } from '@tanstack/react-router'
import GeneralLink from '../general/links/GeneralLink'

interface TreeClusterDashboardProps {
clusterId: string
Expand All @@ -28,7 +29,11 @@ const TreeClusterDashboard = ({ clusterId }: TreeClusterDashboardProps) => {
<h1 className="font-lato font-bold text-3xl mb-4 lg:text-4xl xl:text-5xl">
Bewässerungsgruppe: {treecluster.name}
</h1>
<p>{treecluster.description}</p>
<p className="mb-4">{treecluster.description}</p>
<GeneralLink
url={`/map?lat=${treecluster.latitude}&lng=${treecluster.longitude}&zoom=16&cluster=${treecluster.id}`}
label="Auf der Karte anzeigen"
/>
</div>
<ButtonLink
icon={Pencil}
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/routes/_protected/map/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const mapFilterSchema = z.object({
status: z.array(z.string()).optional(),
hasCluster: z.boolean().optional(),
plantingYears: z.array(z.number()).optional(),
highlighted: z.number().optional(),
})

function MapView() {
Expand Down Expand Up @@ -117,6 +118,8 @@ function MapView() {
activeFilter={activeFilter}
onClickTree={handleTreeClick}
onClickCluster={handleClusterClick}
hasHighlightedTree={search.tree}
hasHighlightedCluster={search.cluster}
/>
</>
)
Expand All @@ -139,13 +142,15 @@ export const Route = createFileRoute('/_protected/map/')({
component: MapViewWithProvider,
validateSearch: mapFilterSchema,

loaderDeps: ({ search: { status, hasCluster, plantingYears } }) => ({
loaderDeps: ({ search: { status, hasCluster, plantingYears, tree, cluster } }) => ({
status: status || [],
hasCluster: hasCluster || undefined,
plantingYears: plantingYears || [],
tree: tree || undefined,
cluster: cluster || undefined,
}),

loader: ({ deps: { status, hasCluster, plantingYears } }) => {
return { status, hasCluster, plantingYears }
loader: ({ deps: { status, hasCluster, plantingYears, tree, cluster } }) => {
return { status, hasCluster, plantingYears, tree, cluster }
},
})

0 comments on commit c1e190e

Please sign in to comment.