Skip to content

Commit

Permalink
Merge pull request #15 from OpenUpSA/fix/broken-images
Browse files Browse the repository at this point in the history
Fix/broken images
  • Loading branch information
paulmwatson authored Jul 23, 2024
2 parents ff9f342 + 16b161a commit 84497fd
Show file tree
Hide file tree
Showing 14 changed files with 1,021 additions and 22 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Cypress Tests

on: push

jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
# Install npm dependencies, cache them correctly
# and run all Cypress tests
- name: Cypress run
uses: cypress-io/github-action@v6
env:
AIRTABLE_API_KEY: ${{ secrets.AIRTABLE_API_KEY }}
IMGKIT_PRIVATE_KEY: ${{ secrets.IMGKIT_PRIVATE_KEY }}
with:
build: yarn build
start: yarn start
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Open Secrets PowerMapper

[![Tests](https://github.com/OpenUpSA/open-secrets-powermapper/actions/workflows/cypress.yml/badge.svg)](https://github.com/OpenUpSA/open-secrets-powermapper/actions/workflows/cypress.yml)

by [OpenUp](https://OpenUp.org.za).

## Development

```
cp env.example .env
```
```

Modify `.env` with real values.

Expand All @@ -17,8 +19,7 @@ yarn dev
## Deployment

Deployed on Netlify:

https://roaring-cactus-a582ea.netlify.app/

https://roaring-cactus-a582ea.netlify.app/

Automatic deployment of `main` and preview deployments of pull-requests.
Automatic deployment of `main` and preview deployments of pull-requests.
16 changes: 16 additions & 0 deletions app/api/power-stations/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ import {
EntityFieldNameToIdMapping,
} from "@/airtableFieldMappings";

import { uploadToImgKit } from "@/utils/imgkit";

import Airtable from "airtable";
import { NextResponse } from "next/server";


export async function GET(req: Request) {
const base = Airtable.base("appZdj1pFZQOBMn4E");

Expand Down Expand Up @@ -178,6 +181,19 @@ export async function GET(req: Request) {
type: image.type,
},
};
// We cache the Airtable image URLs on Imgkit because Airtable image URLs expire after
// 2 hours
uploadToImgKit(
powerStation.images.large.url,
`large_${powerStation.images.large.filename}`,
"powerstations"
);

uploadToImgKit(
powerStation.images.full.url,
`full_${powerStation.images.full.filename}`,
"powerstations"
);
}

if (fields[PowerStationFieldNameToIdMapping["Operator"]]) {
Expand Down
3 changes: 1 addition & 2 deletions components/filterPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,7 @@ function Component(props: Props) {
async function getData() {
initialized.current = true;
const res = await fetch(
`${process.env.NEXT_PUBLIC_URL}/api/power-stations`,
{ next: { revalidate: 3600 } }
`${process.env.NEXT_PUBLIC_URL}/api/power-stations`
);
const powerStationsData = await res.json();
setPowerStations(powerStationsData.powerStations);
Expand Down
3 changes: 1 addition & 2 deletions components/map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ function Component({ powerStations, panelOpen, setPanelOpen }: Props) {
async function getData() {
if (sidePanelEntity) {
const res = await fetch(
`${process.env.NEXT_PUBLIC_URL}/api/entity-info?id=${sidePanelEntity}`,
{ next: { revalidate: 3600 } }
`${process.env.NEXT_PUBLIC_URL}/api/entity-info?id=${sidePanelEntity}`
);
const entityInfoData = await res.json();
setSidePanelEntityInfo(entityInfoData);
Expand Down
4 changes: 2 additions & 2 deletions components/powerStationMarker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export function PowerStationMarker({
<Stack alignItems="center" direction="row" gap={1}>
{powerStation.images && powerStation.images.large && (
<Image
src={powerStation.images.large.url}
src={`https://ik.imagekit.io/powermapper/powerstations/large_${powerStation.images.large.filename}`}
alt={powerStation.name}
width="48"
height="48"
Expand Down Expand Up @@ -170,7 +170,7 @@ export function PowerStationMarker({
{powerStation.images && powerStation.images.full && (
<Image
className="photograph"
src={powerStation.images.full.url}
src={`https://ik.imagekit.io/powermapper/powerstations/full_${powerStation.images.full.filename}`}
alt={powerStation.name}
width={powerStation.images.full.width}
height={powerStation.images.full.height}
Expand Down
10 changes: 10 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from "cypress";

export default defineConfig({
e2e: {
supportFile: false,
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});
10 changes: 10 additions & 0 deletions cypress/e2e/api-entity-info.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
describe("Test Entity Info API endpoint", () => {
it("passes", () => {
cy.request("http://localhost:3000/api/entity-info?id=rec2SisdBnuMAZZJb").as(
"entityInfo"
);
cy.get("@entityInfo").should((response: any) => {
expect(response.body).to.have.property("name");
});
});
});
8 changes: 8 additions & 0 deletions cypress/e2e/api-power-stations.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
describe("Test Power Stations API endpoint", () => {
it("passes", () => {
cy.request("http://localhost:3000/api/power-stations").as("powerStations");
cy.get("@powerStations").should((response: any) => {
expect(response.body).to.have.property("powerStations");
});
});
});
4 changes: 2 additions & 2 deletions env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

AIRTABLE_API_KEY=https://airtable.com/create/tokens
GOOGLE_MAPS_API_KEY=https://console.developers.google.com/apis/credentials
URL=http://localhost:3000
URL=http://localhost:3000
IMGKIT_PRIVATE_KEY=Base64 encoded private key
4 changes: 4 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ const nextConfig = {
protocol: "https",
hostname: "v5.airtableusercontent.com",
},
{
protocol: "https",
hostname: "ik.imagekit.io",
},
],
},
};
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"test": "cypress run"
},
"dependencies": {
"@emotion/cache": "^11.11.0",
Expand All @@ -30,6 +31,7 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"cypress": "^13.13.1",
"eslint": "^8",
"eslint-config-next": "14.2.3",
"typescript": "^5"
Expand Down
27 changes: 27 additions & 0 deletions utils/imgkit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export const uploadToImgKit = (
file: string,
fileName: string,
folder: string
) => {
const url = "https://upload.imagekit.io/api/v2/files/upload";
const form = new FormData();
form.append("file", file);
form.append("fileName", fileName);
form.append("folder", folder);
form.append("useUniqueFileName", "false");

const options = {
method: "POST",
headers: {
Authorization: `Basic ${process.env.IMGKIT_PRIVATE_KEY}` as string,
Accept: "application/json",
},
body: form,
};

try {
fetch(url, options).catch((error) => console.error("error", error));
} catch (error) {
console.error(error);
}
};
Loading

0 comments on commit 84497fd

Please sign in to comment.