Im trying to create a Pizza delivery app with React and next.js. What I'm stuck with is the photos of the pizzas I have in the sanity backend won't render to the app. I can see the json array for the 6 pizzas in the terminal and also the console after i connect the backend. I've been stuck on this all day and appreciate any help. Is there a different way to pass pizzas to the Home function in the index.js? :)
The exact error is below aswell.
error - components\Menu.jsx (17:27) # eval
TypeError: (0 , _lib_client__WEBPACK_IMPORTED_MODULE_1__.default) is not a function
15 | {/* pizzas */}
16 | {pizzas.map((pizza, id) => {
> 17 | const src = urlFor(pizza.image);
| ^
18 | console.log(pizza.image);
19 | return (
20 | <div className={css.pizza} key={id}>
Index.js
import Layout from '../components/layout';
import Hero from '../components/Hero';
import css from '../styles/Home.module.css';
import Services from '../components/Services';
import { client } from '../lib/client';
import Menu from '../components/Menu';
export default function Home({ pizzas }) {
return (
<Layout>
<div className={css.container}>
<Head>
<title>FUDO</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/Logo.png" />
</Head>
{/* body */}
<main>
<Hero />
<Services />
<Menu pizzas={pizzas} />
</main>
</div>
</Layout>
);
}
export const getServerSideProps = async () => {
const query = '*[_type == "pizza"]';
const pizzas = await client.fetch(query);
console.log(pizzas);
return {
props: {
pizzas,
},
};
};
Menu.jsx
import urlFor from '../lib/client';
import Image from 'next/image';
export default function Menu({ pizzas }) {
console.log(pizzas);
return (
<div className={css.container}>
<div className={css.heading}>
<span>OUR MENU</span>
<span>Menu That Always</span>
<span>Make You Fall In Love</span>
</div>
{/* pizzas */}
{pizzas.map((pizza, id) => {
const src = urlFor(pizza.image);
console.log(pizza.image);
return (
<div className={css.pizza} key={id}>
<div className={css.ImageWrapper}>
<Image
loader={() => src}
src={src}
alt=""
objectFit="cover"
layout="fill"
/>
</div>
</div>
);
})}
</div>
);
}
Client.js
import SanityClient from '#sanity/client';
import ImageUrlBuilder from '#sanity/image-url';
export const client = SanityClient({
projectId: 'exiz0rgv',
dataset: 'production',
apiVersion: '2022-09-01',
useCdn: true,
token:
'skT82oCId91vDPWOQoLVx6qVxX3mLxGYzSQeX0tsRRS2KGDFtmWXuIRxz0yyz3RyErMeUHraDpTDTLbWgjoiLcnh4GoL3CChOcNpkGFzQeywcAR73yQiqnxjBlL3Z435QgzTZJEEZJnI7O0R4RdQaCivBTKKIBV79efdtavbNvcfx9iSB2nS',
});
const builder = ImageUrlBuilder(client);
export const urlFor = (source) => builder.image(source);
Related
Actually I wanna create slider with dots, slider is working, but dots are hidden. How should I make dots visible while using react swipper slider.
I am using styled components for css. The thing is, I cannot find what is false in this part of code. please help me to figure out with this problem.
I tried to make my slider dots visible, however they are not showing.
this is my code
import { Pagination, Navigation, Scrollbar, A11y } from 'swiper';
import { Images } from 'assets/images';
import { useWindowDimensions } from 'hooks/useWindowDimensions';
import { useNavigate } from 'react-router-dom';
import { ROUTES } from 'utils/routeNames';
import { Swiper, SwiperSlide } from 'swiper/react';
// Import Swiper styles
import 'swiper/swiper.scss';
import {
CardAndDescriptionBlock,
CardBlock,
CountryImage,
TripDurationAndPrice,
TripDuration,
CardDescription,
TripCountryAndPrice,
CountryStarsPriceWrapper,
TripCountryAndStars,
TripPrice,
PricePerPerson,
TripCountry,
ReadMore,
DescriptionContainer,
} from './styled';
export const HotOffersCarousel = ({ hotOffers }) => {
const navigate = useNavigate();
const { width } = useWindowDimensions();
const navigateToTour = (id) => {
navigate(`${ROUTES.HOT_TOURS}/${id}`);
};
return (
<Swiper
slidesPerView={width < 768 ? 2 : 1}
spaceBetween={10}
slidesPerGroup={width < 768 ? 2 : 1}
loop={true}
pagination={{
dynamicBullets: true,
}}
modules={[Pagination, Navigation, Scrollbar, A11y]}
className="mySwiper"
>
{hotOffers?.map((item) => (
<SwiperSlide key={item.id}>
<CardAndDescriptionBlock>
<CardBlock>
<CountryImage background={item?.main_image}>
<TripDurationAndPrice>
<TripDuration>
{item?.stay_days} Days / {item?.stay_nights} nights
</TripDuration>
<PricePerPerson> $ {item?.price}/Person </PricePerPerson>
</TripDurationAndPrice>
</CountryImage>
<TripCountryAndPrice>
<CountryStarsPriceWrapper>
<TripCountryAndStars>
<TripCountry> {item?.title} </TripCountry>
<img src={Images.stars} />
</TripCountryAndStars>
<TripPrice>$ {item?.price} </TripPrice>
</CountryStarsPriceWrapper>
<DescriptionContainer
isMedia
dangerouslySetInnerHTML={{ __html: item.description }}
/>
<ReadMore onClick={() => navigateToTour(item?.id)} isMedia>
Read More <img src={Images.mainColorRightArrow} />
</ReadMore>
</TripCountryAndPrice>
</CardBlock>
<CardDescription>
<TripCountryAndStars>
<TripCountry> Venice Italy </TripCountry>
<img src={Images.stars} />
</TripCountryAndStars>
<DescriptionContainer
dangerouslySetInnerHTML={{ __html: item.description }}
/>
<ReadMore onClick={() => navigateToTour(item?.id)}>
Read More <img src={Images.mainColorRightArrow} />
</ReadMore>
</CardDescription>
</CardAndDescriptionBlock>
</SwiperSlide>
))}
</Swiper>
);
};
I'm trying to have restaurant cards displayed on my app and I'm not sure what would be the best way to have the image conditionally render according to which restaurant it is. This way it works but it is not optimal since if I have 10 I have to manually add all 10 imports and cases.
import Link from "next/link";
import React from "react";
import styles from "../styles/Card.module.css";
import kegLogo from "../assets/Keg.png";
import Image from "next/image";
import pizzaLogo from "../assets/pizza-logo.png";
function RestaurantCard({ id, title, description }) {
return (
<Link className={styles.link} href={`/restaurants/${title}`}>
<div className={styles.card}>
{id == 1 && (
<Image className={styles.image} src={kegLogo} alt={title} />
)}
{id == 2 && (
<Image className={styles.image} src={pizzaLogo} alt={title} />
)}
<div className={styles.content}>
<h3 className={styles.title}>{title}</h3>
<p className={styles.description}>{description}</p>
</div>
</div>
</Link>
);
}
export default RestaurantCard;
I'm JS newbie making a website :)
When I scroll down from main page,
I want to make it move to each component(Comp1,Comp2..) right away.
But I don't know what to do..
Can you tell me what to look for?
I wrote the react code as below.
import React from 'react'
import {Header} from 'components/Header'
import {Title} from 'style/CommonStyle';
const Comp1 = () => {
return (
<div>
<Title>Title of Comp1</Title>
...
</div>
)
}
const Comp2 = () => {
return (
<div>
<Title>Title of Comp1</Title>
...
</div>
)
}
const MainPage = () => {
return (
<div>
<Header />
<Comp1 />
<Comp2 />
</div>
)
}
export default MainPage
I'm having an issue where my navigation bar created with React-router-dom is not "scrolling/taking" me to the right place in the page, in fact, it is not taking me anywhere at all. This is a single page app
This is my App component where I set the Router and the paths of each component
import React, { useState, useReducer } from 'react'
import Footer from './Components/Footer';
import HeroSection from './Components/HeroSection'
import AboutMe from './Components/AboutMe';
import Projects from './Components/Projects';
import Modal from './Components/Modal';
import Form from './Components/Form'
import ScrollTop from './Components/ScrollTop';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import NavBar from './Components/NavBar'
function App() {
const [show, setShow] = useReducer((p) => !p, false);
const [data, setData] = useState()
const handleData = (newData) => setData(newData)
return (
<div>
<Router>
<NavBar/>
<Switch>
<Route path='/aboutme' component={AboutMe}/>
<Route path='/projects' component={Projects}/>
<Route path='/contact' component={Form}/>
</Switch>
</Router>
<HeroSection/>
<AboutMe/>
<Projects setData={handleData} setShow = {setShow}/>
<Modal data={data} show={show} setShow={setShow} />
<Form/>
<ScrollTop></ScrollTop>
<Footer/>
</div>
)
}
export default App;
This is my NavBarwhere I set up the Links
import React, {useState} from 'react'
import {Link} from 'react-router-dom'
import * as FaIcons from 'react-icons/fa'
import * as AiIcons from 'react-icons/ai'
import {NavBarData} from './NavBarData'
const NavBar = () => {
const [sideBar, setSideBar] = useState(false)
const showSidebar = () => {
setSideBar(!sideBar)
}
return(
<>
<div className="navbar">
<Link to="#" className="menuBars">
<FaIcons.FaBars onClick={showSidebar}/>
</Link>
</div>
<nav className={sideBar ? "navMenuActive" : "navmenu"}>
<ul className="navMenuItems">
<li className="navbarToggle">
<Link to="#" className="menuBars">
<AiIcons.AiOutlineClose/>
</Link>
</li>
{NavBarData.map((item, index) => {
return(
<li key={index}>
<Link to={item.path}>
<span>{item.title}</span>
</Link>
</li>
)
})}
</ul>
</nav>
</>
)
}
export default NavBar
I have a separate file NavBarData where I store the data for each link
export const NavBarData = [
{
title: "About Me",
path: "/aboutme"
},
{
title: "Projects",
path: "/projects"
},
{
title: "Contact",
path: "/contact"
},
]
I have created a miniversion in codesandbox which kind of works frustrating enough but I still can't understand what I am doing wrong.
https://codesandbox.io/s/modest-currying-3o9oq?file=/src/App.js
🐛 Problem
Apparently, you are trying to scroll to a specific section using react-router-dom.
💡 Possible solutions
You can just use a HTML tag for that, using its href property with the section id.
💻 Code
sectionOne.js
function SectionOne() {
return (
<section id="sectionOne">
children
</section>
)
}
export default SectionOne;
NavBarData.js
export const NavBarData = [
{
title: "About Me",
path: "#sectionOne"
}
]
NavBar.js
function NavBar() {
return (
{NavBarData.map((item, index) => (
<li key={index}>
<a href={item.path}>
<span>{item.title}</span>
</a>
</li>
)}
)
export default NavBar;
💡 Extra tip
Using a dependency for this will just increase your bundle size, so unless it really has more than one specific route, it's not necessary to install.
Using the CSS property scroll-behavior: smooth, you can make the effect when the scrolling starts.
I finally find out why it wasn't working. Apparently in single page apps where you need to be scrolled to a certain point in the page rather than navigating, you are meant to use HashLink
I ran npm install --save react-router-hash-link and used a HashRouter in my App.js, going to leave the code here in case someday someone faces a similar issue.
App.js
import React, { useState, useReducer } from 'react'
import Footer from './Components/Footer';
import HeroSection from './Components/HeroSection'
import AboutMe from './Components/AboutMe';
import Projects from './Components/Projects';
import Modal from './Components/Modal';
import Form from './Components/Form'
import ScrollTop from './Components/ScrollTop';
import { HashRouter as Router, Route, Switch } from 'react-router-dom'
import NavBar from './Components/NavBar'
function App() {
const [show, setShow] = useReducer((p) => !p, false);
const [data, setData] = useState()
const handleData = (newData) => setData(newData)
return (
<div>
<Router>
<NavBar/>
<Switch>
<Route path='/aboutme' component={AboutMe}/>
<Route path='/projects' component={Projects}/>
<Route path='/contact' component={Form}/>
</Switch>
</Router>
<HeroSection/>
<AboutMe/>
<Projects setData={handleData} setShow = {setShow}/>
<Modal data={data} show={show} setShow={setShow} />
<Form/>
<ScrollTop></ScrollTop>
<Footer/>
</div>
)
}
export default App;
NavBar.js
import React, {useState} from 'react'
import {HashLink} from 'react-router-hash-link'
import * as AiIcons from 'react-icons/ai'
import * as FaIcons from 'react-icons/fa'
import {NavBarData} from './NavBarData'
const NavBar = () => {
const [sideBar, setSideBar] = useState(false)
const showSidebar = () => {
setSideBar(!sideBar)
}
return(
<>
<div className="navbar">
<HashLink to="#" className="menuBars">
<FaIcons.FaBars onClick={showSidebar}/>
</HashLink>
</div>
<nav className={sideBar ? "navMenuActive" : "navmenu"}>
<ul className="navMenuItems">
<li className="navbarToggle">
<HashLink to="#" className="menuBars">
<AiIcons.AiOutlineClose/>
</HashLink>
</li>
{NavBarData.map((item, index) => {
return(
<li key={index}>
<HashLink to={item.path} smooth>
<span>{item.title}</span>
</HashLink>
</li>
)
})}
</ul>
</nav>
</>
)
}
export default NavBar
EDIT:
For this to work you need to give the section/element you want to scroll to an id attribute and the HashLink to parameter will take /#idgiventoelement
ProductsCard
import React from 'react'
import { Card, Container, Row, Col, ListGroup, Button} from 'react-bootstrap'
function ProductCard(props){
return(
<div>
<Container>
<Row>
<Col md={3} xs={6}>
<Card border="primary" style={{widht:'14rem'}}>
<Card.Img variant="top" src={props.product.image}/>
<Card.Body>
<Card.Title>{props.product.name}</Card.Title>
<Card.Text>Price: ${props.product.price}, Quantity: {props.product.quantity}
</Card.Text>
<Button variant="primary">Add to Cart</Button>
</Card.Body>
</Card>
</Col>
</Row>
</Container>
</div>
)
}
export default ProductCard
Home
import Axios from 'axios';
import React, { useEffect, useState } from 'react';
import {Container, Row, Col, Image, Card, Button, CardDeck} from 'react-bootstrap';
import axios from 'axios';
import ProductCard from './ProductCard';
enter code here
function Home(){
const url = 'http://localhost:8888/ProgWeb/public/api/products'
const [product, setProduct]=useState({
loading: false,
data: null,
error: false
})
useEffect(() => {
setProduct({
loading:true,
data: null,
error: false
})
axios.get(url)
.then(response => {
setProduct({
loading: false,
data: response.data,
error: false
})
})
.catch(() =>{
setProduct({
loading: false,
data: null,
error: true
})
})
}, [url])
let content = null
if(product.data){
content =
product.data.map((product, key) =>
<div key={product.id}>
<ProductCard
product={product}
/>
</div>
)
}
return (
<div>
{content}
</div>
);
}
export default Home;
Now this is my first time using react-bootstrap. So I don't have much clue here.
What I want is for the cards to be generated in such a way that there are THREE cards in a row.
Now this is the code that I have done so far, but I am confused on how can I make the cards horizontal, I already typed in bootstrap but I still get the products vertically
In your ProductsCard component, Give your div container an id, it can be anything. Example:
function ProductCard(props){
return(
<div id=“unique-name”>
<Container>
<Row>
...
</Row>
</Container>
</div>
)
}
Now go to your css file and add the following:
#unique-name {
display: flex;
flex-direction: row;
justify-content: space-around
}
We are making the Container a flexbox and changing the direction to horizontal.
Reference: https://css-tricks.com/almanac/properties/f/flex-direction/
ALTERNATIVELY:
You can Simply add class=“row” to the div element like this:
if(product.data){
content =
product.data.map((product, key) =>
<div class=“row” key={product.id}>
<ProductCard
product={product}
/>
</div>
)
}
Let me know if this helps!