mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-08-24 07:12:18 +10:00
refactor: ponytail audit
This commit is contained in:
@@ -4,7 +4,7 @@ import { Trans } from "@lingui/react/macro";
|
||||
import { ArrowRightIcon, ChatCircleDotsIcon, FilePlusIcon, GearSixIcon } from "@phosphor-icons/react";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import { Link, useNavigate } from "@tanstack/react-router";
|
||||
import { useMemo, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { useIsClient } from "usehooks-ts";
|
||||
import { Badge } from "@reactive-resume/ui/components/badge";
|
||||
@@ -12,6 +12,7 @@ import { Button } from "@reactive-resume/ui/components/button";
|
||||
import { Label } from "@reactive-resume/ui/components/label";
|
||||
import { Spinner } from "@reactive-resume/ui/components/spinner";
|
||||
import { Combobox } from "@/components/ui/combobox";
|
||||
import { useHasUsableAiProvider } from "@/features/settings/integrations/hooks/use-has-usable-ai-provider";
|
||||
import { getOrpcErrorMessage } from "@/libs/error-message";
|
||||
import { orpc } from "@/libs/orpc/client";
|
||||
|
||||
@@ -34,20 +35,12 @@ function isAgentConfigError(error: unknown) {
|
||||
export function NewThreadSetup({ resumeId }: NewThreadSetupProps) {
|
||||
const isClient = useIsClient();
|
||||
const navigate = useNavigate();
|
||||
const {
|
||||
data: providers,
|
||||
isLoading: isLoadingProviders,
|
||||
error: providersError,
|
||||
} = useQuery(orpc.aiProviders.list.queryOptions());
|
||||
const { usableProviders, isLoading: isLoadingProviders, error: providersError } = useHasUsableAiProvider();
|
||||
const { data: resumes, isLoading: isLoadingResumes } = useQuery(
|
||||
orpc.resume.list.queryOptions({ input: { sort: "lastUpdatedAt", tags: [] } }),
|
||||
);
|
||||
const { mutate: createThread, isPending } = useMutation(orpc.agent.threads.create.mutationOptions());
|
||||
|
||||
const usableProviders = useMemo(
|
||||
() => providers?.filter((provider) => provider.enabled && provider.testStatus === "success") ?? [],
|
||||
[providers],
|
||||
);
|
||||
const [aiProviderIdOverride, setAiProviderIdOverride] = useState<string | null | undefined>(undefined);
|
||||
const [sourceResumeIdOverride, setSourceResumeIdOverride] = useState<string | null | undefined>(undefined);
|
||||
const aiProviderId = aiProviderIdOverride ?? usableProviders[0]?.id ?? null;
|
||||
|
||||
@@ -25,6 +25,7 @@ import { ScrollArea } from "@reactive-resume/ui/components/scroll-area";
|
||||
import { cn } from "@reactive-resume/utils/style";
|
||||
import { useConfirm } from "@/hooks/use-confirm";
|
||||
import { getOrpcErrorMessage } from "@/libs/error-message";
|
||||
import { formatRelativeTime } from "@/libs/locale";
|
||||
import { orpc } from "@/libs/orpc/client";
|
||||
|
||||
type AgentThreadSummary = RouterOutput["agent"]["threads"]["list"][number];
|
||||
@@ -41,28 +42,6 @@ type AgentThreadSidebarProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const RELATIVE_TIME_DIVISIONS: Array<{ amount: number; unit: Intl.RelativeTimeFormatUnit }> = [
|
||||
{ amount: 31_536_000_000, unit: "year" },
|
||||
{ amount: 2_592_000_000, unit: "month" },
|
||||
{ amount: 604_800_000, unit: "week" },
|
||||
{ amount: 86_400_000, unit: "day" },
|
||||
{ amount: 3_600_000, unit: "hour" },
|
||||
{ amount: 60_000, unit: "minute" },
|
||||
];
|
||||
|
||||
function formatRelativeTime(value: Date | string, formatter: Intl.RelativeTimeFormat) {
|
||||
const date = value instanceof Date ? value : new Date(value);
|
||||
const diffMs = date.getTime() - Date.now();
|
||||
const absMs = Math.abs(diffMs);
|
||||
|
||||
if (absMs < 60_000) return formatter.format(0, "second");
|
||||
|
||||
const division = RELATIVE_TIME_DIVISIONS.find((candidate) => absMs >= candidate.amount);
|
||||
if (!division) return "";
|
||||
|
||||
return formatter.format(Math.round(diffMs / division.amount), division.unit);
|
||||
}
|
||||
|
||||
function ThreadActions({ thread, activeThreadId }: ThreadActionsProps) {
|
||||
const navigate = useNavigate();
|
||||
const confirm = useConfirm();
|
||||
@@ -164,7 +143,7 @@ function ThreadRow({ thread, activeThreadId }: ThreadRowProps) {
|
||||
>
|
||||
<div className="truncate font-medium">{title}</div>
|
||||
<div className="truncate text-muted-foreground text-xs">
|
||||
{formatRelativeTime(thread.lastMessageAt, relativeTimeFormatter)}
|
||||
{formatRelativeTime(thread.lastMessageAt, relativeTimeFormatter, "")}
|
||||
</div>
|
||||
</Link>
|
||||
<ThreadActions thread={thread} activeThreadId={activeThreadId} />
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createNoindexFollowMeta } from "@/libs/seo";
|
||||
|
||||
export const Route = createFileRoute("/agent")({
|
||||
component: RouteComponent,
|
||||
beforeLoad: async ({ context }) => {
|
||||
beforeLoad: ({ context }) => {
|
||||
if (!context.session) throw redirect({ to: "/auth/login", replace: true });
|
||||
return { session: context.session };
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user