All files / packages/app/features/peers peers.tsx

100% Statements 14/14
100% Branches 2/2
100% Functions 5/5
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120                                                19x       844x 844x     844x                                   19x   264x 264x 264x           264x 40x                                                 251x                       880x               36x           360x              
import type React from "react";
 
import { useSuspenseQuery } from "@tanstack/react-query";
import { Trans, useTranslation } from "react-i18next";
 
import { Peer, SkeletonPeer } from "~app/components/app/peer";
import { EmptyCard } from "~app/components/empty-card";
import {
	PaginationBlock,
	PaginationBlockSkeleton,
} from "~app/components/pagination-block";
import { SuspendedOverlay } from "~app/components/pagination-overlay";
import { suspendedFallback } from "~app/components/suspense-wrapper";
import { useCursorPaging } from "~app/hooks/use-cursor-paging";
import type {
	SearchParamState,
	SearchParamStateDefaulted,
} from "~app/utils/navigation";
import { useTRPC } from "~app/utils/trpc";
import { Icon } from "~components/icons";
import { ButtonLink, Link } from "~components/link";
import { Text } from "~components/text";
import type { PeerId } from "~db/ids";
 
const PeerPreview = suspendedFallback<{
	id: PeerId;
}>(
	({ id }) => {
		const trpc = useTRPC();
		const { data: peer } = useSuspenseQuery(
			trpc.peers.get.queryOptions({ id }),
		);
		return (
			<Link to="/peers/$id" params={{ id: peer.id }}>
				<Peer
					id={peer.id}
					name={peer.name}
					connectedUser={peer.connectedUser}
				/>
			</Link>
		);
	},
	<SkeletonPeer className="self-start" />,
);
 
type Props = {
	limitState: SearchParamStateDefaulted<"/_protected/peers/", "limit">;
	offsetState: SearchParamState<"/_protected/peers/", "offset">;
};
 
export const Peers: React.FC<Props> = suspendedFallback(
	({ limitState: [limit, setLimit], offsetState }) => {
		const { t } = useTranslation("peers");
		const trpc = useTRPC();
		const { data, onPageChange, isPending } = useCursorPaging(
			trpc.peers.getPaged,
			{ limit },
			offsetState,
		);
 
		if (!data.count) {
			return (
				<EmptyCard title={t("list.empty.title")}>
					<Trans
						t={t}
						i18nKey="list.empty.message"
						components={{
							text: <Text variant="h3" />,
							icon: (
								<ButtonLink
									color="primary"
									to="/peers/add"
									title={t("list.addPeer.button")}
									variant="bordered"
									className="mx-2"
									isIconOnly
								>
									<Icon name="add" className="size-6" />
								</ButtonLink>
							),
						}}
					/>
				</EmptyCard>
			);
		}
 
		return (
			<>
				<PaginationBlock
					totalCount={data.count}
					limit={limit}
					setLimit={setLimit}
					offset={offsetState[0]}
					onPageChange={onPageChange}
				/>
				<SuspendedOverlay isPending={isPending}>
					<>
						{data.items.map((id) => (
							<PeerPreview key={id} id={id} />
						))}
					</>
				</SuspendedOverlay>
			</>
		);
	},
	({ limitState }) => (
		<>
			<PaginationBlockSkeleton limit={limitState[0]} />
			<SuspendedOverlay isPending>
				<>
					{Array.from({ length: limitState[0] }).map((_, index) => (
						// oxlint-disable-next-line react/no-array-index-key
						<SkeletonPeer key={index} className="self-start" />
					))}
				</>
			</SuspendedOverlay>
		</>
	),
);