Coding up a React Travel Journal
Tags: react, javascript, css, html
Published: 2022-10-27 20:52:17

I now have two slightly more complicated React projects under my belt. The first, an AirBnB Experiences Clone app, I did as a code-along project with Scrimba. ([Link to repo](https://github.com/atoopdev/air-bnb-experiences-clone).)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ihf7fxv8zw2n8djdqtt.jpg)

## airbnb Experiences Clone

This airbnb experiences clone app pulled in a data file of "experiences" objects, converted them to an array of objects, and then mapped each object to Card() component, which output each objects relevant data in formatted html. The entire project was then styled with CSS. 

Here is the code from my container app - App.js:

```javascript
import logo from './logo.svg';
import Top from "./components/Top"
import Card from "./components/Card"
import photoexperience from "./images/katie-zaferes.png"
import CardData from "./data"

// note had to find custom image solution - https://delftstack.com/howto/react/react-img-src/

function App() {

  //note assign key to eliminate key error
  // pass entire object to Card()
  const cardElements = CardData.map((card)=>{
    return <Card 
    key={card.id}
    card={card}/>
  })

  // console.log("cardElements: ", cardElements)


  return (
   <div>
    <Top />
    <div className="experience-photos">{cardElements}</div>
   </div>
  );
}

export default App;
```
Here is the code from the Card.js component:

```javascript
import React from "react"
import photoexperience from "../images/katie-zaferes.png"
import star from "../images/star.png"

export default function Card(props){
    
    let badgeText
    if(props.card.openSpots===0){
        badgeText = "Sold-Out"
    } else if (props.card.country === "Online"){
        badgeText = "Online"
    }
    console.log(props.card)
    return <div className="experience-listing">
        {/* conditional display if there is badge text*/}
        {badgeText && <div className="experience-status">{badgeText}</div>}
        <img className="experience-img" src={props.card.coverImg} alt={props.card.title}></img>
        <div className="review-div">
        <img className="star-img" src={star} alt="star"></img>
            <span className="rating">{props.card.stats.rating}</span>
            <span className="review-count grey"> ({props.card.stats.reviewCount}) * </span>
            <span className="country grey"> {props.card.location}</span>
            
        </div>
        {/* end review div */}
        <p className="experience-heading">{props.card.title}</p>
        <p className="experience-price"><span className="bold">From ${props.card.price}</span> / person</p>
        </div>
        {/* holds one photo */}

    // holds all photos
}
```
and here is a snippet of the data file:

```javascript
export default [
    {
        id: 1,
        title: "Life Lessons with Katie Zaferes",
        description: "I will share with you what I call \"Positively Impactful Moments of Disappointment.\" Throughout my career, many of my highest moments only came after setbacks and losses. But learning from those difficult moments is what gave me the ability to rise above them and reach my goals.",
        price: 136,
        coverImg: "katie-zaferes.png",
        stats: {
            rating: 5.0,
            reviewCount: 6
        },
        location: "Online",
        openSpots: 0,
    },
<...>
]
```
The main problem that I ran into in this tutorial was understanding where image files needed to be stored in order to be accessible. I was able to search for and find [this resource](https://www.delftstack.com/howto/react/react-img-src/), which explained that if you want to import a local image - the image needs to be stored in a subfolder of the src folder in your App. If you are using a data file with photo file names, like I was, then you need to store those images in the public folder, or in a subfolder ("images" for example.)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/se2zuiejw982klfk4poq.jpg)

## Travel Journal App

Next, I used the basic techniques of the airbnb experiences clone to write up a small travel journal app using React. Each travel journal entry displays a location image, link to Google maps, and short description. The format is essentially the same as above in terms of structure. (Link to [repo](https://github.com/atoopdev/travel-journal/tree/main/travel-journal).)

Here is the container app code:

```javascript
import TravelData from "./data"
import TripCard from './components/tripcard';
import Header from "./components/header"


function App() {
  // get data out of file and into object

  const tripElements = TravelData.map(
    (trip) =>{
      // return <TripCard title={trip.title}/>
      return <TripCard key={trip.id} trip={trip} />
    }
  )
console.log(tripElements)

  return (
    <div>
    <Header />
    <div className="trip-listing">{tripElements}
    </div>
    </div>
  );
}

export default App;

```
The TripCard.js component code:

```javascript
import React from "react"
import MapIcon from "../images/map-pin-solid.svg"

export default function TripCard(props){
    let image = props.trip.imageURL
    console.log(image)
    return <div className="trip-card"><h1 className="trip-title">{props.trip.title}</h1>
    <img className="trip-image" src={props.trip.imageURL} alt={props.trip.title}></img>

    <div className="location">
    <img src={MapIcon} className="location-icon" alt="map pin icon"></img>
    <h2 className="trip-location">{props.trip.location}</h2><a href={props.trip.googleMapsUrl}className="location-link">View on Google Maps</a></div>

    <span className="trip-date">{props.trip.visitDate}</span>
    <p className="trip-description">{props.trip.description}</p>
    </div>
}

```

and a snippet of the data file object -

```javascript
export default [
    {
        id: 1,
        title: "Volcanos National Park",
        location:"USA",
        googleMapsUrl:"https://goo.gl/maps/dPk4XiWD7roXFjhx8",
        visitDate:"June 2010",
        description:"Unique destination to spot live lava flows, lava tubes & glowing craters is popular with tourists.",
        photographerCredits:"https://unsplash.com/photos/xfSdarS1wus",
        imageURL:"https://images.unsplash.com/photo-1509780764860-beca5b971c4b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80"

    },
<...>

]
```