From 8289b4d643dff84332be3186020f99e09c761090 Mon Sep 17 00:00:00 2001 From: Chaim Date: Mon, 4 May 2026 06:44:27 +0000 Subject: [PATCH] refactor(settings): split into tabs (paperclip + 3 stubs) Extracts Paperclip companies + tag-mappings UI into PaperclipTab component, adds stub tabs for Environment / Tools / Registrations, and replaces the flat page.tsx with a shadcn Tabs layout to make room for Tasks 8-10. Co-Authored-By: Claude Sonnet 4.6 --- .../settings/_components/environment-tab.tsx | 1 + .../settings/_components/paperclip-tab.tsx | 225 ++++++++++++++++ .../_components/registrations-tab.tsx | 1 + .../app/settings/_components/tools-tab.tsx | 1 + web-ui/src/app/settings/page.tsx | 254 +++--------------- 5 files changed, 259 insertions(+), 223 deletions(-) create mode 100644 web-ui/src/app/settings/_components/environment-tab.tsx create mode 100644 web-ui/src/app/settings/_components/paperclip-tab.tsx create mode 100644 web-ui/src/app/settings/_components/registrations-tab.tsx create mode 100644 web-ui/src/app/settings/_components/tools-tab.tsx diff --git a/web-ui/src/app/settings/_components/environment-tab.tsx b/web-ui/src/app/settings/_components/environment-tab.tsx new file mode 100644 index 0000000..d56b649 --- /dev/null +++ b/web-ui/src/app/settings/_components/environment-tab.tsx @@ -0,0 +1 @@ +export function EnvironmentTab() { return
Environment tab — coming soon
; } diff --git a/web-ui/src/app/settings/_components/paperclip-tab.tsx b/web-ui/src/app/settings/_components/paperclip-tab.tsx new file mode 100644 index 0000000..a6cae00 --- /dev/null +++ b/web-ui/src/app/settings/_components/paperclip-tab.tsx @@ -0,0 +1,225 @@ +"use client"; + +import { useState } from "react"; +import { Plus, Trash2, Tags, Building2 } from "lucide-react"; +import { Card, CardContent } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Skeleton } from "@/components/ui/skeleton"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { + useTagMappings, + usePaperclipCompanies, + useAddTagMapping, + useDeleteTagMapping, +} from "@/lib/api/settings"; +import { APPEAL_SUBTYPES } from "@/lib/practice-area"; +import { toast } from "sonner"; + +const TAG_SUGGESTIONS = APPEAL_SUBTYPES.filter((s) => s.value !== "unknown"); + +export function PaperclipTab() { + const { data: mappings, isPending: loadingMappings } = useTagMappings(); + const { data: companies, isPending: loadingCompanies } = usePaperclipCompanies(); + const addMapping = useAddTagMapping(); + const deleteMapping = useDeleteTagMapping(); + + const [tag, setTag] = useState(""); + const [tagLabel, setTagLabel] = useState(""); + const [companyId, setCompanyId] = useState(""); + + function handleTagInput(value: string) { + setTag(value); + const match = TAG_SUGGESTIONS.find((s) => s.value === value); + if (match) setTagLabel(match.label); + } + + function handleAdd() { + if (!tag || !companyId) { + toast.error("יש לבחור תגית וחברה"); + return; + } + const company = companies?.find((c) => c.id === companyId); + addMapping.mutate( + { + tag, + tag_label: tagLabel, + company_id: companyId, + company_name: company?.name ?? "", + }, + { + onSuccess: () => { + toast.success("מיפוי נוסף בהצלחה"); + setTag(""); + setTagLabel(""); + setCompanyId(""); + }, + onError: (err) => toast.error(`שגיאה: ${err.message}`), + }, + ); + } + + function handleDelete(id: string, tag: string) { + deleteMapping.mutate(id, { + onSuccess: () => toast.success(`מיפוי "${tag}" נמחק`), + onError: (err) => toast.error(`שגיאה: ${err.message}`), + }); + } + + return ( +
+ + +

+ + חברות ב-Paperclip +

+ {loadingCompanies ? ( + + ) : !companies?.length ? ( +

לא נמצאו חברות

+ ) : ( +
+ {companies.map((c) => ( +
+ {c.name} + + {c.prefix} + +
+ ))} +
+ )} +
+
+ + + +

+ + מיפוי תגיות + + {mappings?.length ?? 0} + +

+ +
+
+ + handleTagInput(e.target.value)} + placeholder="סוג ערר או תגית חופשית" + className="w-[220px]" + /> + + {TAG_SUGGESTIONS.map((s) => ( + + ))} + +
+ +
+ + setTagLabel(e.target.value)} + placeholder="שם לתצוגה" + className="w-[160px]" + /> +
+ +
+ + +
+ + +
+ + {loadingMappings ? ( + + ) : !mappings?.length ? ( +

+ אין מיפויים. הוסף מיפוי כדי שתיקים חדשים ישויכו אוטומטית + לפרויקט בחברה הנכונה. +

+ ) : ( +
+ + + + + + + + + + {mappings.map((m) => ( + + + + + + + ))} + +
TagLabelCompany +
+ + {m.tag} + + {m.tag_label}{m.company_name} + +
+
+ )} +
+
+
+ ); +} diff --git a/web-ui/src/app/settings/_components/registrations-tab.tsx b/web-ui/src/app/settings/_components/registrations-tab.tsx new file mode 100644 index 0000000..94474d5 --- /dev/null +++ b/web-ui/src/app/settings/_components/registrations-tab.tsx @@ -0,0 +1 @@ +export function RegistrationsTab() { return
Registrations tab — coming soon
; } diff --git a/web-ui/src/app/settings/_components/tools-tab.tsx b/web-ui/src/app/settings/_components/tools-tab.tsx new file mode 100644 index 0000000..7a69e44 --- /dev/null +++ b/web-ui/src/app/settings/_components/tools-tab.tsx @@ -0,0 +1 @@ +export function ToolsTab() { return
Tools tab — coming soon
; } diff --git a/web-ui/src/app/settings/page.tsx b/web-ui/src/app/settings/page.tsx index 31847de..424d575 100644 --- a/web-ui/src/app/settings/page.tsx +++ b/web-ui/src/app/settings/page.tsx @@ -1,80 +1,15 @@ "use client"; -import { useState } from "react"; import Link from "next/link"; -import { Plus, Trash2, Tags, Building2 } from "lucide-react"; +import { Server, Wrench, Plug, Building2 } from "lucide-react"; import { AppShell } from "@/components/app-shell"; -import { Card, CardContent } from "@/components/ui/card"; -import { Badge } from "@/components/ui/badge"; -import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; -import { Skeleton } from "@/components/ui/skeleton"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; -import { - useTagMappings, - usePaperclipCompanies, - useAddTagMapping, - useDeleteTagMapping, -} from "@/lib/api/settings"; -import { APPEAL_SUBTYPES } from "@/lib/practice-area"; -import { toast } from "sonner"; - -const TAG_SUGGESTIONS = APPEAL_SUBTYPES.filter((s) => s.value !== "unknown"); +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { PaperclipTab } from "./_components/paperclip-tab"; +import { EnvironmentTab } from "./_components/environment-tab"; +import { ToolsTab } from "./_components/tools-tab"; +import { RegistrationsTab } from "./_components/registrations-tab"; export default function SettingsPage() { - const { data: mappings, isPending: loadingMappings } = useTagMappings(); - const { data: companies, isPending: loadingCompanies } = usePaperclipCompanies(); - const addMapping = useAddTagMapping(); - const deleteMapping = useDeleteTagMapping(); - - const [tag, setTag] = useState(""); - const [tagLabel, setTagLabel] = useState(""); - const [companyId, setCompanyId] = useState(""); - - function handleTagInput(value: string) { - setTag(value); - const match = TAG_SUGGESTIONS.find((s) => s.value === value); - if (match) setTagLabel(match.label); - } - - function handleAdd() { - if (!tag || !companyId) { - toast.error("יש לבחור תגית וחברה"); - return; - } - const company = companies?.find((c) => c.id === companyId); - addMapping.mutate( - { - tag, - tag_label: tagLabel, - company_id: companyId, - company_name: company?.name ?? "", - }, - { - onSuccess: () => { - toast.success("מיפוי נוסף בהצלחה"); - setTag(""); - setTagLabel(""); - setCompanyId(""); - }, - onError: (err) => toast.error(`שגיאה: ${err.message}`), - }, - ); - } - - function handleDelete(id: string, tag: string) { - deleteMapping.mutate(id, { - onSuccess: () => toast.success(`מיפוי "${tag}" נמחק`), - onError: (err) => toast.error(`שגיאה: ${err.message}`), - }); - } - return (
@@ -88,164 +23,37 @@ export default function SettingsPage() {

הגדרות

- ניהול מיפוי תגיות ערר לחברות ב-Paperclip. כל תיק חדש ישויך - אוטומטית לפרויקט בחברה הנכונה לפי סוג הערר. + תצורת המערכת, MCP server, ו-Paperclip integration.

- {/* Companies overview */} - - -

- - חברות ב-Paperclip -

- {loadingCompanies ? ( - - ) : !companies?.length ? ( -

לא נמצאו חברות

- ) : ( -
- {companies.map((c) => ( -
- {c.name} - - {c.prefix} - -
- ))} -
- )} -
-
+ + + + + Paperclip + + + + Environment + + + + Tools + + + + Registrations + + - {/* Tag mappings */} - - -

- - מיפוי תגיות - - {mappings?.length ?? 0} - -

- - {/* Add form */} -
-
- - handleTagInput(e.target.value)} - placeholder="סוג ערר או תגית חופשית" - className="w-[220px]" - /> - - {TAG_SUGGESTIONS.map((s) => ( - - ))} - -
- -
- - setTagLabel(e.target.value)} - placeholder="שם לתצוגה" - className="w-[160px]" - /> -
- -
- - -
- - -
- - {/* Table */} - {loadingMappings ? ( - - ) : !mappings?.length ? ( -

- אין מיפויים. הוסף מיפוי כדי שתיקים חדשים ישויכו אוטומטית - לפרויקט בחברה הנכונה. -

- ) : ( -
- - - - - - - - - - {mappings.map((m) => ( - - - - - - - ))} - -
TagLabelCompany -
- - {m.tag} - - {m.tag_label}{m.company_name} - -
-
- )} -
-
+ + + + +
);