Skip to content

Commit

Permalink
feat: add climate page and reading page
Browse files Browse the repository at this point in the history
  • Loading branch information
oyvindis committed Mar 26, 2022
1 parent 92f3705 commit 0a0a7dd
Show file tree
Hide file tree
Showing 15 changed files with 176 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NEXT_PUBLIC_READING_BASE_URI=https://www.oyvindis.com
1 change: 1 addition & 0 deletions .env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NEXT_PUBLIC_READING_BASE_URI=https://www.oyvindis.com
11 changes: 11 additions & 0 deletions env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { validateEnv } from './utils/common';

const NAMESPACE = process.env.NAMESPACE! ?? 'dev';
const READING_BASE_URI = process.env.NEXT_PUBLIC_READING_BASE_URI! ?? 'https://www.oyvindis.com'

const env = {
NAMESPACE,
READING_BASE_URI
}

export default validateEnv(env);
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"axios": "^0.26.1",
"next": "12.1.0",
"react": "17.0.2",
"react-dom": "17.0.2"
Expand Down
38 changes: 38 additions & 0 deletions pages/climate/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { NextPage } from 'next';
import Link from 'next/link';
import { useEffect, useState } from 'react';

import env from '../../env';
import { Location } from '../../types';
import {getLocations} from '../../services/api/climate-reading/readings';

interface Props {}

const Climate: NextPage<Props> = () => {
const [locations, setLocations] = useState<Location[]>([]);
const { READING_BASE_URI } = env;

useEffect(() => {
getLocations().then(locations => setLocations(locations))
}, [])

return (
<div>
<div>Climate Page12</div>
<div>
{READING_BASE_URI}
</div>
<ul>
{locations?.length > 0 && locations.map(({id, name}) => (
<li key={id} >
<Link href={`/climate/location/${id}`}>
{name}
</Link>
</li>
))}
</ul>
</div>
)
}

export default Climate;
35 changes: 35 additions & 0 deletions pages/climate/location/[id]/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { NextPage } from 'next';
import { useRouter } from 'next/router'
import { useEffect, useState } from 'react';

import { Reading } from '../../../../types';
import { getReadings } from '../../../../services/api/climate-reading/readings';

interface Props {}

const Location: NextPage<Props> = () => {
const [readings, setReadings] = useState<Reading[]>([]);

const router = useRouter()
const { id } = router.query;

useEffect(() => {
getReadings(Array.isArray(id) ? id[0]: id).then(readings => setReadings(readings))
}, [])

return (
<div>
<ul>
{readings?.length > 0 && readings.map(({id, temperatureReading, humidityReading}) => (
<li key={id} >
<div>
{temperatureReading} - {humidityReading}
</div>
</li>
))}
</ul>
</div>
)
}

export default Location;
27 changes: 27 additions & 0 deletions services/api/climate-reading/host.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import axios from 'axios';
import env from '../../../env';

interface Props {
path: string;
method: any;
data?: any;
params?: URLSearchParams;
}

const { READING_BASE_URI } = env;

export const climateReading = ({ path, method, data, params }: Props) =>
axios({
url: `${READING_BASE_URI}${path}`,
method,
data,
params
})
.then(response => response.data)
.catch(() => null);

export const climateReadingPost = (path: string, body: any) =>
climateReading({ path, method: 'POST', data: body });

export const climateReadingGet = (path: string, params?: URLSearchParams) =>
climateReading({ path, method: 'GET', params });
7 changes: 7 additions & 0 deletions services/api/climate-reading/readings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { climateReadingGet } from './host';

export const getReadings = (location: string) =>
climateReadingGet(`/climate-api/reading/${location}`)

export const getLocations = () =>
climateReadingGet('/climate-api/location')
3 changes: 3 additions & 0 deletions types/common.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type Actions<T extends { [key: string]: (...args: any) => any }> = {
[K in keyof T]: ReturnType<T[K]>;
}[keyof T];
12 changes: 12 additions & 0 deletions types/domain.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export interface Location {
id: string;
name: string;
}

export interface Reading {
id: string;
createdDate: string;
temperatureReading: string;
humidityReading: string;
location: Location;
}
3 changes: 3 additions & 0 deletions types/enums.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum Namespace {
DEVELOPMENT = 'dev'
}
4 changes: 4 additions & 0 deletions types/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface EnvironmentVariables {
NAMESPACE: string;
READING_BASE_URI: string;
}
3 changes: 3 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './env';
export * from './common';
export * from './domain';
17 changes: 17 additions & 0 deletions utils/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { EnvironmentVariables } from '../../types';

function assertIsDefined<T>(
key: string,
value: T
): asserts value is NonNullable<T> {
if (value === undefined || value === null) {
throw new Error(`Expected ${key} to be defined, but received ${value}`);
}
}

export const validateEnv = (
env: EnvironmentVariables
): EnvironmentVariables => {
Object.entries(env).forEach(([key, value]) => assertIsDefined(key, value));
return env;
};

0 comments on commit 0a0a7dd

Please sign in to comment.