DEV Community

Christopher Coffee
Christopher Coffee

Posted on

Creating a Keith Lee Food App w/ React.js & ChatGPT

Creating a Keith Lee Food App w/ React.js & ChatGPT

This personal project was inspired by watching Keith Lee and wanting to try the family-owned restaurants he reviewed on his platforms. I was initially using a spreadsheet to keep track of the names and addresses of the places.

Here are his socials for reference:
@keith_lee125 | Twitter, Instagram, TikTok | Linktree

For the weekend, I decided to hack together two simple React.js web apps to improve this process.

UPDATE: Recently added maps and the ability to order food.

Note: I have moved away from firebase, but the following steps will work. I have moved to Supabase for the backend and Netlify for hosting. These platforms are more cost-efficient. I will have articles detailing how to do this soon.

Set up Firebase Firestore

I wanted to store this in a remote database. I chose to use Firebase so I could quickly put this together.

You can create a new project by going to the firebase console.

https://console.firebase.google.com/

Once your project is created. Click on Add app. It’s under your project name at the top center of the page.

Next, choose the web platform.

Give your web app a name and click Register app

Now it will give you instructions on how to install firebase.

We will follow these instructions soon, but first, we need to create a react app. Keep this tab open. We will refer to it soon. Specifically, we will need the firebase config

I also wanted ChatGPT to generate the boilerplate code. So let’s do that first.

ChatGPT

I used ChatGPT to try to make this process easier. It gave a few incorrect code snippets, but this is also maybe because I’m using the latest versions of everything, and ChatGPT was only trained up to a certain time period.

I only wanted to store the information from Keith Lee’s TikTok videos. So this includes the id used on the TikTok web app, the description used in the video, and embedding the TikTok video.

This tool did help improve the process. Here was my first prompt:

Can you create a react frontend that reads data from firebase firestore. example code

It then replied with this code:

import React, { useState, useEffect } from 'react';
import firebase from 'firebase/app';
import 'firebase/firestore';

const config = {
  // Your Firebase project's config object goes here
};

firebase.initializeApp(config);
const db = firebase.firestore();

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    // Get data from the 'users' collection in Firestore
    db.collection('users').get()
      .then(snapshot => {
        const data = snapshot.docs.map(doc => doc.data());
        setData(data);
      })
      .catch(error => {
        console.log(error);
      });
  }, []);

  return (
    <div>
      <h1>Users</h1>
      <ul>
        {data.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Notice the comment // Your Firebase project’s config object goes here. This is the **const firebaseObject code. **The screenshot cuts off the rest of the code, but here is an example:

const firebaseConfig = {
  apiKey: "yourApiKey",
  authDomain: "projectid.firebaseapp.com",
  projectId: "projectid",
  storageBucket: "projectid.appspot.com",
  messagingSenderId: "77777777777",
  appId: "1:777777777777:web:ab7ag7v7a7",
  measurementId: "G-MEASUREMENTID"
};
Enter fullscreen mode Exit fullscreen mode

Create a new React App

To use this code, we need to create a new react project. I created a new app using the following command

npx create-react-app keith-lee-food
Enter fullscreen mode Exit fullscreen mode

After the react project is created, I installed the firebase SDK using the following command

npm install --save firebase
Enter fullscreen mode Exit fullscreen mode

firebase

I want to note that I installed the latest firebase version using npm, so the code in the useEffect won’t work.

We can follow the documentation to update this code. We could have also asked ChatGPT, and it may have known. Not sure how new this latest version of firebase is.
Get started with Cloud Firestore | Firebase

So the updated will look something like this:

import { collection, getDocs } from "firebase/firestore"; 

const querySnapshot = await getDocs(collection(db, "users"));
querySnapshot.forEach((doc) => {
  console.log('${doc.id} => ${doc.data()}');
});
Enter fullscreen mode Exit fullscreen mode

Of course, we don’t have any data in the database, so it won’t return anything. We also will have a different collection name.

This is the next prompt I gave ChatGPT:

can you change the query to read an id and description and show a tiktok embed widget using the id. also show the description under that

This is the code it replied with

 import React, { useState, useEffect } from 'react';
import firebase from 'firebase/app';
import 'firebase/firestore';

const config = {
  // Your Firebase project's config object goes here
};

firebase.initializeApp(config);
const db = firebase.firestore();

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    // Get data from the 'tiktoks' collection in Firestore
    db.collection('tiktoks').get()
      .then(snapshot => {
        const data = snapshot.docs.map(doc => doc.data());
        setData(data);
      })
      .catch(error => {
        console.log(error);
      });
  }, []);

  return (
    <div>
      {data.map(tiktok => (
        <div key={tiktok.id}>
          <h1>{tiktok.description}</h1>
          <iframe 
            src={'https://www.tiktok.com/embed/${tiktok.id}'}
            frameBorder="0" 
            allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" 
            allowFullScreen 
          />
        </div>
      ))}
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

It still gives the code we can’t use in the useEffect. We can give ChatGPT our code, but I just replaced it with the code mentioned earlier in the documentation.

I took off the iframe because it loaded every video, leading to bad performance. It also auto-plays every time you scroll. autoplay option for allow doesn’t cause this.

Setting up Firebase Firestore with React

Now we need to set enable Firestore on the Firebase console. Go back to the Firebase console and click Continue to console.

Click the Build menu option on the left. Click Firestore Database

On the next screen, click Create database.

Now a popup will show asking us what mode we would like to start in. Keep it at Start in production mode. Click Next.

Next will ask where we want the data stored. I kept it at this region and clicked enable.

Now we can add data through the console to quickly test our application. On this screen, click Start collection.

Give a collection id. I will use the id ChatGPT generated, tiktoks. Click Next.

Now we can create a document. If you are unfamiliar with Firestore, this is a record in our collection.

Using the TikTok website, we can figure out what information we need to save. For now, I will just save the id and description.

Observe the following URL: https://www.tiktok.com/@keith_lee125/video/7186098325475839278

The Document ID and id field will be the long number at the end of the URL.

If you go to the URL, it will go to one of Keith Lee’s videos. I copied the description from there. Click **Save **after adding your data.

Now we need to update the code ChatGPT gave to include the config and web 9 version of firebase. Here is an example:

import React, { useState, useEffect } from 'react';
import { collection, getDocs } from "firebase/firestore"; 
import { initializeApp } from "firebase/app";
import { getFirestore } from 'firebase/firestore'

const config = {
  apiKey: "yourApiKey",
  authDomain: "projectid.firebaseapp.com",
  projectId: "projectid",
  storageBucket: "projectid.appspot.com",
  messagingSenderId: "77777777777",
  appId: "1:777777777777:web:ab7ag7v7a7",
  measurementId: "G-MEASUREMENTID"
};


const firebaseApp = initializeApp(config);
const db = getFirestore(firebaseApp);

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    // Get data from the 'tiktoks' collection in Firestore
      const querySnapshot = await getDocs(collection(db, "tiktoks"));
      querySnapshot.forEach((doc) => {
          setData(doc.data());
      });
  }, []);

  return (
    <div>
      {data.map(tiktok => (
        <div key={tiktok.id}>
          <h4>{tiktok.description}</h4>
          <iframe 
            src={'https://www.tiktok.com/embed/${tiktok.id}'}
            frameBorder="0" 
            allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" 
            allowFullScreen 
          />
        </div>
      ))}
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

I left the code for the iframe in here, but you can leave it if you want. I also changed the h1 to h4.

In the root directory of this project, run this in the terminal to start your application.

npm start
Enter fullscreen mode Exit fullscreen mode

I then wanted to show a button to get directions. For this, I wanted to add latitude and longitude in the database.

I gave another request to ChatGPT as follows:

can you give example if we had longitude and latitude from firebase as well and show a button to get directions. can you show example code.

It replied :

Sure, here is an example of how you can modify the code to read longitude and latitude from Firestore, and show a button that, when clicked, opens the default maps application with the location pre-populated as the destination:

import React, { useState, useEffect } from 'react';
import firebase from 'firebase/app';
import 'firebase/firestore';

const config = {
  // Your Firebase project's config object goes here
};

firebase.initializeApp(config);
const db = firebase.firestore();

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    // Get data from the 'locations' collection in Firestore
    db.collection('tiktok').get()
      .then(snapshot => {
        const data = snapshot.docs.map(doc => doc.data());
        setData(data);
      })
      .catch(error => {
        console.log(error);
      });
  }, []);

  return (
    <div>
      {data.map(tiktok => (
        <div key={tiktok.id}>
          <h1>{location.name}</h1>
          <button onClick={() => {
            window.open('https://www.google.com/maps/dir/?api=1&destination=${tiktok.latitude},${tiktok.longitude}');
          }}>Get Directions</button>
        </div>
      ))}
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

This will open Google Maps website on desktop and iPhone devices. It will open the Google Maps app on Android Devices.

I wanted it to open Apple Maps app on iOS devices. I then asked ChatGPT to do this.

can you change the html to consider if the user is on an apple device. can you show example code

ChatGPT replied with this code:

import React, { useState, useEffect } from 'react';
import firebase from 'firebase/app';
import 'firebase/firestore';

const config = {
  // Your Firebase project's config object goes here
};

firebase.initializeApp(config);
const db = firebase.firestore();

function App() {
  const [data, setData] = useState([]);
  const [isApple, setIsApple] = useState(false);

  useEffect(() => {
    // Get data from the 'locations' collection in Firestore
    db.collection('tiktoks').get()
      .then(snapshot => {
        const data = snapshot.docs.map(doc => doc.data());
        setData(data);
      })
      .catch(error => {
        console.log(error);
      });

    // Check if the user is on an Apple device
    const isAppleDevice = /iPad|iPhone|iPod/.test(navigator.userAgent);
    setIsApple(isAppleDevice);
  }, []);

  return (
    <div>
      {data.map(tiktok => (
        <div key={tiktok.id}>
          <h1>{tiktok.name}</h1>
          {isApple ? (
            <a href={'maps://?q=${tiktok.latitude},${tiktok.longitude}'}>Get Directions</a>
          ) : (
            <button onClick={() => {
              window.open('https://www.google.com/maps/dir/?api=1&destination=${tiktok.latitude},${tiktok.longitude}');
            }}>Get Directions</button>
          )}
        </div>
      ))}
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

I wanted to move this location logic to a function.

This is my updated html:

{
    place.lat === undefined ? <div></div> :
    <button onClick={() => goToMap(tiktok)}>Get Directions</button>
}
Enter fullscreen mode Exit fullscreen mode

I’m using a ternary operator to check if lat (latitude) is set. If it is not set, I will show an empty div element. If we have lat it will show the button. The button now calls a function that passes the tiktok object.

Here is the goToMap function.

 const goToMap = (tiktok) => {
        if (isApple) {
            window.open('maps://?q=${tiktok.lat},${tiktok.lng}');
        } else {
            window.open('https://www.google.com/maps/dir/?api=1&destination=${tiktok.lat},${tiktok.lng}');
        }
 }
Enter fullscreen mode Exit fullscreen mode

Now let’s add latitude and longitude fields to the firestore document we created earlier. I found the latitude and longitude using google maps. Click Add field, and add the following lat and lng fields.

lat: 36.11337630000001

lng: -115.3094725

Re-run or refresh the web apps page, and you should now be able to get directions to the location.

Since the embedded TikTok wasn’t going to be a good solution, I wanted to add a button to go to the video to watch the review again and get ideas of the kinds of food they have.

I copied and created a new button above the first button for this.

 <button onClick={() => watchVideo(tiktok.id)}>
     Watch Video
 </button>
Enter fullscreen mode Exit fullscreen mode

Then watchVideo function will look like this:

const watchVideo = (id) => {
    window.open('https://www.tiktok.com/@keith_lee125/video/${id}', '_blank', 'noreferrer');
}
Enter fullscreen mode Exit fullscreen mode

I’m basically recreating the url we based all of the data off of. Re-run the app to get an idea of how it works.

When clicking this button on the desktop, it will go to the videos page on the TikTok website. On iOS and Android devices, it will deep link to the TikTok app if you have it installed.

A couple of more things to note. For the design, I used the react Material UI package. I won’t go over the steps how, but I may in a future post.
MUI: The React component library you always wanted

I also created an admin react app to easily create and edit info.

I won’t go over this in this article but may create another one detailing those steps. For now, I’ll give a high-level overview of how I achieved this.

  1. Create a new react app and copy the files from this project.

  2. Installed react-router to go to the edit and create new page. https://reactrouter.com/en/main

  3. Go to the Google Developers Console and enable the Google Places API for this project, which was created by firebase. Also, get the API key. https://console.developers.google.com/

  4. Used code from here to implement the Google Places API. https://github.com/Gapur/google-place-autocomplete

  5. Once we get a place object from the autocomplete component, we can easily get info such as latitude, longitude, address, etc.

My current version of the Keith Lee Food web app can be found at https://keithleefood.com. Would you try it? Rate it 1–10!

Top comments (0)