42
loading...
This website collects cookies to deliver better user experience
# using npm
npx create-react-app fungram --template @chakra-ui
# or using yarn
yarn create react-app fungram --template @chakra-ui
# Enter the project directory
cd fungram
# Use the following command to open the project in vs-code
code .
src
directory├── App.test.js
├── Logo.js
├── logo.svg
├── reportWebVitals.js
├── serviceWorker.js
├── setupTests.js
└── test-utils.js
import React from 'react';
function App() {
return (
<div>
Hello
</div>
);
}
export default App;
import { ChakraProvider, ColorModeScript, theme } from '@chakra-ui/react';
import React, { StrictMode } from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<StrictMode>
<ChakraProvider theme={theme}>
<ColorModeScript />
<App />
</ChakraProvider>
</StrictMode>,
document.getElementById('root')
);
yarn start
# or
npm run start
Note: I converted JSON data obtained from DummyAPI to Google sheets using this tutorial. (I know I could have directly imported data using the NoCodeAPI import feature but since the data was nested and not working without the Dummy API header, so I had to go through this and then import the .xlsx file to google sheets manually xD. You learn something new every day.)
# using Yarn
yarn add axios
# or using npm
npm install axios
api.js
and add the following code:import axios from 'axios';
export default axios.create({
baseURL: "Your api endpoint from NoCodeAPI",
params: {
tabId: 'Sheet1', // passing the required parameter in the axios instance of api
},
});
.env
file, so let's quickly create one and add our API endpoint with the prefix REACT_APP_
(that is how create-react-app
works, you gotta have this), I am gonna go with the following.REACT_APP_API=your_nocodeapi_endpoint
baseURL
in api.js
, so it will look like this:import axios from 'axios';
export default axios.create({
baseURL: process.env.REACT_APP_API,
params: {
tabId: 'Sheet1',
},
});
App.js
, we will be using the useEffect hook but before that let's add some states to the component using useState hook (don't forget to import it).const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
import api from './api/api'; // importing the api
useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
const res = await api.get('/');
setPosts(res.data.data);
} catch (error) {
setError(error.message);
}
setLoading(false);
};
fetchData();
}, []);
true
since our data is yet to be fetched.try
block, we are awaiting the response from api and saving it in the res
variable.components
folder inside the src
directory. Remember we have a ColorModeSwitch.js
file, move it to the components folder as well.// Adding these in case of data is loading or there is some error
// The components used are simply Chakra UI components (import them)
if (loading)
return (
<Flex alignItems={'center'} justifyContent={'center'} minH={'100vh'}>
<Spinner size="xl" thickness="4px" />
</Flex>
);
if (error) return (
<Flex alignItems={'center'} justifyContent={'center'} minH={'100vh'}>
{error}
</Flex>
);
// when we get the data
return (
<div>
<Box bg={'teal.600'}>
<Container as={'header'} maxW={'container.xl'} py={6}>
<Flex
w={'full'}
alignItems={'center'}
justifyContent={'space-between'}
>
<Text
color={'white'}
fontSize={'4xl'}
fontWeight={'600'}
textTransform={'uppercase'}
>
fungram
</Text>
<ColorModeSwitcher justifySelf="flex-end" />
</Flex>
</Container>
</Box>
<Container as="main" maxW="container.xl" my={10}>
<Grid
templateColumns={{
base: 'repeat(1, 1fr)',
md: 'repeat(2, 1fr)',
lg: 'repeat(3, 1fr)',
}}
>
{posts.map(post => (
<PostCard key={post.id} data={post} />
))}
</Grid>
</Container>
<Box bg={'teal.600'}>
<Container as={'footer'} maxW={'container.xl'} align={'center'} py={6}>
<Text fontSize={'sm'}>
© 2021 Made by{' '}
<Link fontWeight={'600'} href="http://github.com/fabcodingzest">
Fab
</Link>
</Text>
<Text fontSize={'sm'}>
Checkout the code at{' '}
<Link
fontWeight={'600'}
href="http://github.com/fabcodingzest"
>
GitHub
</Link>
</Text>
</Container>
</Box>
</div>
);
ColorModeSwitch
component in the header.<Postcard />
component for each item in the array and pass the data as data
prop along with of course key prop.src/components/
which will look something like this:import {
Image,
Box,
Tag,
Center,
Heading,
Text,
Stack,
Avatar,
useColorModeValue,
HStack,
} from '@chakra-ui/react';
const PostCard = ({ data }) => {
const {
image,
tags,
text,
publishDate,
ownerFirstName,
ownerLastName,
ownerImage,
} = data;
const date = new Date(publishDate).toLocaleDateString();
const tagsArr = tags.split(', ');
return (
<Center py={6}>
<Box
maxW={'350px'}
w={'full'}
bg={useColorModeValue('white', 'gray.700')}
boxShadow={useColorModeValue('2xl', 'sm')}
rounded={'md'}
p={6}
overflow={'hidden'}
>
<Box
h={'210px'}
bg={'gray.100'}
mt={-6}
mx={-6}
mb={6}
pos={'relative'}
>
<Image
src={image}
objectFit={'cover'}
h={'full'}
w={'full'}
alt={text}
/>
</Box>
<Stack>
<HStack spacing={2}>
{tagsArr.map(item => (
<Tag size={'sm'} key={item} variant="solid" colorScheme="teal">
{item}
</Tag>
))}
</HStack>
<Heading
color={useColorModeValue('gray.700', 'white')}
fontSize={'xl'}
fontFamily={'body'}
textTransform="capitalize"
noOfLines={2}
>
{text}
</Heading>
</Stack>
<Stack mt={6} direction={'row'} spacing={4} align={'center'}>
<Avatar src={ownerImage} alt={'Author'} />
<Stack direction={'column'} spacing={0} fontSize={'sm'}>
<Text fontWeight={600}>
{ownerFirstName} {ownerLastName}
</Text>
<Text color={'gray.500'}>{date}</Text>
</Stack>
</Stack>
</Box>
</Center>
);
};
export default PostCard;
publishDate
to a local date string.