浏览代码

[web] Add an example fetch to staff (#1315)

- Add schema validation of the response
- Add an example fetch
Manav Rathi 1 年之前
父节点
当前提交
27410b2da9

+ 2 - 1
web/apps/staff/package.json

@@ -10,7 +10,8 @@
     },
     "dependencies": {
         "react": "^18",
-        "react-dom": "^18"
+        "react-dom": "^18",
+        "yup": "^1.4"
     },
     "devDependencies": {
         "@/build-config": "*",

+ 18 - 1
web/apps/staff/src/App.tsx

@@ -1,11 +1,28 @@
 import React from "react";
+import { getUserDetails } from "./services/support-service";
 import S from "./utils/strings";
 
 export const App: React.FC = () => {
+    const handleClick = () => {
+        const authToken = "xxx";
+        getUserDetails(authToken)
+            .then((userDetails) => {
+                console.log("Fetched user details", userDetails);
+            })
+            .catch((e) => {
+                console.error("Failed to fetch user details", e);
+            });
+    };
+
     return (
         <div>
             <h1>{S.hello}</h1>
-            <a href="https://help.ente.io">help.ente.io</a>
+            <p>
+                <a href="https://help.ente.io">help.ente.io</a>
+            </p>
+            <p>
+                <button onClick={handleClick}>Do something</button>
+            </p>
         </div>
     );
 };

+ 10 - 6
web/apps/staff/src/services/support-service.ts

@@ -1,7 +1,15 @@
+import { object, type InferType } from "yup";
+
 const apiOrigin = import.meta.env.VITE_ENTE_ENDPOINT ?? "https://api.ente.io";
 
+const userDetailsSchema = object({});
+
+export type UserDetails = InferType<typeof userDetailsSchema>;
+
 /** Fetch details of the user associated with the given {@link authToken}. */
-export const getUserDetails = async (authToken: string) => {
+export const getUserDetails = async (
+    authToken: string,
+): Promise<UserDetails> => {
     const url = `${apiOrigin}/users/details/v2`;
     const res = await fetch(url, {
         headers: {
@@ -9,9 +17,5 @@ export const getUserDetails = async (authToken: string) => {
         },
     });
     if (!res.ok) throw new Error(`Failed to fetch ${url}: HTTP ${res.status}`);
-    const json: unknown = await res.json();
-    if (json && typeof json === "object") {
-        return json;
-    }
-    throw new Error(`Unexpected response for ${url}: ${JSON.stringify(json)}`);
+    return await userDetailsSchema.validate(await res.json());
 };

+ 1 - 1
web/packages/utils/package.json

@@ -5,7 +5,7 @@
     "dependencies": {
         "is-electron": "^2.2",
         "libsodium-wrappers": "0.7.9",
-        "yup": "^1.3"
+        "yup": "^1.4"
     },
     "devDependencies": {
         "@/build-config": "*",

+ 4 - 4
web/yarn.lock

@@ -5097,10 +5097,10 @@ yocto-queue@^0.1.0:
   resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
   integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
 
-yup@^1.3:
-  version "1.3.3"
-  resolved "https://registry.yarnpkg.com/yup/-/yup-1.3.3.tgz#d2f6020ad1679754c5f8178a29243d5447dead04"
-  integrity sha512-v8QwZSsHH2K3/G9WSkp6mZKO+hugKT1EmnMqLNUcfu51HU9MDyhlETT/JgtzprnrnQHPWsjc6MUDMBp/l9fNnw==
+yup@^1.4:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/yup/-/yup-1.4.0.tgz#898dcd660f9fb97c41f181839d3d65c3ee15a43e"
+  integrity sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==
   dependencies:
     property-expr "^2.0.5"
     tiny-case "^1.0.3"