diff --git a/.env b/.env new file mode 100644 index 0000000..927915b --- /dev/null +++ b/.env @@ -0,0 +1 @@ +REACT_APP_API_BASE=/_api/ diff --git a/package-lock.json b/package-lock.json index ccb745f..45f90ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,8 @@ "@types/node": "^16.11.45", "@types/react": "^18.0.15", "@types/react-dom": "^18.0.6", + "axios": "^0.27.2", + "http-proxy-middleware": "^2.0.6", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.3.0", @@ -4651,6 +4653,28 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -19833,6 +19857,27 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz", "integrity": "sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==" }, + "axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", diff --git a/package.json b/package.json index 760244f..01914fc 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ "@types/node": "^16.11.45", "@types/react": "^18.0.15", "@types/react-dom": "^18.0.6", + "axios": "^0.27.2", + "http-proxy-middleware": "^2.0.6", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.3.0", diff --git a/src/App.tsx b/src/App.tsx index f5b0174..28ca22e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,8 @@ -import React from 'react'; import './App.css'; +import { World } from './pages/world'; +import { Api } from './api/api'; + +import { useState } from 'react'; import { BrowserRouter as Router, Routes, @@ -8,6 +11,8 @@ import { } from "react-router-dom"; function App() { + let [api] = useState(() => new Api()); + return (
@@ -19,6 +24,9 @@ function App() {
  • About
  • +
  • + World +
  • @@ -26,6 +34,7 @@ function App() { } /> } /> + } />
    ); diff --git a/src/api/api.ts b/src/api/api.ts new file mode 100644 index 0000000..8cbc688 --- /dev/null +++ b/src/api/api.ts @@ -0,0 +1,21 @@ +import { Containers } from './containers'; + +import axios, { AxiosInstance } from 'axios'; + +export interface InstanceProvider { + instance: AxiosInstance; + baseURL: string; +}; + +export class Api { + instance: AxiosInstance; + baseURL = '/'; + + constructor() { + this.instance = axios.create({ + baseURL: '_api/', + }); + } + + containers(): Containers { return new Containers(this); } +}; diff --git a/src/api/containers.ts b/src/api/containers.ts new file mode 100644 index 0000000..a7dfeba --- /dev/null +++ b/src/api/containers.ts @@ -0,0 +1,25 @@ +import { AxiosInstance } from 'axios'; +import { InstanceProvider } from './api'; + +export type Container = { + id: string, + parent?: string, + name: string, +}; + +export class Containers { + instance: AxiosInstance; + baseURL: string; + + constructor(parent: InstanceProvider) { + this.instance = parent.instance; + this.baseURL = parent.baseURL + 'containers/'; + } + + async index(): Promise<[Container]> { + let resp = await this.instance.get(this.baseURL); + console.log(resp); + + return resp.data.content; + } +} diff --git a/src/pages/world.tsx b/src/pages/world.tsx new file mode 100644 index 0000000..c03b784 --- /dev/null +++ b/src/pages/world.tsx @@ -0,0 +1,22 @@ +import { Api } from '../api/api'; +import { Container } from '../api/containers'; + +import { useState, useEffect } from 'react'; + +const World = ({ api }: { api: Api }) => { + let [content, setContent] = useState<[Container]>(); + useEffect(() => { + api.containers().index().then(setContent); + }, [api]); + + let list = content ? content.map((container) =>
    {container.name}
    ) :
    Loading content...
    ; + + return ( + <> +

    Welcome to the world view!

    + {list} + + ); +}; + +export { World }; diff --git a/src/setupProxy.js b/src/setupProxy.js new file mode 100644 index 0000000..2f9ad07 --- /dev/null +++ b/src/setupProxy.js @@ -0,0 +1,11 @@ +const { createProxyMiddleware } = require('http-proxy-middleware'); + +module.exports = function (app) { + app.use( + '/_api/', + createProxyMiddleware({ + target: process.env.REACT_APP_API_BASE, + changeOrigin: true, + }) + ); +};