Procházet zdrojové kódy

[feat] Add proof of concept Notion integration

Sergio Mattei před 2 roky
rodič
revize
ba67862d80

+ 15
- 0
package-lock.json Zobrazit soubor

@@ -33,6 +33,7 @@
33 33
         "react-router": "^5.2.0",
34 34
         "react-router-dom": "^5.2.0",
35 35
         "react-scripts": "^5.0.0",
36
+        "swr": "^1.3.0",
36 37
         "typescript": "^4.1.3",
37 38
         "web-vitals": "^0.2.4",
38 39
         "workbox-background-sync": "^5.1.4",
@@ -14676,6 +14677,14 @@
14676 14677
         "node": ">=4"
14677 14678
       }
14678 14679
     },
14680
+    "node_modules/swr": {
14681
+      "version": "1.3.0",
14682
+      "resolved": "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz",
14683
+      "integrity": "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==",
14684
+      "peerDependencies": {
14685
+        "react": "^16.11.0 || ^17.0.0 || ^18.0.0"
14686
+      }
14687
+    },
14679 14688
     "node_modules/symbol-tree": {
14680 14689
       "version": "3.2.4",
14681 14690
       "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -26863,6 +26872,12 @@
26863 26872
         }
26864 26873
       }
26865 26874
     },
26875
+    "swr": {
26876
+      "version": "1.3.0",
26877
+      "resolved": "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz",
26878
+      "integrity": "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==",
26879
+      "requires": {}
26880
+    },
26866 26881
     "symbol-tree": {
26867 26882
       "version": "3.2.4",
26868 26883
       "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",

+ 1
- 0
package.json Zobrazit soubor

@@ -28,6 +28,7 @@
28 28
     "react-router": "^5.2.0",
29 29
     "react-router-dom": "^5.2.0",
30 30
     "react-scripts": "^5.0.0",
31
+    "swr": "^1.3.0",
31 32
     "typescript": "^4.1.3",
32 33
     "web-vitals": "^0.2.4",
33 34
     "workbox-background-sync": "^5.1.4",

+ 4
- 1
src/components/ListComponent.tsx Zobrazit soubor

@@ -14,7 +14,10 @@ const ListComponent: React.FC<{ title?: string; laws: string[] }> = (props) => {
14 14
 
15 15
       {laws.map((lawName: string) => {
16 16
         return (
17
-          <IonItem routerLink={`/article/${encodeURIComponent(lawName)}`}>
17
+          <IonItem
18
+            key={lawName}
19
+            routerLink={`/article/${encodeURIComponent(lawName)}`}
20
+          >
18 21
             <p className="ListItemText">{lawName}</p>
19 22
           </IonItem>
20 23
         );

+ 1
- 0
src/config.ts Zobrazit soubor

@@ -0,0 +1 @@
1
+export const API_URL = process.env.API_URL ?? "http://localhost:3000";

+ 4
- 0
src/lib/api.ts Zobrazit soubor

@@ -0,0 +1,4 @@
1
+import { API_URL } from "../config";
2
+
3
+export const fetcher = (url: string) =>
4
+  fetch(`${API_URL}${url}`).then((r) => r.json());

+ 30
- 1
src/pages/LawListPage.tsx Zobrazit soubor

@@ -1,13 +1,30 @@
1 1
 import {
2 2
   IonContent,
3 3
   IonHeader,
4
+  IonLoading,
4 5
   IonPage,
5 6
   IonTitle,
7
+  IonToast,
6 8
   IonToolbar,
7 9
 } from "@ionic/react";
10
+import { alertCircleOutline } from "ionicons/icons";
11
+import { useEffect } from "react";
12
+import useSWR from "swr";
8 13
 import ListComponent from "../components/ListComponent";
14
+import { fetcher } from "../lib/api";
15
+
16
+interface Topic {
17
+  blockId: string;
18
+  name: string;
19
+}
9 20
 
10 21
 const LawListPage: React.FC = () => {
22
+  const { data, error } = useSWR<Topic[]>(
23
+    "/api/getTopicList?type=laws",
24
+    fetcher
25
+  );
26
+  const isLoading = !data && !error;
27
+
11 28
   return (
12 29
     <IonPage>
13 30
       <IonHeader>
@@ -21,7 +38,19 @@ const LawListPage: React.FC = () => {
21 38
             <IonTitle size="large">Leyes</IonTitle>
22 39
           </IonToolbar>
23 40
         </IonHeader>
24
-        <ListComponent laws={["Law 1", "Law 2"]} />
41
+        {data && <ListComponent laws={data.map((item) => item.name)} />}
42
+        <IonLoading
43
+          isOpen={isLoading}
44
+          duration={isLoading ? 50 : undefined}
45
+          message="Loading..."
46
+        />
47
+        <IonToast
48
+          icon={alertCircleOutline}
49
+          color="danger"
50
+          isOpen={error}
51
+          message="Failed to load items."
52
+          duration={1500}
53
+        />
25 54
       </IonContent>
26 55
     </IonPage>
27 56
   );