diff --git a/fresh.gen.ts b/fresh.gen.ts
index 94764893ded7..d2a6659d3c9c 100644
--- a/fresh.gen.ts
+++ b/fresh.gen.ts
@@ -42,7 +42,8 @@ import * as $$0 from "./islands/Chart.tsx";
import * as $$1 from "./islands/CommentsList.tsx";
import * as $$2 from "./islands/NotificationsList.tsx";
import * as $$3 from "./islands/PageInput.tsx";
-import * as $$4 from "./islands/VoteButton.tsx";
+import * as $$4 from "./islands/UsersTable.tsx";
+import * as $$5 from "./islands/VoteButton.tsx";
const manifest = {
routes: {
@@ -88,7 +89,8 @@ const manifest = {
"./islands/CommentsList.tsx": $$1,
"./islands/NotificationsList.tsx": $$2,
"./islands/PageInput.tsx": $$3,
- "./islands/VoteButton.tsx": $$4,
+ "./islands/UsersTable.tsx": $$4,
+ "./islands/VoteButton.tsx": $$5,
},
baseUrl: import.meta.url,
};
diff --git a/islands/UsersTable.tsx b/islands/UsersTable.tsx
new file mode 100644
index 000000000000..b0ad0e33d9d7
--- /dev/null
+++ b/islands/UsersTable.tsx
@@ -0,0 +1,87 @@
+// Copyright 2023 the Deno authors. All rights reserved. MIT license.
+import { useSignal } from "@preact/signals";
+import { useEffect } from "preact/hooks";
+import type { User } from "@/utils/db.ts";
+import GitHubAvatarImg from "@/components/GitHubAvatarImg.tsx";
+import { LINK_STYLES } from "@/utils/constants.ts";
+
+const TH_STYLES = "p-4 text-left";
+const TD_STYLES = "p-4";
+
+async function fetchUsers(cursor: string) {
+ let url = "/api/users";
+ if (cursor !== "") url += "?cursor=" + cursor;
+ const resp = await fetch(url);
+ if (!resp.ok) throw new Error(`Request failed: GET ${url}`);
+ return await resp.json() as { users: User[]; cursor: string };
+}
+
+function UserTableRow(props: User) {
+ return (
+
+
+
+
+ {props.login}
+
+ |
+
+ {props.isSubscribed ? "Premium 🦕" : "Basic"}
+ |
+
+ ${(Math.random() * 100).toFixed(2)}
+ |
+
+ );
+}
+
+export default function UsersTable() {
+ const usersSig = useSignal([]);
+ const cursorSig = useSignal("");
+ const isLoadingSig = useSignal(false);
+
+ async function loadMoreUsers() {
+ isLoadingSig.value = true;
+ try {
+ const { users, cursor } = await fetchUsers(cursorSig.value);
+ usersSig.value = [...usersSig.value, ...users];
+ cursorSig.value = cursor;
+ } catch (error) {
+ console.log(error.message);
+ } finally {
+ isLoadingSig.value = false;
+ }
+ }
+
+ useEffect(() => {
+ loadMoreUsers();
+ }, []);
+
+ return (
+
+
+
+
+ User |
+ Subscription |
+ Revenue |
+
+
+
+ {usersSig.value.map((user) => )}
+
+
+ {cursorSig.value !== "" && !isLoadingSig.value && (
+
+ )}
+
+ );
+}
diff --git a/routes/dashboard/users.tsx b/routes/dashboard/users.tsx
index 5a41b785cffa..d8aa31e718dd 100644
--- a/routes/dashboard/users.tsx
+++ b/routes/dashboard/users.tsx
@@ -1,57 +1,15 @@
// Copyright 2023 the Deno authors. All rights reserved. MIT license.
-import { getUsers, User } from "@/utils/db.ts";
import type { RouteContext } from "$fresh/server.ts";
-import GitHubAvatarImg from "@/components/GitHubAvatarImg.tsx";
import Head from "@/components/Head.tsx";
import TabsBar from "@/components/TabsBar.tsx";
import { HEADING_WITH_MARGIN_STYLES } from "@/utils/constants.ts";
+import UsersTable from "@/islands/UsersTable.tsx";
-const TH_STYLES = "p-4 text-left";
-const TD_STYLES = "p-4";
-
-function UsersTable(props: { users: User[] }) {
- return (
-
-
-
-
- User |
- Subscription |
- Revenue |
-
-
-
- {props.users.map((user) => (
-
-
-
-
- {user.login}
-
- |
-
- {user.isSubscribed ? "Premium 🦕" : "Basic"}
- |
-
- ${(Math.random() * 100).toFixed(2)}
- |
-
- ))}
-
-
-
- );
-}
-
+// deno-lint-ignore require-await
export default async function DashboardUsersPage(
_req: Request,
ctx: RouteContext,
) {
- const users = await getUsers();
-
return (
<>
@@ -67,7 +25,7 @@ export default async function DashboardUsersPage(
}]}
currentPath={ctx.url.pathname}
/>
-
+
>
);