Get users to combobox via useSWR

This commit is contained in:
Kalle 2022-08-07 12:07:32 +03:00
parent eb3b5a1cfe
commit 53fa0147c7
5 changed files with 54 additions and 13 deletions

View File

@ -23,7 +23,7 @@ Calendar
## Other
- [ ] User selector allow passing users from top level
- [x] User selector allow passing users from top level
- [ ] Constants use CALENDAR_EVENT object
- [ ] New unfriendly crash if omits dates
- [x] badges inside tag?

View File

@ -3,9 +3,8 @@ import * as React from "react";
import Fuse from "fuse.js";
import clsx from "clsx";
import type { Unpacked } from "~/utils/types";
import { useFetcher } from "@remix-run/react";
import type { UsersLoaderData } from "~/routes/users";
import type { UserWithPlusTier } from "~/db/types";
import { useUsers } from "~/hooks/swr";
const MAX_RESULTS_SHOWN = 6;
@ -115,18 +114,14 @@ export function UserCombobox({
ComboboxProps<Pick<UserWithPlusTier, "discordId" | "plusTier">>,
"inputName" | "onChange" | "className" | "id"
> & { userIdsToOmit?: Set<number>; initialUserId?: number }) {
const fetcher = useFetcher<UsersLoaderData>();
React.useEffect(() => {
if (fetcher.type === "init") fetcher.load("/users");
}, [fetcher]);
const { users, isLoading, isError } = useUsers();
const options = React.useMemo(() => {
if (fetcher.type !== "done") return [];
if (!users) return [];
const data = userIdsToOmit
? fetcher.data.users.filter((user) => !userIdsToOmit.has(user.id))
: fetcher.data.users;
? users.filter((user) => !userIdsToOmit.has(user.id))
: users;
return data.map((u) => ({
label: u.discordFullName,
@ -134,19 +129,27 @@ export function UserCombobox({
discordId: u.discordId,
plusTier: u.plusTier,
}));
}, [fetcher, userIdsToOmit]);
}, [users, userIdsToOmit]);
const initialValue = React.useMemo(() => {
if (!initialUserId) return;
return options.find((o) => o.value === String(initialUserId));
}, [options, initialUserId]);
if (isError) {
return (
<div className="text-sm text-error">
Something went wrong. Try reloading the page.
</div>
);
}
return (
<Combobox
inputName={inputName}
options={options}
placeholder="Sendou#0043"
isLoading={fetcher.type !== "done"}
isLoading={isLoading}
initialValue={initialValue}
onChange={onChange}
className={className}

22
app/hooks/swr.ts Normal file
View File

@ -0,0 +1,22 @@
import useSWRImmutable from "swr/immutable";
import type { UsersLoaderData } from "~/routes/users";
const ALL_USERS_ROUTE = "/users?_data=routes%2Fusers";
const fetcher = async (url: string) => {
const res = await fetch(url);
return res.json();
};
export function useUsers() {
const { data, error } = useSWRImmutable<UsersLoaderData>(
ALL_USERS_ROUTE,
fetcher
);
return {
users: data?.users,
isLoading: !error && !data,
isError: error,
};
}

15
package-lock.json generated
View File

@ -32,6 +32,7 @@
"remix-auth": "^3.2.2",
"remix-auth-oauth2": "^1.3.0",
"remix-i18next": "^4.1.1",
"swr": "^1.3.0",
"tiny-invariant": "^1.2.0",
"zod": "^3.17.10"
},
@ -14159,6 +14160,14 @@
"integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
"dev": true
},
"node_modules/swr": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz",
"integrity": "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==",
"peerDependencies": {
"react": "^16.11.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/table": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz",
@ -25826,6 +25835,12 @@
"integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
"dev": true
},
"swr": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz",
"integrity": "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==",
"requires": {}
},
"table": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz",

View File

@ -51,6 +51,7 @@
"remix-auth": "^3.2.2",
"remix-auth-oauth2": "^1.3.0",
"remix-i18next": "^4.1.1",
"swr": "^1.3.0",
"tiny-invariant": "^1.2.0",
"zod": "^3.17.10"
},