Logo

dev-resources.site

for different kinds of informations.

🌱 Responsive Planto Ecommerce Website with React, Vite, TypeScript & Tailwind CSS 🌱

Published at
12/30/2024
Categories
webdev
react
reactjsdevelopment
tailwindcss
Author
seyma
Author
5 person written this
seyma
open
🌱 Responsive Planto Ecommerce Website with React, Vite, TypeScript & Tailwind CSS 🌱

🌱 Responsive Planto Ecommerce Website with React, Vite, TypeScript & Tailwind CSS 🌱

Welcome to an exciting journey in modern web development! πŸš€ In this project, we’ll create a fully responsive ecommerce website for selling herbs using cutting-edge technologies: React, Vite, TypeScript, and Tailwind CSS. This project is perfect for developers of all levels looking to sharpen their skills while building a practical application.


πŸ’» Features:

  • Stunning Home Page: An eye-catching design to welcome your visitors.
  • Smooth Checkout Process: Simplify purchasing with a user-friendly checkout page.
  • Detailed Plant Product Pages: Highlight the unique benefits of each plant.
  • Organized Plant Types Page: Help users browse by category.
  • Functional Contact Page: Enable users to get in touch effortlessly.

πŸ“¦ What It contains:

  • Responsive Design Best Practices: Ensure your website looks great on any device.
  • Modern Component-Based Development: Build clean, reusable components.
  • Tailwind CSS for Fast and Elegant Styling: Speed up styling with utility-first CSS.

✨ Why Build This Project?

This ecommerce project is an excellent way to master:

  • Developing responsive layouts.
  • Using TypeScript for scalable and maintainable code.
  • Implementing Tailwind CSS to craft modern, visually appealing UIs.

Whether you’re a beginner or an experienced developer, this project will help you gain valuable insights into crafting dynamic web applications.


🚧 Tech Stack:

  • React for UI Development
  • Vite for Blazing-Fast Development
  • TypeScript for Type Safety
  • Tailwind CSS for Utility-First Styling

πŸ”¨ Code Overview:

Here’s a glimpse of how the app is structured:

App.tsx

import { useState, useEffect } from 'react';
import { Routes, Route, useLocation } from 'react-router-dom'; 
import { Cart, Footer, Navbar } from './components';
import { Home, Checkout, PlantsType, Contact, PlantDetail } from './pages';
import { useCart } from './context/CartContext';

export default function App() {
  const [isNavOpen, setIsNavOpen] = useState(false);
  const [isCartOpen, setIsCartOpen] = useState(false);
  const location = useLocation();

  const { cart, updateQuantity, removeFromCart } = useCart();
  const closeCart = () => setIsCartOpen(false);

  useEffect(() => {
    closeCart();
    window.scrollTo(0, 0);
  }, [location]);

  return (
    <div className="min-h-screen bg-sectionColor text-white font-sans relative">
      <Navbar
        isOpen={isNavOpen}
        setIsOpen={setIsNavOpen}
        cart={cart}
        toggleCart={() => setIsCartOpen(prev => !prev)}
      />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/checkout" element={<Checkout />} />
        <Route path="/plants-type" element={<PlantsType />} />
        <Route path="/plant/:plantId" element={<PlantDetail />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
      {isCartOpen && (
          <Cart
            cart={cart}
            updateQuantity={updateQuantity}
            removeFromCart={removeFromCart}
            closeCart={closeCart}
          />
      )}
      <Footer />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Home.tsx

import React from 'react';
import { HeroSection, TopSelling, CustomerReview, BestO2 } from '../components';
import plantsData from '../data/plantsData';

const Home: React.FC = () => {
  return (
    <div>
      <HeroSection />
      <main className="container mx-auto px-4 py-8">
        <TopSelling plants={plantsData} />
        <CustomerReview />
        <BestO2 plants={plantsData} />
      </main>
    </div>
  );
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

Cart.tsx

import React from 'react';
import { useNavigate } from 'react-router-dom';
import { Button }from './';
import { CartProps } from '../types/types';
import { PlusIcon, MinusIcon, TrashIcon, XMarkIcon } from "@heroicons/react/24/solid";

const Cart: React.FC<CartProps> = ({ cart, updateQuantity, removeFromCart, closeCart }) => {
  const total = cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
  const navigate = useNavigate(); 


  const handleCheckout = () => {
    const checkoutData = cart.map(({ id, name, price, quantity }) => ({
      id,
      name,
      price,
      quantity,
    }));

    closeCart();
    navigate('/checkout', { state: { cart: checkoutData } }); 
  };

  return (
    <div className="fixed top-16 right-0 w-full max-w-md bg-[#11170f] rounded-3xl p-4 z-50  max-h-[80vh] overflow-y-auto">
      <div className="container mx-auto px-4 py-8 relative">
        <button 
          className="absolute top-4 right-4 text-gray-300 hover:text-white"
          onClick={closeCart} 
          aria-label="Close cart"
        >
          <XMarkIcon className="h-6 w-6" />
        </button>
        <h1 className="text-3xl font-bold mb-8">Your Cart</h1>
        {cart.length === 0 ? (
          <p>Your cart is empty.</p>
        ) : (
          <div className="grid md:grid-cols-1 gap-8">
            <div className="md:col-span-1">
              {/* Scrollable container for cart items */}
              <div className="max-h-72 overflow-y-auto"> 
                {cart.map((item) => (
                  <div key={item.id} className="flex items-center mb-4 bg-[#d8ebd1] bg-opacity-30 p-4 rounded-lg">
                    <img src={item.image} alt={item.name} className="w-20 h-20 object-cover rounded-md mr-4" />
                    <div className="flex-1">
                      <h3 className="text-lg font-semibold">{item.name}</h3>
                      <p className="text-gray-300">Rs. {item.price}</p>
                      <div className="flex items-center mt-2">
                        <button 
                          className="text-gray-300 hover:text-white"
                          onClick={() => updateQuantity(item.id, Math.max(1, item.quantity - 1))}
                          aria-label="Decrease quantity"
                        >
                          <MinusIcon className="h-4 w-4" />
                        </button>
                        <span className="mx-2">{item.quantity}</span>
                        <button 
                          className="text-gray-300 hover:text-white"
                          onClick={() => updateQuantity(item.id, item.quantity + 1)}
                          aria-label="Increase quantity"
                        >
                          <PlusIcon className="h-4 w-4" />
                        </button>
                      </div>
                    </div>
                    <button 
                      className="text-gray-300 hover:text-white"
                      onClick={() => removeFromCart(item.id)}
                      aria-label={`Remove ${item.name} from cart`}
                    >
                      <TrashIcon className="h-6 w-6" />
                    </button>
                  </div>
                ))}
              </div>
            </div>
            <div className="bg-[#d8ebd1] bg-opacity-30 p-4 rounded-lg h-fit">
              <h3 className="text-xl font-semibold mb-4">Order Summary</h3>
              <div className="space-y-2 mb-4">
                <div className="flex justify-between">
                  <span>Subtotal</span>
                  <span>Rs. {total}</span>
                </div>
                <div className="flex justify-between">
                  <span>Shipping</span>
                  <span>Rs. 50</span>
                </div>
                <div className="flex justify-between font-semibold">
                  <span>Total</span>
                  <span>Rs. {total + 50}</span>
                </div>
              </div>
              <div className="flex justify-end">
                <Button text="Confirm Order" onClick={handleCheckout} />
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

export default Cart;
Enter fullscreen mode Exit fullscreen mode

πŸ“₯ Resources:


πŸ‘€ Connect & Share

If you find this project helpful, don’t forget to like, share, and subscribe! Let’s grow together. 🌟

Feel free to leave your feedback in the comments below. Happy coding! πŸš€


Tags:

#React #Vite #TypeScript #TailwindCSS #WebDevelopment #ResponsiveDesign #reactjs #js

reactjsdevelopment Article's
30 articles in total
Favicon
Introducing EAS Hosting: Simplified deployment for modern React apps
Favicon
React-copytext
Favicon
{ Understanding PROPS in React.js }
Favicon
reactJs
Favicon
How to Check and Fix Memory Leaks in React Applications
Favicon
Top 10 React js interview questions.
Favicon
How ReactJS Development Services Enhance User Experience and Performance
Favicon
Beginner SEO in React JS - React Helmet
Favicon
How We Automated 80% of Our Code with Exocoding
Favicon
Custom Hooks in React: Why and How to Create Them
Favicon
πŸš€ React Best Practices for Scalable Frontends: Part 4 – Performance Optimization and Efficient Rendering
Favicon
SOLID Principles for React / React Native Development
Favicon
How I Started My Journey as a MERN Stack Developer
Favicon
🌱 Responsive Planto Ecommerce Website with React, Vite, TypeScript & Tailwind CSS 🌱
Favicon
A Comprehensive Guide to React JS Courses: Everything You Need to Know
Favicon
React Summit 2025 is back on June 13 & 17!
Favicon
Server-Side Rendering with React.js
Favicon
Getting Started with React Native: From Effort to Ease πŸš€
Favicon
Mastering the Most Useful Next.js and React Features for 2025
Favicon
The Top React Reporting Tools
Favicon
Why Choose ReactJS for Your Development?
Favicon
React & Me: Day 1 Shenanigans 😎
Favicon
Why are Props Immutable in React?
Favicon
The Top React Spreadsheet Tools
Favicon
Exploring React 19 πŸ”₯πŸ”₯
Favicon
Supercharge Your React App with ImageKit.io: Fast & Optimized Images ⚑
Favicon
React Hooks
Favicon
How Much Does It Cost to Build an App Using ReactJS?
Favicon
What's New in React 19 latest stable release?
Favicon
Why React Native is the Best Choice for Your Mobile App?

Featured ones: