- π Motivation
- π§± Build Status
- π¨ Code Style
- πΈ Screenshots
- βοΈ Tech and Frameworks used
- π₯ Features
- π» Code Examples
- βοΈ Installation
- π API Reference
- π§ͺ Tests
- π§π»βπ« How to Use
- π€ Contribute
- Β©οΈ Credits
- π License
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.
- 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
- 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
User Login
Tourist Profile Page
- Edit your personal data.
- Redeem your points.
- Change your password.
- Delete the account.
- Add an address.
Sorting and Filtering
- Choose the criteria to sort the results.
- Choose the constraints to filter the results.
- Price is sorted in ascending order.
Flights Search
- Search flights with departure time and destination time.
- Search flights with departure loaction and destination locations.
- Choose the number of passengers.
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.
Admin Homepage
- Delete user's account.
- View the number of users.
- Toggle between users, registrations and compliants.
Account Deletion Requests
- Approve or deny account deletion requests.
- See previous approved and denied account deletion requests.
Admin Add Product
- Add the required information of a certain Product..
- upload an image of the product.
Admin Edit Product
- Edit the product name.
- Edit the prouct description.
- Edit product price.
- upload an image of the product.
- 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
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.
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;
bash git clone https://github.com/Advanced-computer-lab-2024/Roammate.git cd `
bash cd backend npm install
bash cd ../frontend npm install
- Add a
.env
file in thebackend
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>"
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.
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.
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 |
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
β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.-
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.
-
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.
-
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.
-
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).
-
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.
-
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.
-
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.-
Sign Up and Approval:
- Register as a Tour Guide with your email, username, and password.
- Upload necessary documents for admin approval.
-
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.
-
Track Performance:
- View reports on tourist engagement and earnings.
- Use filters to analyze trends by date or itinerary.
-
Notifications:
- Stay updated on flagged itineraries or system changes via in-app and email notifications.
Advertisers
Promote events and reach your audience effectively.-
Sign Up and Approval:
- Register as an Advertiser with your email, username, and password.
- Provide company details and upload required documents for admin approval.
-
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.
-
Monitor Engagement:
- Access reports showing tourist attendance and revenue for each activity.
- Filter reports by date, activity, or tourist count.
-
Notifications:
- Receive alerts for flagged activities or promotional opportunities.
Sellers
Manage your products and sales seamlessly.-
Sign Up and Approval:
- Register as a Seller with your email, username, and password.
- Submit necessary documents for admin approval.
-
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.
-
Track Inventory and Sales:
- Monitor product stock levels and sales trends.
- Receive notifications for low-stock items.
-
Handle Orders:
- View and fulfill customer orders.
- Respond to customer inquiries about your products.
Tourism Governors
Simplify cultural site management and promotion.-
Account Setup:
- Admin will create your account with a unique username and password.
- Log in and update your profile details.
-
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.
-
Categorize Locations:
- Use the "Tags" feature to assign categories like historical period or type.
-
Monitor Engagement:
- Generate reports to see visitor trends and revenue for your sites.
Admins
Oversee and manage the platform for seamless operations.-
User Management:
- Navigate to "User Requests" to approve or reject registrations for Tour Guides, Advertisers, and Sellers.
- Add new Admins and Tourism Governors.
-
Moderate Content:
- Go to "Moderation" to flag or remove inappropriate events or itineraries.
- Create and update activity categories and preference tags.
-
Handle Complaints:
- Access the "Complaints" section to review and resolve user-submitted issues.
- Filter complaints by status or date.
-
Track Platform Performance:
- View analytics for user growth and revenue trends.
- Generate sales reports for various stakeholders.
-
Manage Promo Codes:
- Create and distribute promo codes, including special birthday rewards for users.
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:
- Fork the repository to your GitHub account.
- Clone your forked repository and create a new branch:
git checkout -b my-new-feature
- Make your changes and commit them:
git commit -am "Add some feature"
- Push your branch to your forked repository:
git push origin my-new-feature
- 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.
- JavaScript Full Course
- NodeJs Crash Course
- ReactJS Crash Course
- MERN Stack Development
- MERN Full Stack Tutorial
- Stripe Integration
- JWT Authentication Tutorial
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.