89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
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>
|
|
} |