Basic setup
- We'll use React.js + ChakraUI for basic UI setup
- Rocketgraph to setup the backend
npx create-react-app messaging-app
Install Chakra UI
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
Install other necessary libs
yarn add react-router-dom
Head over to rocketgraph and create an account. Then click on "Create Project". Don't worry, it comes with a free trail and no CC required.
Wait for the project to boot and go to the Hasura console.
Skeleton App
Now let's build the basic UI without the actual data/backend.
create src/components
directory to hold our components.
In the index.js
file, replace it with the following
// src/index.js
import React from "react";
import ReactDOM from "react-dom";
import { ChakraProvider } from '@chakra-ui/react'
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import App from "./App";
import Message from "./components/Message"
ReactDOM.render(
<React.StrictMode>
<ChakraProvider>
<Router>
<Routes>
<Route path="/login" />
<Route path="/signup" />
<Route path="/messages" element={<Message />} />
<Route path="/" element={<App />} />
</Routes>
</Router>
</ChakraProvider>
</React.StrictMode>,
document.getElementById("root")
);
Now let's create the individual components to show on the app.
Create src/components/Message.js
and add the following code.
import React from "react";
import { useSearchParams } from 'react-router-dom';
import { Input } from '@chakra-ui/react'
import { Button, ButtonGroup } from '@chakra-ui/react'
import { Card, CardHeader, CardBody, CardFooter, Heading, Text, Flex, Avatar, Box } from '@chakra-ui/react'
const messages = [
{
from: "",
to: "",
from_address: "",
to_address: "",
message: "View a summary of all your customers over the last month.",
},
{
from: "",
to: "",
from_address: "",
to_address: "",
message: "View a summary of all your customers over the last month.",
}
]
export default function DrawerExample() {
const [searchParams] = useSearchParams();
console.log(searchParams.get('email')); // โถ URLSearchParams {}
// currentUser = Cookies.get("user")
const currentUser = "kaushik@moneysave.io"
return (
<>
<div className="message-body">
<div className="messages">
{
messages.map((message) => {
return (
<div className={message.to == currentUser ? "message-received" : "message-sent"} m={4}>
<div className="message-text">
<Card>
<CardHeader>
<Flex spacing='4'>
<Flex flex='1' gap='4' alignItems='center' flexWrap='wrap'>
<Avatar name='Segun Adebayo' src='https://bit.ly/sage-adebayo' />
<Box>
<Heading size='sm'>Segun Adebayo</Heading>
<Text>Creator, Chakra UI</Text>
</Box>
</Flex>
</Flex>
</CardHeader>
<CardBody>
<Text>{message.message}</Text>
</CardBody>
</Card>
</div>
</div>
)
})
}
</div>
<div className="main-bottom">
<Input m={2} placeholder='Basic usage' />
<Button m={2} colorScheme='blue'>Button</Button>
</div>
</div>
</>
)
}
Here we have created a dummy message component which displays the chat with a user based on the query parameters in the URL. We will discuss this later.
Once we implement the actual functionality, the messages will become live
And in App.css
add the following code:
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
.message-body {
position: relative;
height: 100vh;
}
.main-bottom {
position: absolute;
bottom: 10px;
left: 0px;
width: 100%;
display: flex;
}
.message-sent {
padding: 10px;
display: flex;
flex-direction: column;
align-items: flex-end;
}
.message-received {
padding: 10px;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.message-text {
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
In App.js
, add the following code
import logo from './logo.svg';
import Profiles from "./components/Profiles"
import './App.css';
function App() {
return (
<div className="App">
<Profiles/>
</div>
);
}
export default App;
Now create src/components/Profiles.js
import {
Heading,
Avatar,
Box,
Center,
Image,
Flex,
Text,
Stack,
Button,
useColorModeValue,
} from '@chakra-ui/react';
export default function SocialProfileWithImage() {
return (
<Center py={6}>
<Box
maxW={'270px'}
w={'full'}
bg={useColorModeValue('white', 'gray.800')}
boxShadow={'2xl'}
rounded={'md'}
overflow={'hidden'}>
<Image
h={'120px'}
w={'full'}
src={
'https://images.unsplash.com/photo-1612865547334-09cb8cb455da?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80'
}
objectFit={'cover'}
/>
<Flex justify={'center'} mt={-12}>
<Avatar
size={'xl'}
src={
'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&fit=crop&h=200&w=200&ixid=eyJhcHBfaWQiOjE3Nzg0fQ'
}
alt={'Author'}
css={{
border: '2px solid white',
}}
/>
</Flex>
<Box p={6}>
<Stack spacing={0} align={'center'} mb={5}>
<Heading fontSize={'2xl'} fontWeight={500} fontFamily={'body'}>
John Doe
</Heading>
<Text color={'gray.500'}>Frontend Developer</Text>
</Stack>
<Button
w={'full'}
mt={8}
bg={useColorModeValue('#151f21', 'gray.900')}
color={'white'}
rounded={'md'}
onClick={() => {window.location = "/messages?email=kaushik@moneysave.io"} }
_hover={{
transform: 'translateY(-2px)',
boxShadow: 'lg',
}}>
Message
</Button>
</Box>
</Box>
</Center>
);
}
Now let's create the login and signup pages as follows:
src/components/login.js
import {
Flex,
Box,
FormControl,
FormLabel,
Input,
Checkbox,
Stack,
Link,
Button,
Heading,
Text,
useColorModeValue,
} from '@chakra-ui/react';
export default function SimpleCard() {
return (
<Flex
minH={'100vh'}
align={'center'}
justify={'center'}
bg={useColorModeValue('gray.50', 'gray.800')}>
<Stack spacing={8} mx={'auto'} maxW={'lg'} py={12} px={6}>
<Stack align={'center'}>
<Heading fontSize={'4xl'}>Sign in to your account</Heading>
<Text fontSize={'lg'} color={'gray.600'}>
to enjoy all of our cool <Link color={'blue.400'}>features</Link> โ๏ธ
</Text>
</Stack>
<Box
rounded={'lg'}
bg={useColorModeValue('white', 'gray.700')}
boxShadow={'lg'}
p={8}>
<Stack spacing={4}>
<FormControl id="email">
<FormLabel>Email address</FormLabel>
<Input type="email" />
</FormControl>
<FormControl id="password">
<FormLabel>Password</FormLabel>
<Input type="password" />
</FormControl>
<Stack spacing={10}>
<Stack
direction={{ base: 'column', sm: 'row' }}
align={'start'}
justify={'space-between'}>
<Checkbox>Remember me</Checkbox>
<Link color={'blue.400'}>Forgot password?</Link>
</Stack>
<Button
bg={'blue.400'}
color={'white'}
_hover={{
bg: 'blue.500',
}}>
Sign in
</Button>
</Stack>
</Stack>
</Box>
</Stack>
</Flex>
);
}
src/components/signup.js
import {
Flex,
Box,
FormControl,
FormLabel,
Input,
Checkbox,
Stack,
Link,
Button,
Heading,
Text,
useColorModeValue,
} from '@chakra-ui/react';
export default function SimpleCard() {
return (
<Flex
minH={'100vh'}
align={'center'}
justify={'center'}
bg={useColorModeValue('gray.50', 'gray.800')}>
<Stack spacing={8} mx={'auto'} maxW={'lg'} py={12} px={6}>
<Stack align={'center'}>
<Heading fontSize={'4xl'}>Create your account</Heading>
<Text fontSize={'lg'} color={'gray.600'}>
to enjoy all of our cool <Link color={'blue.400'}>features</Link> โ๏ธ
</Text>
</Stack>
<Box
rounded={'lg'}
bg={useColorModeValue('white', 'gray.700')}
boxShadow={'lg'}
p={8}>
<Stack spacing={4}>
<FormControl id="email">
<FormLabel>Email address</FormLabel>
<Input type="email" />
</FormControl>
<FormControl id="password">
<FormLabel>Password</FormLabel>
<Input type="password" />
</FormControl>
<Stack spacing={10}>
<Stack
direction={{ base: 'column', sm: 'row' }}
align={'start'}
justify={'space-between'}>
<Checkbox>Remember me</Checkbox>
<Link color={'blue.400'}>Forgot password?</Link>
</Stack>
<Button
bg={'blue.400'}
color={'white'}
_hover={{
bg: 'blue.500',
}}>
Sign in
</Button>
</Stack>
</Stack>
</Box>
</Stack>
</Flex>
);
}
Great, now we finished setting up the skeleton of the front-end of the application. Now we need to inject data into this via the backend. Let's create the backend. Head over to the next article in the series.
Top comments (0)