fullstack web app-golang #5

f

So we basically managed to finish the state management in our app. Now lets add the basic routing. Again we need some npm libraries.

npm i react-router react-router-dom

Now open your app.js file.

import Navbar from './components/main/NavBar'
import Main from './components/main/Main'
import Login from './components/Auth/Login'
import Register from './components/Auth/Register'
import Posts from './components/posts/Posts'
import Addpost from './components/posts/AddPost'
import PrivateRoute from './components/routing/PrivateRoute'
return (
	<div className='App'>
		<AuthState>
			<Router>
				<Navbar />
				<Switch>
					<Route path='/' exact component={Main} />
					<Route path='/login' exact component={Login} />
					<Route path='/register' exact component={Register} />
					<Route path='/home' exact component={Posts} />
					<PrivateRoute path='/addpost' exact component={Addpost} />
				</Switch>
			</Router>
		</AuthState>
	</div>
	)

Nothing special here. Except one thing.

Whats this PrivateRoute?

So basically we want only the authenticated the users to post new data to the /addpost

So we’re gonna create our own route.

  • get props ({ component: Component, …rest }) => {}
  • spread the rest in route
  • use conditionals
const PrivateRoute = ({ component: Component, ...rest }) => {
	const authContext = useContext(AuthContext)
	const { isAuthenticated, loading } = authContext
	return (
		<Route
			{...rest}
			render={props =>
				!isAuthenticated && !loading ? (
					<Redirect to='/login' />
				) : (
					<Component {...props} />
				)
			}
		/>
	)
}

navbar

Now lets concentrate on navbar. Here we have actually two things

	const guestlink = (
		<>
			<li>
				<Link to='/login'>login</Link>
			</li>
			<li>
				<Link to='/register'>register</Link>
			</li>
		</>
	)

and

	const userlink = (
		<>
			<li>
				<Link to='/login' onClick={onLogout}>
					logout
				</Link>
			</li>
			<li>
				<Link to='/home'>home</Link>
			</li>
			<li>
				<Link to='/addpost'>Add Posts</Link>
			</li>
		</>
	)

So we’re gonna use conditions to decide which to render.

<ul id='nav' className='right'>
	{isAuthenticated ? userlink : guestlink}
</ul>

Here’s the full code:

import React, { useContext, useEffect } from 'react'
import { Link } from 'react-router-dom'
import AuthContext from '../../context/Auth/authContext'

const NavBar = props => {
	const authContext = useContext(AuthContext)
	const { logout, loadUser, isAuthenticated } = authContext

	const onLogout = () => {
		logout()
	}

	const guestlink = (
		<>
			<li>
				<Link to='/login'>login</Link>
			</li>
			<li>
				<Link to='/register'>register</Link>
			</li>
		</>
	)

	const userlink = (
		<>
			<li>
				<Link to='/login' onClick={onLogout}>
					logout
				</Link>
			</li>
			<li>
				<Link to='/home'>home</Link>
			</li>
			<li>
				<Link to='/addpost'>Add Posts</Link>
			</li>
		</>
	)
	useEffect(() => {
		loadUser()
		// eslint-disable-next-line
	}, [])

	return (
		<nav>
			<div className='nav-wrapper amber darken-2'>
				<ul id='nav' className='left'>
					<li>
						<Link id='logo' to='/'>
							SEKRETU
						</Link>
					</li>
				</ul>

				<ul id='nav' className='right'>
					{isAuthenticated ? userlink : guestlink}
				</ul>
			</div>
		</nav>
	)
}

export default NavBar

main.js

Its just a welcome page, design it whatever you want.

In my case I just returned some lorem ipsum. lol

<div className='container'>
	<div className='row'>
		<div className='row s12'>
			<h2 className='center webname'>SEKRETU</h2>
		</div>
	<div className='row s12 sub-heading'>
					Veniam ea occaecat fugiat irure irure velit reprehenderit commodo
					velit velit amet. Ut deserunt exercitation Lorem ipsum enim
					exercitation sit nulla do. Pariatur consectetur dolor laborum culpa
					anim duis sunt. Tempor eu minim ea eu sunt adipisicing commodo
					reprehenderit sit sint. Veniam mollit commodo voluptate aliqua aute
					eiusmod. Tempor tempor id dolor sit velit ullamco. Et incididunt
					adipisicing ut consequat excepteur dolor eiusmod tempor sit. Ipsum
					adipisicing nisi culpa cupidatat eiusmod nostrud quis cillum veniam eu
					culpa tempor anim voluptate. Fugiat irure adipisicing ad enim velit
					nisi magna ad quis reprehenderit exercitation consequat veniam.
					Pariatur quis anim adipisicing mollit nostrud reprehenderit incididunt
					magna. Aliqua laboris velit enim enim aute eu ipsum dolore aliqua elit
					et fugiat sunt. Ut excepteur labore est qui culpa ex exercitation eu
					adipisicing cupidatat. Velit eiusmod labore cupidatat est quis nostrud
					quis.
				</div>
				<div className='row s12 btn-group'>
		<div className='col s6 '>
			<Link to='/login' className='waves-effect waves-light btn  amber darken-4 right'>
							login
			</Link>
		</div>
		<div className='col s6'>
				<Link to='/register' className='waves-effect waves-light btn  amber darken-4 left'>
							register
				</Link>
			</div>
		</div>
	</div>
</div>

login.js

First thing first, we don’t wanna authenticated users to see this page, so

	useEffect(() => {
		if (isAuthenticated) {
			props.history.push('/home');
		}
		//eslint-disable-next-line
	}, [isAuthenticated])

Now we got everything normal here. We have a state that holds email, password

	const [state, setstate] = useState({
		email: '',
		password: '',
	})

and we have some handlers.

	const onsubmit = e => {
		e.preventDefault()
		console.log('submitted')

		login(state)
	}

	const onchange = e => {
		setstate({
			...state,
			[e.target.name]: e.target.value,
		})
	}

Do it as below for all the other fields

<input id='email' type='email'								 
autoComplete='new-password' name='email'
value={state.name}
onChange={onchange}
></input>

register.js

Almost the same as LOGIN.JS but have 3 fields

	const [state, setstate] = useState({
		name: '',
		email: '',
		password: ''
	})

All the other handlers are almost similar.


	const onsubmit = e => {
		e.preventDefault()
		console.log('submitted');

		register(state);
	}

	const onchange = e => {
		setstate({
			...state,
			[e.target.name]: e.target.value
		})
	}

add post

we have a similar state and handler here too

	const [post, setpost] = useState({
		title: '',
		body: '',
	})

	const onchange = e => {
		e.preventDefault()
		setpost({
			...post,
			[e.target.name]: e.target.value,
		})
	}

But one thing thats different here is the onsubmit()

We’re goona make a request to /addpost and then go to the main page using router

const onsubmit = e => {
		
		//post to the server
		//go to home
                props.history.push('/home')
}

Here’s the exact code

const onsubmit = e => {
		e.preventDefault()
		console.log('form submitted')
		//post to the server
		const config = {
			headers: {
				'Content-Type': 'application/json',
			},
		}

		axios
			.post(`${BASE_URL}/addpost`, post, config)
			.then(() => {
				props.history.push('/home')
			})
			.catch(err => console.log(err))
	}

posts.js

Here we just gonna make get request to the server / when the component loads

	const BASE_URL = 'http://localhost:8080'
	const [posts, setposts] = useState([])
	useEffect(() => {
		axios
			.get(`${BASE_URL}`)
			.then(res => {
				console.log(res.data)

				setposts(res.data)
			})
			.catch(err => console.log('errrr' + err))
	}, [])

In the return we have,

return (
		<div className='container row post-card-body'>
			<Post data={posts} />
		</div>
	)

post.js

We will be getting arrays of json here. So just iterate through the list. and render the data you want. Here I used map() function

<>
	{!props.data ? (
		<></>
	) : (
	props.data.map(e => (
		<div className='container col l6 m6  center post-card' key={e._id}>
			<div className='card-body'>
				<div className='card mycard  amber darken-4 z-depth-4'>
					<div className='card-content white-text'>
						<span className='card-title'>{e.title}</span>
							<p>{e.body}</p>
					</div>
				</div>
			</div>
		</div>
	))
)}
</>

And thats basically it. We successfully finished the frontend

Happy coding 🙂

About the author

vigneshwar

Add comment

Leave a Reply

By vigneshwar

Most common tags

%d bloggers like this: