Waris-95 / Czybnb

Home Page:https://czybnb.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

🏠 CzyBnB

CzyBnB is a full-stack web application inspired by Airbnb. It allows users to create spots, add reviews, offering a diverse range of accommodations for exploration.

Table of Contents

Explore the minimum viable product feature list required for CzyBnB.

Discover the schema of the PostgreSQL database powering CzyBnB.

Immerse yourself in captivating user stories, detailing each feature's journey and acceptance criteria.

Browse the API documentation for JSON data interaction between frontend and backend routes.

πŸ› οΈ Technologies Used

πŸŒ… Landing Page

Landing Page GIF

🏞️ One Spot Page and Reviews

Spot Page GIF

πŸ’» Code I'm Proud Of

// GET all spots with query filters
/* This route retrieves spots with optional query filters
such as latitude, longitude, price range, etc. It performs a query based
on the provided filters and returns paginated results along with average
ratings and preview images for each spot. */

router.get('/', validateQueryParams, async (req, res, next) => {
  try {
    // Get the query params
    let {
      page = 1,
      size = 20,
      minLat,
      maxLat,
      minLng,
      maxLng,
      minPrice,
      maxPrice,
    } = req.query;

    page = parseInt(page, 10);
    size = parseInt(size, 10);

    // Create the where clause
    const whereClause = {
      ...(minLat && { lat: { [Sequelize.Op.gte]: parseFloat(minLat) } }),
      ...(maxLat && { lat: { [Sequelize.Op.lte]: parseFloat(maxLat) } }),
      ...(minLng && { lng: { [Sequelize.Op.gte]: parseFloat(minLng) } }),
      ...(maxLng && { lng: { [Sequelize.Op.lte]: parseFloat(maxLng) } }),
      ...(minPrice && { price: { [Sequelize.Op.gte]: parseFloat(minPrice) } }),
      ...(maxPrice && { price: { [Sequelize.Op.lte]: parseFloat(maxPrice) } }),
    };

    // Perform the query
    const spotsData = await Spot.findAndCountAll({
      where: whereClause,
      attributes: {
        include: [
          [Sequelize.fn('AVG', Sequelize.col('Reviews.stars')), 'avgRating'],
        ],
      },
      include: [
        {
          model: Review,
          attributes: [],
        },
        {
          model: SpotImage,
          as: 'SpotImages',
          attributes: ['url'],
          where: { preview: true },
          required: false,
        },
      ],
      // Group by the primary keys of the Spot and SpotImages tables
      group: ['Spot.id', 'SpotImages.id'],
      limit: size,
      offset: (page - 1) * size,
      subQuery: false,
      distinct: true,
    });

    // Format the spots to be returned to the client
    const spots = spotsData.rows.map((spot) => {
      const previewImage =
        spot.SpotImages && spot.SpotImages.length > 0
          ? spot.SpotImages[0].url
          : null;
      // Cast the avgRating to a float and round to a single decimal point
      const avgRating = spot.dataValues.avgRating
      ? parseFloat(spot.dataValues.avgRating).toFixed(1)
      : null;
    return {
      id: spot.id,
      ownerId: spot.ownerId,
      address: spot.address,
      city: spot.city,
      state: spot.state,
      country: spot.country,
      lat: parseFloat(spot.lat),
      lng: parseFloat(spot.lng),
      name: spot.name,
      description: spot.description,
      price: parseFloat(spot.price),
      createdAt: spot.createdAt.toISOString(), // Add createdAt field in ISO string format
      updatedAt: spot.updatedAt.toISOString(), // Add updatedAt field in ISO string format
      avgRating: avgRating !== null ? parseFloat(avgRating) : null, // Ensure avgRating is not returned as a string
      previewImage: previewImage,
    };

    });

    res.status(200).json({
      Spots: spots,
      page, 
      size,
    });
  } catch (error) {
    next(error);
  }
});

πŸš€ Getting Started

  1. Clone this repository: CzyBnB Repository
  2. Install dependencies for the backend and frontend by navigating to each directory in separate terminals and running npm install.
  3. Create a .env file using the provided .envexample.
  4. Set up your database with information from your .env file and then run the following commands:
    • npx dotenv sequelize db:create
    • npx dotenv sequelize db:migrate
    • npx dotenv sequelize db:seed:all
  5. Start the app for both backend and frontend using npm start.
  6. Now you can use the Demo User or Create an account.

✨ Features

Spots

  • Users can create a Spot.
  • Users can read/view other Spots.
  • Users can update their Spot.
  • Users can delete their Spot.

Reviews

  • Users can create Reviews on Spots.
  • Users can read/view all of the Reviews on a Spot.
  • Users can delete their Review(s) on a Spot.

About

https://czybnb.vercel.app


Languages

Language:JavaScript 86.8%Language:CSS 12.9%Language:HTML 0.3%