Skip to content

Commit

Permalink
Release 2023-12-13 (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohannaPeanut authored Dec 13, 2023
2 parents 41cd61f + e4e6821 commit dcbee08
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 28 deletions.
5 changes: 4 additions & 1 deletion .env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ S3_UPLOAD_REGION=eu-central-1
S3_UPLOAD_SECRET=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

# Get from https://felt.com/ => Settings
FELT_TOKEN=felt_pat_AAAAAAAAAAAAAAAAAAAAAA
FELT_TOKEN=felt_pat_AAAAAAAAAAAAAAAAAAAAAA

# Admin mail address, mails are sent to
[email protected]
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"
target-branch: "dependabot"
10 changes: 5 additions & 5 deletions .github/workflows/deploy-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
build-push-deploy-docker-images:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Upgrade AWS CLI version and setup lightsailctl
run: |
Expand All @@ -58,17 +58,17 @@ jobs:
sudo chmod +x /usr/local/bin/lightsailctl
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-central-1

- name: Setup buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3

- name: Build app image
uses: docker/build-push-action@v3
uses: docker/build-push-action@v5
with:
file: ./docker/app/Dockerfile
push: false
Expand All @@ -78,7 +78,7 @@ jobs:
tags: public.ecr.aws/n0p8j4k5/trassenscout/app:${{ github.sha }}

- name: Build nginx image
uses: docker/build-push-action@v3
uses: docker/build-push-action@v5
with:
context: ./docker/nginx
push: false
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div align="center"><br><br>
<h1 align="center">Trassenscout (beta)</h1>
<h1 align="center">Trassenscout (Beta)</h1>
</div>

> Trassenscout (beta) supports administrations in the process of evaluating and building cycle highways and in perspective other route based infrastructure.
> Trassenscout (Beta) aids administrations in evaluating and developing cycle highways and other similar route-based infrastructure.
>
> Please contact [email protected] to learn more.
Expand Down
82 changes: 82 additions & 0 deletions mailers/userCreationMailer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import Mailjet from "node-mailjet"
import previewEmail from "preview-email"
import { getPrdOrStgDomain } from "src/core/components/links/getDomain"

type UserCreationMailer = {
userMail: string
userId: number
userFirstname: string | null
userLastname: string | null
}

export function userCreationMailer({
userMail,
userId,
userFirstname,
userLastname,
}: UserCreationMailer) {
const origin = getPrdOrStgDomain()

// mailjet format
const msg = {
From: { Email: "<[email protected]>", Name: "Trassenscout" },
To: [{ Email: process.env.ADMIN_EMAIL }],
Subject: "User hat sich registriert",
TextPart: `
Liebes Trassenscout-Team,
ein neuer Nutzer-Account wurde erstellt, bitte prüfen und einem Projekt zuordnen:
Name: ${userFirstname} ${userLastname}
E-Mail: ${userMail}
Hier können die Rechte vergeben werden: ${origin}/admin/memberships
Viele Grüße
Dein Trassenscout-Nachrichtendienst
`,
HTMLPart: `
<p>Liebes Trassenscout-Team,</p>
<p>ein neuer Nutzer-Account wurde erstellt, bitte prüfen und einem Projekt zuordnen:</p>
<ul>
<li>Name: ${userFirstname} ${userLastname}</li>
<li>E-Mail: ${userMail}</li>
</ul>
<p>Hier können die Rechte vergeben werden: <a href="${origin}/admin/memberships">Zugriffsrechte-Verwaltung</a></p>
<p>Viele Grüße<br/>
Dein Trassenscout-Nachrichtendienst</p>
`,
}

return {
async send() {
if (process.env.NODE_ENV === "production") {
const mailjet = Mailjet.apiConnect(
// @ts-ignore
process.env.MAILJET_APIKEY_PUBLIC,
process.env.MAILJET_APIKEY_PRIVATE,
)
const request = mailjet.post("send", { version: "v3.1" }).request({ Messages: [msg] })
request
.then((result) => {
console.log(result.body)
})
.catch((err) => {
console.error(err.statusCode)
})
} else {
// Preview email in the browser
var { From, To, Subject, TextPart, HTMLPart } = msg
await previewEmail({
from: `${From.Name} <${From.Email}>`,
// @ts-ignore
to: `${To[0]?.Name || ""} <${To[0].Email}>`,
subject: Subject,
text: TextPart,
html: HTMLPart,
})
}
},
}
}
7 changes: 7 additions & 0 deletions src/auth/mutations/signup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { resolver } from "@blitzjs/rpc"
import db from "db"
import { Role } from "types"
import { Signup } from "../validations"
import { userCreationMailer } from "mailers/userCreationMailer"

export default resolver.pipe(
resolver.zod(Signup),
Expand All @@ -21,6 +22,12 @@ export default resolver.pipe(
})

await ctx.session.$create({ userId: user.id, role: user.role as Role })
await userCreationMailer({
userMail: user.email,
userId: user.id,
userFirstname: user.firstName,
userLastname: user.lastName,
}).send()
return user
},
)
6 changes: 4 additions & 2 deletions src/core/components/Map/BaseMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ export type BaseMapProps = Required<Pick<MapProps, "id" | "initialViewState">> &
Point,
{ subsectionSlug: string; subsubsectionSlug?: string; color: string; opacity?: number }
>
dots: [number, number][]
dots?: [number, number][]
classHeight?: string
children: React.ReactNode
children?: React.ReactNode
}

export const BaseMap: React.FC<BaseMapProps> = ({
Expand Down Expand Up @@ -176,6 +176,8 @@ export const BaseMap: React.FC<BaseMapProps> = ({
.flat()
.filter(Boolean)}
hash={hash || false}
// @ts-expect-error: See https://github.com/visgl/react-map-gl/issues/2310
RTLTextPlugin={null}
>
<NavigationControl showCompass={false} />
<ScaleControl />
Expand Down
23 changes: 18 additions & 5 deletions src/core/components/Map/ProjectMap.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Routes, useParam } from "@blitzjs/next"
import { lineString } from "@turf/helpers"
import { along, featureCollection, length } from "@turf/turf"
import { LngLatBoundsLike } from "maplibre-gl"

import { useRouter } from "next/router"
import React, { useEffect, useState } from "react"
import React, { useEffect, useMemo, useState } from "react"
import {
LngLatBoundsLike,
MapEvent,
MapLayerMouseEvent,
Marker,
Expand All @@ -27,9 +28,21 @@ export const ProjectMap: React.FC<Props> = ({ subsections }) => {
const projectSlug = useParam("projectSlug", "string")
const { mainMap } = useMap()

// bundingBox only changes when subsections change / subsections array is created
const boundingBox = useMemo(() => {
return subsectionsBbox(subsections) as LngLatBoundsLike
}, [subsections])

// we do not want to fitBounds everytime the subsections array is created (tanstack query refetches subsections on window focus)
// we could disable refetchOnWindowFocus, in [projectId]/index.tsx with {refetchOnWindowFocus: false} https://blitzjs.com/docs/query-usage
// but then we would not get the latest data when the user comes back to the page

// we spread boundingBox in the dependency array to make sure the effect runs when the values of boundingBox change (not everytime the array is created)
useEffect(() => {
mainMap?.fitBounds(subsectionsBbox(subsections) as LngLatBoundsLike, { padding: 60 })
}, [mainMap, subsections])
// @ts-expect-error
mainMap?.fitBounds(boundingBox, { padding: 60 })
// @ts-expect-error
}, [mainMap, ...boundingBox])

type HandleSelectProps = { subsectionSlug: string; edit: boolean }
const handleSelect = ({ subsectionSlug, edit }: HandleSelectProps) => {
Expand Down Expand Up @@ -117,7 +130,7 @@ export const ProjectMap: React.FC<Props> = ({ subsections }) => {
<BaseMap
id="mainMap"
initialViewState={{
bounds: subsectionsBbox(subsections),
bounds: boundingBox,
fitBoundsOptions: { padding: 60 },
}}
onClick={handleClickMap}
Expand Down
22 changes: 22 additions & 0 deletions src/core/components/Map/ProjectMapFallback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { SubsectionWithPosition } from "src/subsections/queries/getSubsection"
import { BaseMap } from "./BaseMap"
import { subsectionsBbox } from "./utils"

type Props = { subsections: SubsectionWithPosition[] }

export const ProjectMapFallback: React.FC<Props> = ({ subsections }) => {
return (
<section className="mt-3 relative">
<BaseMap
id="mainMap"
initialViewState={{
bounds: subsectionsBbox(subsections),
fitBoundsOptions: { padding: 60 },
}}
/>
<div className="inset-x-0 mx-4 bg-white/80 p-4 px-8 text-center absolute bottom-12 font-sans">
Noch keine Planungsabschnitte angelegt
</div>
</section>
)
}
2 changes: 2 additions & 0 deletions src/core/components/forms/LabeledGeometryFieldPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ export const LabeledGeometryFieldPreview: React.FC<Props> = ({ name, hasError })
id="preview"
mapStyle={vectorStyle}
scrollZoom={false}
// @ts-expect-error: See https://github.com/visgl/react-map-gl/issues/2310
RTLTextPlugin={null}
>
<NavigationControl showCompass={false} />
<ScaleControl />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const NavigationGeneralLogo: React.FC<Props> = ({ beta = true }) => {
height={30}
width={84}
/>
{beta && <span className="ml-2 text-xs uppercase text-gray-400">Alpha</span>}
{beta && <span className="ml-2 text-xs uppercase text-gray-400">Beta</span>}
</div>
)
}
16 changes: 11 additions & 5 deletions src/pages/[projectSlug]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { BlitzPage, Routes, useParam, useRouterQuery } from "@blitzjs/next"
import { useQuery } from "@blitzjs/rpc"
import { Suspense } from "react"
import { Suspense, useMemo } from "react"
import { MapProvider } from "react-map-gl"
import { CalenderDashboard } from "src/calendar-entries/components"
import { SuperAdminLogData } from "src/core/components/AdminBox/SuperAdminLogData"
import { Breadcrumb } from "src/core/components/Breadcrumb/Breadcrumb"
import { ProjectMap } from "src/core/components/Map/ProjectMap"
import { ProjectMapFallback } from "src/core/components/Map/ProjectMapFallback"
import { Markdown } from "src/core/components/Markdown/Markdown"
import { Spinner } from "src/core/components/Spinner"
import { Link } from "src/core/components/links"
Expand All @@ -23,10 +24,10 @@ export const ProjectDashboardWithQuery = () => {
const projectSlug = useParam("projectSlug", "string")
const [project] = useQuery(getProject, { slug: projectSlug })
const [{ subsections }] = useQuery(getSubsections, { projectSlug: projectSlug! })

// We use the URL param `operator` to filter the UI
// Docs: https://blitzjs.com/docs/route-params-query#use-router-query
const params = useRouterQuery()

const filteredSubsections = params.operator
? subsections.filter(
(sec) => typeof params.operator === "string" && sec.operator?.slug === params.operator,
Expand Down Expand Up @@ -73,9 +74,14 @@ export const ProjectDashboardWithQuery = () => {
)}

<OperatorFilterDropdown />
<MapProvider>
<ProjectMap subsections={filteredSubsections} />
</MapProvider>

{Boolean(filteredSubsections.length) ? (
<MapProvider>
<ProjectMap subsections={filteredSubsections} />
</MapProvider>
) : (
<ProjectMapFallback subsections={subsections} />
)}

<SubsectionTable subsections={filteredSubsections} />

Expand Down
12 changes: 5 additions & 7 deletions src/subsections/components/SubsectionTable.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { Routes } from "@blitzjs/next"
import { Subsection } from "@prisma/client"
import clsx from "clsx"
import { useRouter } from "next/router"
import { SubsectionIcon } from "src/core/components/Map/Icons"
import { TableWrapper } from "src/core/components/Table/TableWrapper"
import { Link } from "src/core/components/links"
import { useSlugs } from "src/core/hooks"
import { SubsectionIcon } from "src/core/components/Map/Icons"
import { startEnd } from "src/core/components/text/startEnd"
import { longTitle, shortTitle } from "src/core/components/text"
import { Prettify } from "src/core/types"
import { SubsectionWithPosition } from "../queries/getSubsection"
import { startEnd } from "src/core/components/text/startEnd"
import { useSlugs } from "src/core/hooks"
import { StakeholderSummary } from "src/stakeholdernotes/components/StakeholderSummary"
import clsx from "clsx"
import { SubsectionWithPosition } from "../queries/getSubsection"

type Props = {
subsections: SubsectionWithPosition[]
Expand Down

0 comments on commit dcbee08

Please sign in to comment.