Skip to content

Advanced-computer-lab-2024/Roammate

Repository files navigation

R🌎AMMATE

Table of Contents

  1. πŸš€ Motivation
  2. 🧱 Build Status
  3. 🎨 Code Style
  4. πŸ“Έ Screenshots
  5. βš’οΈ Tech and Frameworks used
  6. πŸ”₯ Features
  7. πŸ’» Code Examples
  8. βš™οΈ Installation
  9. πŸ“š API Reference
  10. πŸ§ͺ Tests
  11. πŸ§‘πŸ»β€πŸ« How to Use
  12. 🀝 Contribute
  13. ©️ Credits
  14. πŸ“œ License

πŸš€ Motivation

The Virtual Trip Planner is an all-in-one travel platform that aims to simplify and enhance vacation planning. Whether you’re exploring historical landmarks, unwinding on tranquil beaches, or seeking thrilling adventures, this app caters to all your travel needs. Its goal is to provide a seamless, intuitive, and enjoyable experience for tourists, advertisers, tour guides, sellers, and administrators.

🧱 Build Status

  • The project is currently in development.
  • Code optimization for faster load times is planned.
  • Performance testing is underway to ensure scalability
  • A CI/CD pipeline needs to be implemented.
  • The project needs to be deployed through cloud services.
  • More documentation should be added

🎨 Code Style

  • Prettier : it is a code formatter that runs automatically before each commit on the whole code so that the codes looks well formatted across the whole project

πŸ“Έ Screenshots

User Login
  • Login with correct username and password.
  • Choose forget password if you can't remember your password. image
Tourist Registration
  • Register as a tourist with essential details.
  • Choose your prefrences.

image

Tourist Profile Page
  • Edit your personal data.
  • Redeem your points.
  • Change your password.
  • Delete the account.
  • Add an address.

image

Sorting and Filtering
  • Choose the criteria to sort the results.
  • Choose the constraints to filter the results.
  • Price is sorted in ascending order.

image

Wishlist
  • List of wishlisted products.

image

User Cart
  • See items in your cart

image

Flights Search
  • Search flights with departure time and destination time.
  • Search flights with departure loaction and destination locations.
  • Choose the number of passengers.

image

Hotels Search
  • Search for hotels by location.
  • Search for hotels by check-in and check-out dates.
  • Search for hotels by the number of guests.

image

User Purchase History
  • Check pending orders.
  • Check past orders.

image

Activity Booking
  • Choose a date to book an activity.

image

Add New Address
  • Fill in the required informat.

image

Admin Homepage
  • Delete user's account.
  • View the number of users.
  • Toggle between users, registrations and compliants.

image

compliants
  • View complaints' details.
  • Approve or reject complaints.
  • View past compliants.

image

Account Deletion Requests
  • Approve or deny account deletion requests.
  • See previous approved and denied account deletion requests.

image

Admin Add Product
  • Add the required information of a certain Product..
  • upload an image of the product.

image

Admin Edit Product
  • Edit the product name.
  • Edit the prouct description.
  • Edit product price.
  • upload an image of the product.

image

Admin Filter Products
  • Filter by archived products.

image

Birthday Promo Code
  • Recieve a promo code by email on the saved birthday.

image

Payment Reciept
  • Recieve a reciept by email once you pay for anything on the app.

image

βš’οΈ Tech and Frameworks Used

JavaScript HTML5 React ExpressJs Node.js MongoDB Stripe JWT Nodemailer Axios MUI Chart.js Postman Vite

  • Backend: Node.js, Express, Mongoose, JWT, Axios, Nodemailer, Cron
  • Frontend: React.js, Material-UI, React-Router, Chart.js, Framer-Motion
  • Database: MongoDB
  • Authentication: JWT
  • APIs: Stripe, Amadeus API
  • Development Tools: Postman, Nodemon, Vite, Prettier

πŸ”₯ Features

Common Features across all stakeholders
  • Login: Allows stakeholders to securely log in using their username and password.
  • Change Password: Provides the ability for stakeholders to update their password at any time.
  • Forgot Password: Enables stakeholders to reset their password using an OTP sent to their registered email address.
  • Multi-Stakeholder Access: Seamlessly supports multiple roles such as Admin, Tourist, Seller, Tourism Governor, Advertiser, and Tour Guide.
Admin
  • User Management: Approve or reject registrations for tour guides, advertisers, sellers, and tourism governors based on uploaded documents. Add new admins or tourism governors to the system.
  • Content Moderation: Review, flag, or remove inappropriate events, itineraries, or other activities. Manage activity categories, preference tags, and historical location tags.
  • Complaint Handling: Access, review, and respond to complaints. Mark complaints as resolved or pending and filter them by status or date.
  • Performance Monitoring: Track the total number of users, new user registrations per month, and system-wide revenue trends through detailed sales reports.
  • System-Wide Insights: Analyze system activities and generate reports for events, itineraries, and sales for enhanced decision-making.
  • Stock and Product Management: View and manage inventory levels for all sellers' products, monitor sales trends, and track product performance, archive and unarchive a product.
  • User Interaction: Communicate with users regarding flagged content, account deletions, or complaint resolutions.
  • promo code handling: Create new promo codes.
Tourist
  • User Profile & Preferences: Update profile, choose currency for viewing the prices, set preferences (budget, family-friendly, historic areas, etc.), and view wallet.
  • Booking & Payment: Book activities, itineraries, flights, hotels or transportation and pay using credit/debit or wallet with Stripe integration, recieve a payment receipt via email uppon paying.
  • Event & Itinerary Management: Search, view, bookmark, sort or filter upcoming activities and itineraries; request to receive notifications for bookings and reminders.
  • Engagement & Feedback: Rate, comment on, and share activities, itineraries, and tour guides; redeem loyalty points for cash in wallet.
  • History & Cancellation: View past and upcoming bookings; cancel bookings (with refunds to wallet) and track cancellation status.
  • Complaint System: File complaints with details and track resolution status.
  • Exclusive Rewards: Earn loyalty points and badges for participation and purchases.
  • Wishlist Management: Save products to your wishlist, view saved items, and remove them when needed.
  • Cart Management: Add items to your cart (from wishlist or directly), update quantities, or remove items.
  • Order Management: Checkout your order, add orchoose a delivery address, and pay via wallet, credit/debit card (Stripe), or cash on delivery.
  • Order History: View current and past orders, order details, and status.
  • Cancellations and Refunds: Cancel orders and view refunded amounts in your wallet. Feedback and Reviews: Rate and review purchased products.
  • promo codes: Recieve promo code on his birthday, apply the promo code on anything in the website.
Seller
  • Profile Management: Create, update, and manage a seller profile, including descriptions, and upload images to showcase products effectively.
  • Product Management: Add, update, and delete products, including details like name, price, description, and images, with the ability to manage stock levels, view, search, filter or sort all available products, archive and unarchive a product.
  • Sales Insights: View and filter sales reports by product, date, or month, and track revenue trends.
  • Customer Interaction: Respond to tourist inquiries or feedback related to products.
  • Stock Monitoring: Receive low-stock notifications to restock promptly and ensure availability.
  • Revenue Tracking: Access detailed sales reports showing performance metrics for each product.
  • Compliance with Admin: Collaborate with the admin to ensure product approval and adherence to guidelines.
  • Account management: request account to be deleted off the system.
Tourism Governor
  • Historical Site Management: Create, update, and manage museums and historical places, including descriptions, pictures, locations, opening hours, and ticket prices, create tags for different historical locations.
  • Tagging System: Assign tags to historical locations based on type, historical period, or other defining characteristics.
  • Activity Review: Monitor and manage activities or itineraries related to historical places in collaboration with tour guides and advertisers.
  • Performance Reports: Generate reports to analyze visitor engagement with museums and historical places.
  • Collaboration: Coordinate with admins, tour guides, and advertisers for better management and promotion of cultural and historical tourism.
Advertiser
  • Profile Setup & Updates: Create and manage a comprehensive profile including company details, website links, hotline, and other contact information.
  • Activity Management: Create, update, and delete activities with details like date, time, location (via Google Maps), pricing, categories, tags, and special discounts.
  • Sales Insights & Reporting: View and filter sales reports by activity or date and analyze tourist attendance for events.
  • Flagging & Notifications: Receive alerts if an event is flagged as inappropriate by the admin, both in-app and via email.
  • Event Visibility & Filtering: Ensure activities are visible to users through category, tag, and budget filters.
  • Account management: request account to be deleted off the system.
Tour Guide
  • Comprehensive Profile Management: Set up and manage a profile with personal details, years of experience, past projects, and uploaded documents.
  • Itinerary Creation & Management: Design, update, and manage detailed itineraries, including activities, locations, pricing, and availability, view list of all my created activities, itineraries.
  • Booking & Accessibility Control: Handle itinerary bookings, activate/deactivate itineraries, and ensure accessibility features for tourists.
  • Sales Tracking & Reporting: Monitor sales reports, filter by date or itinerary, and view tourist engagement statistics.
  • Feedback System: Access tourist ratings and comments for improvement and reputation building.
  • Notifications: Get alerted via email and app for flagged itineraries or system updates.
  • Account management: request account to be deleted off the system.

πŸ’» Code Examples

BackEnd
Product Controller
const addProduct = async (req, res) => {
  const { name, image, price, description, seller, quantity } = req.body;

  const newProduct = new Product({
    name,
    // image,
    price,
    description,
    seller,
    quantity,
  });
  try {
    await newProduct.save();
    res.status(201).json(newProduct);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
};
const getProductById = async (req, res) => {
  const { id } = req.params;
  const { currency = "USD" } = req.query;
  try {
    const product = await Product.findById(id)
      .populate("seller", "username")
      .populate({
        path: "reviews",
        populate: { path: "user" },
      });

    if (!product) {
      return res.status(404).json({ message: "Product not found" });
    }

    const convertedPrice = convertCurrency(product.price, "USD", currency);
    res.status(200).json({
      ...product.toObject(),
      price: convertedPrice.toFixed(2),
      currency,
    });
  } catch (error) {
    res.status(500).json({ message: "Error retrieving product", error });
  }
};
const deleteProductById = async (req, res) => {
  const { id } = req.params;
  try {
    const deletedProduct = await Product.findByIdAndDelete(id);
    if (!deletedProduct) {
      return res.status(404).json({ message: "Product not found" });
    }
    res.status(200).json({ message: "Product deleted successfully" });
  } catch (error) {
    res.status(500).json({ message: "Error deleting product", error });
  }
};
const updateProductById = async (req, res) => {
  const { id } = req.params;
  const { name, image, price, description, quantity, reviews, averageRating } =
    req.body;

  try {
    const updatedProduct = await Product.findByIdAndUpdate(
      id,
      {
        name,
        image,
        price,
        description,
        quantity,
        reviews,
        averageRating,
      },
      { new: true, runValidators: true }
    );

    if (!updatedProduct) {
      return res.status(404).json({ message: "Product not found" });
    }

    res.status(200).json({
      message: "Product updated successfully",
      product: updatedProduct,
    });
  } catch (error) {
    res.status(500).json({ message: "Error updating product", error });
  }
};
Product Model
const mongoose = require("mongoose");

const productSchema = mongoose.Schema(
  {
    name: {
      type: String,
      required: true,
    },
    image: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "uploads.files",
      // required: true,
    },
    price: {
      type: Number,
      required: true,
    },
    description: {
      type: String,
      required: true,
    },
    seller: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
      required: true,
    },
    reviews: [
      {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Review",
      },
    ],
    quantity: {
      type: Number,
      required: true,
    },
    averageRating: {
      type: Number,
      min: 0,
      max: 5,
      default: 0,
    },
    archived: {
      type: Boolean,
      default: false,
    },
  },
  {
    timestamps: true,
  }
);

// Create a text index for name and description fields for full-text search
productSchema.index({ name: "text", description: "text" });

const Product = mongoose.model("Product", productSchema);

module.exports = Product;
Autherntication middleware
const jwt = require("jsonwebtoken");

const requireAuth = (req, res, next) => {
  const token = req.cookies.token;
  //store current url to redirect to it after login
  const currentUrl = req.originalUrl;

  // check json web token exists & is verified
  if (token) {
    jwt.verify(token, process.env.JWT_SECRET, (err, decodedToken) => {
      if (err) {
        res.status(401).send("Token verification failed");
      } else {
        //console.log(decodedToken);
        req.userId = decodedToken.id;
        next();
      }
    });
  } else {
    res.status(401).send("Unauthorized. Please login first");
  }
};

module.exports = { requireAuth };
NodeMailer Util
var nodemailer = require("nodemailer");

const myEmail = "[email protected]";
const myPassword = "jegt vgtk omja pzqu";

var transporter = nodemailer.createTransport({
  service: "gmail",
  auth: {
    user: myEmail,
    pass: myPassword,
  },
  tls: {
    rejectUnauthorized: false, // Disable certificate validation (use with caution in production)
  },
});

const sendEmail = (email, subject, text) => {
  const mailOptions = {
    from: myEmail,
    to: email,
    subject: subject,
    text: text,
  };
  transporter.sendMail(mailOptions, function (error, info) {
    if (error) {
      console.log(error);
    } else {
    //   console.log("Email sent: " + info.response);
    }
  });
};

module.exports = sendEmail;
FrontEnd
ShareLink Componenet
import React from "react";
import { Alert, Avatar, Button, Dialog, DialogTitle, IconButton, List, ListItem, ListItemAvatar, ListItemButton, ListItemText, Snackbar, Typography } from "@mui/material";
import ShareIcon from '@mui/icons-material/Share';
import LinkIcon from '@mui/icons-material/Link';
import EmailIcon from '@mui/icons-material/Email';


function SimpleDialog(props) {
    const { copyLink, emailLink, onClose, open } = props;

    return (
        <Dialog onClose={onClose} open={open}>
            <DialogTitle sx={{
                textAlign: 'center',
            }}>Share with friends</DialogTitle>
            <List sx={{ pt: 0 }}>
                <ListItem disableGutters>
                    <ListItemButton
                        onClick={copyLink}
                    >
                        <ListItemAvatar>
                            <Avatar>
                                <LinkIcon />
                            </Avatar>
                        </ListItemAvatar>
                        <ListItemText primary="Copy link to clipboard" />
                    </ListItemButton>
                </ListItem>

                <ListItem disableGutters>
                    <ListItemButton
                        onClick={emailLink}
                    >
                        <ListItemAvatar>
                            <Avatar>
                                <EmailIcon />
                            </Avatar>
                        </ListItemAvatar>
                        <ListItemText primary="Send link via Email" />
                    </ListItemButton>
                </ListItem>
            </List>
        </Dialog>
    );
}

const ShareLink = ({ id, type }) => {
    const [open, setOpen] = React.useState(false);
    const [copied, setCopied] = React.useState(false);

    const getLink = () => {
        let link = 'localhost:5173/tourist/'
        switch (type) {
            case "activity":
                link += 'activities?id='
                break;
            case "itinerary":
                link += 'itineraries?id='
                break;
            case "product":
                link += 'products?id='
                break;
            case "monument":
                link += 'monuments?id='
                break;
            default:
                break;
        }
        link += id
        return link;
    }


    const copyLinkToClipboard = async () => {
        const link = getLink();
        await navigator.clipboard.writeText(link);
        setOpen(false)
        setCopied(true);
    };

    const sendEmailLink = () => {
        const link = getLink();
        const subject = `Check out this ${type}!`;
        const body = `I thought you'd like it: \n ${link}`;
        window.location.href = `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
        setOpen(false);
    };

    const handleClick = () => {
        setOpen(true);
    }

    const handleClose = () => {
        setOpen(false);
        setCopied(false);
    }

    return (
        <div>
            <Snackbar open={copied} autoHideDuration={1500} onClose={handleClose}>
                <Alert
                    onClose={handleClose}
                    sx={{
                        width: '100%',
                        backgroundColor: '#FFBF00',
                    }}
                >
                    Link Copied to Clipboard
                </Alert>
            </Snackbar>


            <IconButton onClick={handleClick} sx={{
                mt: '-10px',
                mr: '-10px',
                ml: '5px'
            }}>
                <ShareIcon />
            </IconButton>
            <SimpleDialog
                copyLink={copyLinkToClipboard}
                emailLink={sendEmailLink}
                open={open}
                onClose={handleClose}
            />


        </div>

    );
}

export default ShareLink;
SearchBar Component
import React from 'react';
import { Box, IconButton } from '@mui/material';
import SearchIcon from '@mui/icons-material/Search';

const SearchBar = ({ searchQuery, setSearchQuery, setFetch }) => {
    return (
        <Box sx={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            width: '100%',
            mb: '30px',
        }}>
            <IconButton sx={{
                fontSize: '20px',
                mt: '5px',
                mr: "5px",
                padding: "10px",
            }}
                onClick={() => setFetch((prev) => prev + 1)}>
                <SearchIcon />
            </IconButton>
            <input style={
                {
                    border: 'none',
                    width: '300px',
                    height: '40px',
                    padding: '10px',
                    borderRadius: '50px',
                    boxShadow: '1px 1px 2px 0px #00000033',
                }
            }
                placeholder='Search'
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}>
            </input>
        </Box>);
}

export default SearchBar;
Add Admin Page
import React, { useState } from "react";
import { addAdmin } from "../../services/api";
import {
  Container,
  TextField,
  Button,
  Typography,
  Box,
  Alert,
  Paper,
} from "@mui/material";

const AddAdminPage = () => {
  const [formData, setFormData] = useState({ username: "", password: "" });
  const [message, setMessage] = useState(null);
  const [error, setError] = useState(null);

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData({ ...formData, [name]: value });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const result = await addAdmin(formData);
      setMessage(`Admin "${result.username}" added successfully!`);
      setError(null);
      setFormData({ username: "", password: "" });
    } catch (err) {
      setError(err.error || "Failed to add admin.");
      setMessage(null);
    }
  };

  return (
    <Container maxWidth="sm" sx={{ mt: 8 }}>
      <Paper elevation={3} sx={{ padding: 4, borderRadius: 2 }}>
        <Typography
          variant="h5"
          sx={{ mb: 3, fontWeight: "bold", textAlign: "center" }}
        >
          Add Admin
        </Typography>
        <Box
          component="form"
          onSubmit={handleSubmit}
          sx={{ display: "flex", flexDirection: "column", gap: 2 }}
        >
          <TextField
            label="Username"
            name="username"
            value={formData.username}
            onChange={handleChange}
            variant="outlined"
            required
            fullWidth
          />
          <TextField
            label="Password"
            name="password"
            type="password"
            value={formData.password}
            onChange={handleChange}
            variant="outlined"
            required
            fullWidth
          />
          <Button
            type="submit"
            variant="contained"
            color="primary"
            sx={{ fontWeight: "bold" }}
          >
            Add Admin
          </Button>
          {message && <Alert severity="success">{message}</Alert>}
          {error && <Alert severity="error">{error}</Alert>}
        </Box>
      </Paper>
    </Container>
  );
};

export default AddAdminPage;
Product Image Component
import React, { useState, useEffect } from "react";
import { downloadImage } from "../../services/api";
import CardMedia from '@mui/material/CardMedia';
import placeholder from "../../assets/images/placeholder.png";
import { Box } from "@mui/material";

const ProductImage = ({ imageId }) => {
    const [image, setImage] = useState(null);

    const fetchImage = async () => {
        try {
            const response = await downloadImage(imageId);
            const blob = response.data;
            const imageUrl = URL.createObjectURL(blob);
            setImage(imageUrl);
        } catch (error) {
            console.error("Error fetching the product image:", error);
        }
    };

    useEffect(() => {
        if (imageId)
            fetchImage();
    }, [imageId]);

    return (

        <CardMedia
            component="img"
            image={image ? image : placeholder}
            alt="Product Image"
            sx={{
                objectFit: 'cover',
                objectPosition: 'center',
                width: '100%',
                height: '100%',
                borderRadius: '5px',
            }}
        />

    );
};

export default ProductImage;

βš™οΈ Installation

Clone the repository:

bash git clone https://github.com/Advanced-computer-lab-2024/Roammate.git cd `

Install backend dependencies

bash cd backend npm install

Install frontend dependencies

bash cd ../frontend npm install

  • Add a .env file in the backend directory of the project with the following variables (replace the values with your own):
PORT=8000
MONGO_URI="mongodb+srv://<your_username>:<your_password>@cluster0.ls7js.mongodb.net/Roammate?retryWrites=true&w=majority&appName=Cluster0"
AMADEUS_API_KEY="<Your Amadeus API Key>"
AMADEUS_API_SECRET="<Your Amadeus API Secret>"
JWT_SECRET="<A secret string to use for hashing JWT tokens>"

Run the Backend:

cd backend
node server.js

Once started, the backend server will be accessible at http://localhost:8000. This is where all API requests will be handled.

Run the Frontend:

cd frontend
npm run dev

The frontend application will run at http://localhost:5173. Open this URL in your browser to interact with the application's user interface.

πŸ“š API Reference

User Management
HTTP Method Endpoint Description
GET /users Get all users
DELETE /users/:id Delete a user by ID
PATCH /users/status Update the status of all users
PATCH /users/status/:id Update the status of a specific user
GET /users/status/:id Get the status of a specific user
GET /users/pending Get all users with 'Pending' status
GET /users/notifications/:id Get all notifications for a user
PATCH /users/notifications/:id Mark all notifications as read for a user
POST /users/forgot-password Forgot password for a user
POST /users/verify-otp Verify OTP for a user
POST /users/reset-password Reset password for a user
Admin Management
HTTP Method Endpoint Description
POST /admin Add a new admin
GET /admin/:id Get admin by ID
PATCH /admin/:id Update admin by ID
GET /admin Get all admins
DELETE /admin/:id Delete an admin by ID
Advertiser Management
HTTP Method Endpoint Description
POST /advertiser Register a new advertiser
GET /advertiser/:id Get advertiser by ID
PATCH /advertiser/:id Update advertiser by ID
GET /advertiser Get all advertisers
POST /advertiser/identification/upload Upload identification for advertiser
POST /advertiser/taxation/upload Upload taxation document for advertiser
POST /advertiser/logo/upload Upload logo for advertiser
DELETE /request-delete-advertiser/:id Request advertiser deletion if no bookings
Seller Management
HTTP Method Endpoint Description
POST /seller Register a new seller
GET /seller/:id Get seller by ID
PATCH /seller/:id Update seller by ID
GET /seller Get all sellers
POST /seller/identification/upload Upload identification for seller
POST /seller/taxation/upload Upload taxation document for seller
POST /seller/logo/upload Upload logo for seller
DELETE /request-delete-seller/:id Request seller deletion if no upcoming products
Tourist Management
HTTP Method Endpoint Description
POST /tourist Register a new tourist
GET /tourist/:id Get tourist by ID
PATCH /tourist/:id Update tourist by ID
GET /tourist Get all tourists
DELETE /request-delete-tourist/:id Request tourist deletion if no bookings
Tourism Governor Management
HTTP Method Endpoint Description
POST /tourismGovernor Add a new tourism governor
GET /tourismGovernor Get all tourism governors
GET /tourismGovernor/:id Get tourism governor by ID
PATCH /tourismGovernor/:id Update tourism governor by ID
Tour Guide Management
HTTP Method Endpoint Description
POST /tourGuide Register a new tour guide
GET /tourGuide/:id Get tour guide by ID
PATCH /tourGuide/:id Update tour guide by ID
GET /tourGuide Get all tour guides
POST /tourGuide/identification/upload Upload identification for tour guide
POST /tourGuide/certificate/upload Upload certificate for tour guide
POST /tourGuide/photo/upload Upload photo for tour guide
POST /tourGuide/review/:id Add review for a tour guide
DELETE /request-delete-tourguide/:id Request tour guide deletion if no bookings
Product Management
HTTP Method Endpoint Description
POST /product Add a new product
GET /product Get all products
GET /product/:id Get product by ID
GET /product-seller/:id Get products by seller ID
DELETE /product/:id Delete product by ID
PATCH /product/:id Update product by ID
GET /product-search Search products with filters
PUT /product/:id/toggle-archived Toggle archived status of a product
GET /product/:id/check-archived Check if a product is archived
POST /product/image/upload Upload image for a product
GET /product/:id/product-sales Get stock and sales of a product
Activity Management
HTTP Method Endpoint Description
POST /activity Create a new activity
GET /activity Get all activities
GET /activity/:id Get activity by ID
PATCH /activity/:id Update activity by ID
DELETE /activity/:id Delete activity by ID
GET /activity-search Search activities with filters and sorting
GET /activity-advertiser/:id Get activities by advertiser ID
GET /activity-tourist/:id Get booked activities by tourist ID
GET /check-activity-booking/:activityId Check if an activity is booked
Itinerary Management
HTTP Method Endpoint Description
POST /itinerary Create a new itinerary
GET /itinerary Get all itineraries
GET /itinerary/:id Get itinerary by ID
PATCH /itinerary/:id Update itinerary by ID
DELETE /itinerary/:id Delete itinerary by ID
GET /itinerary-search Search itineraries with filters and sorting
GET /itinerary/tourGuide/:id Get itineraries by tour guide ID
Tags and Categories
HTTP Method Endpoint Description
POST /preferenceTags Create a new preference tag
GET /preferenceTags Get all preference tags
PATCH /preferenceTags/:id Update a preference tag by ID
DELETE /preferenceTags/:id Delete a preference tag by ID
POST /activityCategory Create a new activity category
GET /activityCategory Get all activity categories
PATCH /activityCategory/:id Update an activity category by ID
DELETE /activityCategory/:id Delete an activity category by ID
Complaints Management
HTTP Method Endpoint Description
POST /complaint Create a new complaint
GET /complaints Get all complaints
GET /complaints/:issuerId Get complaints by issuer ID
GET /complaint/:id Get complaint details by ID
DELETE /complaint/:id Delete a complaint by ID
PUT /complaint/:id Mark a complaint as resolved by ID
Monument Management
HTTP Method Endpoint Description
POST /monument Create a new monument
GET /monument Get all monuments
GET /monument/:id Get monument by ID
PATCH /monument/:id Update a monument by ID
DELETE /monument/:id Delete a monument by ID
GET /monument-search Search monuments with filters
GET /monument/tourismGovernor/:id Get monuments by tourism governor ID
Monument Tags Management
HTTP Method Endpoint Description
POST /monumentTags Create a new monument tag
GET /monumentTags Get all monument tags
PATCH /monumentTags/:id Update a monument tag by ID
DELETE /monumentTags/:id Delete a monument tag by ID
Booking Management
HTTP Method Endpoint Description
POST /bookActivity Book an activity
DELETE /activityBookings/:id Cancel an activity booking
GET /activityBookings/:id Get booked activities for a tourist
GET /activityBookings-count/:id Get activity bookings count
POST /bookItinerary Book an itinerary
DELETE /itineraryBookings/:id Cancel an itinerary booking
GET /itineraryBookings/:id Get booked itineraries for a tourist
GET /itineraryBookings-count/:id Get itinerary bookings count
Transportation Management
HTTP Method Endpoint Description
POST /addTransportation Add a new transportation
GET /listTransportation Get a list of all transportations
POST /bookTransportation Book a transportation
GET /availableTransportation Get all available transportations
GET /touristTransportationBookings Get all booked transportations for a tourist
Wallet Management
HTTP Method Endpoint Description
POST /redeem-points/:touristId Redeem points to cash for a tourist
POST /wallet/pay Pay with the wallet
POST /wallet/refund Refund to the wallet
Wishlist Management
HTTP Method Endpoint Description
POST /wishlist/:userId/add Add a product to the user's wishlist
GET /wishlist/:userId Get the user's wishlist
POST /wishlist/:userId/toggle Toggle a product in the user's wishlist
User Cart Management
HTTP Method Endpoint Description
POST /cart/:userId/add Add a product to the user's cart
PATCH /cart/:userId/update Update product quantity in the user's cart
DELETE /cart/:userId/remove Remove a product from the user's cart
GET /cart/:userId Get the user's cart
Promo Code Management
HTTP Method Endpoint Description
POST /promoCodes Create a new promo code
POST /promoCodes/apply Apply a promo code
GET /promoCodes Get all promo codes
GET /promoCodes/user/:userId Get all promo codes for a user
Sales Reports
HTTP Method Endpoint Description
GET /advertiser-analytics Get advertiser revenue analytics
GET /tourguide-analytics Get tour guide revenue analytics
GET /seller-analytics Get seller revenue analytics
GET /vtp-analytics-giftshop Get gift shop revenue analytics
GET /vtp-analytics-total Get total revenue analytics
Bookmarks Management
HTTP Method Endpoint Description
POST /addBookmark Add a bookmarked activity
GET /getBookmarks Get all bookmarked activities
DELETE /removeBookmark Remove a bookmarked activity
POST /addBookmarkitinerary Add a bookmarked itinerary
DELETE /removeBookmarkitinerary Remove a bookmarked itinerary
GET /getBookmarkeditinerary Get all bookmarked itineraries
Interested Tourists
HTTP Method Endpoint Description
POST /addInterestToActivity Add interest to an activity
POST /addInterestToItinerary Add interest to an itinerary
DELETE /removeInterestFromActivity Remove interest from an activity
DELETE /removeInterestFromItinerary Remove interest from an itinerary
File Management
HTTP Method Endpoint Description
GET /image/:id Get an image file by ID
GET /pdf/:id Get a PDF file by ID
Flight and Hotel Bookings
HTTP Method Endpoint Description
POST /search-flights Search for flights
GET /fetch-flights/:id Get all flight bookings by ID
POST /book-flight Book a flight
GET /hotels Get hotel details
GET /search-hotel Search hotel by details
GET /list-hotels List hotels by city
Deletion Requests
HTTP Method Endpoint Description
GET /deletion-requests Get all deletion requests with filters
GET /deletion-requests/user/:userId Get deletion requests by user ID
DELETE /deletion-requests/:id Delete a deletion request by ID
PATCH /deletion-requests/:id Update a deletion request status by ID
PUT /deletion-requests/:deletionRequestId/approve Approve a deletion request
PUT /deletion-requests/:deletionRequestId/deny Deny a deletion request
GET /deletion-request-status Check deletion request status
Miscellaneous
HTTP Method Endpoint Description
POST /change-password Change the password of a user
POST /login Login a user
POST /logout Logout a user
GET /userRole Get the role of the logged-in user

πŸ§ͺ Tests

We used Postman to test each API endpoint by sending requests with specified URLs, parameters, and request bodies. The responses were verified to ensure proper functionality, including handling of edge cases, error messages, and data validation.

Some of our tests Routes are listed on our Postman documentation

Postman Documentation

πŸ§‘πŸ»β€πŸ« How to Use

❓FAQ
General

Q: How can I log in to the system?
A: You can log in using your username and password. If you're new, you'll need to register first.

Q: What if I forget my password?
A: Use the "Forgot Password" option on the login page. You'll receive an OTP at your registered email to reset your password.

Q: How do I change my password?
A: After logging in, navigate to your profile or settings, where you'll find the "Change Password" option.

Q: Can I register as a different user type (e.g., Tourist, Seller, etc.)?
A: Yes, guests can register as a Tourist, Tour Guide, Advertiser, or Seller by providing the required information.

For Tourists

Q: Can I cancel a booking?
A: Yes, bookings can be canceled at least 48 hours before the event starts. The refund amount will be credited to your wallet.

Q: How do I manage my wishlist and cart?
A: You can save products or activities to your wishlist, add them to your cart, adjust quantities, or remove items before checkout.

Q: What are loyalty points and badges?
A: You earn loyalty points and badges for completing bookings and participating in activities. Points can be redeemed for wallet cash.

Q: How can I get a promocode?
A: Promocodes are sent via email on your birthday or special occasions.

Q: Can I file a complaint?
A: Yes, you can submit complaints with details like title, description, and date, and track their status (pending/resolved).

For Tour Guides

Q: Can I activate or deactivate itineraries?
A: Yes, itineraries can be activated or deactivated even if they have existing bookings.

Q: How can I track my performance?
A: View detailed sales reports and filter them by date, activity, or itinerary. You can also see the number of tourists using your services.

For Advertisers

Q: Can I track attendance and revenue?
A: Yes, you can view and filter reports to track the total number of tourists and revenue generated from your activities.

Q: What happens if my activity is flagged?
A: You will receive an in-app notification and an email if an activity is flagged by the admin.

For Sellers

Q: How do I create or update my profile?
A: Once approved, you can add or edit your profile details, such as your name and description.

Q: How do I manage products?
A: Add, update, or delete products, including details like name, price, description, and images. You can also archive or unarchive products.

Q: Can I track sales and stock levels?
A: Yes, view sales reports and stock levels. You'll also receive low-stock notifications via email.

For Tourism Governors

Q: How do I manage historical places or museums?
A: Add, update, or delete details like descriptions, pictures, ticket prices, and opening hours.

Q: Can I assign tags to locations?
A: Yes, you can create tags based on the type or historical period for easier categorization.

🧭 Guided Usage for Stakeholders
Tourists Your guide to planning the perfect vacation using our app.
  1. Sign Up:

    • Click on the "Register" button on the homepage.
    • Fill in your details (email, username, password, mobile number, DOB, job, etc.).
    • Verify your account through the confirmation email.
  2. Set Preferences:

    • Navigate to your profile and update your travel preferences (e.g., budget, family-friendly options, historic interests).
    • These preferences will personalize your recommendations.
  3. Explore Activities and Itineraries:

    • Use the search bar or filters (budget, category, date, etc.) to browse available activities and itineraries.
    • View details, including pricing, location, and reviews.
  4. Book Your Experience:

    • Select an activity or itinerary.
    • Click "Book Now" and proceed to checkout.
    • Pay securely using your wallet, credit card, or debit card (via Stripe).
  5. Manage Bookings:

    • View upcoming and past bookings under the "My Bookings" section.
    • Cancel bookings (at least 48 hours in advance) and receive refunds in your wallet.
  6. Shop in the Gift Store:

    • Browse products by category, price, or rating.
    • Add items to your cart and proceed to checkout.
    • Choose delivery options and payment methods.
  7. Track and Redeem Rewards:

    • Earn loyalty points for bookings and purchases.
    • Redeem points in your wallet for future purchases.
Tour Guides Easily manage itineraries and provide exceptional tourist experiences.
  1. Sign Up and Approval:

    • Register as a Tour Guide with your email, username, and password.
    • Upload necessary documents for admin approval.
  2. Create and Manage Itineraries:

    • Once approved, go to the "My Itineraries" section.
    • Add a new itinerary with details like activities, locations, pricing, and accessibility options.
    • Update or delete existing itineraries as needed.
  3. Track Performance:

    • View reports on tourist engagement and earnings.
    • Use filters to analyze trends by date or itinerary.
  4. Notifications:

    • Stay updated on flagged itineraries or system changes via in-app and email notifications.
Advertisers Promote events and reach your audience effectively.
  1. Sign Up and Approval:

    • Register as an Advertiser with your email, username, and password.
    • Provide company details and upload required documents for admin approval.
  2. Create and Manage Activities:

    • Go to the "My Activities" section and click "Add Activity."
    • Fill in details like date, location (Google Maps integration), price, and tags.
    • Edit or delete activities as needed.
  3. Monitor Engagement:

    • Access reports showing tourist attendance and revenue for each activity.
    • Filter reports by date, activity, or tourist count.
  4. Notifications:

    • Receive alerts for flagged activities or promotional opportunities.
Sellers Manage your products and sales seamlessly.
  1. Sign Up and Approval:

    • Register as a Seller with your email, username, and password.
    • Submit necessary documents for admin approval.
  2. Add and Manage Products:

    • Navigate to the "My Products" section and click "Add Product."
    • Upload product details (name, price, description, and images).
    • Edit, delete, or archive products as needed.
  3. Track Inventory and Sales:

    • Monitor product stock levels and sales trends.
    • Receive notifications for low-stock items.
  4. Handle Orders:

    • View and fulfill customer orders.
    • Respond to customer inquiries about your products.
Tourism Governors Simplify cultural site management and promotion.
  1. Account Setup:

    • Admin will create your account with a unique username and password.
    • Log in and update your profile details.
  2. Manage Historical Sites:

    • Go to the "Historical Sites" section and click "Add Site."
    • Enter details like description, location, ticket prices, and images.
    • Update or delete existing entries as needed.
  3. Categorize Locations:

    • Use the "Tags" feature to assign categories like historical period or type.
  4. Monitor Engagement:

    • Generate reports to see visitor trends and revenue for your sites.
Admins Oversee and manage the platform for seamless operations.
  1. User Management:

    • Navigate to "User Requests" to approve or reject registrations for Tour Guides, Advertisers, and Sellers.
    • Add new Admins and Tourism Governors.
  2. Moderate Content:

    • Go to "Moderation" to flag or remove inappropriate events or itineraries.
    • Create and update activity categories and preference tags.
  3. Handle Complaints:

    • Access the "Complaints" section to review and resolve user-submitted issues.
    • Filter complaints by status or date.
  4. Track Platform Performance:

    • View analytics for user growth and revenue trends.
    • Generate sales reports for various stakeholders.
  5. Manage Promo Codes:

    • Create and distribute promo codes, including special birthday rewards for users.

🀝 Contribute

Contributions are always welcome to Roammate!

Whether you're here to fix bugs, propose new features, or help improve documentation, we're thrilled to have your support.

Getting Started

To begin contributing:

  1. Fork the repository to your GitHub account.
  2. Clone your forked repository and create a new branch:
    git checkout -b my-new-feature
  3. Make your changes and commit them:
    git commit -am "Add some feature"
  4. Push your branch to your forked repository:
    git push origin my-new-feature
  5. Open a Pull Request (PR) against the main branch of this repository.
Reporting Issues

If you encounter any issues, feel free to report them using the GitHub Issues feature. For a helpful bug report, please include:

  • A brief summary or background of the issue.
  • Detailed steps to reproduce the issue.
  • Any sample code or context.
  • The expected and actual outcomes.
  • Any additional notes or observations.
Feature Requests

Have an idea for a new feature? We'd love to hear it! Open a GitHub issue with your proposal, making sure to provide context, motivation, and detailed examples of how it would benefit the project.

Pull Requests

We appreciate your efforts to contribute via Pull Requests. Here's how you can make the process smoother:

  • Ensure the tests pass before submitting your PR.
  • Include tests for any new functionality you've added.
  • Make sure your changes align with the project's goals.

©️ Credits

Docs

YouTube Videos

πŸ“œ License

This software is licensed under the GNU General Public License v3.0.

Note: This project integrates with Stripe for payment processing. Portions of the Stripe software may be licensed under the Apache License 2.0. Please refer to Stripe's documentation for further details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 10

Languages