46 lines
1.5 KiB
TypeScript
46 lines
1.5 KiB
TypeScript
import { Button, Container, Flex, Heading, Text } from "@radix-ui/themes"
|
|
import { createFileRoute } from "@tanstack/react-router"
|
|
import { AsyncResult } from "effect/unstable/reactivity"
|
|
import { Component, Mutation, View } from "effect-fc-next"
|
|
import { fetchPost, type Post } from "@/post"
|
|
import { runtime } from "@/runtime"
|
|
|
|
|
|
const PostResultView = (props: { readonly result: AsyncResult.AsyncResult<Post, Error> }) =>
|
|
AsyncResult.match(props.result, {
|
|
onInitial: () => <Text>Ready to load.</Text>,
|
|
onFailure: () => <Text>Request failed.</Text>,
|
|
onSuccess: result => (
|
|
<>
|
|
<Heading>{result.value.title}</Heading>
|
|
<Text>{result.value.body}</Text>
|
|
</>
|
|
),
|
|
})
|
|
|
|
const ResultRouteComponent = Component.make("ResultRouteView")(function*() {
|
|
const mutation = yield* Component.useOnMount(() => Mutation.make({
|
|
f: (_: undefined) => fetchPost(1),
|
|
}))
|
|
const [result] = yield* View.useAll([mutation.state])
|
|
const runPromise = yield* Component.useRunPromise()
|
|
|
|
return (
|
|
<Container>
|
|
<Flex direction="column" gap="2">
|
|
<Button onClick={() => void runPromise(mutation.mutate(undefined))}>
|
|
Load post
|
|
</Button>
|
|
|
|
<PostResultView result={result} />
|
|
</Flex>
|
|
</Container>
|
|
)
|
|
}).pipe(
|
|
Component.withContext(runtime.context),
|
|
)
|
|
|
|
export const Route = createFileRoute("/result")({
|
|
component: ResultRouteComponent,
|
|
})
|