Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix raw HTML visible on page load, fix broken links, improve readme #495

Merged
merged 6 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions .babelrc

This file was deleted.

39 changes: 33 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ That’s why we’re building a data-driven movement of climate-savvy developers

#Klimatkollen #FreeClimateData

## Climate Data Pipeline Overview

Please see full [description here](data/README.md).

Feel free to explore the repository to understand more about how we collect, process, and display climate data.

## Building and running locally

If your're starting from scratch, and working with GitHub, NodeJS and so on is new to you, read [doc/getting-started.md](doc/getting-started.md).
Expand All @@ -39,6 +33,37 @@ The project can also be run with docker (although with much slower refresh time)
# starts the container
docker run -t -i --rm -p 3000:3000 --name klimatkollen klimatkollen

# Data overview

In very general terms, Klimatkollen presents:
- Detailed information about Swedish municipalities' emissions...
- ...and their remaining emission budget based on the Paris Agreement.
- Other key point indicators for sustainability transition, such electric car charger density.
- Contextual information to help understand the significance of the above.

# File overview

The toplevel directory contains a lot of files and folders. You can just ignore most of them. Take note of:
- `README.md` - this document.
- `data`: Our data processing pipeline, written in Python. This can more or less be used/edited independently of the rest of the repository. See `data/README.md`.
- `data/facts`: Copies of source datasets.
- `doc`: Documentation and guides, they might answer many questions.
- `doc/getting-started.md`: Detailed setup instructions for the web project.
- `doc/contributing.md`: Good to know before making your first contribution.
- `pages` and `components`: Source code for almost everything visible on the website's pages.
- `public`: Files that will be served directly on the website.
- `public/locales`: Language files defininig translations of the website.

# Code architecture overview

How does everything fit together, code-wise?
- Copies of source datasets are under `data/facts`.
- We run the Python scripts under `data` to produce `data/output/climate-data.json` from those datasets.
- The latest copy of `data/output/climate-data.json` is always checked into version control.
- The rest of the website source code loads `data/output/climate-data.json`.
- The framework `next.js` is used to compile actual HTML pages at runtime.
- `next.js` caches each page for serving, to serve it faster for each new visitor.

## Contributing

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 All @@ -49,6 +74,8 @@ Looking for ideas on what needs to be done? We appreciate help on existing [issu

Testing, bug fixes, typos or fact checking of our data is highly appreciated.

See [doc/contributing.md] before making your first contribution.

## Contact

Join the Discord server in the introduction or send an email to [[email protected]](mailto:[email protected]).
Expand Down
6 changes: 3 additions & 3 deletions __tests__/utils/generateMunipacitySitemap.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TFunction } from 'next-i18next'
import {
generateMunipacitySitemapData,
generateMunicipalitySitemapData,
generateSitemap,
} from '../../utils/generateMunipacitySitemap'
import { Municipality } from '../../utils/types'
Expand All @@ -11,7 +11,7 @@ const t = vi.fn((str) => str) as unknown as TFunction

describe('generateSitemap', () => {
it('should generate valid municipality sitemap data', () => {
const siteMap = generateMunipacitySitemapData({ municipalities })
const siteMap = generateMunicipalitySitemapData({ municipalities })
expect(siteMap).toEqual([
{
url: 'https://klimatkollen.se/kommun/stockholm',
Expand All @@ -31,7 +31,7 @@ describe('generateSitemap', () => {
})

it('should generate a valid sitemap XML string', () => {
const siteMap = generateMunipacitySitemapData({ municipalities })
const siteMap = generateMunicipalitySitemapData({ municipalities })
const sitemapXml = generateSitemap(siteMap, t)
expect(() => new DOMParser().parseFromString(sitemapXml, 'text/xml')).not.toThrow()
})
Expand Down
2 changes: 1 addition & 1 deletion components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Main = styled.main`
}
`

export default function Layout({ children }: { children: JSX.Element }) {
export default function Layout({ children }: { children: JSX.Element | JSX.Element[] }) {
return (
<>
<Header />
Expand Down
16 changes: 15 additions & 1 deletion components/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import ReactMarkdown, { Components, Options } from 'react-markdown'
import rehypeExternalLinks from 'rehype-external-links'
import styled from 'styled-components'
import Link from 'next/link'
import { Ref } from 'react'

import {
H1, H2, H3, Paragraph, ParagraphBold, ParagraphItalic,
Expand All @@ -19,7 +20,20 @@ const defaultComponents: Partial<Components> = {
// Workaround to inherit styles and just change the HTML element
strong: styled(ParagraphBold).attrs({ as: 'strong' })``,
em: styled(ParagraphItalic).attrs({ as: 'em' })``,
a: Link as Components['a'],
// Ensure public assets served from the same domain (currently only PDFs) are opened in a new tab
// This prevents unwanted behavior where Next.js tries to preload data for URLs that are outside of the Next.js app.
a: ({
href, target, ref, rel, children,
}) => (
<Link
href={href as string}
target={href?.endsWith('.pdf') ? '_blank' : target}
rel={rel}
ref={ref as Ref<HTMLAnchorElement>}
>
{children}
</Link>
),
h1: H1,
h2: H2,
h3: H3,
Expand Down
18 changes: 6 additions & 12 deletions components/ToggleSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,21 @@ const Arrow = styled(ArrowSvg)<{ open: boolean }>`
const HeaderSection = styled.summary`
display: flex;
justify-content: space-between;
width: 100%;
list-style: none; /* remove default arrow in Firefox */

& .arrow {
display: block;
}
&::-webkit-details-marker {
display: none; /* remove default arrow in Chrome */

&:hover {
cursor: pointer;
}
}
`

const InfoSection = styled.div`
display: flex;
flex-direction: column;

.mobile {
background: black;
}

.desktop {
background: yellow;
}
`

type Props = {
Expand All @@ -60,7 +54,7 @@ function ToggleSection({ header, text }: Props) {
<TextSection onToggle={(event) => setOpen((event.target as HTMLDetailsElement).open)}>
<HeaderSection>
<H5>{header}</H5>
<Arrow open={open} className="arrow" />
<Arrow open={open} />
</HeaderSection>
<InfoSection>
{typeof text === 'string' ? <Markdown>{text}</Markdown> : text}
Expand Down
78 changes: 78 additions & 0 deletions doc/contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Klimatkollen contribution guidelines

Thank you for wanting to contribute to Klimatkollen! Please read this before starting to code :)

## What to expect from the team

Klimatkollen is driven by a small team that does a lot more than coding. From media outreach and fundraising to data analysis and hackathons, there's a lot going on. We sometimes have to push changes through in sync with exernal deadlines, for example to publish some data at the same time as a debate article. In such times we might not be able to review all proposed changes as soon as we would like to. As a rule of thumb we aspire to respond to every issue/PR within a week, and often much faster than that.

## How to get in touch

The best way to get in touch with us is through the discord (link in README). It's a very active server and all the discussions happen there, as well as many other day-to-day updates. You can also email at [email protected].

## Guide: How to make your first contribution

### Step 1. Find something to work on.

Either pick an issue from the GitHub issues tab, or create a new one to describe your suggestion/idea/bug report.

If you are creating a new issue, make sure to look for similar ones first. Use the search function!

Issues labelled "good first issue" are the best to start with if you are new to the project.

### Step 2. Let others know you're working on it.

Once you decide to pick an issue up, leave a comment saying so, to avoid others starting on the same one at the same time.

### Step 3. Make your changes

For most issues you will start with making sure you can run Klimatkollen locally, see [doc/getting-started.md] for instructions on that.

Run `git log -1` to see the latest commit in your local repo, and make sure this is the same as the `staging` branch on GitHub. This is to make sure you are up to date on everyone's changes.

(optional but recommended) Run `git checkout -b <issue-id>`, replacing `<issue-id>` with the id of the issue or another good name, to create a branch for you changes.

Make the code changes you would like to address the issue you are working on. It doesn't have to be perfect on first attempt, a prototype showing how an issue can be partially solved is already a step in the right direction.

Commit your work. You can make multiple commits if you like, and we don't enforce any particular style commit messages.

### Don't forget!

Your code contribution must not introduce new warnings or errors, or reduce the quality of the code. We will check this as part of review, but you can make the process faster by making sure we won't find anything.

Checklist before finishing your PR:

[ ] Run `npm run build` to compile all pages. Make sure there are no new warnings or errors.
[ ] Run `npm run lint` - same story.
[ ] Run `npm run start` to test the site locally and click through a few pages. Particularly focus on the places where you made your changes.

Also consider what it will be like for someone else to read your code. Will they be able to read it and understand what's going on?

### Step 4. Publish your work.

Push your commits to your fork of Klimatkollen. If you haven't created a fork already, use the "fork" button on GitHub and then add your fork as a remote by running `git remote add my-fork <git address of your fork>` where `my-fork` is an arbitrary name for the fork locally.

Create a pull request. Either follow the link git showed after pushing to your fork, or create it from the GitHub web interface. Double check the branches in the PR! Make sure your are merging from your own branch, on your own repo, into "staging" on "klimatkollen". A common mistake is to accidentally start merging into "staging" on your own repo.

In the PR desscription, write "Fixes #XXX" where XXX is the id of the issue you are fixing. E.g. `Fixes #413`

If the PR is not ready for review yet, prefix the title wiht "Draft: ". Remove this once you're ready.

In the body, describe the changes you have made, what you have done to test your work, if there's anything you're unsure about, or if some parts of the code are unfinished. Focus on the changes and how they address the issues - but try to keep discussion of the issue itself, in the issue.

### Step 5. Get your work reviewed.

Once the PR is created and has left the "draft" stage, someone from the team will eventually review it. This can normally take at least a few days - please be patient. At the same time, it is completely fine to let us know you're waiting for a review on Discord, and ask if you are unsure about anything.

The reviewer will most likely have some comments, questions, or feedback, which you will be expected to address.

In some cases, the reviewer might make some changes to your PR themselves and commit it, if they need to get the fix in quickly.

The reviewer might also conclude that the changes should not be made, or that there currently isn't time to review it. Such a scenario is unlikely but if it does happen, please be understanding and remember that the reviwer wants what's best for the project, just like you.

Klimatkollen's team has the final say on what goes into the code.

### Step 6. After the PR is merged

It might take some days before code merged to `staging` is published to production.

12 changes: 12 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})

/** @type {require('next').NextConfig} */
module.exports = withBundleAnalyzer({
webpack(config) {
config.module.rules.push({
Expand All @@ -17,6 +18,17 @@ module.exports = withBundleAnalyzer({
},

reactStrictMode: true,
compiler: {
styledComponents: {
ssr: true,
displayName: true,
},
},
// i18n configuration
i18n: {
locales: ['sv'],
defaultLocale: 'sv',
},
i18n,

// Redirects configuration
Expand Down
21 changes: 9 additions & 12 deletions pages/404.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@ import styled from 'styled-components'
import { useTranslation } from 'next-i18next'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import { GetStaticProps } from 'next'
import { H1 } from '../components/Typography'

const Wrapper = styled.div`
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
`
import { H1 } from '../components/Typography'
import Layout from '../components/Layout'
import PageWrapper from '../components/PageWrapper'

const Button = styled.button`
height: 56px;
Expand All @@ -35,10 +30,12 @@ function FourOhFour() {
const { t } = useTranslation()

return (
<Wrapper>
<H1>{t('common:errors.notFound')}</H1>
<Button onClick={handleClick}>{t('common:actions.goHome')}</Button>
</Wrapper>
<Layout>
<PageWrapper backgroundColor="black">
<H1>{t('common:errors.notFound')}</H1>
<Button onClick={handleClick}>{t('common:actions.goHome')}</Button>
</PageWrapper>
</Layout>
)
}

Expand Down
Loading
Loading