0% found this document useful (0 votes)
10 views19 pages

Web-Dev-101 - Walkthrough

This document provides a detailed walkthrough for setting up a React application using Vite, including the installation of necessary tools and packages. It covers the creation of components, routing with react-router-dom, form handling with react-hook-form, and integration with Firebase for event management functionalities such as creating, viewing, and deleting events. The document also includes code snippets for styling and functionality for each component involved in the event management system.

Uploaded by

Aditya Gorrepati
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views19 pages

Web-Dev-101 - Walkthrough

This document provides a detailed walkthrough for setting up a React application using Vite, including the installation of necessary tools and packages. It covers the creation of components, routing with react-router-dom, form handling with react-hook-form, and integration with Firebase for event management functionalities such as creating, viewing, and deleting events. The document also includes code snippets for styling and functionality for each component involved in the event management system.

Uploaded by

Aditya Gorrepati
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Walkthrough:

1. Install VSCode in your computer


Extensions to be installed in VSCode:
● ES7+ React/Redux/React-Native snippets
● JavaScript (ES6) code snippets
2. Install node in your computer
3. Create a new vite+react app using
● npm create vite@latest
● Enter the project name : eventmanager
● Select React from the template using Arrow keys and Enter
4. Explore the file structure in vscode
5. Remove excess code in App.jsx

● Remove all code in App.css


● Add the code in App.css:
*{
box-sizing: border-box;
margin: 0;
padding: 0;
}

6. Create a new folder called components and create the below files:
CreateEvent.jsx
ViewEvents.jsx
EditEvent.jsx
EventCard.jsx

7. Create a Navbar in componentsL


Create the new file Navbar.jsx and put “rfce” basic code
8. Enter “rfce”, in all the files to get basic template code

You will get this template code


Do this for all component files
9. Now let us create the router to handle in which url which page is being shown
● First install the package “react-router-dom” by doing:
npm install react-router-dom
● Create a new File called Router.jsx in src folder
Code:
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import App from "./App";
import ViewEvents from "./components/ViewEvents";
import CreateEvent from "./components/CreateEvent";
import EditEvent from "./components/EditEvent";

function AppRouter() {
return (
<Router>
<Routes>
<Route path="/" element={<App/>}>
<Route index element={<ViewEvents/>}/>
<Route path="/events" element={<ViewEvents/>}/>
<Route path="/add-event" element={<CreateEvent/>}/>
<Route path="/update-event/:id" element={<EditEvent/>}/>
</Route>
</Routes>
</Router>
)
}

export default AppRouter


● Update the App.jsx to have layout of Navbar and Outlet
Code:
import './App.css'
import { Outlet } from "react-router-dom";
import Navbar from "./components/Navbar";

function App() {

return (
<>
<Navbar/>
<Outlet/>
</>
)
}

export default App


● Update main.jsx to put AppRouter from Router.jsx
Code:
Before:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
<StrictMode>
<App/>
</StrictMode>,
)

After:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
import AppRouter from './Router.jsx'

createRoot(document.getElementById('root')).render(
<StrictMode>
<AppRouter/>
</StrictMode>,
)
10. Now let us create a simple navbar for our web application
● First create Navbar.css file

● Now link this to Navbar.jsx file

● Now write jsx code for Navigation bar


import React from 'react'
import { Link } from 'react-router-dom'
import './Navbar.css'

function Navbar() {
return (
<nav className="navbar">
<h2>Event Planner</h2>
<ul>
<li><Link to="/events">View Events</Link></li>
<li><Link to="/add-event">Add Event</Link></li>
</ul>
</nav>
)
}

export default Navbar

● Now write the code for Navbar.css:


.navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #007bff;
padding: 10px 20px;
color: white;
box-sizing: border-box;
}

.navbar h2 {
margin: 0;
font-size: 20px;
white-space: nowrap;
}

.navbar ul {
list-style: none;
display: flex;
gap: 15px;
margin: 0;
padding: 0;
}

.navbar li {
display: inline;
}

.navbar a {
text-decoration: none;
color: white;
font-weight: bold;
white-space: nowrap;
}

.navbar a:hover {
text-decoration: underline;
}

11. Now we will make a CreateEvent.jsx component, to add a new event


● Firstly install “react-hook-form” package

● Now make css file CreateEvent.css to add styles to the form and import to
CreateEvent.jsx

import './CreateEvent.css'

● Now write the form code in CreateEvent.jsx:


import React from 'react'
import { useForm } from 'react-hook-form'

function CreateEvent() {
const {register,handleSubmit,formState:{errors},} = useForm();
return (
<div>
<h2>Create Event</h2>
<form>
<label>Event Name:</label>
<input type="text" name="" id="" {...register("name",{required:'Event name is
required'})}/>
{errors.name && <p className="error">{errors.name.message}</p>}

<label>Date:</label>
<input type="date" name="" id="" {...register("date",{required:'Date is
required'})}/>
{errors.date && <p className="error">{errors.date.message}</p>}

<label>Time:</label>
<input type="time" name="" id="" {...register("time", { required: "Time is
required" })}/>
{errors.time && <p className="error">{errors.time.message}</p>}

<label>Venue</label>
<input type="text" name="" id="" {...register("venue", { required: "Venue is
required" })} />
{errors.venue && <p className="error">{errors.venue.message}</p>}

<button type='submit'>Create Event</button>


</form>
</div>
)
}

export default CreateEvent

● Now add styling to the form in CreateEvent.jsx

.parent-container{
display: flex;
justify-content: center;
align-items: center;
margin-top: 100px;
}
.form-container {
width: 400px;
padding: 20px;
border: 1px solid #ccc;
border-radius: 8px;
color: black;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
background-color: #fff;
text-align: center;
}

h2 {
margin-bottom: 20px;
}

form {
display: flex;
flex-direction: column;
}

label {
font-weight: bold;
margin: 10px 0 5px;
}

input {
padding: 8px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
width: 100%;
}

button {
margin-top: 15px;
padding: 10px;
background-color: #007bff;
color: white;
font-size: 16px;
border: none;
border-radius: 4px;
cursor: pointer;
}

button:hover {
background-color: #0056b3;
}

.error {
color: red;
font-size: 14px;
margin-top: 5px;
}

● Now add functionality of posting the event to backend (POST Request):


Add onSubmit function
const onSubmit = (data)=>{
console.log(data)
}

Link the function to the form


<form onSubmit={handleSubmit(onSubmit)}>

● Now post this data to firebase

Create a file named firebaseConfig.js and add the Firebase configuration:

Add the firebaseConfig.js content i.e the configuration:


import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
// TODO: Add SDKs for Firebase products that you want to use
//
https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration


// For Firebase JS SDK v7.20.0 and later, measurementId is
optional
const firebaseConfig = {
apiKey: "--API--KEY",
authDomain: "domain",
projectId: "id",
storageBucket: "XXXXX",
messagingSenderId: "XXXXXX",
appId: "XXXXX",
measurementId: "G-TCLR65VPZC"
};

const app = initializeApp(firebaseConfig);


const db = getFirestore(app);

export { db };

Get these credentials from (To find the credentials)


Firebase Console → Project Settings., Scroll down and click on add app, and click on
</> for web and then get the content

//Import firebase db and firestore to CreateEvent.jsx

The code for onSubmit to post the data to the firebase storage:
const onSubmit = async (data)=>{
try {
const docRef = await addDoc(collection(db, "events"), {
eventName: data.name,
date: data.date,
time: data.time,
venue: data.venue,
createdAt: new Date()
});
console.log("Document written with ID:", docRef.id);
alert("Event Added")
} catch (error) {
console.error("Error adding document:", error);
}
}

12. Now we will create the card to display details about each event in CreateEvent.jsx:

Code:
import React from 'react'
import './EventCard.css'

const EventCard = ({ event }) => {


return (
<div className="event-card">
<h3>{event.eventName}</h3>
<p><strong>Date:</strong> {event.date}</p>
<p><strong>Time:</strong> {event.time}</p>
<p><strong>Venue:</strong> {event.venue}</p>

<div className="buttons">
<button className="edit-btn">Edit</button>
<button className="delete-btn">Delete</button>
</div>
</div>
);
};

export default EventCard;


● Now create the EventCard.css file and link it to EventCard.jsx to style the card
CSS:
.event-card {
background-color: #ffffff;
border-radius: 8px;
padding: 16px;
margin: 10px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
text-align: center;
width: 300px;
}
h3 {
margin-bottom: 8px;
color: #333;
}

p{
margin: 4px 0;
color: #555;
}

.buttons {
margin-top: 12px;
display: flex;
justify-content: center;
gap: 10px;
}

.edit-btn, .delete-btn {
padding: 8px 12px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}

.edit-btn {
background-color: #007bff;
color: white;
}

.edit-btn:hover {
background-color: #0056b3;
}

.delete-btn {
background-color: #dc3545;
color: white;
}

.delete-btn:hover {
background-color: #b02a37;
}
13. Now create the ViewEvents.jsx file to show all events which have been created

Code:
import React from "react";
import './ViewEvents.css'
import { useState, useEffect } from "react";
import { collection, getDocs } from "firebase/firestore";
import { db } from "../firebaseConfig";
import EventCard from "./EventCard";
import "./ViewEvents.css";

const ViewEvents = () => {


const [events, setEvents] = useState([]);

useEffect(() => {
const fetchEvents = async () => {
try {
const querySnapshot = await getDocs(collection(db, "events"));
const eventsList = querySnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
setEvents(eventsList);
} catch (error) {
console.error("Error fetching events:", error);
}
};

fetchEvents();
}, [events]);

return (
<div className="view-events">
{events.length > 0 ? (
<div className="events-grid">
{events.map(event => (
<EventCard key={event.id} event={event} />
))}
</div>
):(
<p className="no-events">No events available</p>
)}
</div>
);
};
export default ViewEvents;
● Now create the ViewEvents.css file to style the components, and link it to the
ViewEvents.jsx code

CSS:

.view-events {
text-align: center;
margin-top: 30px;
padding: 20px;
}

h2 {
margin-bottom: 20px;
color: #333;
}

.events-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
justify-content: center;
padding: 20px;
}

@media (max-width: 1024px) {


.events-grid {
grid-template-columns: repeat(2, 1fr);
}
}

@media (max-width: 600px) {


.events-grid {
grid-template-columns: repeat(1, 1fr);
}
}

To get events in order:


const fetchEvents = async () => {
try {
const q = query(collection(db, "events"), orderBy("date", "asc")); // Oldest events first
const querySnapshot = await getDocs(q);
const eventsList = querySnapshot.docs.map(doc => ({
id: doc.id,
...doc.data(),
}));
console.log(eventsList);
} catch (error) {
console.error("Error fetching events:", error);
}
};
14. Now add the functionality to delete button
● In ViewEvents.jsx let us write function to delete an event:
const handleDelete = async (event)=>{
const confirm = window.confirm("Are you sure you want to delete this event");
if(confirm){
try {
await deleteDoc(doc(db, "events", event.id));
setEvents(events.filter(e => e.id !== event.id));
} catch (error) {
console.error("Error deleting event:", error);
}
}
}

● Modify EventCard.jsx file to pass the delete and edit functions, and call them
when buttons are clicked:
const EventCard = ({ event ,onDelete,onEdit}) => {
return (
<div className="event-card">
<h3>{event.eventName}</h3>
<p><strong>Date:</strong> {event.date}</p>
<p><strong>Time:</strong> {event.time}</p>
<p><strong>Venue:</strong> {event.venue}</p>

<div className="buttons">
<button className="edit-btn" onClick={() => onEdit(event)}>Edit</button>
<button className="delete-btn"onClick={() =>
onDelete(event)}>Delete</button>
</div>
</div>
);
};
● Now pass the functions in ViewEvents.jsx:
{events.map(event => (
<EventCard key={event.id} event={event}
onDelete={handleDelete} onEdit={handleEdit}/>
))}

15. Now let us add the edit functionality


● Let us redirect all edit to the EditEvent.jsx page:
In ViewEvents.jsx add
import { useNavigate } from "react-router-dom";

const ViewEvents = () => {


const [events, setEvents] = useState([]);
const navigate = useNavigate()
…..
● In EditEvent.jsx put the whole code as CreateEvent.jsx
● Create EditEvent.css,link it to EditEvent.jsx and put CreateEvent.css content in
EditEvent.css
● EditEvent.jsx final code:
import React from 'react'
import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { doc, getDoc, updateDoc } from "firebase/firestore";
import { useForm } from "react-hook-form";
import { db } from "../firebaseConfig";
import './EditEvent.css'

function EditEvent() {
const { id } = useParams();
const navigate = useNavigate();
const { register, handleSubmit, setValue ,formState:{errors}} = useForm();
const [loading, setLoading] = useState(false);

useEffect(() => {
const fetchEvent = async () => {
try {
console.log("Fetching event with ID:", id);
const docRef = doc(db, "events", id);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
const eventData = docSnap.data();
console.log("Event data:", eventData)
// Populate form fields with existing data
setValue("eventName", eventData.eventName);
setValue("date", eventData.date);
setValue("time", eventData.time);
setValue("venue", eventData.venue);
setEventLoaded(true);
} else {
setError("Event not found");
}
} catch (error) {
console.error("Error fetching event:", error);
setError("Failed to load event");
}
};
fetchEvent();
}, [id, setValue]);

const onSubmit = async (data) => {


setLoading(true);
try {
const docRef = doc(db, "events", id);
await updateDoc(docRef, data);
console.log("Event updated successfully");
navigate("/events");
} catch (error) {
console.error("Error updating event:", error);
}
setLoading(false);
};
return (
<div className='parent-container'>
<div className='form-container'>
<h2>Edit Event</h2>
<form onSubmit={handleSubmit(onSubmit)}>
<label>Event Name:</label>
<input type="text" name="" id="" {...register("name",{required:'Event name is
required'})}/>
{errors.name && <p className="error">{errors.name.message}</p>}

<label>Date:</label>
<input type="date" name="" id="" {...register("date",{required:'Date is
required'})}/>
{errors.date && <p className="error">{errors.date.message}</p>}

<label>Time:</label>
<input type="time" name="" id="" {...register("time", { required: "Time is
required" })}/>
{errors.time && <p className="error">{errors.time.message}</p>}
<label>Venue</label>
<input type="text" name="" id="" {...register("venue", { required: "Venue is
required" })} />
{errors.venue && <p className="error">{errors.venue.message}</p>}

<button type="submit" disabled={loading}>{loading ? "Updating..." : "Update


Event"}</button>
</form>
</div>
</div>
)
}
export default EditEvent

You might also like