@cosmicstack/mercury-agent 1.1.6 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -1
- package/dist/index.js +14347 -5964
- package/dist/index.js.map +1 -1
- package/dist/web/static/vendor/geist/Geist-Italic[wght].woff2 +0 -0
- package/dist/web/static/vendor/geist/Geist-Variable.woff2 +0 -0
- package/dist/web/static/vendor/geist/GeistMono-Italic[wght].woff2 +0 -0
- package/dist/web/static/vendor/geist/GeistMono-Variable.woff2 +0 -0
- package/dist/web/static/vendor/graphology.min.js +2 -0
- package/dist/web/static/vendor/icons.svg +108 -0
- package/dist/web/static/vendor/sql-wasm.wasm +0 -0
- package/dist/web/ui/assets/Chat-DCFkzIwn.js +28 -0
- package/dist/web/ui/assets/Chat-DCFkzIwn.js.map +1 -0
- package/dist/web/ui/assets/Dashboard-B81ollv8.js +2 -0
- package/dist/web/ui/assets/Dashboard-B81ollv8.js.map +1 -0
- package/dist/web/ui/assets/Goals-D0cR8yIP.js +12 -0
- package/dist/web/ui/assets/Goals-D0cR8yIP.js.map +1 -0
- package/dist/web/ui/assets/Graph-C3eHp3_J.js +7 -0
- package/dist/web/ui/assets/Graph-C3eHp3_J.js.map +1 -0
- package/dist/web/ui/assets/Kanban-DrkTRyni.js +45 -0
- package/dist/web/ui/assets/Kanban-DrkTRyni.js.map +1 -0
- package/dist/web/ui/assets/Login-GRQ-LjgN.js +2 -0
- package/dist/web/ui/assets/Login-GRQ-LjgN.js.map +1 -0
- package/dist/web/ui/assets/MarkdownRenderer-Dvh1jwyj.js +22 -0
- package/dist/web/ui/assets/MarkdownRenderer-Dvh1jwyj.js.map +1 -0
- package/dist/web/ui/assets/Memory-dAZsKmWz.js +12 -0
- package/dist/web/ui/assets/Memory-dAZsKmWz.js.map +1 -0
- package/dist/web/ui/assets/Permissions-DCiyUUfI.js +17 -0
- package/dist/web/ui/assets/Permissions-DCiyUUfI.js.map +1 -0
- package/dist/web/ui/assets/PersonDetail-iZgApJog.js +2 -0
- package/dist/web/ui/assets/PersonDetail-iZgApJog.js.map +1 -0
- package/dist/web/ui/assets/Persons-Bs_HhYjC.js +2 -0
- package/dist/web/ui/assets/Persons-Bs_HhYjC.js.map +1 -0
- package/dist/web/ui/assets/Providers-CL6wMWni.js +7 -0
- package/dist/web/ui/assets/Providers-CL6wMWni.js.map +1 -0
- package/dist/web/ui/assets/Schedules-BQwE1hP5.js +17 -0
- package/dist/web/ui/assets/Schedules-BQwE1hP5.js.map +1 -0
- package/dist/web/ui/assets/Settings-26SF-okR.js +12 -0
- package/dist/web/ui/assets/Settings-26SF-okR.js.map +1 -0
- package/dist/web/ui/assets/Skills-DANyYK_d.js +7 -0
- package/dist/web/ui/assets/Skills-DANyYK_d.js.map +1 -0
- package/dist/web/ui/assets/Tasks-DbwRozzx.js +7 -0
- package/dist/web/ui/assets/Tasks-DbwRozzx.js.map +1 -0
- package/dist/web/ui/assets/Usage-i_q6Ri4s.js +12 -0
- package/dist/web/ui/assets/Usage-i_q6Ri4s.js.map +1 -0
- package/dist/web/ui/assets/Workspace-ZR5syf-9.js +52 -0
- package/dist/web/ui/assets/Workspace-ZR5syf-9.js.map +1 -0
- package/dist/web/ui/assets/activity-CIP1IzSg.js +7 -0
- package/dist/web/ui/assets/activity-CIP1IzSg.js.map +1 -0
- package/dist/web/ui/assets/alert-dialog-CW-j2nG4.js +7 -0
- package/dist/web/ui/assets/alert-dialog-CW-j2nG4.js.map +1 -0
- package/dist/web/ui/assets/arrow-left-D2YO-iMS.js +7 -0
- package/dist/web/ui/assets/arrow-left-D2YO-iMS.js.map +1 -0
- package/dist/web/ui/assets/avatar-BLsf3GhK.js +7 -0
- package/dist/web/ui/assets/avatar-BLsf3GhK.js.map +1 -0
- package/dist/web/ui/assets/badge-DfDJNUtd.js +2 -0
- package/dist/web/ui/assets/badge-DfDJNUtd.js.map +1 -0
- package/dist/web/ui/assets/button-TaFPR-zy.js +2 -0
- package/dist/web/ui/assets/button-TaFPR-zy.js.map +1 -0
- package/dist/web/ui/assets/card-DAYo4Zl5.js +2 -0
- package/dist/web/ui/assets/card-DAYo4Zl5.js.map +1 -0
- package/dist/web/ui/assets/chevron-down-CQi0yuay.js +12 -0
- package/dist/web/ui/assets/chevron-down-CQi0yuay.js.map +1 -0
- package/dist/web/ui/assets/circle-check-DweDcOkA.js +7 -0
- package/dist/web/ui/assets/circle-check-DweDcOkA.js.map +1 -0
- package/dist/web/ui/assets/circle-x-BmL20etA.js +7 -0
- package/dist/web/ui/assets/circle-x-BmL20etA.js.map +1 -0
- package/dist/web/ui/assets/collapsible-BU_K9n8f.js +2 -0
- package/dist/web/ui/assets/collapsible-BU_K9n8f.js.map +1 -0
- package/dist/web/ui/assets/dialog-DovgkMhT.js +2 -0
- package/dist/web/ui/assets/dialog-DovgkMhT.js.map +1 -0
- package/dist/web/ui/assets/download-_QBatDio.js +7 -0
- package/dist/web/ui/assets/download-_QBatDio.js.map +1 -0
- package/dist/web/ui/assets/eye-Wpgtfmgw.js +7 -0
- package/dist/web/ui/assets/eye-Wpgtfmgw.js.map +1 -0
- package/dist/web/ui/assets/file-text-2EGFNyc1.js +7 -0
- package/dist/web/ui/assets/file-text-2EGFNyc1.js.map +1 -0
- package/dist/web/ui/assets/folder-open-C-OiZn9P.js +7 -0
- package/dist/web/ui/assets/folder-open-C-OiZn9P.js.map +1 -0
- package/dist/web/ui/assets/git-branch-BT9gCKgG.js +7 -0
- package/dist/web/ui/assets/git-branch-BT9gCKgG.js.map +1 -0
- package/dist/web/ui/assets/index-BhxU0YlT.js +163 -0
- package/dist/web/ui/assets/index-BhxU0YlT.js.map +1 -0
- package/dist/web/ui/assets/index-CUT6Fr2C.js +2 -0
- package/dist/web/ui/assets/index-CUT6Fr2C.js.map +1 -0
- package/dist/web/ui/assets/index-DOw1nKre.css +1 -0
- package/dist/web/ui/assets/input-L1uz5xAQ.js +2 -0
- package/dist/web/ui/assets/input-L1uz5xAQ.js.map +1 -0
- package/dist/web/ui/assets/loader-circle-BTFgt3hG.js +7 -0
- package/dist/web/ui/assets/loader-circle-BTFgt3hG.js.map +1 -0
- package/dist/web/ui/assets/pencil-uxK07iYy.js +7 -0
- package/dist/web/ui/assets/pencil-uxK07iYy.js.map +1 -0
- package/dist/web/ui/assets/plus-DcWFYr4m.js +7 -0
- package/dist/web/ui/assets/plus-DcWFYr4m.js.map +1 -0
- package/dist/web/ui/assets/power-DVIqVIMj.js +12 -0
- package/dist/web/ui/assets/power-DVIqVIMj.js.map +1 -0
- package/dist/web/ui/assets/progress-DMwOdxli.js +2 -0
- package/dist/web/ui/assets/progress-DMwOdxli.js.map +1 -0
- package/dist/web/ui/assets/search-D1OOxb1X.js +7 -0
- package/dist/web/ui/assets/search-D1OOxb1X.js.map +1 -0
- package/dist/web/ui/assets/select-Dnx_bUgy.js +2 -0
- package/dist/web/ui/assets/select-Dnx_bUgy.js.map +1 -0
- package/dist/web/ui/assets/send-D4uxqmyH.js +7 -0
- package/dist/web/ui/assets/send-D4uxqmyH.js.map +1 -0
- package/dist/web/ui/assets/sparkles-DLSJA4xU.js +7 -0
- package/dist/web/ui/assets/sparkles-DLSJA4xU.js.map +1 -0
- package/dist/web/ui/assets/switch-CvDDbCUA.js +2 -0
- package/dist/web/ui/assets/switch-CvDDbCUA.js.map +1 -0
- package/dist/web/ui/assets/terminal-DI3J3W_z.js +7 -0
- package/dist/web/ui/assets/terminal-DI3J3W_z.js.map +1 -0
- package/dist/web/ui/assets/textarea-CXLsr8tf.js +2 -0
- package/dist/web/ui/assets/textarea-CXLsr8tf.js.map +1 -0
- package/dist/web/ui/assets/vendor-dnd-DRBSMxXo.js +6 -0
- package/dist/web/ui/assets/vendor-dnd-DRBSMxXo.js.map +1 -0
- package/dist/web/ui/assets/vendor-markdown-DwTbvico.js +30 -0
- package/dist/web/ui/assets/vendor-markdown-DwTbvico.js.map +1 -0
- package/dist/web/ui/assets/vendor-motion-Dwx3-JO5.js +18 -0
- package/dist/web/ui/assets/vendor-motion-Dwx3-JO5.js.map +1 -0
- package/dist/web/ui/assets/vendor-radix-3UdfCgs_.js +65 -0
- package/dist/web/ui/assets/vendor-radix-3UdfCgs_.js.map +1 -0
- package/dist/web/ui/assets/vendor-react-C7pctHW3.js +44 -0
- package/dist/web/ui/assets/vendor-react-C7pctHW3.js.map +1 -0
- package/dist/web/ui/assets/vendor-syntax-xZUI6Op9.js +17 -0
- package/dist/web/ui/assets/vendor-syntax-xZUI6Op9.js.map +1 -0
- package/dist/web/ui/assets/zap-C-0oH5gt.js +7 -0
- package/dist/web/ui/assets/zap-C-0oH5gt.js.map +1 -0
- package/dist/web/ui/favicon.svg +10 -0
- package/dist/web/ui/icons/icon-192.svg +10 -0
- package/dist/web/ui/icons/icon-512-maskable.svg +10 -0
- package/dist/web/ui/icons/icon-512.svg +10 -0
- package/dist/web/ui/index.html +24 -0
- package/dist/web/ui/logo-dark.png +0 -0
- package/dist/web/ui/logo-full-dark.png +0 -0
- package/dist/web/ui/logo-full-light.png +0 -0
- package/dist/web/ui/logo-light.png +0 -0
- package/dist/web/ui/manifest.webmanifest +1 -0
- package/dist/web/ui/registerSW.js +1 -0
- package/dist/web/ui/sw.js +11 -0
- package/dist/web/ui/sw.js.map +1 -0
- package/dist/web/ui/workbox-0bb07689.js +3 -0
- package/dist/web/ui/workbox-0bb07689.js.map +1 -0
- package/package.json +11 -6
- package/src/web/static/vendor/geist/Geist-Italic[wght].woff2 +0 -0
- package/src/web/static/vendor/geist/Geist-Variable.woff2 +0 -0
- package/src/web/static/vendor/geist/GeistMono-Italic[wght].woff2 +0 -0
- package/src/web/static/vendor/geist/GeistMono-Variable.woff2 +0 -0
- package/src/web/static/vendor/graphology.min.js +2 -0
- package/src/web/static/vendor/icons.svg +108 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Persons-Bs_HhYjC.js","sources":["../../src/pages/brain/Persons.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { motion } from \"framer-motion\";\nimport { Search, Users, UserCircle, Brain } from \"lucide-react\";\nimport api, { type Person } from \"@/lib/api\";\nimport { cn } from \"@/lib/utils\";\nimport { Input } from \"@/components/ui/input\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Avatar, AvatarFallback } from \"@/components/ui/avatar\";\n\n// ── Skeleton ──\n\nfunction PersonCardSkeleton() {\n return (\n <div className=\"rounded-xl border border-border bg-card p-5 animate-pulse\">\n <div className=\"flex items-center gap-3 mb-3\">\n <div className=\"h-11 w-11 rounded-full bg-muted\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-4 w-28 rounded bg-muted\" />\n <div className=\"h-3 w-16 rounded bg-muted\" />\n </div>\n </div>\n <div className=\"space-y-2 mb-3\">\n <div className=\"h-3 w-full rounded bg-muted\" />\n <div className=\"h-3 w-3/4 rounded bg-muted\" />\n </div>\n <div className=\"flex gap-1.5\">\n <div className=\"h-5 w-14 rounded bg-muted\" />\n <div className=\"h-5 w-12 rounded bg-muted\" />\n </div>\n </div>\n );\n}\n\n// ── Animation variants ──\n\nconst container = {\n hidden: {},\n show: {\n transition: { staggerChildren: 0.04 },\n },\n};\n\nconst item = {\n hidden: { opacity: 0, y: 12 },\n show: { opacity: 1, y: 0, transition: { duration: 0.3, ease: \"easeOut\" as const } },\n};\n\n// ── Page ──\n\nexport function PersonsPage() {\n const [persons, setPersons] = useState<Person[]>([]);\n const [total, setTotal] = useState(0);\n const [query, setQuery] = useState(\"\");\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const fetchPersons = useCallback(async (q: string) => {\n try {\n setError(null);\n setLoading(true);\n const res = await api.brain.persons.list({\n q: q || undefined,\n limit: 200,\n });\n setPersons(res.persons);\n setTotal(res.total);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load persons\");\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n fetchPersons(\"\");\n }, [fetchPersons]);\n\n const handleSearch = (value: string) => {\n setQuery(value);\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => fetchPersons(value), 300);\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div>\n <div className=\"flex items-center gap-2.5\">\n <Users className=\"h-6 w-6 text-[#00d4ff]\" />\n <h1 className=\"text-2xl font-semibold text-foreground\">\n Persons\n {!loading && (\n <span className=\"ml-2 text-base font-normal text-muted-foreground\">\n ({total})\n </span>\n )}\n </h1>\n </div>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n People Mercury knows about\n </p>\n </div>\n\n {/* Search */}\n <div className=\"relative max-w-md\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n placeholder=\"Search by name...\"\n value={query}\n onChange={(e) => handleSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n\n {/* Error */}\n {error && (\n <Card>\n <CardContent className=\"py-8 text-center text-destructive\">\n {error}\n </CardContent>\n </Card>\n )}\n\n {/* Loading */}\n {loading && (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {Array.from({ length: 6 }).map((_, i) => (\n <PersonCardSkeleton key={i} />\n ))}\n </div>\n )}\n\n {/* Empty */}\n {!loading && !error && persons.length === 0 && (\n <Card>\n <CardContent className=\"flex flex-col items-center gap-3 py-12 text-center text-muted-foreground\">\n <UserCircle className=\"h-10 w-10\" />\n <div>\n <p className=\"font-medium text-foreground\">No persons found</p>\n <p className=\"text-sm\">\n {query\n ? \"Try a different search term.\"\n : \"Mercury hasn't recorded any people yet.\"}\n </p>\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Grid */}\n {!loading && !error && persons.length > 0 && (\n <motion.div\n className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\"\n variants={container}\n initial=\"hidden\"\n animate=\"show\"\n >\n {persons.map((person) => (\n <motion.div key={person.id} variants={item}>\n <Link\n to={`/second-brain/persons/${person.id}`}\n className=\"block\"\n >\n <Card\n className={cn(\n \"cursor-pointer transition-all duration-200\",\n \"hover:-translate-y-0.5 hover:shadow-lg hover:border-[#00d4ff]/30\"\n )}\n >\n <CardContent className=\"p-5\">\n {/* Avatar + name */}\n <div className=\"flex items-center gap-3 mb-3\">\n <Avatar className=\"h-11 w-11\">\n <AvatarFallback className=\"bg-[#00d4ff]/10 text-[#00d4ff] font-semibold text-sm\">\n {person.name.charAt(0).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-base font-semibold text-foreground\">\n {person.name}\n </p>\n {person.relationship && (\n <Badge\n variant=\"secondary\"\n className=\"mt-0.5 text-[10px] capitalize\"\n >\n {person.relationship}\n </Badge>\n )}\n </div>\n </div>\n\n {/* Summary */}\n {person.summary && (\n <p className=\"mb-3 line-clamp-2 text-sm text-muted-foreground\">\n {person.summary}\n </p>\n )}\n\n {/* Footer: traits + memory count */}\n <div className=\"flex flex-wrap items-center gap-1.5\">\n {person.traits?.slice(0, 4).map((trait) => (\n <Badge\n key={trait}\n variant=\"outline\"\n className=\"text-[10px]\"\n >\n {trait}\n </Badge>\n ))}\n {person.memoryCount != null && person.memoryCount > 0 && (\n <span className=\"ml-auto flex items-center gap-1 text-xs text-muted-foreground\">\n <Brain className=\"h-3 w-3\" />\n {person.memoryCount} memories\n </span>\n )}\n </div>\n </CardContent>\n </Card>\n </Link>\n </motion.div>\n ))}\n </motion.div>\n )}\n </div>\n );\n}\n"],"names":["PersonCardSkeleton","jsxs","jsx","container","item","PersonsPage","persons","setPersons","useState","total","setTotal","query","setQuery","loading","setLoading","error","setError","debounceRef","useRef","fetchPersons","useCallback","q","res","api","err","useEffect","handleSearch","value","Users","Search","Input","e","Card","CardContent","_","i","UserCircle","motion","person","Link","cn","Avatar","AvatarFallback","Badge","_a","trait","Brain"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{j as e,A as b,m as j}from"./vendor-motion-Dwx3-JO5.js";import{r as c}from"./vendor-react-C7pctHW3.js";import{e as I,a as h,d as y,c as m}from"./index-BhxU0YlT.js";import{C as f,c as p,a as S}from"./card-DAYo4Zl5.js";import{I as v}from"./input-L1uz5xAQ.js";import{B as N}from"./button-TaFPR-zy.js";import{S as L}from"./switch-CvDDbCUA.js";import{B as w}from"./badge-DfDJNUtd.js";import{C as K}from"./circle-x-BmL20etA.js";import{E as M}from"./eye-Wpgtfmgw.js";import{C as B}from"./circle-check-DweDcOkA.js";import{L as E}from"./loader-circle-BTFgt3hG.js";import"./vendor-syntax-xZUI6Op9.js";import"./vendor-radix-3UdfCgs_.js";import"./index-CUT6Fr2C.js";/**
|
|
2
|
+
* @license lucide-react v0.511.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const z=[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],O=I("eye-off",z),_=d=>({apiKey:"",baseUrl:d.baseUrl,model:d.model,enabled:d.enabled,showKey:!1,saving:!1,testing:!1,feedback:null,testResult:null});function D(){return e.jsxs(f,{className:"border-border/50 bg-card/60 backdrop-blur",children:[e.jsx(S,{className:"pb-4",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"h-9 w-9 animate-pulse rounded-lg bg-muted"}),e.jsx("div",{className:"h-5 w-28 animate-pulse rounded bg-muted"})]}),e.jsx("div",{className:"h-5 w-9 animate-pulse rounded-full bg-muted"})]})}),e.jsxs(p,{className:"space-y-4",children:[[1,2,3].map(d=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("div",{className:"h-3.5 w-16 animate-pulse rounded bg-muted"}),e.jsx("div",{className:"h-9 w-full animate-pulse rounded-md bg-muted"})]},d)),e.jsxs("div",{className:"flex gap-2 pt-2",children:[e.jsx("div",{className:"h-9 w-20 animate-pulse rounded-md bg-muted"}),e.jsx("div",{className:"h-9 w-32 animate-pulse rounded-md bg-muted"})]})]})]})}function re(){const[d,P]=c.useState([]),[k,C]=c.useState({}),[u,T]=c.useState(!0),[g,R]=c.useState(null),x=c.useRef({}),n=c.useCallback(async()=>{try{const s=await h.providers.list();P(s),C(t=>{const a={};for(const i of s)a[i.name]=t[i.name]?{...t[i.name],enabled:i.enabled}:_(i);return a}),R(null)}catch(s){R(s instanceof Error?s.message:"Failed to load providers")}finally{T(!1)}},[]);c.useEffect(()=>(n(),()=>{Object.values(x.current).forEach(clearTimeout)}),[n]);const r=(s,t)=>{C(a=>({...a,[s]:{...a[s],...t}}))},o=(s,t,a)=>{x.current[s]&&clearTimeout(x.current[s]),r(s,{feedback:{type:t,message:a}}),x.current[s]=setTimeout(()=>{r(s,{feedback:null})},4e3)},U=async s=>{const t=k[s];if(t){r(s,{saving:!0});try{await h.providers.update(s,{...t.apiKey?{apiKey:t.apiKey}:{},baseUrl:t.baseUrl,model:t.model,enabled:t.enabled}),o(s,"success","Configuration saved"),r(s,{apiKey:"",saving:!1}),n()}catch(a){o(s,"error",a instanceof Error?a.message:"Save failed"),r(s,{saving:!1})}}},A=async s=>{r(s,{testing:!0,testResult:null});try{const t=await h.providers.test(s);r(s,{testing:!1,testResult:t}),o(s,t.success?"success":"error",t.success?"Connection successful":"Connection failed")}catch(t){r(s,{testing:!1}),o(s,"error",t instanceof Error?t.message:"Test failed")}},F=async(s,t)=>{r(s,{enabled:t});try{await h.providers.update(s,{enabled:t}),n()}catch{o(s,"error","Failed to toggle provider"),r(s,{enabled:!t})}};return e.jsxs("div",{className:"space-y-6 p-6",children:[e.jsx("div",{children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-[#00d4ff]/20 to-[#a78bfa]/20 ring-1 ring-[#00d4ff]/30",children:e.jsx(y,{className:"h-5 w-5 text-[#00d4ff]"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold text-foreground",children:"Providers"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Configure your AI model providers"})]})]})}),g&&!u&&e.jsx(f,{className:"border-destructive/50 bg-destructive/5",children:e.jsxs(p,{className:"flex items-center gap-3 py-4",children:[e.jsx(K,{className:"h-5 w-5 text-destructive"}),e.jsx("p",{className:"text-sm text-destructive",children:g}),e.jsx(N,{variant:"outline",size:"sm",className:"ml-auto",onClick:n,children:"Retry"})]})}),u&&e.jsx("div",{className:"grid gap-6 md:grid-cols-1 lg:grid-cols-2",children:[1,2,3,4].map(s=>e.jsx(D,{},s))}),!u&&d.length>0&&e.jsx("div",{className:"grid gap-6 md:grid-cols-1 lg:grid-cols-2",children:e.jsx(b,{mode:"popLayout",children:d.map((s,t)=>{var i;const a=k[s.name];return a?e.jsx(j.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},exit:{opacity:0,y:-10},transition:{duration:.3,delay:t*.05},children:e.jsxs(f,{className:m("border-border/50 bg-card/60 backdrop-blur transition-all duration-300",a.enabled&&"ring-1 ring-[#00d4ff]/20"),children:[e.jsx(S,{className:"pb-4",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:m("flex h-9 w-9 items-center justify-center rounded-lg transition-colors",a.enabled?"bg-gradient-to-br from-[#00d4ff]/20 to-[#a78bfa]/20":"bg-muted"),children:e.jsx(y,{className:m("h-4.5 w-4.5 transition-colors",a.enabled?"text-[#00d4ff]":"text-muted-foreground")})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-base font-medium text-foreground",children:s.name}),e.jsx(w,{variant:a.enabled?"default":"secondary",className:m("text-[10px] px-1.5 py-0",a.enabled&&"bg-[#00d4ff]/15 text-[#00d4ff] border-[#00d4ff]/30 hover:bg-[#00d4ff]/20"),children:a.enabled?"Active":"Disabled"})]})]}),e.jsx(L,{checked:a.enabled,onCheckedChange:l=>F(s.name,l)})]})}),e.jsxs(p,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground",children:"API Key"}),e.jsxs("div",{className:"relative",children:[e.jsx(v,{type:a.showKey?"text":"password",placeholder:s.maskedKey||"Enter API key",value:a.apiKey,onChange:l=>r(s.name,{apiKey:l.target.value}),className:"pr-9 bg-background/50"}),e.jsx("button",{type:"button",onClick:()=>r(s.name,{showKey:!a.showKey}),className:"absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",children:a.showKey?e.jsx(O,{className:"h-4 w-4"}):e.jsx(M,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("label",{className:"text-xs font-medium text-muted-foreground",children:["Base URL"," ",e.jsx("span",{className:"text-muted-foreground/60",children:"(optional)"})]}),e.jsx(v,{placeholder:"https://api.openai.com/v1",value:a.baseUrl,onChange:l=>r(s.name,{baseUrl:l.target.value}),className:"bg-background/50"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground",children:"Model"}),e.jsx(v,{placeholder:"gpt-4o",value:a.model,onChange:l=>r(s.name,{model:l.target.value}),className:"bg-background/50"})]}),e.jsx(b,{children:a.feedback&&e.jsx(j.div,{initial:{opacity:0,height:0},animate:{opacity:1,height:"auto"},exit:{opacity:0,height:0},className:"overflow-hidden",children:e.jsxs("div",{className:m("flex items-center gap-2 rounded-md px-3 py-2 text-sm",a.feedback.type==="success"?"bg-emerald-500/10 text-emerald-400":"bg-destructive/10 text-destructive"),children:[a.feedback.type==="success"?e.jsx(B,{className:"h-4 w-4 shrink-0"}):e.jsx(K,{className:"h-4 w-4 shrink-0"}),a.feedback.message]})})}),e.jsx(b,{children:((i=a.testResult)==null?void 0:i.success)&&a.testResult.models&&e.jsx(j.div,{initial:{opacity:0,height:0},animate:{opacity:1,height:"auto"},exit:{opacity:0,height:0},className:"overflow-hidden",children:e.jsxs("div",{className:"rounded-md border border-border/50 bg-background/30 p-3 space-y-2",children:[a.testResult.recommendedModel&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Recommended:"," ",e.jsx("span",{className:"font-medium text-[#00d4ff]",children:a.testResult.recommendedModel})]}),e.jsxs("div",{className:"flex flex-wrap gap-1.5",children:[a.testResult.models.slice(0,12).map(l=>e.jsx(w,{variant:"secondary",className:"text-[10px] cursor-pointer hover:bg-[#00d4ff]/15 hover:text-[#00d4ff] transition-colors",onClick:()=>r(s.name,{model:l}),children:l},l)),a.testResult.models.length>12&&e.jsxs(w,{variant:"secondary",className:"text-[10px]",children:["+",a.testResult.models.length-12," more"]})]})]})})}),e.jsxs("div",{className:"flex gap-2 pt-1",children:[e.jsxs(N,{size:"sm",onClick:()=>U(s.name),disabled:a.saving,className:"bg-gradient-to-r from-[#00d4ff] to-[#a78bfa] text-white hover:opacity-90 transition-opacity",children:[a.saving&&e.jsx(E,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}),"Save"]}),e.jsxs(N,{size:"sm",variant:"outline",onClick:()=>A(s.name),disabled:a.testing,children:[a.testing&&e.jsx(E,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}),"Test Connection"]})]})]})]})},s.name):null})})}),!u&&!g&&d.length===0&&e.jsx(f,{className:"border-border/50 bg-card/60",children:e.jsxs(p,{className:"py-12 text-center",children:[e.jsx(y,{className:"mx-auto h-10 w-10 text-muted-foreground/40 mb-3"}),e.jsx("p",{className:"text-muted-foreground",children:"No providers configured yet."})]})})]})}export{re as ProvidersPage};
|
|
7
|
+
//# sourceMappingURL=Providers-CL6wMWni.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Providers-CL6wMWni.js","sources":["../../node_modules/lucide-react/dist/esm/icons/eye-off.js","../../src/pages/Providers.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\",\n key: \"ct8e1f\"\n }\n ],\n [\"path\", { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\", key: \"151rxh\" }],\n [\n \"path\",\n {\n d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\",\n key: \"13bj9a\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n];\nconst EyeOff = createLucideIcon(\"eye-off\", __iconNode);\n\nexport { __iconNode, EyeOff as default };\n//# sourceMappingURL=eye-off.js.map\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { Cpu, Eye, EyeOff, Loader2, CheckCircle2, XCircle } from \"lucide-react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport api, { type ProviderInfo, type ProviderTestResult } from \"@/lib/api\";\nimport { cn } from \"@/lib/utils\";\nimport { Card, CardHeader, CardContent } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { Switch } from \"@/components/ui/switch\";\nimport { Badge } from \"@/components/ui/badge\";\n\n/* ── Per-provider local form state ── */\ninterface ProviderForm {\n apiKey: string;\n baseUrl: string;\n model: string;\n enabled: boolean;\n showKey: boolean;\n saving: boolean;\n testing: boolean;\n feedback: { type: \"success\" | \"error\"; message: string } | null;\n testResult: ProviderTestResult | null;\n}\n\nconst emptyForm = (p: ProviderInfo): ProviderForm => ({\n apiKey: \"\",\n baseUrl: p.baseUrl,\n model: p.model,\n enabled: p.enabled,\n showKey: false,\n saving: false,\n testing: false,\n feedback: null,\n testResult: null,\n});\n\n/* ── Skeleton ── */\nfunction ProviderSkeleton() {\n return (\n <Card className=\"border-border/50 bg-card/60 backdrop-blur\">\n <CardHeader className=\"pb-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"h-9 w-9 animate-pulse rounded-lg bg-muted\" />\n <div className=\"h-5 w-28 animate-pulse rounded bg-muted\" />\n </div>\n <div className=\"h-5 w-9 animate-pulse rounded-full bg-muted\" />\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"space-y-1.5\">\n <div className=\"h-3.5 w-16 animate-pulse rounded bg-muted\" />\n <div className=\"h-9 w-full animate-pulse rounded-md bg-muted\" />\n </div>\n ))}\n <div className=\"flex gap-2 pt-2\">\n <div className=\"h-9 w-20 animate-pulse rounded-md bg-muted\" />\n <div className=\"h-9 w-32 animate-pulse rounded-md bg-muted\" />\n </div>\n </CardContent>\n </Card>\n );\n}\n\nexport function ProvidersPage() {\n const [providers, setProviders] = useState<ProviderInfo[]>([]);\n const [forms, setForms] = useState<Record<string, ProviderForm>>({});\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const feedbackTimers = useRef<Record<string, ReturnType<typeof setTimeout>>>({});\n\n const fetchProviders = useCallback(async () => {\n try {\n const data = await api.providers.list();\n setProviders(data);\n setForms((prev) => {\n const next: Record<string, ProviderForm> = {};\n for (const p of data) {\n next[p.name] = prev[p.name]\n ? { ...prev[p.name], enabled: p.enabled }\n : emptyForm(p);\n }\n return next;\n });\n setError(null);\n } catch (e) {\n setError(e instanceof Error ? e.message : \"Failed to load providers\");\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n fetchProviders();\n return () => {\n Object.values(feedbackTimers.current).forEach(clearTimeout);\n };\n }, [fetchProviders]);\n\n /* helpers */\n const updateForm = (name: string, patch: Partial<ProviderForm>) => {\n setForms((prev) => ({ ...prev, [name]: { ...prev[name], ...patch } }));\n };\n\n const showFeedback = (\n name: string,\n type: \"success\" | \"error\",\n message: string\n ) => {\n if (feedbackTimers.current[name]) clearTimeout(feedbackTimers.current[name]);\n updateForm(name, { feedback: { type, message } });\n feedbackTimers.current[name] = setTimeout(() => {\n updateForm(name, { feedback: null });\n }, 4000);\n };\n\n const handleSave = async (name: string) => {\n const f = forms[name];\n if (!f) return;\n updateForm(name, { saving: true });\n try {\n await api.providers.update(name, {\n ...(f.apiKey ? { apiKey: f.apiKey } : {}),\n baseUrl: f.baseUrl,\n model: f.model,\n enabled: f.enabled,\n });\n showFeedback(name, \"success\", \"Configuration saved\");\n updateForm(name, { apiKey: \"\", saving: false });\n fetchProviders();\n } catch (e) {\n showFeedback(name, \"error\", e instanceof Error ? e.message : \"Save failed\");\n updateForm(name, { saving: false });\n }\n };\n\n const handleTest = async (name: string) => {\n updateForm(name, { testing: true, testResult: null });\n try {\n const result = await api.providers.test(name);\n updateForm(name, { testing: false, testResult: result });\n showFeedback(\n name,\n result.success ? \"success\" : \"error\",\n result.success ? \"Connection successful\" : \"Connection failed\"\n );\n } catch (e) {\n updateForm(name, { testing: false });\n showFeedback(name, \"error\", e instanceof Error ? e.message : \"Test failed\");\n }\n };\n\n const handleToggle = async (name: string, enabled: boolean) => {\n updateForm(name, { enabled });\n try {\n await api.providers.update(name, { enabled });\n fetchProviders();\n } catch (e) {\n showFeedback(name, \"error\", \"Failed to toggle provider\");\n updateForm(name, { enabled: !enabled });\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div>\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-[#00d4ff]/20 to-[#a78bfa]/20 ring-1 ring-[#00d4ff]/30\">\n <Cpu className=\"h-5 w-5 text-[#00d4ff]\" />\n </div>\n <div>\n <h1 className=\"text-2xl font-semibold text-foreground\">Providers</h1>\n <p className=\"text-sm text-muted-foreground\">\n Configure your AI model providers\n </p>\n </div>\n </div>\n </div>\n\n {/* Error state */}\n {error && !loading && (\n <Card className=\"border-destructive/50 bg-destructive/5\">\n <CardContent className=\"flex items-center gap-3 py-4\">\n <XCircle className=\"h-5 w-5 text-destructive\" />\n <p className=\"text-sm text-destructive\">{error}</p>\n <Button variant=\"outline\" size=\"sm\" className=\"ml-auto\" onClick={fetchProviders}>\n Retry\n </Button>\n </CardContent>\n </Card>\n )}\n\n {/* Loading */}\n {loading && (\n <div className=\"grid gap-6 md:grid-cols-1 lg:grid-cols-2\">\n {[1, 2, 3, 4].map((i) => (\n <ProviderSkeleton key={i} />\n ))}\n </div>\n )}\n\n {/* Provider Grid */}\n {!loading && providers.length > 0 && (\n <div className=\"grid gap-6 md:grid-cols-1 lg:grid-cols-2\">\n <AnimatePresence mode=\"popLayout\">\n {providers.map((provider, idx) => {\n const f = forms[provider.name];\n if (!f) return null;\n return (\n <motion.div\n key={provider.name}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -10 }}\n transition={{ duration: 0.3, delay: idx * 0.05 }}\n >\n <Card\n className={cn(\n \"border-border/50 bg-card/60 backdrop-blur transition-all duration-300\",\n f.enabled && \"ring-1 ring-[#00d4ff]/20\"\n )}\n >\n <CardHeader className=\"pb-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n \"flex h-9 w-9 items-center justify-center rounded-lg transition-colors\",\n f.enabled\n ? \"bg-gradient-to-br from-[#00d4ff]/20 to-[#a78bfa]/20\"\n : \"bg-muted\"\n )}\n >\n <Cpu\n className={cn(\n \"h-4.5 w-4.5 transition-colors\",\n f.enabled ? \"text-[#00d4ff]\" : \"text-muted-foreground\"\n )}\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-base font-medium text-foreground\">\n {provider.name}\n </span>\n <Badge\n variant={f.enabled ? \"default\" : \"secondary\"}\n className={cn(\n \"text-[10px] px-1.5 py-0\",\n f.enabled &&\n \"bg-[#00d4ff]/15 text-[#00d4ff] border-[#00d4ff]/30 hover:bg-[#00d4ff]/20\"\n )}\n >\n {f.enabled ? \"Active\" : \"Disabled\"}\n </Badge>\n </div>\n </div>\n <Switch\n checked={f.enabled}\n onCheckedChange={(val) => handleToggle(provider.name, val)}\n />\n </div>\n </CardHeader>\n\n <CardContent className=\"space-y-4\">\n {/* API Key */}\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n API Key\n </label>\n <div className=\"relative\">\n <Input\n type={f.showKey ? \"text\" : \"password\"}\n placeholder={provider.maskedKey || \"Enter API key\"}\n value={f.apiKey}\n onChange={(e) =>\n updateForm(provider.name, { apiKey: e.target.value })\n }\n className=\"pr-9 bg-background/50\"\n />\n <button\n type=\"button\"\n onClick={() =>\n updateForm(provider.name, { showKey: !f.showKey })\n }\n className=\"absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors\"\n >\n {f.showKey ? (\n <EyeOff className=\"h-4 w-4\" />\n ) : (\n <Eye className=\"h-4 w-4\" />\n )}\n </button>\n </div>\n </div>\n\n {/* Base URL */}\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n Base URL{\" \"}\n <span className=\"text-muted-foreground/60\">(optional)</span>\n </label>\n <Input\n placeholder=\"https://api.openai.com/v1\"\n value={f.baseUrl}\n onChange={(e) =>\n updateForm(provider.name, { baseUrl: e.target.value })\n }\n className=\"bg-background/50\"\n />\n </div>\n\n {/* Model */}\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n Model\n </label>\n <Input\n placeholder=\"gpt-4o\"\n value={f.model}\n onChange={(e) =>\n updateForm(provider.name, { model: e.target.value })\n }\n className=\"bg-background/50\"\n />\n </div>\n\n {/* Feedback */}\n <AnimatePresence>\n {f.feedback && (\n <motion.div\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: \"auto\" }}\n exit={{ opacity: 0, height: 0 }}\n className=\"overflow-hidden\"\n >\n <div\n className={cn(\n \"flex items-center gap-2 rounded-md px-3 py-2 text-sm\",\n f.feedback.type === \"success\"\n ? \"bg-emerald-500/10 text-emerald-400\"\n : \"bg-destructive/10 text-destructive\"\n )}\n >\n {f.feedback.type === \"success\" ? (\n <CheckCircle2 className=\"h-4 w-4 shrink-0\" />\n ) : (\n <XCircle className=\"h-4 w-4 shrink-0\" />\n )}\n {f.feedback.message}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Test result details */}\n <AnimatePresence>\n {f.testResult?.success && f.testResult.models && (\n <motion.div\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: \"auto\" }}\n exit={{ opacity: 0, height: 0 }}\n className=\"overflow-hidden\"\n >\n <div className=\"rounded-md border border-border/50 bg-background/30 p-3 space-y-2\">\n {f.testResult.recommendedModel && (\n <p className=\"text-xs text-muted-foreground\">\n Recommended:{\" \"}\n <span className=\"font-medium text-[#00d4ff]\">\n {f.testResult.recommendedModel}\n </span>\n </p>\n )}\n <div className=\"flex flex-wrap gap-1.5\">\n {f.testResult.models.slice(0, 12).map((m) => (\n <Badge\n key={m}\n variant=\"secondary\"\n className=\"text-[10px] cursor-pointer hover:bg-[#00d4ff]/15 hover:text-[#00d4ff] transition-colors\"\n onClick={() =>\n updateForm(provider.name, { model: m })\n }\n >\n {m}\n </Badge>\n ))}\n {f.testResult.models.length > 12 && (\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n +{f.testResult.models.length - 12} more\n </Badge>\n )}\n </div>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Actions */}\n <div className=\"flex gap-2 pt-1\">\n <Button\n size=\"sm\"\n onClick={() => handleSave(provider.name)}\n disabled={f.saving}\n className=\"bg-gradient-to-r from-[#00d4ff] to-[#a78bfa] text-white hover:opacity-90 transition-opacity\"\n >\n {f.saving && (\n <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" />\n )}\n Save\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleTest(provider.name)}\n disabled={f.testing}\n >\n {f.testing && (\n <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" />\n )}\n Test Connection\n </Button>\n </div>\n </CardContent>\n </Card>\n </motion.div>\n );\n })}\n </AnimatePresence>\n </div>\n )}\n\n {/* Empty state */}\n {!loading && !error && providers.length === 0 && (\n <Card className=\"border-border/50 bg-card/60\">\n <CardContent className=\"py-12 text-center\">\n <Cpu className=\"mx-auto h-10 w-10 text-muted-foreground/40 mb-3\" />\n <p className=\"text-muted-foreground\">No providers configured yet.</p>\n </CardContent>\n </Card>\n )}\n </div>\n );\n}\n"],"names":["__iconNode","EyeOff","createLucideIcon","emptyForm","p","ProviderSkeleton","jsxs","Card","jsx","CardHeader","CardContent","i","ProvidersPage","providers","setProviders","useState","forms","setForms","loading","setLoading","error","setError","feedbackTimers","useRef","fetchProviders","useCallback","data","api","prev","next","e","useEffect","updateForm","name","patch","showFeedback","type","message","handleSave","f","handleTest","result","handleToggle","enabled","Cpu","XCircle","Button","AnimatePresence","provider","idx","motion","cn","Badge","Switch","val","Input","Eye","CheckCircle2","_a","m","Loader2"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import{j as e,m as g,A as L}from"./vendor-motion-Dwx3-JO5.js";import{r}from"./vendor-react-C7pctHW3.js";import{C as $,c as O,a as H,b as U}from"./card-DAYo4Zl5.js";import{B as b}from"./badge-DfDJNUtd.js";import{B as y}from"./button-TaFPR-zy.js";import{I as u}from"./input-L1uz5xAQ.js";import{D as q,a as W,b as G,c as J,d as K,e as Q}from"./dialog-DovgkMhT.js";import{T as V,A as X,a as Y,b as Z,c as ee,d as se,e as te,f as ae,g as ie}from"./alert-dialog-CW-j2nG4.js";import{e as w,a as C,c as _,C as re,t as le,h as P}from"./index-BhxU0YlT.js";import{S as ne}from"./sparkles-DLSJA4xU.js";import{P as ce}from"./pencil-uxK07iYy.js";import"./index-CUT6Fr2C.js";import"./vendor-radix-3UdfCgs_.js";import"./vendor-syntax-xZUI6Op9.js";/**
|
|
2
|
+
* @license lucide-react v0.511.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const oe=[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}]],de=w("calendar",oe);/**
|
|
7
|
+
* @license lucide-react v0.511.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const me=[["line",{x1:"10",x2:"14",y1:"2",y2:"2",key:"14vaq8"}],["line",{x1:"12",x2:"15",y1:"14",y2:"11",key:"17fdiu"}],["circle",{cx:"12",cy:"14",r:"8",key:"1e1u0o"}]],pe=w("timer",me);/**
|
|
12
|
+
* @license lucide-react v0.511.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const ue=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],xe=w("triangle-alert",ue),he={hidden:{opacity:0,y:12},visible:a=>({opacity:1,y:0,transition:{delay:a*.07,duration:.35,ease:"easeOut"}})};function D({className:a}){return e.jsx("div",{className:_("animate-pulse rounded-lg bg-muted",a)})}function fe(a){const c=a.trim().split(/\s+/);if(c.length<5)return a;const[n,l,x,,d]=c;return a==="* * * * *"?"Every minute":n==="0"&&l==="*"?"Every hour":n==="*/5"&&l==="*"?"Every 5 minutes":n==="*/10"&&l==="*"?"Every 10 minutes":n==="*/15"&&l==="*"?"Every 15 minutes":n==="*/30"&&l==="*"?"Every 30 minutes":x==="*"&&d==="*"&&l!=="*"&&n!=="*"?`Daily at ${l.padStart(2,"0")}:${n.padStart(2,"0")}`:d==="1-5"&&l!=="*"?`Weekdays at ${l.padStart(2,"0")}:${n.padStart(2,"0")}`:a}function ge(a){return a<60?`${a}s delay`:a<3600?`${Math.round(a/60)}m delay`:`${(a/3600).toFixed(1)}h delay`}function $e(){const[a,c]=r.useState([]),[n,l]=r.useState(!0),[x,d]=r.useState(""),[m,p]=r.useState(null),[F,h]=r.useState(!1),[j,M]=r.useState(null),[i,o]=r.useState({description:"",cron:"",delaySeconds:"",prompt:"",skillName:""}),[E,A]=r.useState(!1),[f,v]=r.useState(null),[N,T]=r.useState(!1),I=r.useCallback(()=>{l(!0),C.schedules.list().then(s=>{c(s.schedules),d("")}).catch(s=>d(s.message)).finally(()=>l(!1))},[]);r.useEffect(()=>{I()},[I]),r.useEffect(()=>{if(!m)return;const s=setTimeout(()=>p(null),3e3);return()=>clearTimeout(s)},[m]);function z(s){var t;M(s.id),o({description:s.description,cron:s.cron??"",delaySeconds:((t=s.delaySeconds)==null?void 0:t.toString())??"",prompt:s.prompt??"",skillName:s.skillName??""}),h(!0)}async function R(){if(j){A(!0);try{const s={description:i.description};i.cron.trim()&&(s.cron=i.cron.trim()),i.delaySeconds.trim()&&(s.delaySeconds=Number(i.delaySeconds)),i.prompt.trim()&&(s.prompt=i.prompt.trim()),i.skillName.trim()&&(s.skillName=i.skillName.trim());const t=await C.schedules.update(j,s);t.success&&(c(S=>S.map(k=>k.id===j?{...k,...t.schedule}:k)),p({type:"success",message:"Schedule updated"}),h(!1))}catch(s){p({type:"error",message:s instanceof Error?s.message:"Update failed"})}finally{A(!1)}}}async function B(){if(f){T(!0);try{(await C.schedules.delete(f)).success&&(c(t=>t.filter(S=>S.id!==f)),p({type:"success",message:"Schedule deleted"}))}catch(s){p({type:"error",message:s instanceof Error?s.message:"Delete failed"})}finally{T(!1),v(null)}}}return x&&!a.length?e.jsx("div",{className:"flex h-full items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-destructive",children:x})}):n?e.jsxs("div",{className:"space-y-6 p-6 lg:p-8",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(D,{className:"h-8 w-40"}),e.jsx(D,{className:"h-4 w-56"})]}),e.jsx("div",{className:"flex flex-col gap-4",children:Array.from({length:3}).map((s,t)=>e.jsx(D,{className:"h-[140px]"},t))})]}):e.jsxs("div",{className:"space-y-6 p-6 lg:p-8",children:[e.jsxs(g.div,{initial:{opacity:0,y:-8},animate:{opacity:1,y:0},transition:{duration:.3},children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Schedules"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Automated recurring tasks"})]}),e.jsx(L,{children:m&&e.jsx(g.div,{initial:{opacity:0,y:-8},animate:{opacity:1,y:0},exit:{opacity:0,y:-8},className:_("rounded-lg border px-4 py-2.5 text-sm font-medium",m.type==="success"?"border-emerald-500/30 bg-emerald-500/10 text-emerald-500":"border-destructive/30 bg-destructive/10 text-destructive"),children:m.message})}),a.length===0?e.jsx(g.div,{initial:{opacity:0,scale:.96},animate:{opacity:1,scale:1},transition:{duration:.3},children:e.jsx($,{children:e.jsxs(O,{className:"flex flex-col items-center justify-center py-16 text-center",children:[e.jsx(re,{className:"mb-4 h-10 w-10 text-muted-foreground/50"}),e.jsx("p",{className:"text-lg font-medium text-muted-foreground",children:"No scheduled tasks"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground/70",children:"Schedules will appear here once configured via the API or CLI."})]})})}):e.jsx("div",{className:"flex flex-col gap-4",children:a.map((s,t)=>e.jsx(g.div,{custom:t,variants:he,initial:"hidden",animate:"visible",children:e.jsxs($,{children:[e.jsxs(H,{className:"flex flex-row items-start justify-between gap-4 pb-3",children:[e.jsxs("div",{className:"min-w-0 flex-1 space-y-1",children:[e.jsx(U,{className:"text-base",children:s.description}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[s.cron&&e.jsxs(b,{variant:"secondary",className:"gap-1",children:[e.jsx(de,{className:"h-3 w-3"}),fe(s.cron)]}),s.delaySeconds!=null&&e.jsxs(b,{variant:"secondary",className:"gap-1",children:[e.jsx(pe,{className:"h-3 w-3"}),ge(s.delaySeconds)]}),s.skillName&&e.jsxs(b,{variant:"default",className:"gap-1",children:[e.jsx(ne,{className:"h-3 w-3"}),s.skillName]})]})]}),e.jsxs("div",{className:"flex shrink-0 gap-1",children:[e.jsx(y,{variant:"ghost",size:"icon",onClick:()=>z(s),children:e.jsx(ce,{className:"h-4 w-4"})}),e.jsx(y,{variant:"ghost",size:"icon",onClick:()=>v(s.id),children:e.jsx(V,{className:"h-4 w-4 text-destructive"})})]})]}),e.jsx(O,{children:e.jsxs("div",{className:"flex flex-col gap-2 text-sm",children:[s.prompt&&e.jsxs("p",{className:"text-muted-foreground",children:[e.jsx("span",{className:"font-medium text-foreground",children:"Prompt: "}),le(s.prompt,100)]}),e.jsxs("div",{className:"flex flex-wrap gap-x-6 gap-y-1 text-xs text-muted-foreground",children:[s.lastRun&&e.jsxs("span",{children:["Last run:"," ",e.jsx("span",{className:"font-medium tabular-nums text-foreground",children:P(s.lastRun)})]}),s.nextRun&&e.jsxs("span",{children:["Next run:"," ",e.jsx("span",{className:"font-medium tabular-nums text-foreground",children:P(s.nextRun)})]})]})]})})]})},s.id))}),e.jsx(q,{open:F,onOpenChange:h,children:e.jsxs(W,{children:[e.jsxs(G,{children:[e.jsx(J,{children:"Edit Schedule"}),e.jsx(K,{children:"Update the schedule configuration."})]}),e.jsxs("div",{className:"flex flex-col gap-4 py-2",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium",children:"Description"}),e.jsx(u,{value:i.description,onChange:s=>o(t=>({...t,description:s.target.value})),placeholder:"Schedule description"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium",children:"Cron Expression"}),e.jsx(u,{value:i.cron,onChange:s=>o(t=>({...t,cron:s.target.value})),placeholder:"*/30 * * * *"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium",children:"Delay (seconds)"}),e.jsx(u,{type:"number",value:i.delaySeconds,onChange:s=>o(t=>({...t,delaySeconds:s.target.value})),placeholder:"3600"})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium",children:"Prompt"}),e.jsx(u,{value:i.prompt,onChange:s=>o(t=>({...t,prompt:s.target.value})),placeholder:"Optional prompt text"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium",children:"Skill Name"}),e.jsx(u,{value:i.skillName,onChange:s=>o(t=>({...t,skillName:s.target.value})),placeholder:"Optional skill name"})]})]}),e.jsxs(Q,{children:[e.jsx(y,{variant:"outline",onClick:()=>h(!1),children:"Cancel"}),e.jsx(y,{onClick:R,disabled:E||!i.description.trim(),children:E?"Saving...":"Save"})]})]})}),e.jsx(X,{open:!!f,onOpenChange:s=>!s&&v(null),children:e.jsxs(Y,{children:[e.jsxs(Z,{children:[e.jsxs(ee,{className:"flex items-center gap-2",children:[e.jsx(xe,{className:"h-5 w-5 text-destructive"}),"Delete Schedule"]}),e.jsx(se,{children:"This action cannot be undone. The scheduled task will be permanently removed."})]}),e.jsxs(te,{children:[e.jsx(ae,{disabled:N,children:"Cancel"}),e.jsx(ie,{onClick:B,disabled:N,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:N?"Deleting...":"Delete"})]})]})})]})}export{$e as SchedulesPage};
|
|
17
|
+
//# sourceMappingURL=Schedules-BQwE1hP5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Schedules-BQwE1hP5.js","sources":["../../node_modules/lucide-react/dist/esm/icons/calendar.js","../../node_modules/lucide-react/dist/esm/icons/timer.js","../../node_modules/lucide-react/dist/esm/icons/triangle-alert.js","../../src/pages/Schedules.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"4\", rx: \"2\", key: \"1hopcy\" }],\n [\"path\", { d: \"M3 10h18\", key: \"8toen8\" }]\n];\nconst Calendar = createLucideIcon(\"calendar\", __iconNode);\n\nexport { __iconNode, Calendar as default };\n//# sourceMappingURL=calendar.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"line\", { x1: \"10\", x2: \"14\", y1: \"2\", y2: \"2\", key: \"14vaq8\" }],\n [\"line\", { x1: \"12\", x2: \"15\", y1: \"14\", y2: \"11\", key: \"17fdiu\" }],\n [\"circle\", { cx: \"12\", cy: \"14\", r: \"8\", key: \"1e1u0o\" }]\n];\nconst Timer = createLucideIcon(\"timer\", __iconNode);\n\nexport { __iconNode, Timer as default };\n//# sourceMappingURL=timer.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\",\n key: \"wmoenq\"\n }\n ],\n [\"path\", { d: \"M12 9v4\", key: \"juzpu7\" }],\n [\"path\", { d: \"M12 17h.01\", key: \"p32p05\" }]\n];\nconst TriangleAlert = createLucideIcon(\"triangle-alert\", __iconNode);\n\nexport { __iconNode, TriangleAlert as default };\n//# sourceMappingURL=triangle-alert.js.map\n","import { useEffect, useState, useCallback } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport {\n Clock,\n Pencil,\n Trash2,\n Calendar,\n Timer,\n Sparkles,\n AlertTriangle,\n} from \"lucide-react\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \"@/components/ui/dialog\";\nimport {\n AlertDialog,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogAction,\n AlertDialogCancel,\n} from \"@/components/ui/alert-dialog\";\nimport { cn, formatDate, truncate } from \"@/lib/utils\";\nimport api, { type Schedule } from \"@/lib/api\";\n\nconst fadeUp = {\n hidden: { opacity: 0, y: 12 },\n visible: (i: number) => ({\n opacity: 1,\n y: 0,\n transition: { delay: i * 0.07, duration: 0.35, ease: \"easeOut\" as const },\n }),\n};\n\nfunction Skeleton({ className }: { className?: string }) {\n return (\n <div className={cn(\"animate-pulse rounded-lg bg-muted\", className)} />\n );\n}\n\nfunction humanizeCron(cron: string): string {\n const parts = cron.trim().split(/\\s+/);\n if (parts.length < 5) return cron;\n const [min, hour, dom, , dow] = parts;\n\n if (cron === \"* * * * *\") return \"Every minute\";\n if (min === \"0\" && hour === \"*\") return \"Every hour\";\n if (min === \"*/5\" && hour === \"*\") return \"Every 5 minutes\";\n if (min === \"*/10\" && hour === \"*\") return \"Every 10 minutes\";\n if (min === \"*/15\" && hour === \"*\") return \"Every 15 minutes\";\n if (min === \"*/30\" && hour === \"*\") return \"Every 30 minutes\";\n if (dom === \"*\" && dow === \"*\" && hour !== \"*\" && min !== \"*\")\n return `Daily at ${hour.padStart(2, \"0\")}:${min.padStart(2, \"0\")}`;\n if (dow === \"1-5\" && hour !== \"*\")\n return `Weekdays at ${hour.padStart(2, \"0\")}:${min.padStart(2, \"0\")}`;\n return cron;\n}\n\nfunction humanizeDelay(seconds: number): string {\n if (seconds < 60) return `${seconds}s delay`;\n if (seconds < 3600) return `${Math.round(seconds / 60)}m delay`;\n return `${(seconds / 3600).toFixed(1)}h delay`;\n}\n\ninterface EditForm {\n description: string;\n cron: string;\n delaySeconds: string;\n prompt: string;\n skillName: string;\n}\n\nexport function SchedulesPage() {\n const [schedules, setSchedules] = useState<Schedule[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(\"\");\n const [feedback, setFeedback] = useState<{ type: \"success\" | \"error\"; message: string } | null>(null);\n\n // Edit dialog state\n const [editOpen, setEditOpen] = useState(false);\n const [editId, setEditId] = useState<string | null>(null);\n const [editForm, setEditForm] = useState<EditForm>({\n description: \"\",\n cron: \"\",\n delaySeconds: \"\",\n prompt: \"\",\n skillName: \"\",\n });\n const [saving, setSaving] = useState(false);\n\n // Delete dialog state\n const [deleteId, setDeleteId] = useState<string | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const load = useCallback(() => {\n setLoading(true);\n api.schedules\n .list()\n .then((res) => {\n setSchedules(res.schedules);\n setError(\"\");\n })\n .catch((err: Error) => setError(err.message))\n .finally(() => setLoading(false));\n }, []);\n\n useEffect(() => {\n load();\n }, [load]);\n\n // Auto-dismiss feedback\n useEffect(() => {\n if (!feedback) return;\n const t = setTimeout(() => setFeedback(null), 3000);\n return () => clearTimeout(t);\n }, [feedback]);\n\n function openEdit(schedule: Schedule) {\n setEditId(schedule.id);\n setEditForm({\n description: schedule.description,\n cron: schedule.cron ?? \"\",\n delaySeconds: schedule.delaySeconds?.toString() ?? \"\",\n prompt: schedule.prompt ?? \"\",\n skillName: schedule.skillName ?? \"\",\n });\n setEditOpen(true);\n }\n\n async function handleSave() {\n if (!editId) return;\n setSaving(true);\n try {\n const payload: Partial<Schedule> = {\n description: editForm.description,\n };\n if (editForm.cron.trim()) payload.cron = editForm.cron.trim();\n if (editForm.delaySeconds.trim())\n payload.delaySeconds = Number(editForm.delaySeconds);\n if (editForm.prompt.trim()) payload.prompt = editForm.prompt.trim();\n if (editForm.skillName.trim())\n payload.skillName = editForm.skillName.trim();\n\n const res = await api.schedules.update(editId, payload);\n if (res.success) {\n setSchedules((prev) =>\n prev.map((s) => (s.id === editId ? { ...s, ...res.schedule } : s))\n );\n setFeedback({ type: \"success\", message: \"Schedule updated\" });\n setEditOpen(false);\n }\n } catch (err) {\n setFeedback({\n type: \"error\",\n message: err instanceof Error ? err.message : \"Update failed\",\n });\n } finally {\n setSaving(false);\n }\n }\n\n async function handleDelete() {\n if (!deleteId) return;\n setDeleting(true);\n try {\n const res = await api.schedules.delete(deleteId);\n if (res.success) {\n setSchedules((prev) => prev.filter((s) => s.id !== deleteId));\n setFeedback({ type: \"success\", message: \"Schedule deleted\" });\n }\n } catch (err) {\n setFeedback({\n type: \"error\",\n message: err instanceof Error ? err.message : \"Delete failed\",\n });\n } finally {\n setDeleting(false);\n setDeleteId(null);\n }\n }\n\n if (error && !schedules.length) {\n return (\n <div className=\"flex h-full items-center justify-center p-8\">\n <p className=\"text-sm text-destructive\">{error}</p>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"space-y-6 p-6 lg:p-8\">\n <div className=\"space-y-1\">\n <Skeleton className=\"h-8 w-40\" />\n <Skeleton className=\"h-4 w-56\" />\n </div>\n <div className=\"flex flex-col gap-4\">\n {Array.from({ length: 3 }).map((_, i) => (\n <Skeleton key={i} className=\"h-[140px]\" />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6 lg:p-8\">\n {/* Header */}\n <motion.div\n initial={{ opacity: 0, y: -8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3 }}\n >\n <h1 className=\"text-2xl font-bold tracking-tight\">Schedules</h1>\n <p className=\"text-sm text-muted-foreground\">\n Automated recurring tasks\n </p>\n </motion.div>\n\n {/* Feedback toast */}\n <AnimatePresence>\n {feedback && (\n <motion.div\n initial={{ opacity: 0, y: -8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n className={cn(\n \"rounded-lg border px-4 py-2.5 text-sm font-medium\",\n feedback.type === \"success\"\n ? \"border-emerald-500/30 bg-emerald-500/10 text-emerald-500\"\n : \"border-destructive/30 bg-destructive/10 text-destructive\"\n )}\n >\n {feedback.message}\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Empty state */}\n {schedules.length === 0 ? (\n <motion.div\n initial={{ opacity: 0, scale: 0.96 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.3 }}\n >\n <Card>\n <CardContent className=\"flex flex-col items-center justify-center py-16 text-center\">\n <Clock className=\"mb-4 h-10 w-10 text-muted-foreground/50\" />\n <p className=\"text-lg font-medium text-muted-foreground\">\n No scheduled tasks\n </p>\n <p className=\"mt-1 text-sm text-muted-foreground/70\">\n Schedules will appear here once configured via the API or CLI.\n </p>\n </CardContent>\n </Card>\n </motion.div>\n ) : (\n <div className=\"flex flex-col gap-4\">\n {schedules.map((schedule, idx) => (\n <motion.div\n key={schedule.id}\n custom={idx}\n variants={fadeUp}\n initial=\"hidden\"\n animate=\"visible\"\n >\n <Card>\n <CardHeader className=\"flex flex-row items-start justify-between gap-4 pb-3\">\n <div className=\"min-w-0 flex-1 space-y-1\">\n <CardTitle className=\"text-base\">\n {schedule.description}\n </CardTitle>\n <div className=\"flex flex-wrap items-center gap-2\">\n {schedule.cron && (\n <Badge variant=\"secondary\" className=\"gap-1\">\n <Calendar className=\"h-3 w-3\" />\n {humanizeCron(schedule.cron)}\n </Badge>\n )}\n {schedule.delaySeconds != null && (\n <Badge variant=\"secondary\" className=\"gap-1\">\n <Timer className=\"h-3 w-3\" />\n {humanizeDelay(schedule.delaySeconds)}\n </Badge>\n )}\n {schedule.skillName && (\n <Badge variant=\"default\" className=\"gap-1\">\n <Sparkles className=\"h-3 w-3\" />\n {schedule.skillName}\n </Badge>\n )}\n </div>\n </div>\n <div className=\"flex shrink-0 gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => openEdit(schedule)}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setDeleteId(schedule.id)}\n >\n <Trash2 className=\"h-4 w-4 text-destructive\" />\n </Button>\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"flex flex-col gap-2 text-sm\">\n {schedule.prompt && (\n <p className=\"text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Prompt: </span>\n {truncate(schedule.prompt, 100)}\n </p>\n )}\n <div className=\"flex flex-wrap gap-x-6 gap-y-1 text-xs text-muted-foreground\">\n {schedule.lastRun && (\n <span>\n Last run:{\" \"}\n <span className=\"font-medium tabular-nums text-foreground\">\n {formatDate(schedule.lastRun)}\n </span>\n </span>\n )}\n {schedule.nextRun && (\n <span>\n Next run:{\" \"}\n <span className=\"font-medium tabular-nums text-foreground\">\n {formatDate(schedule.nextRun)}\n </span>\n </span>\n )}\n </div>\n </div>\n </CardContent>\n </Card>\n </motion.div>\n ))}\n </div>\n )}\n\n {/* Edit Dialog */}\n <Dialog open={editOpen} onOpenChange={setEditOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Edit Schedule</DialogTitle>\n <DialogDescription>\n Update the schedule configuration.\n </DialogDescription>\n </DialogHeader>\n <div className=\"flex flex-col gap-4 py-2\">\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">Description</label>\n <Input\n value={editForm.description}\n onChange={(e) =>\n setEditForm((f) => ({ ...f, description: e.target.value }))\n }\n placeholder=\"Schedule description\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">Cron Expression</label>\n <Input\n value={editForm.cron}\n onChange={(e) =>\n setEditForm((f) => ({ ...f, cron: e.target.value }))\n }\n placeholder=\"*/30 * * * *\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">Delay (seconds)</label>\n <Input\n type=\"number\"\n value={editForm.delaySeconds}\n onChange={(e) =>\n setEditForm((f) => ({ ...f, delaySeconds: e.target.value }))\n }\n placeholder=\"3600\"\n />\n </div>\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">Prompt</label>\n <Input\n value={editForm.prompt}\n onChange={(e) =>\n setEditForm((f) => ({ ...f, prompt: e.target.value }))\n }\n placeholder=\"Optional prompt text\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">Skill Name</label>\n <Input\n value={editForm.skillName}\n onChange={(e) =>\n setEditForm((f) => ({ ...f, skillName: e.target.value }))\n }\n placeholder=\"Optional skill name\"\n />\n </div>\n </div>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setEditOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleSave} disabled={saving || !editForm.description.trim()}>\n {saving ? \"Saving...\" : \"Save\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Delete Confirmation */}\n <AlertDialog open={!!deleteId} onOpenChange={(open) => !open && setDeleteId(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle className=\"flex items-center gap-2\">\n <AlertTriangle className=\"h-5 w-5 text-destructive\" />\n Delete Schedule\n </AlertDialogTitle>\n <AlertDialogDescription>\n This action cannot be undone. The scheduled task will be permanently removed.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deleting}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={handleDelete}\n disabled={deleting}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {deleting ? \"Deleting...\" : \"Delete\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n"],"names":["__iconNode","Calendar","createLucideIcon","Timer","TriangleAlert","fadeUp","i","Skeleton","className","cn","humanizeCron","cron","parts","min","hour","dom","dow","humanizeDelay","seconds","SchedulesPage","schedules","setSchedules","useState","loading","setLoading","error","setError","feedback","setFeedback","editOpen","setEditOpen","editId","setEditId","editForm","setEditForm","saving","setSaving","deleteId","setDeleteId","deleting","setDeleting","load","useCallback","api","res","err","useEffect","t","openEdit","schedule","_a","handleSave","payload","prev","s","handleDelete","jsx","jsxs","_","motion","AnimatePresence","Card","CardContent","Clock","idx","CardHeader","CardTitle","Badge","Sparkles","Button","Pencil","Trash2","truncate","formatDate","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","Input","e","f","DialogFooter","AlertDialog","open","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertTriangle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction"],"mappings":"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","x_google_ignoreList":[0,1,2]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import{j as e,m as g,A as ie}from"./vendor-motion-Dwx3-JO5.js";import{r as a}from"./vendor-react-C7pctHW3.js";import{e as $,u as le,a as x,i as oe,n as y,o as V,j as me,p as ue,c as G}from"./index-BhxU0YlT.js";import{C as d,c,a as p}from"./card-DAYo4Zl5.js";import{I as r}from"./input-L1uz5xAQ.js";import{B as h}from"./button-TaFPR-zy.js";import{C as J}from"./circle-x-BmL20etA.js";import{S as xe}from"./sparkles-DLSJA4xU.js";import{L as w}from"./loader-circle-BTFgt3hG.js";import{C as he}from"./circle-check-DweDcOkA.js";import"./vendor-syntax-xZUI6Op9.js";import"./vendor-radix-3UdfCgs_.js";import"./index-CUT6Fr2C.js";/**
|
|
2
|
+
* @license lucide-react v0.511.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const ge=[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]],pe=$("lock",ge);/**
|
|
7
|
+
* @license lucide-react v0.511.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const fe=[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]],X=$("user",fe);function k({feedback:t}){return e.jsx(ie,{children:t&&e.jsx(g.div,{initial:{opacity:0,height:0},animate:{opacity:1,height:"auto"},exit:{opacity:0,height:0},className:"overflow-hidden",children:e.jsxs("div",{className:G("flex items-center gap-2 rounded-md px-3 py-2 text-sm",t.type==="success"?"bg-emerald-500/10 text-emerald-400":"bg-destructive/10 text-destructive"),children:[t.type==="success"?e.jsx(he,{className:"h-4 w-4 shrink-0"}):e.jsx(J,{className:"h-4 w-4 shrink-0"}),t.message]})})})}function C(){return e.jsxs(d,{className:"border-border/50 bg-card/60 backdrop-blur",children:[e.jsxs(p,{children:[e.jsx("div",{className:"h-5 w-32 animate-pulse rounded bg-muted"}),e.jsx("div",{className:"h-3.5 w-56 animate-pulse rounded bg-muted mt-1"})]}),e.jsx(c,{className:"space-y-4",children:[1,2,3].map(t=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("div",{className:"h-3.5 w-20 animate-pulse rounded bg-muted"}),e.jsx("div",{className:"h-9 w-full animate-pulse rounded-md bg-muted"})]},t))})]})}function S(){const[t,i]=a.useState(null),l=a.useCallback(o=>{i(o),setTimeout(()=>i(null),4e3)},[]);return[t,l]}const n={initial:{opacity:0,y:16},animate:{opacity:1,y:0},transition:{duration:.35}};function Be(){const[t,i]=a.useState(!0),[l,o]=a.useState(null),[K,Q]=a.useState(""),[P,U]=a.useState(""),[E,F]=a.useState(0),[B,I]=a.useState(!1),[W,D]=S(),[f,L]=a.useState(""),[j,z]=a.useState(""),[A,M]=a.useState(!1),[Y,b]=S(),[N,T]=a.useState(""),[m,_]=a.useState(""),[q,H]=a.useState(""),[R,O]=a.useState(!1),[Z,u]=S(),{theme:ee,setTheme:se}=le(),v=a.useCallback(async()=>{try{const s=await x.config.get();Q(s.identity),U(s.defaultProvider),F(s.tokenBudget),o(null)}catch(s){o(s instanceof Error?s.message:"Failed to load settings")}finally{i(!1)}},[]);a.useEffect(()=>{v()},[v]);const ae=async()=>{I(!0);try{await x.config.update({identity:K,defaultProvider:P,tokenBudget:E}),D({type:"success",message:"Settings saved"})}catch(s){D({type:"error",message:s instanceof Error?s.message:"Save failed"})}finally{I(!1)}},te=async()=>{if(!f||!j){b({type:"error",message:"Both fields are required"});return}M(!0);try{await x.auth.changeUsername(f,j),b({type:"success",message:"Username updated"}),L(""),z("")}catch(s){b({type:"error",message:s instanceof Error?s.message:"Update failed"})}finally{M(!1)}},re=async()=>{if(!N||!m){u({type:"error",message:"All fields are required"});return}if(m!==q){u({type:"error",message:"Passwords do not match"});return}O(!0);try{await x.auth.changePassword(N,m),u({type:"success",message:"Password updated"}),T(""),_(""),H("")}catch(s){u({type:"error",message:s instanceof Error?s.message:"Update failed"})}finally{O(!1)}},ne=[{value:"light",label:"Light",icon:V},{value:"dark",label:"Dark",icon:me},{value:"system",label:"System",icon:ue}];return t?e.jsxs("div",{className:"space-y-6 p-6",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"h-10 w-10 animate-pulse rounded-xl bg-muted"}),e.jsxs("div",{children:[e.jsx("div",{className:"h-6 w-24 animate-pulse rounded bg-muted"}),e.jsx("div",{className:"h-4 w-48 animate-pulse rounded bg-muted mt-1"})]})]}),e.jsx(C,{}),e.jsx(C,{}),e.jsx(C,{})]}):e.jsxs("div",{className:"space-y-6 p-6 max-w-3xl",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-[#00d4ff]/20 to-[#a78bfa]/20 ring-1 ring-[#00d4ff]/30",children:e.jsx(oe,{className:"h-5 w-5 text-[#00d4ff]"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold text-foreground",children:"Settings"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage agent identity, credentials, and preferences"})]})]}),l&&e.jsx(d,{className:"border-destructive/50 bg-destructive/5",children:e.jsxs(c,{className:"flex items-center gap-3 py-4",children:[e.jsx(J,{className:"h-5 w-5 text-destructive"}),e.jsx("p",{className:"text-sm text-destructive",children:l}),e.jsx(h,{variant:"outline",size:"sm",className:"ml-auto",onClick:v,children:"Retry"})]})}),e.jsx(g.div,{...n,transition:{...n.transition,delay:0},children:e.jsxs(d,{className:"border-border/50 bg-card/60 backdrop-blur",children:[e.jsxs(p,{className:"pb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(xe,{className:"h-4 w-4 text-[#a78bfa]"}),e.jsx("h2",{className:"text-lg font-medium text-foreground",children:"Defaults"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Default provider and daily token budget"})]}),e.jsxs(c,{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground",children:"Default Provider"}),e.jsx(r,{placeholder:"openai",value:P,onChange:s=>U(s.target.value),className:"bg-background/50"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground",children:"Daily Token Budget"}),e.jsx(r,{type:"number",min:0,placeholder:"100000",value:E||"",onChange:s=>F(Number(s.target.value)),className:"bg-background/50"})]})]}),e.jsx(k,{feedback:W}),e.jsx("div",{className:"pt-1",children:e.jsxs(h,{size:"sm",onClick:ae,disabled:B,className:"bg-gradient-to-r from-[#00d4ff] to-[#a78bfa] text-white hover:opacity-90 transition-opacity",children:[B&&e.jsx(w,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}),"Save"]})})]})]})}),e.jsx(y,{className:"bg-border/40"}),e.jsx(g.div,{...n,transition:{...n.transition,delay:.1},children:e.jsxs(d,{className:"border-border/50 bg-card/60 backdrop-blur",children:[e.jsxs(p,{className:"pb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(X,{className:"h-4 w-4 text-[#00d4ff]"}),e.jsx("h2",{className:"text-lg font-medium text-foreground",children:"Account"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Update your login credentials"})]}),e.jsxs(c,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(X,{className:"h-3.5 w-3.5 text-muted-foreground"}),e.jsx("span",{className:"text-sm font-medium text-foreground",children:"Change Username"})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground",children:"Current Password"}),e.jsx(r,{type:"password",placeholder:"Enter current password",value:f,onChange:s=>L(s.target.value),className:"bg-background/50"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground",children:"New Username"}),e.jsx(r,{placeholder:"Enter new username",value:j,onChange:s=>z(s.target.value),className:"bg-background/50"})]})]}),e.jsx(k,{feedback:Y}),e.jsxs(h,{size:"sm",variant:"outline",onClick:te,disabled:A,children:[A&&e.jsx(w,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}),"Update Username"]})]}),e.jsx(y,{className:"bg-border/30"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(pe,{className:"h-3.5 w-3.5 text-muted-foreground"}),e.jsx("span",{className:"text-sm font-medium text-foreground",children:"Change Password"})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground",children:"Current Password"}),e.jsx(r,{type:"password",placeholder:"Current",value:N,onChange:s=>T(s.target.value),className:"bg-background/50"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground",children:"New Password"}),e.jsx(r,{type:"password",placeholder:"New",value:m,onChange:s=>_(s.target.value),className:"bg-background/50"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground",children:"Confirm Password"}),e.jsx(r,{type:"password",placeholder:"Confirm",value:q,onChange:s=>H(s.target.value),className:"bg-background/50"})]})]}),e.jsx(k,{feedback:Z}),e.jsxs(h,{size:"sm",variant:"outline",onClick:re,disabled:R,children:[R&&e.jsx(w,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}),"Update Password"]})]})]})]})}),e.jsx(y,{className:"bg-border/40"}),e.jsx(g.div,{...n,transition:{...n.transition,delay:.2},children:e.jsxs(d,{className:"border-border/50 bg-card/60 backdrop-blur",children:[e.jsxs(p,{className:"pb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(V,{className:"h-4 w-4 text-[#00d4ff]"}),e.jsx("h2",{className:"text-lg font-medium text-foreground",children:"Appearance"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Choose your preferred theme"})]}),e.jsx(c,{children:e.jsx("div",{className:"flex gap-2",children:ne.map(({value:s,label:de,icon:ce})=>e.jsxs("button",{onClick:()=>se(s),className:G("flex items-center gap-2 rounded-lg border px-4 py-2.5 text-sm font-medium transition-all",ee===s?"border-[#00d4ff]/50 bg-[#00d4ff]/10 text-[#00d4ff] ring-1 ring-[#00d4ff]/20":"border-border/50 bg-background/50 text-muted-foreground hover:text-foreground hover:border-border"),children:[e.jsx(ce,{className:"h-4 w-4"}),de]},s))})})]})})]})}export{Be as SettingsPage};
|
|
12
|
+
//# sourceMappingURL=Settings-26SF-okR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Settings-26SF-okR.js","sources":["../../node_modules/lucide-react/dist/esm/icons/lock.js","../../node_modules/lucide-react/dist/esm/icons/user.js","../../src/pages/Settings.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"11\", x: \"3\", y: \"11\", rx: \"2\", ry: \"2\", key: \"1w4ew1\" }],\n [\"path\", { d: \"M7 11V7a5 5 0 0 1 10 0v4\", key: \"fwvmzm\" }]\n];\nconst Lock = createLucideIcon(\"lock\", __iconNode);\n\nexport { __iconNode, Lock as default };\n//# sourceMappingURL=lock.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\", key: \"975kel\" }],\n [\"circle\", { cx: \"12\", cy: \"7\", r: \"4\", key: \"17ys0d\" }]\n];\nconst User = createLucideIcon(\"user\", __iconNode);\n\nexport { __iconNode, User as default };\n//# sourceMappingURL=user.js.map\n","import { useCallback, useEffect, useState } from \"react\";\nimport {\n Settings,\n Loader2,\n CheckCircle2,\n XCircle,\n Sun,\n Moon,\n Monitor,\n User,\n Lock,\n Sparkles,\n} from \"lucide-react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport api, { type AppConfig } from \"@/lib/api\";\nimport { cn } from \"@/lib/utils\";\nimport { Card, CardHeader, CardContent } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { useThemeStore } from \"@/stores/theme\";\n\n/* ── Feedback toast inline ── */\ninterface Feedback {\n type: \"success\" | \"error\";\n message: string;\n}\n\nfunction FeedbackBanner({ feedback }: { feedback: Feedback | null }) {\n return (\n <AnimatePresence>\n {feedback && (\n <motion.div\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: \"auto\" }}\n exit={{ opacity: 0, height: 0 }}\n className=\"overflow-hidden\"\n >\n <div\n className={cn(\n \"flex items-center gap-2 rounded-md px-3 py-2 text-sm\",\n feedback.type === \"success\"\n ? \"bg-emerald-500/10 text-emerald-400\"\n : \"bg-destructive/10 text-destructive\"\n )}\n >\n {feedback.type === \"success\" ? (\n <CheckCircle2 className=\"h-4 w-4 shrink-0\" />\n ) : (\n <XCircle className=\"h-4 w-4 shrink-0\" />\n )}\n {feedback.message}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n\n/* ── Skeleton ── */\nfunction SectionSkeleton() {\n return (\n <Card className=\"border-border/50 bg-card/60 backdrop-blur\">\n <CardHeader>\n <div className=\"h-5 w-32 animate-pulse rounded bg-muted\" />\n <div className=\"h-3.5 w-56 animate-pulse rounded bg-muted mt-1\" />\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"space-y-1.5\">\n <div className=\"h-3.5 w-20 animate-pulse rounded bg-muted\" />\n <div className=\"h-9 w-full animate-pulse rounded-md bg-muted\" />\n </div>\n ))}\n </CardContent>\n </Card>\n );\n}\n\n/* ── Hook: auto-dismiss feedback ── */\nfunction useFeedback(): [Feedback | null, (f: Feedback) => void] {\n const [fb, setFb] = useState<Feedback | null>(null);\n const show = useCallback((f: Feedback) => {\n setFb(f);\n setTimeout(() => setFb(null), 4000);\n }, []);\n return [fb, show];\n}\n\n/* ── Fade wrapper ── */\nconst fadeIn = {\n initial: { opacity: 0, y: 16 },\n animate: { opacity: 1, y: 0 },\n transition: { duration: 0.35 },\n};\n\nexport function SettingsPage() {\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n /* Identity state */\n const [identity, setIdentity] = useState(\"\");\n const [defaultProvider, setDefaultProvider] = useState(\"\");\n const [tokenBudget, setTokenBudget] = useState(0);\n const [identitySaving, setIdentitySaving] = useState(false);\n const [identityFb, showIdentityFb] = useFeedback();\n\n /* Account state */\n const [unCurrent, setUnCurrent] = useState(\"\");\n const [newUsername, setNewUsername] = useState(\"\");\n const [unSaving, setUnSaving] = useState(false);\n const [unFb, showUnFb] = useFeedback();\n\n const [pwCurrent, setPwCurrent] = useState(\"\");\n const [newPassword, setNewPassword] = useState(\"\");\n const [confirmPassword, setConfirmPassword] = useState(\"\");\n const [pwSaving, setPwSaving] = useState(false);\n const [pwFb, showPwFb] = useFeedback();\n\n /* Theme */\n const { theme, setTheme } = useThemeStore();\n\n const fetchConfig = useCallback(async () => {\n try {\n const cfg: AppConfig = await api.config.get();\n setIdentity(cfg.identity);\n setDefaultProvider(cfg.defaultProvider);\n setTokenBudget(cfg.tokenBudget);\n setError(null);\n } catch (e) {\n setError(e instanceof Error ? e.message : \"Failed to load settings\");\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n fetchConfig();\n }, [fetchConfig]);\n\n /* Handlers */\n const saveIdentity = async () => {\n setIdentitySaving(true);\n try {\n await api.config.update({ identity, defaultProvider, tokenBudget });\n showIdentityFb({ type: \"success\", message: \"Settings saved\" });\n } catch (e) {\n showIdentityFb({\n type: \"error\",\n message: e instanceof Error ? e.message : \"Save failed\",\n });\n } finally {\n setIdentitySaving(false);\n }\n };\n\n const changeUsername = async () => {\n if (!unCurrent || !newUsername) {\n showUnFb({ type: \"error\", message: \"Both fields are required\" });\n return;\n }\n setUnSaving(true);\n try {\n await api.auth.changeUsername(unCurrent, newUsername);\n showUnFb({ type: \"success\", message: \"Username updated\" });\n setUnCurrent(\"\");\n setNewUsername(\"\");\n } catch (e) {\n showUnFb({\n type: \"error\",\n message: e instanceof Error ? e.message : \"Update failed\",\n });\n } finally {\n setUnSaving(false);\n }\n };\n\n const changePassword = async () => {\n if (!pwCurrent || !newPassword) {\n showPwFb({ type: \"error\", message: \"All fields are required\" });\n return;\n }\n if (newPassword !== confirmPassword) {\n showPwFb({ type: \"error\", message: \"Passwords do not match\" });\n return;\n }\n setPwSaving(true);\n try {\n await api.auth.changePassword(pwCurrent, newPassword);\n showPwFb({ type: \"success\", message: \"Password updated\" });\n setPwCurrent(\"\");\n setNewPassword(\"\");\n setConfirmPassword(\"\");\n } catch (e) {\n showPwFb({\n type: \"error\",\n message: e instanceof Error ? e.message : \"Update failed\",\n });\n } finally {\n setPwSaving(false);\n }\n };\n\n const themeOptions: { value: \"dark\" | \"light\" | \"system\"; label: string; icon: typeof Sun }[] = [\n { value: \"light\", label: \"Light\", icon: Sun },\n { value: \"dark\", label: \"Dark\", icon: Moon },\n { value: \"system\", label: \"System\", icon: Monitor },\n ];\n\n if (loading) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center gap-3\">\n <div className=\"h-10 w-10 animate-pulse rounded-xl bg-muted\" />\n <div>\n <div className=\"h-6 w-24 animate-pulse rounded bg-muted\" />\n <div className=\"h-4 w-48 animate-pulse rounded bg-muted mt-1\" />\n </div>\n </div>\n <SectionSkeleton />\n <SectionSkeleton />\n <SectionSkeleton />\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6 max-w-3xl\">\n {/* Header */}\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-[#00d4ff]/20 to-[#a78bfa]/20 ring-1 ring-[#00d4ff]/30\">\n <Settings className=\"h-5 w-5 text-[#00d4ff]\" />\n </div>\n <div>\n <h1 className=\"text-2xl font-semibold text-foreground\">Settings</h1>\n <p className=\"text-sm text-muted-foreground\">\n Manage agent identity, credentials, and preferences\n </p>\n </div>\n </div>\n\n {error && (\n <Card className=\"border-destructive/50 bg-destructive/5\">\n <CardContent className=\"flex items-center gap-3 py-4\">\n <XCircle className=\"h-5 w-5 text-destructive\" />\n <p className=\"text-sm text-destructive\">{error}</p>\n <Button variant=\"outline\" size=\"sm\" className=\"ml-auto\" onClick={fetchConfig}>\n Retry\n </Button>\n </CardContent>\n </Card>\n )}\n\n {/* ── Defaults Section ── */}\n <motion.div {...fadeIn} transition={{ ...fadeIn.transition, delay: 0 }}>\n <Card className=\"border-border/50 bg-card/60 backdrop-blur\">\n <CardHeader className=\"pb-4\">\n <div className=\"flex items-center gap-2\">\n <Sparkles className=\"h-4 w-4 text-[#a78bfa]\" />\n <h2 className=\"text-lg font-medium text-foreground\">Defaults</h2>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n Default provider and daily token budget\n </p>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n Default Provider\n </label>\n <Input\n placeholder=\"openai\"\n value={defaultProvider}\n onChange={(e) => setDefaultProvider(e.target.value)}\n className=\"bg-background/50\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n Daily Token Budget\n </label>\n <Input\n type=\"number\"\n min={0}\n placeholder=\"100000\"\n value={tokenBudget || \"\"}\n onChange={(e) => setTokenBudget(Number(e.target.value))}\n className=\"bg-background/50\"\n />\n </div>\n </div>\n\n <FeedbackBanner feedback={identityFb} />\n\n <div className=\"pt-1\">\n <Button\n size=\"sm\"\n onClick={saveIdentity}\n disabled={identitySaving}\n className=\"bg-gradient-to-r from-[#00d4ff] to-[#a78bfa] text-white hover:opacity-90 transition-opacity\"\n >\n {identitySaving && (\n <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" />\n )}\n Save\n </Button>\n </div>\n </CardContent>\n </Card>\n </motion.div>\n\n <Separator className=\"bg-border/40\" />\n\n {/* ── Account Section ── */}\n <motion.div {...fadeIn} transition={{ ...fadeIn.transition, delay: 0.1 }}>\n <Card className=\"border-border/50 bg-card/60 backdrop-blur\">\n <CardHeader className=\"pb-4\">\n <div className=\"flex items-center gap-2\">\n <User className=\"h-4 w-4 text-[#00d4ff]\" />\n <h2 className=\"text-lg font-medium text-foreground\">Account</h2>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n Update your login credentials\n </p>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n {/* Change Username */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <User className=\"h-3.5 w-3.5 text-muted-foreground\" />\n <span className=\"text-sm font-medium text-foreground\">\n Change Username\n </span>\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n Current Password\n </label>\n <Input\n type=\"password\"\n placeholder=\"Enter current password\"\n value={unCurrent}\n onChange={(e) => setUnCurrent(e.target.value)}\n className=\"bg-background/50\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n New Username\n </label>\n <Input\n placeholder=\"Enter new username\"\n value={newUsername}\n onChange={(e) => setNewUsername(e.target.value)}\n className=\"bg-background/50\"\n />\n </div>\n </div>\n <FeedbackBanner feedback={unFb} />\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={changeUsername}\n disabled={unSaving}\n >\n {unSaving && <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" />}\n Update Username\n </Button>\n </div>\n\n <Separator className=\"bg-border/30\" />\n\n {/* Change Password */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Lock className=\"h-3.5 w-3.5 text-muted-foreground\" />\n <span className=\"text-sm font-medium text-foreground\">\n Change Password\n </span>\n </div>\n <div className=\"grid gap-3 sm:grid-cols-3\">\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n Current Password\n </label>\n <Input\n type=\"password\"\n placeholder=\"Current\"\n value={pwCurrent}\n onChange={(e) => setPwCurrent(e.target.value)}\n className=\"bg-background/50\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n New Password\n </label>\n <Input\n type=\"password\"\n placeholder=\"New\"\n value={newPassword}\n onChange={(e) => setNewPassword(e.target.value)}\n className=\"bg-background/50\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n Confirm Password\n </label>\n <Input\n type=\"password\"\n placeholder=\"Confirm\"\n value={confirmPassword}\n onChange={(e) => setConfirmPassword(e.target.value)}\n className=\"bg-background/50\"\n />\n </div>\n </div>\n <FeedbackBanner feedback={pwFb} />\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={changePassword}\n disabled={pwSaving}\n >\n {pwSaving && <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" />}\n Update Password\n </Button>\n </div>\n </CardContent>\n </Card>\n </motion.div>\n\n <Separator className=\"bg-border/40\" />\n\n {/* ── Appearance Section ── */}\n <motion.div {...fadeIn} transition={{ ...fadeIn.transition, delay: 0.2 }}>\n <Card className=\"border-border/50 bg-card/60 backdrop-blur\">\n <CardHeader className=\"pb-4\">\n <div className=\"flex items-center gap-2\">\n <Sun className=\"h-4 w-4 text-[#00d4ff]\" />\n <h2 className=\"text-lg font-medium text-foreground\">Appearance</h2>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n Choose your preferred theme\n </p>\n </CardHeader>\n <CardContent>\n <div className=\"flex gap-2\">\n {themeOptions.map(({ value, label, icon: Icon }) => (\n <button\n key={value}\n onClick={() => setTheme(value)}\n className={cn(\n \"flex items-center gap-2 rounded-lg border px-4 py-2.5 text-sm font-medium transition-all\",\n theme === value\n ? \"border-[#00d4ff]/50 bg-[#00d4ff]/10 text-[#00d4ff] ring-1 ring-[#00d4ff]/20\"\n : \"border-border/50 bg-background/50 text-muted-foreground hover:text-foreground hover:border-border\"\n )}\n >\n <Icon className=\"h-4 w-4\" />\n {label}\n </button>\n ))}\n </div>\n </CardContent>\n </Card>\n </motion.div>\n </div>\n );\n}\n"],"names":["__iconNode","Lock","createLucideIcon","User","FeedbackBanner","feedback","jsx","AnimatePresence","motion","jsxs","cn","CheckCircle2","XCircle","SectionSkeleton","Card","CardHeader","CardContent","i","useFeedback","fb","setFb","useState","show","useCallback","f","fadeIn","SettingsPage","loading","setLoading","error","setError","identity","setIdentity","defaultProvider","setDefaultProvider","tokenBudget","setTokenBudget","identitySaving","setIdentitySaving","identityFb","showIdentityFb","unCurrent","setUnCurrent","newUsername","setNewUsername","unSaving","setUnSaving","unFb","showUnFb","pwCurrent","setPwCurrent","newPassword","setNewPassword","confirmPassword","setConfirmPassword","pwSaving","setPwSaving","pwFb","showPwFb","theme","setTheme","useThemeStore","fetchConfig","cfg","api","e","useEffect","saveIdentity","changeUsername","changePassword","themeOptions","Sun","Moon","Monitor","Settings","Button","Sparkles","Input","Loader2","Separator","value","label","Icon"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{j as e,m as c,A}from"./vendor-motion-Dwx3-JO5.js";import{r as i}from"./vendor-react-C7pctHW3.js";import{C as h,c as u}from"./card-DAYo4Zl5.js";import{B as j}from"./button-TaFPR-zy.js";import{I as F}from"./input-L1uz5xAQ.js";import{B as P}from"./badge-DfDJNUtd.js";import{A as B,h as z,T as M,a as U,b as $,c as O,d as _,e as R,f as V,g as q}from"./alert-dialog-CW-j2nG4.js";import{e as H,a as d,c as C}from"./index-BhxU0YlT.js";import{S as X}from"./sparkles-DLSJA4xU.js";import{D as G}from"./download-_QBatDio.js";import{L as b}from"./loader-circle-BTFgt3hG.js";import{F as J}from"./folder-open-C-OiZn9P.js";import{a as K,P as Q}from"./power-DVIqVIMj.js";import{C as W}from"./circle-check-DweDcOkA.js";import{C as Y}from"./circle-x-BmL20etA.js";import"./vendor-radix-3UdfCgs_.js";import"./index-CUT6Fr2C.js";import"./vendor-syntax-xZUI6Op9.js";/**
|
|
2
|
+
* @license lucide-react v0.511.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const Z=[["path",{d:"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",key:"1a0edw"}],["path",{d:"M12 22V12",key:"d0xqtd"}],["polyline",{points:"3.29 7 12 12 20.71 7",key:"ousv84"}],["path",{d:"m7.5 4.27 9 5.15",key:"1c824w"}]],ee=H("package",Z),se={hidden:{opacity:0,y:12},visible:r=>({opacity:1,y:0,transition:{delay:r*.06,duration:.35,ease:"easeOut"}}),exit:{opacity:0,y:-8,transition:{duration:.2}}},ae={visible:{transition:{staggerChildren:.06}}};function te({toasts:r}){return e.jsx("div",{className:"fixed bottom-6 right-6 z-50 flex flex-col gap-2",children:e.jsx(A,{children:r.map(l=>e.jsxs(c.div,{initial:{opacity:0,x:40},animate:{opacity:1,x:0},exit:{opacity:0,x:40},className:C("flex items-center gap-2 rounded-lg border px-4 py-3 text-sm shadow-lg backdrop-blur-sm",l.type==="success"?"border-emerald-500/30 bg-emerald-500/10 text-emerald-400":"border-destructive/30 bg-destructive/10 text-destructive"),children:[l.type==="success"?e.jsx(W,{className:"h-4 w-4"}):e.jsx(Y,{className:"h-4 w-4"}),l.message]},l.id))})})}function n({className:r}){return e.jsx("div",{className:C("animate-pulse rounded-lg bg-muted",r)})}function ie(){return e.jsx(h,{children:e.jsxs(u,{className:"p-5 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(n,{className:"h-5 w-32"}),e.jsx(n,{className:"h-5 w-16 rounded-md"})]}),e.jsx(n,{className:"h-4 w-full"}),e.jsx(n,{className:"h-3 w-48"}),e.jsxs("div",{className:"flex gap-2 pt-1",children:[e.jsx(n,{className:"h-8 w-24"}),e.jsx(n,{className:"h-8 w-20"})]})]})})}function be(){const[r,l]=i.useState([]),[D,S]=i.useState(!0),[m,y]=i.useState(""),[f,v]=i.useState(!1),[g,x]=i.useState({}),[k,N]=i.useState([]),t=i.useCallback((s,a)=>{const w=Date.now();N(p=>[...p,{id:w,type:s,message:a}]),setTimeout(()=>{N(p=>p.filter(L=>L.id!==w))},3500)},[]),o=i.useCallback(async()=>{try{const s=await d.skills.list();l(s.skills)}catch(s){t("error",s instanceof Error?s.message:"Failed to load skills")}finally{S(!1)}},[t]);i.useEffect(()=>{o()},[o]);const I=async()=>{if(m.trim()){v(!0);try{const s=await d.skills.install(m.trim());t("success",`Installed "${s.name}" successfully`),y(""),await o()}catch(s){t("error",s instanceof Error?s.message:"Installation failed")}finally{v(!1)}}},T=async s=>{x(a=>({...a,[s.name]:!0}));try{s.active?(await d.skills.deactivate(s.name),t("success",`Deactivated "${s.name}"`)):(await d.skills.activate(s.name),t("success",`Activated "${s.name}"`)),await o()}catch(a){t("error",a instanceof Error?a.message:"Toggle failed")}finally{x(a=>({...a,[s.name]:!1}))}},E=async s=>{x(a=>({...a,[s]:!0}));try{await d.skills.delete(s),t("success",`Deleted "${s}"`),await o()}catch(a){t("error",a instanceof Error?a.message:"Delete failed")}finally{x(a=>({...a,[s]:!1}))}};return e.jsxs("div",{className:"space-y-6 p-6",children:[e.jsx(c.div,{initial:{opacity:0,y:-8},animate:{opacity:1,y:0},transition:{duration:.3},children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-10 w-10 items-center justify-center rounded-lg bg-[#00d4ff]/10",children:e.jsx(X,{className:"h-5 w-5 text-[#00d4ff]"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold text-foreground",children:"Skills"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Extend Mercury with installable capabilities"})]})]})}),e.jsx(c.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},transition:{delay:.1,duration:.3},children:e.jsx(h,{children:e.jsxs(u,{className:"p-5",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(G,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-sm font-medium text-foreground",children:"Install a Skill"})]}),e.jsxs("form",{onSubmit:s=>{s.preventDefault(),I()},className:"flex gap-3",children:[e.jsx(F,{placeholder:"https://github.com/user/skill-package",value:m,onChange:s=>y(s.target.value),disabled:f,className:"flex-1"}),e.jsx(j,{type:"submit",disabled:f||!m.trim(),children:f?e.jsxs(e.Fragment,{children:[e.jsx(b,{className:"h-4 w-4 animate-spin"}),"Installing"]}):"Install"})]})]})})}),D?e.jsx("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-3",children:Array.from({length:3}).map((s,a)=>e.jsx(ie,{},a))}):r.length===0?e.jsx(c.div,{initial:{opacity:0},animate:{opacity:1},transition:{delay:.2},children:e.jsx(h,{children:e.jsxs(u,{className:"flex flex-col items-center justify-center py-16 text-center",children:[e.jsx("div",{className:"flex h-14 w-14 items-center justify-center rounded-full bg-muted mb-4",children:e.jsx(ee,{className:"h-7 w-7 text-muted-foreground"})}),e.jsx("h3",{className:"text-base font-medium text-foreground mb-1",children:"No skills installed"}),e.jsx("p",{className:"text-sm text-muted-foreground max-w-sm",children:"Install skills from a URL above to extend Mercury's capabilities with new tools, workflows, and integrations."})]})})}):e.jsx(c.div,{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-3",variants:ae,initial:"hidden",animate:"visible",children:e.jsx(A,{mode:"popLayout",children:r.map((s,a)=>e.jsx(c.div,{custom:a,variants:se,initial:"hidden",animate:"visible",exit:"exit",layout:!0,children:e.jsx(h,{className:"h-full",children:e.jsxs(u,{className:"p-5 flex flex-col gap-3 h-full",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsx("h3",{className:"text-sm font-semibold text-foreground leading-tight",children:s.name}),e.jsx(P,{variant:s.active?"success":"secondary",children:s.active?"Active":"Inactive"})]}),s.description&&e.jsx("p",{className:"text-sm text-muted-foreground leading-relaxed",children:s.description}),e.jsxs("div",{className:"flex items-center gap-1.5 mt-auto",children:[e.jsx(J,{className:"h-3 w-3 text-muted-foreground/60 shrink-0"}),e.jsx("span",{className:"text-xs text-muted-foreground/60 truncate font-mono",children:s.path})]}),e.jsxs("div",{className:"flex items-center gap-2 pt-1 border-t border-border",children:[e.jsx(j,{size:"sm",variant:s.active?"outline":"default",disabled:!!g[s.name],onClick:()=>T(s),className:"flex-1",children:g[s.name]?e.jsx(b,{className:"h-3.5 w-3.5 animate-spin"}):s.active?e.jsxs(e.Fragment,{children:[e.jsx(K,{className:"h-3.5 w-3.5"}),"Deactivate"]}):e.jsxs(e.Fragment,{children:[e.jsx(Q,{className:"h-3.5 w-3.5"}),"Activate"]})}),e.jsxs(B,{children:[e.jsx(z,{asChild:!0,children:e.jsx(j,{size:"sm",variant:"ghost",disabled:!!g[s.name],className:"text-muted-foreground hover:text-destructive",children:e.jsx(M,{className:"h-3.5 w-3.5"})})}),e.jsxs(U,{children:[e.jsxs($,{children:[e.jsx(O,{children:"Delete Skill"}),e.jsxs(_,{children:["Are you sure you want to delete “",s.name,"”? This will remove the skill and all its data permanently."]})]}),e.jsxs(R,{children:[e.jsx(V,{children:"Cancel"}),e.jsx(q,{onClick:()=>E(s.name),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"Delete"})]})]})]})]})]})})},s.name))})}),e.jsx(te,{toasts:k})]})}export{be as SkillsPage};
|
|
7
|
+
//# sourceMappingURL=Skills-DANyYK_d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skills-DANyYK_d.js","sources":["../../node_modules/lucide-react/dist/esm/icons/package.js","../../src/pages/Skills.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z\",\n key: \"1a0edw\"\n }\n ],\n [\"path\", { d: \"M12 22V12\", key: \"d0xqtd\" }],\n [\"polyline\", { points: \"3.29 7 12 12 20.71 7\", key: \"ousv84\" }],\n [\"path\", { d: \"m7.5 4.27 9 5.15\", key: \"1c824w\" }]\n];\nconst Package = createLucideIcon(\"package\", __iconNode);\n\nexport { __iconNode, Package as default };\n//# sourceMappingURL=package.js.map\n","import { useEffect, useState, useCallback } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport {\n Sparkles,\n Download,\n Loader2,\n Trash2,\n Power,\n PowerOff,\n Package,\n FolderOpen,\n CheckCircle2,\n XCircle,\n} from \"lucide-react\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Badge } from \"@/components/ui/badge\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\";\nimport { cn } from \"@/lib/utils\";\nimport api, { type Skill } from \"@/lib/api\";\n\n/* ── Animations ─────────────────────────────────────────────── */\n\nconst fadeUp = {\n hidden: { opacity: 0, y: 12 },\n visible: (i: number) => ({\n opacity: 1,\n y: 0,\n transition: { delay: i * 0.06, duration: 0.35, ease: \"easeOut\" as const },\n }),\n exit: { opacity: 0, y: -8, transition: { duration: 0.2 } },\n};\n\nconst stagger = {\n visible: { transition: { staggerChildren: 0.06 } },\n};\n\n/* ── Toast-style Feedback ───────────────────────────────────── */\n\ninterface Toast {\n id: number;\n type: \"success\" | \"error\";\n message: string;\n}\n\nfunction ToastBar({ toasts }: { toasts: Toast[] }) {\n return (\n <div className=\"fixed bottom-6 right-6 z-50 flex flex-col gap-2\">\n <AnimatePresence>\n {toasts.map((t) => (\n <motion.div\n key={t.id}\n initial={{ opacity: 0, x: 40 }}\n animate={{ opacity: 1, x: 0 }}\n exit={{ opacity: 0, x: 40 }}\n className={cn(\n \"flex items-center gap-2 rounded-lg border px-4 py-3 text-sm shadow-lg backdrop-blur-sm\",\n t.type === \"success\"\n ? \"border-emerald-500/30 bg-emerald-500/10 text-emerald-400\"\n : \"border-destructive/30 bg-destructive/10 text-destructive\"\n )}\n >\n {t.type === \"success\" ? (\n <CheckCircle2 className=\"h-4 w-4\" />\n ) : (\n <XCircle className=\"h-4 w-4\" />\n )}\n {t.message}\n </motion.div>\n ))}\n </AnimatePresence>\n </div>\n );\n}\n\n/* ── Skeleton ───────────────────────────────────────────────── */\n\nfunction Skeleton({ className }: { className?: string }) {\n return (\n <div className={cn(\"animate-pulse rounded-lg bg-muted\", className)} />\n );\n}\n\nfunction SkillCardSkeleton() {\n return (\n <Card>\n <CardContent className=\"p-5 space-y-3\">\n <div className=\"flex items-center justify-between\">\n <Skeleton className=\"h-5 w-32\" />\n <Skeleton className=\"h-5 w-16 rounded-md\" />\n </div>\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-3 w-48\" />\n <div className=\"flex gap-2 pt-1\">\n <Skeleton className=\"h-8 w-24\" />\n <Skeleton className=\"h-8 w-20\" />\n </div>\n </CardContent>\n </Card>\n );\n}\n\n/* ── Main Page ──────────────────────────────────────────────── */\n\nexport function SkillsPage() {\n const [skills, setSkills] = useState<Skill[]>([]);\n const [loading, setLoading] = useState(true);\n const [installUrl, setInstallUrl] = useState(\"\");\n const [installing, setInstalling] = useState(false);\n const [actionLoading, setActionLoading] = useState<Record<string, boolean>>({});\n const [toasts, setToasts] = useState<Toast[]>([]);\n\n const toast = useCallback((type: \"success\" | \"error\", message: string) => {\n const id = Date.now();\n setToasts((prev) => [...prev, { id, type, message }]);\n setTimeout(() => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, 3500);\n }, []);\n\n const fetchSkills = useCallback(async () => {\n try {\n const res = await api.skills.list();\n setSkills(res.skills);\n } catch (err: unknown) {\n toast(\"error\", err instanceof Error ? err.message : \"Failed to load skills\");\n } finally {\n setLoading(false);\n }\n }, [toast]);\n\n useEffect(() => {\n fetchSkills();\n }, [fetchSkills]);\n\n const handleInstall = async () => {\n if (!installUrl.trim()) return;\n setInstalling(true);\n try {\n const res = await api.skills.install(installUrl.trim());\n toast(\"success\", `Installed \"${res.name}\" successfully`);\n setInstallUrl(\"\");\n await fetchSkills();\n } catch (err: unknown) {\n toast(\"error\", err instanceof Error ? err.message : \"Installation failed\");\n } finally {\n setInstalling(false);\n }\n };\n\n const handleToggle = async (skill: Skill) => {\n setActionLoading((prev) => ({ ...prev, [skill.name]: true }));\n try {\n if (skill.active) {\n await api.skills.deactivate(skill.name);\n toast(\"success\", `Deactivated \"${skill.name}\"`);\n } else {\n await api.skills.activate(skill.name);\n toast(\"success\", `Activated \"${skill.name}\"`);\n }\n await fetchSkills();\n } catch (err: unknown) {\n toast(\"error\", err instanceof Error ? err.message : \"Toggle failed\");\n } finally {\n setActionLoading((prev) => ({ ...prev, [skill.name]: false }));\n }\n };\n\n const handleDelete = async (name: string) => {\n setActionLoading((prev) => ({ ...prev, [name]: true }));\n try {\n await api.skills.delete(name);\n toast(\"success\", `Deleted \"${name}\"`);\n await fetchSkills();\n } catch (err: unknown) {\n toast(\"error\", err instanceof Error ? err.message : \"Delete failed\");\n } finally {\n setActionLoading((prev) => ({ ...prev, [name]: false }));\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <motion.div\n initial={{ opacity: 0, y: -8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3 }}\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-[#00d4ff]/10\">\n <Sparkles className=\"h-5 w-5 text-[#00d4ff]\" />\n </div>\n <div>\n <h1 className=\"text-2xl font-semibold text-foreground\">Skills</h1>\n <p className=\"text-sm text-muted-foreground\">\n Extend Mercury with installable capabilities\n </p>\n </div>\n </div>\n </motion.div>\n\n {/* Install Section */}\n <motion.div\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: 0.1, duration: 0.3 }}\n >\n <Card>\n <CardContent className=\"p-5\">\n <div className=\"flex items-center gap-2 mb-3\">\n <Download className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-sm font-medium text-foreground\">\n Install a Skill\n </span>\n </div>\n <form\n onSubmit={(e) => {\n e.preventDefault();\n handleInstall();\n }}\n className=\"flex gap-3\"\n >\n <Input\n placeholder=\"https://github.com/user/skill-package\"\n value={installUrl}\n onChange={(e) => setInstallUrl(e.target.value)}\n disabled={installing}\n className=\"flex-1\"\n />\n <Button type=\"submit\" disabled={installing || !installUrl.trim()}>\n {installing ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Installing\n </>\n ) : (\n \"Install\"\n )}\n </Button>\n </form>\n </CardContent>\n </Card>\n </motion.div>\n\n {/* Skills List */}\n {loading ? (\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {Array.from({ length: 3 }).map((_, i) => (\n <SkillCardSkeleton key={i} />\n ))}\n </div>\n ) : skills.length === 0 ? (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: 0.2 }}\n >\n <Card>\n <CardContent className=\"flex flex-col items-center justify-center py-16 text-center\">\n <div className=\"flex h-14 w-14 items-center justify-center rounded-full bg-muted mb-4\">\n <Package className=\"h-7 w-7 text-muted-foreground\" />\n </div>\n <h3 className=\"text-base font-medium text-foreground mb-1\">\n No skills installed\n </h3>\n <p className=\"text-sm text-muted-foreground max-w-sm\">\n Install skills from a URL above to extend Mercury's capabilities\n with new tools, workflows, and integrations.\n </p>\n </CardContent>\n </Card>\n </motion.div>\n ) : (\n <motion.div\n className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\"\n variants={stagger}\n initial=\"hidden\"\n animate=\"visible\"\n >\n <AnimatePresence mode=\"popLayout\">\n {skills.map((skill, i) => (\n <motion.div\n key={skill.name}\n custom={i}\n variants={fadeUp}\n initial=\"hidden\"\n animate=\"visible\"\n exit=\"exit\"\n layout\n >\n <Card className=\"h-full\">\n <CardContent className=\"p-5 flex flex-col gap-3 h-full\">\n {/* Name + Status */}\n <div className=\"flex items-start justify-between gap-3\">\n <h3 className=\"text-sm font-semibold text-foreground leading-tight\">\n {skill.name}\n </h3>\n <Badge variant={skill.active ? \"success\" : \"secondary\"}>\n {skill.active ? \"Active\" : \"Inactive\"}\n </Badge>\n </div>\n\n {/* Description */}\n {skill.description && (\n <p className=\"text-sm text-muted-foreground leading-relaxed\">\n {skill.description}\n </p>\n )}\n\n {/* Path */}\n <div className=\"flex items-center gap-1.5 mt-auto\">\n <FolderOpen className=\"h-3 w-3 text-muted-foreground/60 shrink-0\" />\n <span className=\"text-xs text-muted-foreground/60 truncate font-mono\">\n {skill.path}\n </span>\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center gap-2 pt-1 border-t border-border\">\n <Button\n size=\"sm\"\n variant={skill.active ? \"outline\" : \"default\"}\n disabled={!!actionLoading[skill.name]}\n onClick={() => handleToggle(skill)}\n className=\"flex-1\"\n >\n {actionLoading[skill.name] ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : skill.active ? (\n <>\n <PowerOff className=\"h-3.5 w-3.5\" />\n Deactivate\n </>\n ) : (\n <>\n <Power className=\"h-3.5 w-3.5\" />\n Activate\n </>\n )}\n </Button>\n\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n disabled={!!actionLoading[skill.name]}\n className=\"text-muted-foreground hover:text-destructive\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete Skill</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to delete “{skill.name}”?\n This will remove the skill and all its data permanently.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => handleDelete(skill.name)}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </CardContent>\n </Card>\n </motion.div>\n ))}\n </AnimatePresence>\n </motion.div>\n )}\n\n <ToastBar toasts={toasts} />\n </div>\n );\n}\n"],"names":["__iconNode","Package","createLucideIcon","fadeUp","i","stagger","ToastBar","toasts","jsx","AnimatePresence","t","jsxs","motion","cn","CheckCircle2","XCircle","Skeleton","className","SkillCardSkeleton","Card","CardContent","SkillsPage","skills","setSkills","useState","loading","setLoading","installUrl","setInstallUrl","installing","setInstalling","actionLoading","setActionLoading","setToasts","toast","useCallback","type","message","id","prev","fetchSkills","res","api","err","useEffect","handleInstall","handleToggle","skill","handleDelete","name","Sparkles","Download","e","Input","Button","Fragment","Loader2","_","Badge","FolderOpen","PowerOff","Power","AlertDialog","AlertDialogTrigger","Trash2","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{j as e}from"./vendor-motion-Dwx3-JO5.js";import{C as s,c as t}from"./card-DAYo4Zl5.js";import{e as a}from"./index-BhxU0YlT.js";import"./vendor-react-C7pctHW3.js";import"./vendor-syntax-xZUI6Op9.js";import"./vendor-radix-3UdfCgs_.js";/**
|
|
2
|
+
* @license lucide-react v0.511.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const r=[["path",{d:"M21 10.5V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h12.5",key:"1uzm8b"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]],o=a("square-check-big",r);function l(){return e.jsxs("div",{className:"space-y-4 p-6",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(o,{className:"h-6 w-6 text-muted-foreground"}),e.jsx("h1",{className:"text-2xl font-semibold text-foreground",children:"Tasks"})]}),e.jsx(s,{children:e.jsx(t,{className:"py-8 text-center text-muted-foreground",children:"Task management coming soon."})})]})}export{l as TasksPage};
|
|
7
|
+
//# sourceMappingURL=Tasks-DbwRozzx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tasks-DbwRozzx.js","sources":["../../node_modules/lucide-react/dist/esm/icons/square-check-big.js","../../src/pages/Tasks.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 10.5V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h12.5\", key: \"1uzm8b\" }],\n [\"path\", { d: \"m9 11 3 3L22 4\", key: \"1pflzl\" }]\n];\nconst SquareCheckBig = createLucideIcon(\"square-check-big\", __iconNode);\n\nexport { __iconNode, SquareCheckBig as default };\n//# sourceMappingURL=square-check-big.js.map\n","import { CheckSquare } from \"lucide-react\";\nimport { Card, CardContent } from \"@/components/ui/card\";\n\nexport function TasksPage() {\n return (\n <div className=\"space-y-4 p-6\">\n <div className=\"flex items-center gap-2\">\n <CheckSquare className=\"h-6 w-6 text-muted-foreground\" />\n <h1 className=\"text-2xl font-semibold text-foreground\">Tasks</h1>\n </div>\n <Card>\n <CardContent className=\"py-8 text-center text-muted-foreground\">\n Task management coming soon.\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"names":["__iconNode","SquareCheckBig","createLucideIcon","TasksPage","jsxs","jsx","CheckSquare","Card","CardContent"],"mappings":"gPAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAa,CACjB,CAAC,OAAQ,CAAE,EAAG,iEAAkE,IAAK,QAAQ,CAAE,EAC/F,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAQ,CAAE,CACjD,EACMC,EAAiBC,EAAiB,mBAAoBF,CAAU,ECV/D,SAASG,GAAY,CAC1B,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,gBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAC,EAAAA,IAACC,EAAA,CAAY,UAAU,+BAAA,CAAgC,EACvDD,EAAAA,IAAC,KAAA,CAAG,UAAU,yCAAyC,SAAA,OAAA,CAAK,CAAA,EAC9D,QACCE,EAAA,CACC,SAAAF,MAACG,GAAY,UAAU,yCAAyC,wCAEhE,CAAA,CACF,CAAA,EACF,CAEJ","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import{j as e,m as r}from"./vendor-motion-Dwx3-JO5.js";import{r as f}from"./vendor-react-C7pctHW3.js";import{C as i,a as l,b as n,c as d}from"./card-DAYo4Zl5.js";import{P as O}from"./progress-DMwOdxli.js";import{B as p}from"./badge-DfDJNUtd.js";import{e as y,a as P,b as c,m as E,h as U,c as R,M as S}from"./index-BhxU0YlT.js";import{Z as _}from"./zap-C-0oH5gt.js";import{A as g}from"./activity-CIP1IzSg.js";import{T as B}from"./terminal-DI3J3W_z.js";import"./vendor-radix-3UdfCgs_.js";import"./index-CUT6Fr2C.js";import"./vendor-syntax-xZUI6Op9.js";/**
|
|
2
|
+
* @license lucide-react v0.511.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const D=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]],w=y("globe",D);/**
|
|
7
|
+
* @license lucide-react v0.511.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const I=[["path",{d:"M16 17h6v-6",key:"t6n2it"}],["path",{d:"m22 17-8.5-8.5-5 5L2 7",key:"x473p"}]],$=y("trending-down",I),o={hidden:{opacity:0,y:12},visible:t=>({opacity:1,y:0,transition:{delay:t*.07,duration:.35,ease:"easeOut"}})};function m({className:t}){return e.jsx("div",{className:R("animate-pulse rounded-lg bg-muted",t)})}const z={openai:"#10b981",anthropic:"#f59e0b",google:"#3b82f6",groq:"#ef4444",ollama:"#8b5cf6",openrouter:"#ec4899"},A={web:w,telegram:S,cli:B};function H(t){return z[t.toLowerCase()]??"#6b7280"}function Z(t){return A[t.toLowerCase()]??g}function ae(){const[t,C]=f.useState(null),[N,k]=f.useState("");if(f.useEffect(()=>{P.usage.get().then(C).catch(s=>k(s.message))},[]),N)return e.jsx("div",{className:"flex h-full items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-destructive",children:N})});if(!t)return e.jsxs("div",{className:"space-y-6 p-6 lg:p-8",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(m,{className:"h-8 w-32"}),e.jsx(m,{className:"h-4 w-64"})]}),e.jsx("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-3",children:Array.from({length:3}).map((s,a)=>e.jsx(m,{className:"h-[130px]"},a))}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(m,{className:"h-[240px]"}),e.jsx(m,{className:"h-[240px]"})]}),e.jsx(m,{className:"h-[320px]"})]});const b=t.dailyBudget?Math.min(Math.round(t.dailyUsed/t.dailyBudget*100),100):0,h=Object.entries(t.byProvider),T=h.reduce((s,[,a])=>s+a,0)||1,j=Object.entries(t.byChannel),L=j.reduce((s,[,a])=>s+a,0)||1;return e.jsxs("div",{className:"space-y-6 p-6 lg:p-8",children:[e.jsxs(r.div,{initial:{opacity:0,y:-8},animate:{opacity:1,y:0},transition:{duration:.3},children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Usage"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Token consumption and budget tracking"})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-3",children:[e.jsx(r.div,{custom:0,variants:o,initial:"hidden",animate:"visible",children:e.jsxs(i,{className:"mercury-glow-sm",children:[e.jsxs(l,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(n,{className:"text-sm font-medium text-muted-foreground",children:"Daily Used / Budget"}),e.jsx(_,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(d,{children:[e.jsxs("p",{className:"text-2xl font-bold tabular-nums",children:[c(t.dailyUsed),e.jsxs("span",{className:"ml-1 text-sm font-normal text-muted-foreground",children:["/ ",c(t.dailyBudget)]})]}),e.jsx(O,{value:b,className:"mt-3"}),e.jsxs("p",{className:"mt-1.5 text-xs text-muted-foreground tabular-nums",children:[b,"% consumed"]})]})]})}),e.jsx(r.div,{custom:1,variants:o,initial:"hidden",animate:"visible",children:e.jsxs(i,{children:[e.jsxs(l,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(n,{className:"text-sm font-medium text-muted-foreground",children:"Remaining"}),e.jsx($,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(d,{children:[e.jsx("p",{className:"text-2xl font-bold tabular-nums",children:c(t.remaining)}),e.jsx("p",{className:"mt-1.5 text-xs text-muted-foreground",children:"tokens left today"})]})]})}),e.jsx(r.div,{custom:2,variants:o,initial:"hidden",animate:"visible",children:e.jsxs(i,{children:[e.jsxs(l,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(n,{className:"text-sm font-medium text-muted-foreground",children:"Total Requests"}),e.jsx(g,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(d,{children:[e.jsx("p",{className:"text-2xl font-bold tabular-nums",children:t.requestLog.length.toLocaleString()}),e.jsx("p",{className:"mt-1.5 text-xs text-muted-foreground",children:"requests today"})]})]})})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(r.div,{custom:3,variants:o,initial:"hidden",animate:"visible",children:e.jsxs(i,{children:[e.jsx(l,{children:e.jsxs(n,{className:"flex items-center gap-2 text-base",children:[e.jsx(E,{className:"h-4 w-4"}),"Usage by Provider"]})}),e.jsx(d,{children:h.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No provider usage recorded yet."}):e.jsx("div",{className:"flex flex-col gap-4",children:h.sort(([,s],[,a])=>a-s).map(([s,a])=>{const x=Math.round(a/T*100),u=H(s);return e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(p,{variant:"secondary",className:"capitalize",children:s}),e.jsxs("span",{className:"text-sm font-medium tabular-nums text-muted-foreground",children:[c(a)," ",e.jsxs("span",{className:"text-xs",children:["(",x,"%)"]})]})]}),e.jsx("div",{className:"h-2 w-full overflow-hidden rounded-full bg-muted",children:e.jsx(r.div,{className:"h-full rounded-full",style:{backgroundColor:u},initial:{width:0},animate:{width:`${x}%`},transition:{duration:.6,ease:"easeOut",delay:.3}})})]},s)})})})]})}),e.jsx(r.div,{custom:4,variants:o,initial:"hidden",animate:"visible",children:e.jsxs(i,{children:[e.jsx(l,{children:e.jsxs(n,{className:"flex items-center gap-2 text-base",children:[e.jsx(w,{className:"h-4 w-4"}),"Usage by Channel"]})}),e.jsx(d,{children:j.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No channel usage recorded yet."}):e.jsx("div",{className:"flex flex-col gap-4",children:j.sort(([,s],[,a])=>a-s).map(([s,a],x)=>{const u=Math.round(a/L*100),q=Z(s),v=["#00d4ff","#8b5cf6","#f59e0b","#10b981"],M=v[x%v.length];return e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(q,{className:"h-3.5 w-3.5 text-muted-foreground"}),e.jsx(p,{variant:"secondary",className:"capitalize",children:s})]}),e.jsxs("span",{className:"text-sm font-medium tabular-nums text-muted-foreground",children:[c(a)," ",e.jsxs("span",{className:"text-xs",children:["(",u,"%)"]})]})]}),e.jsx("div",{className:"h-2 w-full overflow-hidden rounded-full bg-muted",children:e.jsx(r.div,{className:"h-full rounded-full",style:{backgroundColor:M},initial:{width:0},animate:{width:`${u}%`},transition:{duration:.6,ease:"easeOut",delay:.35}})})]},s)})})})]})})]}),e.jsx(r.div,{custom:5,variants:o,initial:"hidden",animate:"visible",children:e.jsxs(i,{children:[e.jsx(l,{children:e.jsxs(n,{className:"flex items-center gap-2 text-base",children:[e.jsx(g,{className:"h-4 w-4"}),"Request Log"]})}),e.jsx(d,{children:t.requestLog.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No requests recorded yet."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-border text-left",children:[e.jsx("th",{className:"pb-3 pr-4 font-medium text-muted-foreground",children:"Time"}),e.jsx("th",{className:"pb-3 pr-4 font-medium text-muted-foreground",children:"Provider"}),e.jsx("th",{className:"pb-3 text-right font-medium text-muted-foreground",children:"Tokens"})]})}),e.jsx("tbody",{children:t.requestLog.slice().reverse().slice(0,50).map((s,a)=>e.jsxs(r.tr,{className:"border-b border-border/50 last:border-0",initial:{opacity:0},animate:{opacity:1},transition:{delay:.4+a*.02,duration:.2},children:[e.jsx("td",{className:"py-2.5 pr-4 tabular-nums text-muted-foreground",children:U(s.timestamp)}),e.jsx("td",{className:"py-2.5 pr-4",children:e.jsx(p,{variant:"outline",className:"capitalize",children:s.provider})}),e.jsx("td",{className:"py-2.5 text-right font-medium tabular-nums",children:c(s.totalTokens)})]},`${s.timestamp}-${a}`))})]})})})]})})]})}export{ae as UsagePage};
|
|
12
|
+
//# sourceMappingURL=Usage-i_q6Ri4s.js.map
|