Celebrating a Milestone: Capstone Project Unveiled
Tags: webdev, react, rails, programming
Published: 2023-06-28 04:57:23

I am delighted to announce that I have successfully reached the final phase of the *Software Engineering* bootcamp at Flatiron. This journey has been filled with both triumphs and challenges, including moments of imposter syndrome. However, I have persevered through it all, allowing me to experience significant personal growth. As the pinnacle of this remarkable journey, I take great pride in presenting my capstone project: **hey-Destination**. This project demonstrates the culmination of my skills in front-end development utilizing JavaScript, React, CSS, and HTML, complemented by the robustness of backend built with Ruby on Rails.

![capstone1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wumfx7q7z06xpxsgmft.png)

**hey-Destination** provides users with a seamless browsing experience, enabling them to explore a diverse collection of exquisite villas and discover exciting activities in each location. Users can also conveniently send inquiries about a villa. Additionally, **hey-Destination** places a strong emphasis on security and efficiency by integrating robust authentication and authorization mechanisms, powered by Rails. This empowers Admin Users with efficient rental management capabilities, streamlining the entire process for enhanced convenience.

In my application, I have meticulously planned and implemented six models to ensure smooth data management and associations. **UserAdmin**, utilizes has_secure_password to ensure secure user authentication. It establishes a one-to-many relationship with the **Villa** model, allowing each UserAdmin to manage multiple villas. Additionally, UserAdmin has a through association with Inquiry. **Location** model represents various destinations available for villa rentals. It establishes associations with multiple models, including Villa, Inquiry, ActivityLocation, and Activity. Each location can have multiple villas, inquiries, and activity locations, and it can also be associated with activities through the ActivityLocation - the joined table model.


![capstone2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qkp8zyw5qro1qz0tv4kh.png)

The **Inquiry** model is linked to the Villa model through a belongs-to association, allowing each inquiry to be associated with a specific villa. It has a has-one-through association with UserAdmin, providing convenient access to the user admin associated with the villa.

Lastly, the **Activity** model represents different activities available at each location. It establishes a one-to-many association with the ActivityLocation model, allowing multiple activity locations to be associated with an activity. The ActivityLocation model acts as a join table, representing a many-to-many relationship between the Activity and Location models.


![capstone3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jpdr2vmwihp0k21xdu1r.png)

Creating this project has been an enjoyable, although it did come with its fair share of challenges and bugs. As we entered the final phase, we were tasked with implementing a tech stack that hadn't been covered in our coursework. Initially, I had planned to incorporate *Active Storage with Cloudinary* as the cloud service provider. While searching for solutions, I came across a helpful and insightful blog post from [Nemwel Boniface "From Theory to Practice: Using Active Storage for File Management in Rails"](https://dev.to/nemwelboniface/from-theory-to-practice-using-active-storage-for-file-management-in-rails-4o3f) that provided valuable insights on this topic. However, due to subscription issues, I couldn't proceed with that approach, and time was running out. As a workaround, I decided to leverage the React Carousel library instead.

![capstone4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q8p07xc4bx7wvj02aj92.png)

I discovered a variety of [React Carousel](https://turbofuture.com/internet/React-Gallery-Carousel) libraries that are ideal for e-commerce platforms and apps like Instagram or personal portfolios. Ultimately, I opted for the React Responsive Carousel as I find it visually appealing and interactive.

First step run command:

```
npm install react-responsive-carousel
```

Then import it to your Component:

```
import { Carousel } from "react-responsive-carousel";
 import "react-responsive-carousel/lib/styles/carousel.min.css";
```

Here, I have the state declaration using the useState hook. I define two state variables: currentIndex and setCurrentIndex. The currentIndex holds the index of the current villa being displayed in the carousel, while setCurrentIndex is a function to update the value of currentIndex.

```
const [currentIndex, setCurrentIndex] = useState(0);
```

Next, define two functions: **nextVilla** and **prevVilla**. The nextVilla function is responsible for navigating to the next villa in the carousel. It checks if the current index is at the end of the villas array. If it is, an alert is displayed to indicate that the user has reached the end. Otherwise, the setCurrentIndex function is called with the previous index plus one, effectively moving to the next villa.


```
const nextVilla = () => {
    if (currentIndex === villas.length - 1) {
      alert("You have reached the end.");
    } else {
      setCurrentIndex((prevIndex) => prevIndex + 1);
    }
  };
```

Similarly, the prevVilla function handles navigation to the previous villa. It checks if the current index is at the beginning (0) of the villas array. If it is, an alert is displayed to indicate that the user is on the first page. Otherwise, the setCurrentIndex function is called with the previous index minus one, allowing the user to move to the previous villa.

```
const prevVilla = () => {
    if (currentIndex === 0) {
      alert("You are on the first page.");
    } else {
      setCurrentIndex((prevIndex) => prevIndex - 1);
    }
  };
```


Finally, the JSX code that renders the carousel and its contents. The Carousel component is used to create a container for displaying the villa images. Within the Carousel, we use the spread syntax [...Array(10)] to create an array of length 10 --you can change the value-depending on your project. Each element in this array is mapped to a **div** element with a unique key set to the index value. Inside the **div**, an **img** tag is used to display the image of the current villa, retrieved using the template expression currentVilla[image${index + 1}].


![react-responsive](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hrw336tppw9veujsa3m2.png)


And with that, I proudly conclude this chapter of my journey. It is a privilege to share this exciting endeavor with all of you, and I am filled with gratitude for the invaluable experience I gained during my time at Flatiron School. The friendships formed and the support received from my cohorts have been instrumental in shaping my growth as a software engineer. Now, equipped with newfound knowledge and skills, I stand ready to soar to new heights and pursue my end goal. With unwavering determination and a passion for innovation, I am prepared to embrace the challenges that lie ahead and turn them into stepping stones towards success. I am eager to seize every opportunity that comes my way. So, join me as we embark on this next chapter together, fueled by ambition, resilience, and the belief that dreams are meant to be realized. Let's inspire, create, and make a lasting impact in the world of technology.