feat: add credential routes and mcp manifest
This commit is contained in:
89
src/pages/dashboard/credential/credential_page.tsx
Normal file
89
src/pages/dashboard/credential/credential_page.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import apiFetch from "@/lib/apiFetch";
|
||||
import { Button, Card, Container, Flex, Group, Paper, Stack, Text, TextInput, Title } from "@mantine/core";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
import { showNotification } from "@mantine/notifications";
|
||||
import { useState } from "react";
|
||||
import useSwr from 'swr'
|
||||
import { proxy, subscribe, useSnapshot } from 'valtio'
|
||||
|
||||
const state = proxy({
|
||||
reload: ""
|
||||
})
|
||||
|
||||
function reloadState() {
|
||||
state.reload = Math.random().toString()
|
||||
}
|
||||
|
||||
export default function CredentialPage() {
|
||||
return <Container size={"md"} w={"100%"}>
|
||||
<Stack>
|
||||
<CredentialCreate />
|
||||
<CredentialList />
|
||||
</Stack>
|
||||
</Container>
|
||||
}
|
||||
|
||||
function CredentialCreate() {
|
||||
const [name, setName] = useState("")
|
||||
const [apikey, setApikey] = useState("")
|
||||
|
||||
async function handleSubmit() {
|
||||
const { data } = await apiFetch.api.credential.create.post({
|
||||
name: name,
|
||||
value: apikey
|
||||
})
|
||||
|
||||
setName("")
|
||||
setApikey("")
|
||||
|
||||
showNotification({
|
||||
message: data?.message
|
||||
})
|
||||
|
||||
reloadState()
|
||||
}
|
||||
return <Card>
|
||||
<Stack>
|
||||
<Title>Credential Create</Title>
|
||||
<TextInput placeholder="name" value={name} onChange={(e) => setName(e.target.value)} />
|
||||
<TextInput placeholder="apikey" value={apikey} onChange={(e) => setApikey(e.target.value)} />
|
||||
<Group>
|
||||
<Button onClick={handleSubmit}>Save</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Card>
|
||||
}
|
||||
|
||||
function CredentialList() {
|
||||
const { data, mutate } = useSwr("/", () => apiFetch.api.credential.list.get())
|
||||
|
||||
useShallowEffect(() => {
|
||||
const unsubscribe = subscribe(state, async () => {
|
||||
console.log('state has changed to', state)
|
||||
mutate()
|
||||
})
|
||||
|
||||
return () => unsubscribe()
|
||||
}, [])
|
||||
|
||||
async function handleRm(id: string) {
|
||||
await apiFetch.api.credential.rm.delete({
|
||||
id: id
|
||||
})
|
||||
|
||||
reloadState()
|
||||
|
||||
}
|
||||
return <Card>
|
||||
<Stack>
|
||||
{data?.data?.list.map((v, k) => <Stack key={k}>
|
||||
<Flex justify={"space-between"}>
|
||||
<Text>{v.name}</Text>
|
||||
<Group>
|
||||
<Button onClick={() => handleRm(v.id)}>delete</Button>
|
||||
</Group>
|
||||
</Flex>
|
||||
</Stack>)}
|
||||
</Stack>
|
||||
</Card>
|
||||
}
|
||||
@@ -21,7 +21,9 @@ import { useLocalStorage } from '@mantine/hooks'
|
||||
import {
|
||||
IconChevronLeft,
|
||||
IconChevronRight,
|
||||
IconDashboard
|
||||
IconDashboard,
|
||||
IconKey,
|
||||
IconLock
|
||||
} from '@tabler/icons-react'
|
||||
import type { User } from 'generated/prisma'
|
||||
import { Outlet, useLocation, useNavigate } from 'react-router-dom'
|
||||
@@ -170,11 +172,18 @@ function NavigationDashboard() {
|
||||
/>
|
||||
<NavLink
|
||||
active={isActive('/dashboard/apikey')}
|
||||
leftSection={<IconDashboard size={20} />}
|
||||
leftSection={<IconKey size={20} />}
|
||||
label="Dashboard Overview"
|
||||
description="Quick summary and activity highlights"
|
||||
onClick={() => navigate(clientRoutes['/dashboard/apikey'])}
|
||||
/>
|
||||
<NavLink
|
||||
active={isActive('/dashboard/credential')}
|
||||
leftSection={<IconLock size={20} />}
|
||||
label="Dashboard Overview"
|
||||
description="Quick summary and activity highlights"
|
||||
onClick={() => navigate(clientRoutes['/dashboard/credential'])}
|
||||
/>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user