resolve bot comments and lint errors

This commit is contained in:
Vedanta-Gawande
2026-06-30 11:25:37 -07:00
parent 485da76210
commit b62c26bc03
8 changed files with 35 additions and 17 deletions
@@ -15,7 +15,7 @@ import { captureError } from "@hexclave/shared/dist/utils/errors";
import { runAsynchronouslyWithAlert } from "@hexclave/shared/dist/utils/promises";
import { ArrowsClockwiseIcon } from "@phosphor-icons/react";
import { ErrorBoundary } from "next/dist/client/components/error-boundary";
import { Suspense, useCallback, useRef, useState } from "react";
import { Suspense, useCallback, useEffect, useRef, useState } from "react";
import { AppEnabledGuard } from "../app-enabled-guard";
import { PageLayout } from "../page-layout";
import { useAdminApp } from "../use-admin-app";
@@ -87,6 +87,18 @@ export default function PageClient() {
setUsersMetricsSnapshot({ metrics, userCounts });
}, [hexclaveAdminApp]);
useEffect(() => {
const refresh = () => runAsynchronouslyWithAlert(refreshUsersMetrics);
const refreshAfterPageRestore = (event: PageTransitionEvent) => {
if (event.persisted) {
refresh();
}
};
refresh();
window.addEventListener("pageshow", refreshAfterPageRestore);
return () => window.removeEventListener("pageshow", refreshAfterPageRestore);
}, [refreshUsersMetrics]);
const handleTableReloadChange = useCallback((reload: () => void) => {
tableReloadRef.current = reload;
}, []);
@@ -96,9 +108,9 @@ export default function PageClient() {
runAsynchronouslyWithAlert(refreshUsersMetrics);
}, [refreshUsersMetrics]);
const handleRefresh = useCallback(async () => {
const handleRefresh = useCallback(() => {
tableReloadRef.current();
await refreshUsersMetrics();
runAsynchronouslyWithAlert(refreshUsersMetrics);
}, [refreshUsersMetrics]);
const hasUsers = usersMetricsSnapshot != null
@@ -133,7 +133,7 @@ function parseEmailDomains(input: string) {
// ─── Column definitions ──────────────────────────────────────────────
function createUserTableColumns(
onUserMutated?: () => void | Promise<void>,
onUserMutated: () => void | Promise<void>,
): DataGridColumnDef<ExtendedServerUser>[] {
return [
{
@@ -223,7 +223,7 @@ const USER_EXPORT_FIELDS: DataGridExportField<ExtendedServerUser>[] = [
// ─── UserTable ───────────────────────────────────────────────────────
export function UserTable(props: {
onUserMutated?: () => void | Promise<void>,
onUserMutated: () => void | Promise<void>,
onReloadChange?: (reload: () => void) => void,
}) {
const [filters, setFilters] = useState<FilterState>(DEFAULT_FILTERS);
@@ -236,7 +236,7 @@ export function UserTable(props: {
function UserTableBody(props: {
filters: FilterState,
setFilters: React.Dispatch<React.SetStateAction<FilterState>>,
onUserMutated?: () => void | Promise<void>,
onUserMutated: () => void | Promise<void>,
onReloadChange?: (reload: () => void) => void,
}) {
const { filters, setFilters, onUserMutated, onReloadChange } = props;
@@ -612,7 +612,7 @@ function EmailDomainFilter(props: {
function UserActions(props: {
user: ExtendedServerUser,
onUserMutated?: () => void | Promise<void>,
onUserMutated: () => void | Promise<void>,
}) {
const { user, onUserMutated } = props;
const hexclaveAdminApp = useAdminApp();
@@ -2,6 +2,7 @@ import { useAdminApp } from "@/app/(main)/(protected)/projects/[projectId]/use-a
import { ServerUser } from "@hexclave/next";
import { KnownErrors } from "@hexclave/shared";
import { countryCodeSchema, emailSchema, jsonStringOrEmptySchema, passwordSchema } from "@hexclave/shared/dist/schema-fields";
import { runAsynchronouslyWithAlert } from "@hexclave/shared/dist/utils/promises";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Button, Typography } from "@/components/ui";
import { DesignButton, DesignDialog, DesignDialogClose } from "@/components/design-components";
import { WarningCircleIcon } from "@phosphor-icons/react";
@@ -130,7 +131,6 @@ export function UserDialog(props: {
} else {
await adminApp.createUser(userValues);
}
await props.onUserMutated?.();
} catch (error) {
if (KnownErrors.UserWithEmailAlreadyExists.isInstance(error)) {
setErrorDialog({
@@ -148,6 +148,9 @@ export function UserDialog(props: {
}
throw error;
}
if (props.onUserMutated) {
runAsynchronouslyWithAlert(Promise.resolve().then(() => props.onUserMutated?.()));
}
}
return <>
@@ -1,5 +1,6 @@
import { ServerUser } from '@hexclave/next';
import { ActionDialog, CopyField, Typography } from "@/components/ui";
import { runAsynchronouslyWithAlert } from "@hexclave/shared/dist/utils/promises";
import { deindent } from "@hexclave/shared/dist/utils/strings";
import { Link } from './link';
import { useRouter } from './router';
@@ -14,7 +15,7 @@ export function DeleteUserDialog(props: {
onDeleted?: () => void | Promise<void>,
}) {
const router = useRouter();
const userLabel = props.user.displayName ?? props.user.primaryEmail ?? props.user.id;
const userLabel = props.user.displayName?.trim() || props.user.primaryEmail?.trim() || props.user.id;
return <ActionDialog
open={props.open}
onOpenChange={props.onOpenChange}
@@ -24,7 +25,9 @@ export function DeleteUserDialog(props: {
okButton={{
label: "Delete User", onClick: async () => {
await props.user.delete();
await props.onDeleted?.();
if (props.onDeleted) {
runAsynchronouslyWithAlert(Promise.resolve().then(() => props.onDeleted?.()));
}
if (props.redirectTo) {
router.push(props.redirectTo);
}
@@ -36,10 +39,9 @@ export function DeleteUserDialog(props: {
Are you sure you want to delete the user &quot;<Link
href={props.profileHref}
className="inline underline underline-offset-2"
onClick={(event) => {
event.preventDefault();
prefetch={false}
onClick={() => {
props.onOpenChange(false);
router.push(props.profileHref);
}}
>
{userLabel}
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -24,6 +24,7 @@ Below are some reminders on Hexclave and how to learn more about it. If you're s
- There is a `useHexclaveApp()` hook as a named export from the package itself that serves as a shortcut to get the current Hexclave App object from the React context. Similarly, the `useUser(...args)` named export is short for `useHexclaveApp().useUser(...args)`.
- Other
- Hexclave also has a REST API with near-full feature parity with the SDK. It can be used for both client and server-side code.
- If available, always prefer editing the `hexclave.config.ts` file directly over asking the user to make changes on the dashboard. When implementing new features, you can always update the config file, and then tell the user about the changes you've made.
- If available, always prefer editing the `hexclave.config.ts` file directly over asking the user to make changes on the dashboard. When implementing new features, you can always update the config file, and then tell the user about the changes you've made. The config file is automatically synced when using the local dashboard/dev environment with `npx @hexclave/cli dev --config-file <path-to-config-file>`.
- Hexclave's config files allow dot notation for nested properties. For example, the config `{ auth: { allowSignUp: true }, "auth.password": { allowSignIn: true } }` is the same as `{ auth: { allowSignUp: true, password: { allowSignIn: true } } }`.
- You can use the `npx @hexclave/cli exec <javascript>` command to run JavaScript with a pre-configured HexclaveServerApp available as `hexclaveServerApp`. This allows you to read and write from and to the Hexclave project as you would on the dashboard, but from the CLI. To read and write project configuration, see the note on the config file above.
- Hexclave was formerly known as Stack Auth. You may still see references to it as Stack Auth in some places.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long