Skip to content

Commit

Permalink
Merge pull request #406 from Klimatbyran/staging
Browse files Browse the repository at this point in the history
Improved drop-down search, add docker build, improved UI, fixed typos and cleanup
  • Loading branch information
elvbom authored Mar 8, 2024
2 parents 23b3eb4 + 9f96488 commit d361129
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 59 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.git
*Dockerfile*
*docker-compose*
node_modules
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM node:21-alpine3.18

WORKDIR /app

COPY package.json ./

RUN npm install

COPY . ./

EXPOSE 3000

ENTRYPOINT [ "npm" ]

CMD [ "run", "dev" ]
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ We use next.js and Typescript and it's pretty straightforward to get started. Ju

This opens up a webserver on http://localhost:3000. Just edit the code and see the live refresh.

The project can also be run with docker (although with much slower refresh time):

# builds the image
docker build -t klimatkollen .

# starts the container
docker run -t -i --rm -p 3000:3000 --name klimatkollen klimatkollen

## Contribute

The idea behind Klimatkollen is to give citizens access to the climate data we need to meet the goals of the Paris Agreement – and save our own future.
Expand Down
30 changes: 30 additions & 0 deletions __tests__/components/DropDown.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { test } from 'vitest'
import { getSortedMunicipalities, search } from '../../components/DropDown'

test('Municipalities should be sorted by Swedish alphabetical order', () => {
expect(
getSortedMunicipalities(['Örebro', 'Säffle', 'Älmhult', 'Åre', 'Karlshamn']),
).toEqual(['Karlshamn', 'Säffle', 'Åre', 'Älmhult', 'Örebro'])
})

describe('When searching a list of sorted municipalities', () => {
const municipalities = ['Göteborg', 'Malmö', 'Stockholm', 'Södertälje']

test('Results that do not include the query should be filtered out', () => {
expect(search('holm', municipalities)).toEqual(['Stockholm'])
expect(search('s', municipalities)).toEqual(['Stockholm', 'Södertälje'])
})

test('The search is case-insensitive', () => {
expect(search('göt', municipalities)).toEqual(['Göteborg'])
expect(search('GÖt', municipalities)).toEqual(['Göteborg'])
})

test('Results that start with the query should be prioritized', () => {
expect(search('st', ['Avesta', 'Mariestad', 'Stockholm'])).toEqual([
'Stockholm',
'Avesta',
'Mariestad',
])
})
})
3 changes: 2 additions & 1 deletion components/BackArrow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const StyledButton = styled.button`
border: none;
cursor: pointer;
background-color: transparent;
align-self: flex-start;
width: 60px;
text-align: left;
`

type BackArrowProps = {
Expand Down
31 changes: 29 additions & 2 deletions components/DropDown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,35 @@ type Props = {
className: string
}

export function getSortedMunicipalities(municipalitiesName: Array<string>) {
return municipalitiesName.sort((a, b) => a.localeCompare(b, 'sv'))
}

export function search(query: string, municipalitiesName: Array<string>) {
const queryLowerCase = query.toLowerCase()

return municipalitiesName
.filter((municipality) => municipality.toLowerCase().includes(queryLowerCase))
.sort((a, b) => {
const lowerA = a.toLowerCase()
const lowerB = b.toLowerCase()

const startsWithQueryA = lowerA.startsWith(queryLowerCase)
const startsWithQueryB = lowerB.startsWith(queryLowerCase)

if (startsWithQueryA && !startsWithQueryB) {
return -1
}
if (!startsWithQueryA && startsWithQueryB) {
return 1
}

return 0
})
}

function DropDown({ municipalitiesName, placeholder, className }: Props) {
const sortedMunicipalities = municipalitiesName.sort((a, b) => a.localeCompare(b))
const sortedMunicipalities = getSortedMunicipalities(municipalitiesName)
const [showDropDown, setShowDropDown] = useState(false)
const [selectedMunicipality, setSelectedMunicipality] = useState<string>('')
const [municipalities, setMunicipalities] = useState(sortedMunicipalities)
Expand Down Expand Up @@ -128,7 +155,7 @@ function DropDown({ municipalitiesName, placeholder, className }: Props) {
} else {
setShowDropDown(true)
}
const filteredMunicipalities = sortedMunicipalities.filter((test) => test.toLowerCase().includes(value.toLowerCase()))
const filteredMunicipalities = search(value, sortedMunicipalities)
setMunicipalities(filteredMunicipalities)
}

Expand Down
6 changes: 3 additions & 3 deletions components/Graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ function Graph({
// @ts-ignore
id: 'budget',
fill: true,
data: budgetDataset,
borderWidth: 2,
data: step >= 2 ? budgetDataset : budgetDataset.map(({ x }) => ({ x, y: 0 })),
borderWidth: step >= 2 ? 2 : 0,
borderColor: colorTheme.lightGreen,
backgroundColor: colorTheme.lightGreenOpaqe,
pointRadius: 0,
tension: 0.15,
hidden: step < 2,
hidden: false,
},
{
// @ts-ignore
Expand Down
11 changes: 6 additions & 5 deletions components/Municipality/Municipality.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import styled from 'styled-components'

import { H1, ParagraphBold } from '../Typography'
import { H1NoPad, ParagraphBold } from '../Typography'
import BackArrow from '../BackArrow'
import PageWrapper from '../PageWrapper'
import DropDown from '../DropDown'
Expand All @@ -16,7 +16,8 @@ import Scorecard from './MunicipalityScorecard'
const StyledContainer = styled.div`
display: flex;
flex-direction: column;
gap: 2rem;
align-items center;
gap: 1.5rem;
margin-bottom: 48px;
`

Expand All @@ -29,7 +30,7 @@ const HeaderSection = styled.div`
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-top: 20px;
margin-top: 10px;
`

const Bottom = styled.div`
Expand Down Expand Up @@ -74,10 +75,10 @@ function Municipality(props: Props) {
return (
<>
<PageWrapper backgroundColor="lightBlack">
<BackArrow route="/" />
<StyledContainer>
<HeaderSection>
<H1>{municipality.Name}</H1>
<BackArrow route="/" />
<H1NoPad>{municipality.Name}</H1NoPad>
{coatOfArmsImage && (
<CoatOfArmsImage
src={coatOfArmsImage}
Expand Down
18 changes: 18 additions & 0 deletions components/Typography.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,31 @@ export const H1 = styled.h1`
font-size: 48px;
line-height: 1.25;
margin: 0 0 16px 0;
@media (max-width: 768px) {
font-size: 42px;
}
`

export const H1NoPad = styled.h1`
font-weight: bold;
font-size: 48px;
line-height: 1.25;
@media (max-width: 768px) {
font-size: 35px;
}
`

export const H2 = styled.h2`
font-weight: bold;
font-size: 32px;
line-height: 1.25;
margin: 0 0 8px 0;
@media (max-width: 768px) {
font-size: 24px;
}
`

export const H2Regular = styled.h2`
Expand Down
2 changes: 1 addition & 1 deletion pages/om-oss/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ function OmOss() {
</Paragraph>
<Paragraph>
Våra samarbetspartners under de första två åren har varit Världsnaturfonden WWF,
Postkodstiftelsen, PwC, ClimateView,, Klimatklubben, Våra barns klimat,
Postkodstiftelsen, PwC, ClimateView, Klimatklubben, Våra barns klimat,
Researchers’ Desk, Argand Partners och We Don’t Have Time.
</Paragraph>
</>
Expand Down
94 changes: 47 additions & 47 deletions utils/datasetDescriptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,6 @@ export const datasetDescriptions: DatasetDescriptions = {
formattedDataPoint: (dataPoint) => ((dataPoint as number) * 100).toFixed(1),
},

Elbilarna: {
title: 'Elbilsökning',
body: 'Ökningstakten i kommunerna för andel nyregistrerade laddbara bilar 2015–2022, angivet i procentenheter per år.',
source: (
<>
Källa:
{' '}
<a href="https://www.trafa.se/vagtrafik/fordon/" target="_blank" rel="noreferrer">
Trafikanalys
</a>
</>
),
boundaries: [0.04, 0.05, 0.06, 0.07, 0.08],
labels: ['4 -', '4–5', '5–6', '6–7', '7–8', '8 +'],
labelRotateUp: [true, true, true, true, true, true],
columnHeader: 'Ökning elbilar',
sortAscending: false,
rawDataPoint: (item) => item.ElectricCarChangePercent,
formattedDataPoint: (dataPoint) => ((dataPoint as number) * 100).toFixed(1),
},

Klimatplanerna: {
title: 'Klimatplan',
body: (
Expand Down Expand Up @@ -106,6 +85,53 @@ export const datasetDescriptions: DatasetDescriptions = {
formattedDataPoint: (dataPoint) => (dataPoint === 'Saknas' ? 'Nej' : 'Ja'),
},

Elbilarna: {
title: 'Elbilsökning',
body: 'Ökningstakten i kommunerna för andel nyregistrerade laddbara bilar 2015–2022, angivet i procentenheter per år.',
source: (
<>
Källa:
{' '}
<a href="https://www.trafa.se/vagtrafik/fordon/" target="_blank" rel="noreferrer">
Trafikanalys
</a>
</>
),
boundaries: [0.04, 0.05, 0.06, 0.07, 0.08],
labels: ['4 -', '4–5', '5–6', '6–7', '7–8', '8 +'],
labelRotateUp: [true, true, true, true, true, true],
columnHeader: 'Ökning elbilar',
sortAscending: false,
rawDataPoint: (item) => item.ElectricCarChangePercent,
formattedDataPoint: (dataPoint) => ((dataPoint as number) * 100).toFixed(1),
},

Laddarna: {
title: 'Elbilar per laddare',
body: 'Antal laddbara bilar per offentliga laddpunkter år 2023. EU rekommenderar max 10 bilar per laddare.',
source: (
<>
Källa:
{' '}
<a
href="https://powercircle.org/elbilsstatistik/"
target="_blank"
rel="noreferrer"
>
Power Circle ELIS
</a>
{' '}
</>
),
boundaries: [1e6, 40, 30, 20, 10],
labels: ['Inga laddare', '40 +', '30-40', '20-30', '10-20', '10 -'],
labelRotateUp: [],
columnHeader: 'Elbil per laddare',
sortAscending: true,
rawDataPoint: (item) => item.ElectricVehiclePerChargePoints,
formattedDataPoint: (dataPoint) => ((dataPoint as number) < 1e5 ? (dataPoint as number).toFixed(1) : 'Laddare saknas'),
},

Cyklarna: {
title: 'Cykelvägslängd',
body: 'Antal meter cykelväg per invånare per kommun år 2022.',
Expand Down Expand Up @@ -173,32 +199,6 @@ export const datasetDescriptions: DatasetDescriptions = {
formattedDataPoint: (dataPoint) => (dataPoint as number).toFixed(1),
},

Laddarna: {
title: 'Elbilar per laddare',
body: 'Antal laddbara bilar per offentliga laddpunkter år 2023. EU rekommenderar max 10 bilar per laddare.',
source: (
<>
Källa:
{' '}
<a
href="https://powercircle.org/elbilsstatistik/"
target="_blank"
rel="noreferrer"
>
Power Circle ELIS
</a>
{' '}
</>
),
boundaries: [1e6, 40, 30, 20, 10],
labels: ['Inga laddare', '40 +', '30-40', '20-30', '10-20', '10 -'],
labelRotateUp: [],
columnHeader: 'Elbil per laddare',
sortAscending: true,
rawDataPoint: (item) => item.ElectricVehiclePerChargePoints,
formattedDataPoint: (dataPoint) => ((dataPoint as number) < 1e5 ? (dataPoint as number).toFixed(1) : 'Laddare saknas'),
},

Koldioxidbudgetarna: {
title: 'Budget slut om',
body: 'Datum då kommunens koldioxidbudget tar slut om utsläppen fortsätter enligt nuvarande trend. Några kommuner kommer att hålla budgeten om trenden står sig.',
Expand Down

0 comments on commit d361129

Please sign in to comment.