import { Link, createFileRoute } from "@tanstack/react-router"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { CaretRightIcon } from "@phosphor-icons/react"; import { useEffect, useMemo, useState } from "react"; import { IoLogoGithub } from "react-icons/io5"; import type { ReposPayload, TeamSettings } from "@/lib/api"; import { AppShell, SettingsRow, SettingsSection } from "@/components/AppShell"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { Switch } from "@/components/ui/switch"; import { Textarea } from "@/components/ui/textarea"; import { ApiError, api } from "@/lib/api"; import { RequireLogin } from "@/lib/auth-redirect"; import { useSession } from "@/lib/session"; export const Route = createFileRoute("/review")({ component: ReviewPage }); const DEFAULT_SETTINGS: TeamSettings = { review_draft_prs: false, pr_summaries: true, review_trace_links: true, review_tracing_project: null, org_guidelines: null, default_agent_model: null, default_agent_reasoning_effort: null, default_agent_subagent_model: null, default_agent_subagent_reasoning_effort: null, default_reviewer_model: null, default_reviewer_reasoning_effort: null, default_reviewer_subagent_model: null, default_reviewer_subagent_reasoning_effort: null, }; function ReviewPage() { const session = useSession(); const qc = useQueryClient(); const settings = useQuery({ queryKey: ["teamSettings"], queryFn: api.getTeamSettings, enabled: !!session.data, }); const [local, setLocal] = useState(DEFAULT_SETTINGS); const [guidelinesDraft, setGuidelinesDraft] = useState(""); const [error, setError] = useState(null); useEffect(() => { if (settings.data) { setLocal(settings.data); setGuidelinesDraft(settings.data.org_guidelines ?? ""); } }, [settings.data]); const save = useMutation({ mutationFn: (body: TeamSettings) => api.saveTeamSettings(body), onSuccess: (saved) => { qc.setQueryData(["teamSettings"], saved); setError(null); }, onError: (e: Error) => setError(e.message), }); if (session.isLoading) { return (
); } if (!session.data) return ; const current: TeamSettings = local; const canEdit = session.data.is_admin; const persist = (patch: Partial) => { const next: TeamSettings = { ...current, ...patch }; setLocal(next); if (canEdit) save.mutate(next); }; const trimmedGuidelines = guidelinesDraft.trim(); const savedGuidelines = current.org_guidelines ?? ""; const guidelinesDirty = trimmedGuidelines !== savedGuidelines.trim(); const saveGuidelines = () => { if (!canEdit) return; persist({ org_guidelines: trimmedGuidelines || null }); }; return (
Review Style Prompts Per-repo style guides learned from past PR review feedback.