redux-devtools/packages/redux-devtools-rtk-query-monitor/demo/src/features/posts/PostsManager.tsx
renovate[bot] 6d27879515
fix(deps): update dependency react-router-dom to v6 (#940)
* fix(deps): update dependency react-router-dom to v6

* inspector-monitor demo

* test-tab demo

* rtk-query-monitor

* Fix

Co-authored-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: Nathan Bierema <nbierema@gmail.com>
2022-05-15 21:47:09 +00:00

168 lines
3.7 KiB
TypeScript

import {
Box,
Button,
Center,
Divider,
Flex,
FormControl,
FormLabel,
Heading,
Input,
List,
ListIcon,
ListItem,
Spacer,
Stat,
StatLabel,
StatNumber,
useToast,
} from '@chakra-ui/react';
import { Route, Routes, useNavigate } from 'react-router-dom';
import { MdBook } from 'react-icons/md';
import React, { useState } from 'react';
import {
Post,
useAddPostMutation,
useGetPostsQuery,
} from '../../services/posts';
import { PostDetail } from './PostDetail';
const AddPost = () => {
const initialValue = { name: '' };
const [post, setPost] = useState<Pick<Post, 'name'>>(initialValue);
const [addPost, { isLoading }] = useAddPostMutation();
const toast = useToast();
const handleChange = ({ target }: React.ChangeEvent<HTMLInputElement>) => {
setPost((prev) => ({
...prev,
[target.name]: target.value,
}));
};
const handleAddPost = async () => {
try {
await addPost(post).unwrap();
setPost(initialValue);
} catch {
toast({
title: 'An error occurred',
description: "We couldn't save your post, try again!",
status: 'error',
duration: 2000,
isClosable: true,
});
}
};
return (
<Flex p={'5px 0'} flexDirection="row" flexWrap="wrap" maxWidth={'85%'}>
<Box flex={'5 0 auto'} padding="0 5px 0 0">
<FormControl
flexDirection="column"
isInvalid={Boolean(post.name.length < 3 && post.name)}
>
<FormLabel htmlFor="name">Post name</FormLabel>
<Input
id="name"
name="name"
placeholder="Enter post name"
value={post.name}
onChange={handleChange}
/>
</FormControl>
</Box>
<Box>
<Button
mt={8}
colorScheme="purple"
isLoading={isLoading}
onClick={handleAddPost}
>
Add Post
</Button>
</Box>
</Flex>
);
};
const PostList = () => {
const { data: posts, isLoading } = useGetPostsQuery();
const navigate = useNavigate();
if (isLoading) {
return <div>Loading</div>;
}
if (!posts) {
return <div>No posts :(</div>;
}
return (
<List spacing={3}>
{posts.map(({ id, name }) => (
<ListItem key={id} onClick={() => navigate(`/posts/${id}`)}>
<ListIcon as={MdBook} color="green.500" /> {name}
</ListItem>
))}
</List>
);
};
export const PostsCountStat = () => {
const { data: posts } = useGetPostsQuery();
if (!posts) return null;
return (
<Stat>
<StatLabel>Active Posts</StatLabel>
<StatNumber>{posts?.length}</StatNumber>
</Stat>
);
};
export const PostsManager = () => {
return (
<Box>
<Flex bg="#011627" p={4} color="white">
<Box>
<Heading size="xl">Manage Posts</Heading>
</Box>
<Spacer />
<Box>
<PostsCountStat />
</Box>
</Flex>
<Divider />
<AddPost />
<Divider />
<Flex wrap="wrap">
<Box flex={1} borderRight="1px solid #eee">
<Box p={4} borderBottom="1px solid #eee">
<Heading size="sm">Posts</Heading>
</Box>
<Box p={4}>
<PostList />
</Box>
</Box>
<Box flex={2}>
<Routes>
<Route path="posts/:id" element={<PostDetail />} />
<Route
index
element={
<Center h="200px">
<Heading size="md">Select a post to edit!</Heading>
</Center>
}
/>
</Routes>
</Box>
</Flex>
</Box>
);
};
export default PostsManager;