refactor: ponytail audit

This commit is contained in:
Amruth Pillai
2026-07-27 20:26:16 +02:00
parent bb1fb3a7d6
commit 9110e86997
157 changed files with 1082 additions and 2177 deletions
@@ -0,0 +1,19 @@
import type { ReactNode } from "react";
import { m } from "motion/react";
type ActionButtonProps = {
children: ReactNode;
};
export function ActionButton({ children }: ActionButtonProps) {
return (
<m.div
className="will-change-transform"
whileHover={{ y: -1, scale: 1.01 }}
whileTap={{ scale: 0.99 }}
transition={{ duration: 0.14, ease: "easeOut" }}
>
{children}
</m.div>
);
}
@@ -21,9 +21,7 @@ export function PasskeysSection() {
});
const registerPasskeyMutation = useMutation({
mutationFn: async () => {
return await authClient.passkey.addPasskey();
},
mutationFn: () => authClient.passkey.addPasskey(),
onSuccess: async ({ data, error }) => {
if (error) {
toast.error(
@@ -77,9 +75,7 @@ export function PasskeysSection() {
});
const deletePasskeyMutation = useMutation({
mutationFn: async (id: string) => {
return await authClient.passkey.deletePasskey({ id });
},
mutationFn: (id: string) => authClient.passkey.deletePasskey({ id }),
onSuccess: async ({ error }) => {
if (error) {
toast.error(
@@ -1,41 +1,18 @@
import { Trans } from "@lingui/react/macro";
import { PasswordIcon, PencilSimpleLineIcon } from "@phosphor-icons/react";
import { Link, useNavigate } from "@tanstack/react-router";
import { Link } from "@tanstack/react-router";
import { m } from "motion/react";
import { useCallback } from "react";
import { Button } from "@reactive-resume/ui/components/button";
import { useDialogStore } from "@/dialogs/store";
import { ActionButton } from "./action-button";
import { useAuthAccounts } from "./hooks";
// ponytail: m.div wrapper is identical for both branches — extracted, match(boolean) removed
function ActionButton({ children }: { children: React.ReactNode }) {
return (
<m.div
className="will-change-transform"
whileHover={{ y: -1, scale: 1.01 }}
whileTap={{ scale: 0.99 }}
transition={{ duration: 0.14, ease: "easeOut" }}
>
{children}
</m.div>
);
}
export function PasswordSection() {
const navigate = useNavigate();
const { openDialog } = useDialogStore();
const { hasAccount } = useAuthAccounts();
const hasPassword = hasAccount("credential");
const handleUpdatePassword = useCallback(() => {
if (hasPassword) {
openDialog("auth.change-password", undefined);
} else {
void navigate({ to: "/auth/forgot-password" });
}
}, [hasPassword, navigate, openDialog]);
return (
<m.div
initial={{ y: -20 }}
@@ -50,7 +27,7 @@ export function PasswordSection() {
<ActionButton>
{hasPassword ? (
<Button variant="outline" onClick={handleUpdatePassword}>
<Button variant="outline" onClick={() => openDialog("auth.change-password", undefined)}>
<PencilSimpleLineIcon />
<Trans>Update Password</Trans>
</Button>
@@ -2,25 +2,11 @@ import type { AuthProvider } from "@reactive-resume/auth/types";
import { Trans } from "@lingui/react/macro";
import { LinkBreakIcon, LinkIcon } from "@phosphor-icons/react";
import { m } from "motion/react";
import { useCallback } from "react";
import { Button } from "@reactive-resume/ui/components/button";
import { Separator } from "@reactive-resume/ui/components/separator";
import { ActionButton } from "./action-button";
import { getProviderIcon, getProviderName, useAuthAccounts, useAuthProviderActions } from "./hooks";
// ponytail: shared hover/tap wrapper — identical in both branches, match(boolean) removed
function ActionButton({ children }: { children: React.ReactNode }) {
return (
<m.div
className="will-change-transform"
whileHover={{ y: -1, scale: 1.01 }}
whileTap={{ scale: 0.99 }}
transition={{ duration: 0.14, ease: "easeOut" }}
>
{children}
</m.div>
);
}
type SocialProviderSectionProps = {
provider: AuthProvider;
name?: string;
@@ -37,15 +23,6 @@ export function SocialProviderSection({ provider, name, animationDelay = 0 }: So
const account = getAccountByProviderId(provider);
const isConnected = hasAccount(provider);
const handleLink = useCallback(async () => {
await link(provider);
}, [link, provider]);
const handleUnlink = useCallback(async () => {
if (!account?.accountId) return;
await unlink(provider, account.accountId);
}, [account, unlink, provider]);
return (
<m.div
className="will-change-[transform,opacity]"
@@ -63,14 +40,19 @@ export function SocialProviderSection({ provider, name, animationDelay = 0 }: So
<ActionButton>
{isConnected ? (
<Button variant="outline" onClick={handleUnlink}>
<Button
variant="outline"
onClick={() => {
if (account?.accountId) void unlink(provider, account.accountId);
}}
>
<LinkBreakIcon />
<Trans comment="Authentication settings action to unlink a connected social login provider">
Disconnect
</Trans>
</Button>
) : (
<Button variant="outline" onClick={handleLink}>
<Button variant="outline" onClick={() => void link(provider)}>
<LinkIcon />
<Trans comment="Authentication settings action to link a social login provider">Connect</Trans>
</Button>
@@ -1,27 +1,13 @@
import { Trans } from "@lingui/react/macro";
import { KeyIcon, LockOpenIcon, ToggleLeftIcon, ToggleRightIcon } from "@phosphor-icons/react";
import { m } from "motion/react";
import { useCallback } from "react";
import { Button } from "@reactive-resume/ui/components/button";
import { Separator } from "@reactive-resume/ui/components/separator";
import { useDialogStore } from "@/dialogs/store";
import { authClient } from "@/libs/auth/client";
import { ActionButton } from "./action-button";
import { useAuthAccounts } from "./hooks";
// ponytail: shared hover/tap wrapper — identical in both branches, match(boolean) removed
function ActionButton({ children }: { children: React.ReactNode }) {
return (
<m.div
className="will-change-transform"
whileHover={{ y: -1, scale: 1.01 }}
whileTap={{ scale: 0.99 }}
transition={{ duration: 0.14, ease: "easeOut" }}
>
{children}
</m.div>
);
}
export function TwoFactorSection() {
const { openDialog } = useDialogStore();
const { hasAccount } = useAuthAccounts();
@@ -30,14 +16,6 @@ export function TwoFactorSection() {
const hasPassword = hasAccount("credential");
const hasTwoFactor = session?.user.twoFactorEnabled ?? false;
const handleTwoFactorAction = useCallback(() => {
if (hasTwoFactor) {
openDialog("auth.two-factor.disable", undefined);
} else {
openDialog("auth.two-factor.enable", undefined);
}
}, [hasTwoFactor, openDialog]);
if (!hasPassword) return null;
return (
@@ -56,7 +34,10 @@ export function TwoFactorSection() {
</h2>
<ActionButton>
<Button variant="outline" onClick={handleTwoFactorAction}>
<Button
variant="outline"
onClick={() => openDialog(hasTwoFactor ? "auth.two-factor.disable" : "auth.two-factor.enable", undefined)}
>
{hasTwoFactor ? (
<>
<ToggleLeftIcon />
@@ -6,12 +6,13 @@ import { orpc } from "@/libs/orpc/client";
* Replaces the predicate that was duplicated across the import dialog, agent setup, and AI settings.
*/
export function useHasUsableAiProvider() {
const { data: providers, isLoading } = useQuery(orpc.aiProviders.list.queryOptions());
const { data: providers, isLoading, error } = useQuery(orpc.aiProviders.list.queryOptions());
const usableProviders = (providers ?? []).filter((provider) => provider.enabled && provider.testStatus === "success");
return {
error,
hasUsableProvider: usableProviders.length > 0,
usableProviders,
isLoading,
usableProviders,
};
}