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 ( +
+ + + + + + + + + + {usersSig.value.map((user) => )} + +
UserSubscriptionRevenue
+ {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 ( -
- - - - - - - - - - {props.users.map((user) => ( - - - - - - ))} - -
UserSubscriptionRevenue
- - - {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} /> - + );