Background story
I wanted to learn about how to create a React website from the ground up but I really didn't know if I should use CSS modules or styled-components. But after watching a tutorial on Youtube on how to use styled-components and props, I decided to make a simple site to practice. Some things I had to google like how to use global styles, import a font family, etc. The good thing is learning how to google is also a skill in the industry, I didn't get frustrated or think I was wasting time. If you are self-taught I am sure you are already used to doing this. The next step I will need to do is to refactor the code and make it clean (I promise I will do thatπ€).
After finishing the website, I thought it would be great if I shared how I built it from the Figma wireframes to the design and finally to code. Week three of learning React has been fun so far, hope any code newbie will find the content useful. Next, I will build another site that has more clean code by creating a data file and using the map method.
Some Useful tips
Before starting you can download the following extensions if you don't have them.
Quick intro to styled-components
- Styled-components utilises tagged template literals to style your components. Example
- Let's create a button
// The wrapper will render the section which will contain the button
const FeatureWrapper = styled.section`
background-color: #f9f9f9;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
`;
// The FeatureButton component will render the button with thestyles below
const FeatureButton = styled.button`
border-radius: 20px;
background-color: #0F111C;
color: #fff;
padding: 18px 30px;
font-size: 20px;
outline: none;
cursor: pointer;
border: none;
`;
render(
<FeatureWrapper>
<FeatureButton> Explore Components</FeatureButton>
</FeatureWrapper>
)
- Result
Making props with styled-components
- Inside a styled-component, you can pass a function to change it based on its props. Example
- We want a button styled-component which can have a background colour of orange when it's primary and black when it's not. Plus on hover, the black button will have a background colour of orange and the primary button, orange will have a black background.
const ButtonWrapper = styled.section`
background-color: #f9f9f9;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
`;
const Button = styled.button`
border-radius: 20px;
background-color: background-color: ${({primary}) => primary? '#E38B06': '#000'};
color: color: ${({primary}) => primary ? '#000': '#fff'};
padding: 18px 30px;
font-size: 20px;
outline: none;
cursor: pointer;
border: none;
transition: transform .2s ease;
&:hover{
background-color: ${({primary}) => primary? '#fff': '#E38B06'};
transform: translateY(-.5rem) scale(1.02);
color: #000;
}
`;
render(
<div>
<ButtonWrapper>
<Button primary> Primary </Button>
<Button> Not primary </Button>
</ButtonWrapper>
</div>
)
- Result
- This makes it easier to write a variety of styles depending on the props us, which is more dynamic. When primary is true the button will have the orange background, if it's false it will have the black background. For more go through the Styled-component documentation.
Let's create a simple website
Design
You can also view the Figma file and see the designs. (It's not all that flashy, but basic haha π) . To give you the visuals of how the website should look like. Here is the design image.
If you want the code, it's available on my Github.
1) First create the react app by running
npm init react-app Homemade-website
2) Delete files in the src file and leave the App.js and index.js
|__src
|
|__App.js
|__index.js
3) Create the components folder in the source file. This is where we are going to create the major components like Navbar, hero section, welcome section, personalized meals section and footer section.
Add index.js in components folder to export the components in on file. It makes your app files less cluttered and organized.
Inside the components, folder created a Navbar folder. Then add Navbar.js
and Navbar.styles.js
.
|--components
|--Navbar
|--Navbar.js
|--Navbar.styles.js
|--index.js
In the index.js folder, we will export all our components.
export {default as Navbar} from './Navbar/Navbar';
Import styled-components and write global styles for the website
- Import styled-components in your react project
npm install --save styled-components
- Create a GlobalStyles.js folder in the Src folder.
|__src
| |__components
|
|__App.js
|__GlobalStyles.js
|__index.js
- Add font family and some global styles you want to add in your website. I used Nunito for this website. For more read style component docs
I didn't know how to use Global styles, especially how to import a font family but with the documentation and joining the Styled-component community on the spectrum helped.
- These styles will be used globally and for that, I added the container and the buttons that shall be used through the pages.
- The good thing about Styled-components is, you can use props to create different variations of elements like buttons.
import styled, {createGlobalStyle} from 'styled-components';
const GlobalStyles = createGlobalStyle`
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;800;900&family=Rubik:wght@800&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: inherit;
}
html {
box-sizing: border-box;
font-size: 62.5%;
@media only screen and (max-width: 1200px){
font-size: 58%;
}
@media only screen and (min-width: 1980px){
font-size: 70%;
}
}
body{
font-family: 'Nunito', sans-serif;
font-weight: 400;
line-height: 1.6;
font-size: 1.6rem;
background: #F9F9F9;
color: #333;
}
`;
export default GlobalStyles;
export const Container = styled.div`
margin: 0 auto;
padding: 0 50px;
max-width: 1300px;
width: 100%;
@media (max-width:400px){
padding: 0 10px;
}
@media (max-width:991px) {
padding: 0 30px;
}
@media (min-width: 1500px) {
max-width: 1500px;
}
@media (min-width: 1800px) {
max-width: 1800px;
padding: 0 30px;
}
`;
export const Button = styled.button`
border-radius: ${({bigRadius}) => bigRadius ? '30px': '20px'};
background-color: ${({primary}) => primary? '#E38B06': '#000'};
color: ${({primary}) => primary ? '#000': '#fff'};
padding: ${({big}) => big? '18px 30px' : '10px 28px'};
font-size: ${({bigFont}) => bigFont? '20px': '18px'};
outline: none;
cursor: pointer;
border: none;
transition: all .5s ease;
&:hover{
background-color: ${({primary}) => primary? '#fff': '#E38B06'};
transform: translateY(-.5rem) scale(1.02);
color: #000;
}
&:active{
transform: translateY(.5rem);
}
@media only screen and (max-width:1000px) {
/* width: 100%; */
padding: ${({big}) => big? '18px 30px' : '10px 20px'};
}
@media only screen and (max-width:375px) {
padding: ${({big}) => big? '12px 20px' : '10px 20px'};
font-size: ${({bigFont}) => bigFont? '16px': '18px'};
}
`;
export const OutlineButton = styled.button`
border-radius: ${({bigRadius})=> bigRadius? '40px' : '30px'};
border: 2px solid #333;
color: #333;
outline: none;
padding: ${({big}) => big? '15px 60px' : '13px 55px'};
font-size: ${({fontBig}) => fontBig? '22px':'18px'};
transition: all .5s ease;
background-color: #fefefe;
&:hover {
background-color: #333;
color: #fff;
border: none;
transform: translateY(-.5rem) scale(1.02);
}
&:active{
transform: translateY(.5rem);
}
@media only screen and (max-width: 1200px) {
border-radius: ${({bigRadius})=> bigRadius? '20px' : '18px'};
padding: ${({big}) => big? '9px 30px' : '8px 28px'};
font-size: ${({fontBig}) => fontBig? '18px':'16px'};
}
`;
// add it to the App.js file and put it at the top.
<GlobalStyles/>
Component 1: Let's start adding and styling the Navbar
1) Let's create the navbar with the logo and the menu icon
- We need to import react-router and some react icons
- To import react-router to use the link plus later to navigate through the pages.
- I don't know why, but creating the Nav took me longer than expected. Especially to make it work on click. But been new at this, it was expected.
npm install react-router-dom
- Import react icons
npm install react-icons --save-
- In the Navbar.js write the code below.
- For the menu icon we will use
useState
to handle the click function. - Add IconContext.Provider to add colour to the Menu Icon. This made possible by React icons that we installed earlier on.
//In the Navbar.js file
import { BiMenu, BiX } from "react-icons/bi";
import {Button} from '../../Globalstyles';
import
{
Nav,
NavbarContainer,
NavLogo,
NavIcon
} from './Navbar.styles';
const Navbar = () => {
//click is the initial state and setclick will be the update state
const [click, setClick] = useState(false);
//Create a function to handle the click state of the menu icon.
//if the menu icon was the menu bar at the beginning when clicked it will have the close icon
const handleClick = () => setClick(!click);
return (
<div>
<IconContext.Provider value={{ color: '#fff'}}> //turns the menu icon to white
<Nav>
<NavbarContainer>
<NavLogo to="/">
<NavIcon/>
Home Made
</NavLogo>
<MenuIcon onClick={handleClick}>
{click ? <BiX/> : <BiMenu/>}
</MenuIcon>
<Menu onClick={handleClick} click={click}>
<MenuItem>
<MenuLink onClick={closeMenu} to="/">Home</MenuLink>
</MenuItem>
<MenuItem>
<MenuLink onClick={closeMenu} to="/about">About</MenuLink>
</MenuItem>
<MenuItem>
<MenuLink onClick={closeMenu} to="/recipe">Recipes</MenuLink>
</MenuItem>
<MenuItemBtn>
{button?(
<MenuLinkBtn to="/order-now">
<Button primary>Order Now</Button>
</MenuLinkBtn>
): (
<MenuLinkBtn to="/order-now">
<Button primary bigFont onClick={closeMenu}>Order Now</Button>
</MenuLinkBtn>
)
}
</MenuItemBtn>
</Menu>
</NavbarContainer>
</Nav>
</IconContext.Provider>
</div>
)
}
export default Navbar;
- In the Navbar.styles.js write the code below. I used flexbox for the navbar. On top of that, I used chrome dev tools to make it precise. (No, I didn't just know how to place them, I inspected the elements until I got something that worked. Plus I had the design, that helped too. π€)
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import {BiRestaurant} from 'react-icons/bi';
import {Container} from '../../Globalstyles';
export const Nav = styled.nav`
font-size: 18px;
position: sticky;
top: 0;
z-index: 999;
height: 80px;
background-color: rgba(0, 0, 0, 0.5);
/* box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.5); */
box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.15);
display: flex;
justify-content: center;
align-items: center;
`;
export const NavbarContainer = styled(Container)`
display: flex;
justify-content: space-between;
align-items: center;
height: 80px;
${Container};
`;
export const NavLogo = styled(Link)`
color: #fff;
cursor: pointer;
display: flex;
align-items: center;
text-decoration: none;
font-size: 2.5rem;
font-weight: 800;
transition: all .5s ease;
&:hover{
transform: scale(1.08);
}
`;
export const NavIcon = styled(BiRestaurant)`
margin-right: .8rem;
transition: all .5s ease;
&:hover {
transform: scale(2);
}
`;
export const MenuIcon = styled.div`
display: none;
@media (max-width: 1000px) {
display: block;
position: absolute;
top: 0;
right: 0;
transform: translate(-50%, 20%);
font-size: 4rem;
cursor: pointer;
}
`;
export const Menu = styled.ul`
display: flex;
align-items: center;
text-align: center;
@media only screen and (max-width:1000px) {
display: flex;
flex-direction: column;
width: 100%;
height: 100vh;
position: absolute;
top: 80px;
left: ${({click}) => click ? '0' : '-100%'};
background-color: rgba(0, 0, 0, 0.9);
transition: all .5s ease;
}
`;
export const MenuItem = styled.li`
list-style: none;
height: 80px;
@media only screen and (max-width:1000px){
width: 100%;
&:hover {
border: none;
}
}
`;
export const MenuLink = styled(Link)`
text-decoration: none;
font-weight: bold;
font-size: 2rem;
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
height: 100%;
transition: all .2s ease;
&:hover {
color: #E38B06;
transform: traslateY(-3rem);
}
&:active {
transform: traslateY(3rem);
color: #E38B06;
}
@media only screen and (max-width:1000px){
display: block;
padding: 3rem;
text-align: center;
transition: all .2s ease;
}
`;
export const MenuItemBtn = styled.li`
list-style: none;
@media screen and (max-width:1000px){
display: flex;
justify-content: center;
align-items: center;
width: 50%;
height: 120px;
}
`;
export const MenuLinkBtn = styled(Link)`
text-decoration: none;
display: flex;
justify-content: center;
align-items: center;
padding: 8px 16px;
height: 100%;
width: 100%;
border: none;
outline: none;
`;
- In the App.js you need to add the router
If not you will get this error
`Error: Invariant failed: You should not use <Link> outside a <Router>`
//Wrap your components inside the router.
import {BrowserRouter as Router,Switch,Route,Link} from "react-router-dom";
import {Navbar} from './components';
import GlobalStyles from './Globalstyles';
function App() {
return (
<Router>
<GlobalStyles/>
<Navbar/>
</Router>
);
}
export default App;
Component 2: The Hero component
This section will contain the Navbar, the background image, the text and the button.
- Create the Hero folder, add the
Hero.js
andHero.styles.js
|--components
|--Navbar
|--Navbar.js
|--Navbar.styles.js
|--Hero
|--Hero.js
|--Hero.styles.js
|--index.js
In the index.js folder, we will export all our components.
export {default as Hero} from './Hero/Hero';
- Coding the Hero section In the Hero.js, we will import the Button component from the GlobalStyle component created earlier. I used flexbox for this section since the content was less.
import Navbar from '../Navbar/Navbar';
import {Button} from '../../Globalstyles';
import {
HeroContainer,
HeroContent,
HeroContentText,
HeroTitle,
HeroTitleText,
HeroSubTitle,
HeroText,
HeroBtn,
} from './Hero.styles';
const Hero = () =>{
return(
<div>
<HeroContainer>
<Navbar/>
<HeroContent>
<HeroContentText>
<HeroTitle>
<HeroTitleText>Healthy</HeroTitleText>
<HeroTitleText>Meals All Day</HeroTitleText>
</HeroTitle>
<HeroSubTitle>For a longer Life</HeroSubTitle>
<HeroText>
Get a fresh and tasty recepies that are well balanced and
will improve your wellness, plus add nutrients to your body.
</HeroText>
<HeroBtn to="/order-now">
<Button primary big bigFont bigRadius>Pick your meals</Button>
</HeroBtn>
</HeroContentText>
</HeroContent>
</HeroContainer>
</div>
)
}
export default Hero;
- Styles of the Hero section => Hero.styles.js
Component 3: How it works section
This section only has 3 cards in it, I used flexbox but you can use the grid to make it easier for the layout part. To centre the text you should definitely use flexbox to centre the text.
display: flex;
justify-content: center;
align-items: center;
- Create the Works folder, add the
Works.js
andWorks.styles.js
I not that good at naming folders, haha, bare with me.
|--components
|--Navbar
|--Navbar.js
|--Navbar.styles.js
|--Hero
|--Hero.js
|--Hero.styles.js
|--Works
|--Works.js
|--Works.styles.js
|--index.js
In the index.js folder, we will export all our components.
export {default as Works} from './Works/Works';
- Let's code the section. Inside the Works.js file add the code below. For the icons, I used react-icons that we installed earlier. I picked Boxicons for the site, that I also included in the design files. π
import {
WorksContainer,
WorksContent,
WorksTitle,
WorksCardContent,
WorksCard,
WorksIconContainer,
WorksIcon1,
WorksIcon2,
WorksIcon3,
WorksCardTitle,
WorksCardText
} from './works.styles';
const Works = () => {
return (
<div>
<WorksContent>
<WorksContainer>
<WorksTitle> How it works</WorksTitle>
<WorksCardContent>
<WorksCard>
<WorksIconContainer>
<WorksIcon1 className="Icon"/>
</WorksIconContainer>
<WorksCardTitle>Pick a meal</WorksCardTitle>
<WorksCardText>
There are different meals every week to choose from.
This gives you a variety of options to switch it up.
</WorksCardText>
</WorksCard>
<WorksCard>
<WorksIconContainer>
<WorksIcon2/>
</WorksIconContainer>
<WorksCardTitle>Customize it</WorksCardTitle>
<WorksCardText>
Choose your favourite recipes that you want to cook.
Pick the category you love.
</WorksCardText>
</WorksCard>
<WorksCard>
<WorksIconContainer>
<WorksIcon3/>
</WorksIconContainer>
<WorksCardTitle>Cook it up</WorksCardTitle>
<WorksCardText>
Order the meal you have chosen.
Fresh and packed ingredients straight to your doorstep.
</WorksCardText>
</WorksCard>
</WorksCardContent>
</WorksContainer>
</WorksContent>
</div>
)
}
export default Works;
- Styles of the Works section => Works.styles.js
component 4: Welcome section
This is really simple you can use grid for the layout and as usual flexbox for the text in the welcome content.
- Create the Welcome folder and add
welcome.js
andwelcome.styles.js
files. Also, remember to export it to theindex.js
file as I showed earlier. - For this part, I had to google how to import local images in a react app. Here is how it's done.
import PizzaImg from '../../images/pizza.png';
<Img src={PizzaImg} alt=" Delious Pizza"/>
- In the welcome.js file, add the following code.
import {
WelcomeContainer,
WelcomeContent,
WelcomeImg,
WelcomeContentText,
WelcomeContentTitle,
WelcomeText,
Img
} from './Welcome.styles';
import PizzaImg from '../../images/pizza.png';
const Welcome = () => {
return (
<div>
<WelcomeContainer>
<WelcomeContent>
<WelcomeImg>
<Img src={PizzaImg} alt=" Delious Pizza"/>
</WelcomeImg>
<WelcomeContentText>
<WelcomeContentTitle>Welcome</WelcomeContentTitle>
<WelcomeText>
Home made is a great way to make meals at home that are health and enjoyable.
We have a variety of categories to choose from that help meet your needs in your health journey.
You can customize the ingredients you want to be added to your meal. This can be due to health
resources, you donβt have to use everything on the list.
</WelcomeText>
<WelcomeText>
The order will be sent straight to your doorstep in less then
1hr pre-packed for you in portions.
Start cooking by following the visual guide in your order and serve your family a healthy meal.
</WelcomeText>
</WelcomeContentText>
</WelcomeContent>
</WelcomeContainer>
</div>
)
}
export default Welcome;
- Styles of the Welcome section => Welcome.styles.js
Component 5 : Recipe section
This section was fun to make. Got the idea from dribble. I loved the overall outcome with the layout. For the responsive design, it was a bit of pain at first but I got it to work. You can check the link on my Github.
Create the Recipe folder, add the
recipe.js
andrecipe.styles.js
file. For code, as usual, it will be in the recipe.js file and the styling using styled-components will be in the recipe.styles.js file.In the recipe.js file, you can add the code below.
Ps: this is one of the files I need to refactor, the code even hurts my eyes, haha. π«
import {OutlineButton} from '../../Globalstyles';
import SalmonImg from '../../images/salmon.png';
import ChickenImg from '../../images/Chicken.svg';
import PizzaImg from '../../images/Italian-pizza.svg';
import PastaImg from '../../images/Pasta.svg';
import SaladImg from '../../images/salad.png';
import {
RecipeContainer,
RecipeWrapper,
RecipeTitle,
RecipeContentContainer,
RecipeTabContainer,
RecipeBtn,
RecipeCardWrapper,
RecipeFeature,
RecipeFeatureContent,
RecipeFeatureTitle,
RecipeFeatureText,
RecipeFeatureDetails,
RecipeFeatureItem,
RecipeItemTitle,
RecipeItemContent,
RecipeItemIcon,
RecipeItemText,
RecipeCardSection,
RecipeSmallCards,
RecipeCard,
RecipeCardContent,
RecipeCardHeading,
RecipeCardDetails,
RecipeCardItems,
RecipeCardTitle,
RecipeCardItem,
RecipeCardIcon,
RecipeCardText,
RecipeImg,
Img,
} from './Recipes.styles';
const Recipes = () => {
return (
<div>
<RecipeWrapper>
<RecipeContainer>
<RecipeTitle>Recipes</RecipeTitle>
<RecipeContentContainer>
<RecipeTabContainer>
<RecipeBtn to='/sea-food'>
<OutlineButton big bigFont bigRadius>Sea Food</OutlineButton>
</RecipeBtn>
<RecipeBtn to='/Vegetarian'>
<OutlineButton big bigFont bigRadius>Vegetarian</OutlineButton>
</RecipeBtn>
<RecipeBtn to='/meat'>
<OutlineButton big bigFont bigRadius>Meat and Poultry</OutlineButton>
</RecipeBtn>
<RecipeBtn to='/easy-preps'>
<OutlineButton big bigFont bigRadius>Easy meal preps</OutlineButton>
</RecipeBtn>
</RecipeTabContainer>
<RecipeCardWrapper>
<RecipeFeature>
<RecipeImg src={SalmonImg} alt="Salmon Recipe"/>
<RecipeFeatureContent>
<RecipeFeatureTitle>
Salmon and Hot Honey Butter
</RecipeFeatureTitle>
<RecipeFeatureText>
The hot honey kinda sounds like a hype name used before the 20s, (I used it back then).
Itβs a perfect coating for the salmon to enrich it with sweetness and heat.
</RecipeFeatureText>
<RecipeFeatureDetails>
<RecipeFeatureItem>
<RecipeItemTitle>Serving</RecipeItemTitle>
<RecipeItemContent>
<RecipeItemIcon/>
<RecipeItemText>2</RecipeItemText>
</RecipeItemContent>
</RecipeFeatureItem>
<RecipeFeatureItem>
<RecipeItemTitle>Cook time</RecipeItemTitle>
<RecipeItemText>35-45 min</RecipeItemText>
</RecipeFeatureItem>
<RecipeFeatureItem>
<RecipeItemTitle>Difficulty level</RecipeItemTitle>
<RecipeItemText>20%</RecipeItemText>
</RecipeFeatureItem>
</RecipeFeatureDetails>
</RecipeFeatureContent>
</RecipeFeature>
<RecipeCardSection>
<RecipeSmallCards>
<RecipeCard>
<Img src={ChickenImg} alt="Chicken Recipe"/>
<RecipeCardContent>
<RecipeCardHeading>
Pretzel-Crusted Chicken
</RecipeCardHeading>
<RecipeCardDetails>
<RecipeCardItems>
<RecipeCardTitle>Serving</RecipeCardTitle>
<RecipeCardItem>
<RecipeCardIcon/>
<RecipeCardText>2</RecipeCardText>
</RecipeCardItem>
</RecipeCardItems>
<RecipeCardItems>
<RecipeCardTitle>Cook time</RecipeCardTitle>
<RecipeCardText>30-45 min</RecipeCardText>
</RecipeCardItems>
<RecipeCardItems>
<RecipeCardTitle>Difficulty level</RecipeCardTitle>
<RecipeCardText>20%</RecipeCardText>
</RecipeCardItems>
</RecipeCardDetails>
</RecipeCardContent>
</RecipeCard>
<RecipeCard>
<Img src={SaladImg} alt="Salad Recipe"/>
<RecipeCardContent>
<RecipeCardHeading>
Sesame Asian Salad
</RecipeCardHeading>
<RecipeCardDetails>
<RecipeCardItems>
<RecipeCardTitle>Serving</RecipeCardTitle>
<RecipeCardItem>
<RecipeCardIcon/>
<RecipeCardText>2</RecipeCardText>
</RecipeCardItem>
</RecipeCardItems>
<RecipeCardItems>
<RecipeCardTitle>Cook time</RecipeCardTitle>
<RecipeCardText>10-15 min</RecipeCardText>
</RecipeCardItems>
<RecipeCardItems>
<RecipeCardTitle>Difficulty level</RecipeCardTitle>
<RecipeCardText>10%</RecipeCardText>
</RecipeCardItems>
</RecipeCardDetails>
</RecipeCardContent>
</RecipeCard>
</RecipeSmallCards>
<RecipeSmallCards>
<RecipeCard>
<Img src={PizzaImg} alt="Pizza Recipe"/>
<RecipeCardContent>
<RecipeCardHeading>
Italian Pizza with Cheese
</RecipeCardHeading>
<RecipeCardDetails>
<RecipeCardItems>
<RecipeCardTitle>Serving</RecipeCardTitle>
<RecipeCardItem>
<RecipeCardIcon/>
<RecipeCardText>2</RecipeCardText>
</RecipeCardItem>
</RecipeCardItems>
<RecipeCardItems>
<RecipeCardTitle>Cook time</RecipeCardTitle>
<RecipeCardText>30-45 min</RecipeCardText>
</RecipeCardItems>
<RecipeCardItems>
<RecipeCardTitle>Difficulty level</RecipeCardTitle>
<RecipeCardText>20%</RecipeCardText>
</RecipeCardItems>
</RecipeCardDetails>
</RecipeCardContent>
</RecipeCard>
<RecipeCard>
<Img src={PastaImg} alt="Pasta Recipe"/>
<RecipeCardContent>
<RecipeCardHeading>
Pasta with creamy sause
</RecipeCardHeading>
<RecipeCardDetails>
<RecipeCardItems>
<RecipeCardTitle>Serving</RecipeCardTitle>
<RecipeCardItem>
<RecipeCardIcon/>
<RecipeCardText>2</RecipeCardText>
</RecipeCardItem>
</RecipeCardItems>
<RecipeCardItems>
<RecipeCardTitle>Cook time</RecipeCardTitle>
<RecipeCardText>10-15 min</RecipeCardText>
</RecipeCardItems>
<RecipeCardItems>
<RecipeCardTitle>Difficulty level</RecipeCardTitle>
<RecipeCardText>10%</RecipeCardText>
</RecipeCardItems>
</RecipeCardDetails>
</RecipeCardContent>
</RecipeCard>
</RecipeSmallCards>
</RecipeCardSection>
</RecipeCardWrapper>
</RecipeContentContainer>
</RecipeContainer>
</RecipeWrapper>
</div>
);
}
export default Recipes;
- Styles of the Recipes section => Recipes.styles.js
- For the styles, I used flexbox hence the increase of code. But you can style it however you want, maybe use grid layout.
Component 6: Personalize meals section
This is a simple section similar to the welcome section. You can use grid or flexbox for this, no need to worry.
Remember to create the folder where you will write your code for the component and export it to the index.js file.
- In the meals.js file add the following code. (Yes, I know I am bad naming folders, haha πͺ)
import {Button} from '../../Globalstyles';
import ChickenImg from '../../images/Big-chicken.svg';
import {
MealsContainer,
MealsWrapper,
MealsImage,
Img,
MealsContent,
MealsContentTitle,
MealsContentText,
MealsContentItems,
MealsContentList,
MealsContentDetails,
MealsContentIcon,
MealsContentCategory,
MealsContentBtn
} from './Meals.styles';
function Meals() {
return (
<div>
<MealsContainer>
<MealsWrapper>
<MealsImage>
<Img src={ChickenImg} alt= "Personalized Chicken meal"/>
</MealsImage>
<MealsContent>
<MealsContentTitle>Personalize your Meals</MealsContentTitle>
<MealsContentText>
Choose your weekly or daily meal plan from our meals to kick
start your month. All meanu are fresh and set for you in portion to make it easier to cook immediately.
</MealsContentText>
<MealsContentItems>
<MealsContentList>
<MealsContentDetails>
<MealsContentIcon/>
<MealsContentCategory> Vegetarian</MealsContentCategory>
</MealsContentDetails>
<MealsContentDetails>
<MealsContentIcon/>
<MealsContentCategory>Gluten-Free</MealsContentCategory>
</MealsContentDetails>
<MealsContentDetails>
<MealsContentIcon/>
<MealsContentCategory>Card-conscious</MealsContentCategory>
</MealsContentDetails>
<MealsContentDetails>
<MealsContentIcon/>
<MealsContentCategory>Calorie -conscious</MealsContentCategory>
</MealsContentDetails>
</MealsContentList>
<MealsContentList>
<MealsContentDetails>
<MealsContentIcon/>
<MealsContentCategory>15 mins pre-kit</MealsContentCategory>
</MealsContentDetails>
<MealsContentDetails>
<MealsContentIcon/>
<MealsContentCategory>Featured Meals</MealsContentCategory>
</MealsContentDetails>
<MealsContentDetails>
<MealsContentIcon/>
<MealsContentCategory>New recipes</MealsContentCategory>
</MealsContentDetails>
<MealsContentDetails>
<MealsContentIcon/>
<MealsContentCategory>Low fat meals</MealsContentCategory>
</MealsContentDetails>
</MealsContentList>
</MealsContentItems>
<MealsContentBtn to='/order-now'>
<Button big bigFont bigRadius>Explore Our Meals</Button>
</MealsContentBtn>
</MealsContent>
</MealsWrapper>
</MealsContainer>
</div>
)
}
export default Meals;
- Styles for the Meals section => Meals.styles.js
Component 7: The footer section
This is the last component for the website. The footer section is easier to style with flexbox. Just look at the content in terms of the bigger block inside small blocks. Your eyes should work like Pesticide chrome extension, try to see the bigger picture of the layout, the big blocks inside small blocks, etc. (Haha, it's a trick that works for me, plus it makes coding easier.π€)
- Create the footer folder, add the
Footer.js
andFooter.styles.js
file. Inside the footer.js file add the code below.
import {
FooterSection,
FooterContainer,
FooterNewsletter,
FooterNewsletterTitle,
FooterNewsletterText,
FooterNewsletterForm,
FooterNewsletterInput,
FooterBtn,
FooterLinkContainer,
FooterLinksWrapper,
FooterLinks,
FooterLinkTitle,
FooterLink,
FooterCopyRight,
FooterLabel
} from './Footer.styles';
function Footer() {
return (
<div>
<FooterSection>
<FooterContainer>
<FooterNewsletter>
<FooterNewsletterTitle>Join our listing for execlusive discounts and new recipes</FooterNewsletterTitle>
<FooterNewsletterText>We create new recipes every week and cooking tips</FooterNewsletterText>
<FooterNewsletterForm>
<FooterLabel htmlFor="email">Email address</FooterLabel>
<FooterNewsletterInput name="email" id="email" type="email" placeholder="Email address" />
<FooterBtn>Submit</FooterBtn>
</FooterNewsletterForm>
</FooterNewsletter>
<FooterLinkContainer>
<FooterLinksWrapper>
<FooterLinks>
<FooterLinkTitle>About Us</FooterLinkTitle>
<FooterLink to='/'>Our Chefs</FooterLink>
<FooterLink to='/'>Our Farm</FooterLink>
<FooterLink to='/'>Testimonials</FooterLink>
<FooterLink to='/'>Terms of service</FooterLink>
</FooterLinks>
<FooterLinks>
<FooterLinkTitle>Services</FooterLinkTitle>
<FooterLink to='/about'>How it works</FooterLink>
<FooterLink to='/'>Meal prep kit</FooterLink>
<FooterLink to='/'>Gift cards</FooterLink>
<FooterLink to='/'>Orders</FooterLink>
</FooterLinks>
</FooterLinksWrapper>
<FooterLinksWrapper>
<FooterLinks>
<FooterLinkTitle>Resources</FooterLinkTitle>
<FooterLink to='/'>Kitchenware</FooterLink>
<FooterLink to='/'>Recipes</FooterLink>
<FooterLink to='/'>FAQ & Support</FooterLink>
<FooterLink to='/'>Affiliate Program</FooterLink>
</FooterLinks>
<FooterLinks>
<FooterLinkTitle>Contact</FooterLinkTitle>
<FooterLink to='/'>Instagram</FooterLink>
<FooterLink to='/'>Facebook</FooterLink>
<FooterLink to='/'>Youtube</FooterLink>
<FooterLink to='/'>Linkedin</FooterLink>
</FooterLinks>
</FooterLinksWrapper>
</FooterLinkContainer>
<FooterCopyRight to='https://github.com/muchirijane'> © Copyright 2020, Designed and coded with π by Jane Tracy</FooterCopyRight>
</FooterContainer>
</FooterSection>
</div>
)
}
export default Footer;
- Styles for the Footer section => Footer.styles.js
- Remember to export the footer component inside the index.js file.
The App.js file
In the app.js file will import our components.
import {BrowserRouter as Router,Switch,Route} from "react-router-dom";
import {Hero, Works,Welcome,Recipes,Meals,Footer} from './components';
import GlobalStyles from './Globalstyles';
function App() {
return (
<Router>
<GlobalStyles/>
<Hero/>
<Works/>
<Welcome/>
<Recipes/>
<Meals/>
<Footer/>
</Router>
);
}
export default App;
- For the whole code check my Github. Congratulations you just made a simple react website. I couldn't put all the code because the post would be extremely long, but I tried to cover the most important parts.
In conclusion
The only way to learn is by doing. Go to Figma app and start doing your wireframes and code it up. Along the way, you will learn a lot as your google stuff you don't understand or don't know how to use. To give you a simple picture, I google how to import a font family, import local images, etc. Don't feel like you can't do it, yes you can Code Newbie. π€(I have a feeling I am gonna laugh at my code 5yrs to come.)
I really did a lot to create this post even though it is long I hope it's useful in any way. I can't wait to learn more about React. Week three of learning React was terrific.
If you find this post useful, share it with your peers or beginners who are learning React and might find this article useful to their journey. You can also buy me coffee for support as I write more posts. π
Top comments (8)
nice Job Jane
Thank you. Much appreciate it, Samuel :)
Wow ! Its time I try my hand at styled-components. Thanks for the guide Jane :)
You will enjoy it, especially if you love SASS.
Glad you enjoyed it Ridhik :)
super awesome
Some comments may only be visible to logged-in visitors. Sign in to view all comments.