Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #10 (Overlapping Rides) Resolved along with Issues #6, #8, #12 #14

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,41 @@ async def create_user(
conn.rollback()
raise HTTPException(status_code=500, detail="Internal Server Error")

@app.post("/find_overlapping")
async def find_overlapping_rides(
booking: schemas.Booking, email: str = Depends(verify_auth_token)
):
"""
Check if overlapping rides exist when user tries to create a new ride
"""
print(booking)
# get respected ids for locations
from_id = queries.get_loc_id(conn, place=booking.from_loc)
to_id = queries.get_loc_id(conn, place=booking.to_loc)
if from_id is None or to_id is None:
raise HTTPException(status_code=400, detail="Invalid Location")

verify_exists(email)

try:
start_time=booking.start_time.astimezone(timezone("Asia/Kolkata"))
end_time=booking.end_time.astimezone(timezone("Asia/Kolkata"))

res = queries.filter_all(
conn,
from_loc=from_id,
to_loc=to_id,
start_time=start_time,
end_time=end_time,
)

bookings = get_bookings(res)
return {"overlapping_bookings_count": len(bookings)}

except Exception as e:
print(e) # TODO: Replace with logger
conn.rollback()
raise HTTPException(status_code=500, detail="Some Error Occured")

@app.post("/bookings")
async def create_booking(
Expand Down
6 changes: 3 additions & 3 deletions package.json
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these dependency changes required for this issue? If not, please address them separately

Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
"dotenv": "^16.3.1",
"jwt-decode": "^3.1.2",
"mui-tel-input": "^3.2.2",
"next": "12.1.6",
"react": "^17.0.0",
"next": "^13.5.6",
"react": "^18.2.0",
"react-copy-to-clipboard": "^5.1.0",
"react-dom": "^17.0.0",
"react-dom": "^18.2.0",
"react-toastify": "^9.1.3",
"sharp": "^0.30.6",
"styled-components": "^5.3.5"
Expand Down
82 changes: 48 additions & 34 deletions src/components/allUsersSpecific/AllUserBookings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ const places = [
"Hyd. Deccan Stn.",
];

const AllUserBookings = () => {
const [startTime, setStartTime] = useState(null);
const [endTime, setEndTime] = useState(null);
const [fromValue, setFromValue] = useState(null);
const [toValue, setToValue] = useState(null);
const AllUserBookings = ({startTimeProp, endTimeProp, fromValueProp, toValueProp}) => {
const router = useRouter();
const [startTime, setStartTime] = useState(startTimeProp);
const [endTime, setEndTime] = useState(endTimeProp);
const [fromValue, setFromValue] = useState(fromValueProp);
const [toValue, setToValue] = useState(toValueProp);
const [filteredBookings, setFilteredBookings] = useState([]);
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const router = useRouter();
const [show_all, setShowAll] = useState(false);
const [checked, setChecked] = useState(false);
const [request_checked, setRequestChecked] = useState(false);
Expand All @@ -64,9 +64,12 @@ const AllUserBookings = () => {
let apiURL = `${process.env.NEXT_PUBLIC_BACKEND_URL}/bookings`;

if (fromValue && toValue) {
if(endTime < startTime) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

it is possible to filter rides based on just one time field, so please put a not null check for endTime and startTime and only then show the warning.

toast.warn("End Time can't be before Start Time");
}
if (startTime || endTime) {
const isoStartTime = startTime?.toISOString();
const isoEndTime = endTime?.toISOString();
const isoStartTime = startTime ? new Date(startTime).toISOString() : null;
const isoEndTime = endTime ? new Date(endTime).toISOString() : null;

// makes sure that the query string takes care of null values
const queryString = (isoStartTime && isoEndTime) ? `?from_loc=${fromValue}&to_loc=${toValue}&start_time=${isoStartTime}&end_time=${isoEndTime}`
Expand All @@ -79,8 +82,8 @@ const AllUserBookings = () => {
apiURL += `?from_loc=${fromValue}&to_loc=${toValue}`;
}
} else if (startTime || endTime) {
const isoStartTime = startTime?.toISOString();
const isoEndTime = endTime?.toISOString();
const isoStartTime = startTime ? new Date(startTime).toISOString() : null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary?

I think the optional chaining present here should automatically handle it?

const isoEndTime = endTime ? new Date(endTime).toISOString() : null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto as above.


// makes sure that the query string takes care of null values
const queryString = (isoStartTime && isoEndTime) ? `?start_time=${isoStartTime}&end_time=${isoEndTime}`
Expand Down Expand Up @@ -421,37 +424,48 @@ const AllUserBookings = () => {
(startTime === null &&
endTime === null &&
toValue === null &&
fromValue === null)
fromValue === null) ||
(fromValue === toValue)
}
>
Search
</button>
</div>
</div>
</div>
<div className="sm:my-10">
{filteredBookings?.map((item, index) => {
if (show_all || item.capacity > item.travellers.length) {
return (
<CabShareSmall
fetchFilteredBookings={fetchFilteredBookings}
userSpecific={false}
key={index}
index={index}
bookingData={item}
username={username}
email={email}
phone={phone}
loaded_phone={loaded_phone}
is_there_a_phone_number={is_there_a_phone_number}
setIsThereAPhoneNumber={setIsThereAPhoneNumber}
setPhone={setPhone}
setLoadedPhone={setLoadedPhone}
/>
);
}
})}
</div>
{filteredBookings.length == 0 ? (
<div className="sm:my-10">
<div
className={`bg-secondary/10 px-2 md:p-5 py-2 sm:py-0 sm:mx-auto sm:mt-5 border-t-2 border-black/20 sm:border-2 sm:three-d sm:shadow-md sm:border-black text-black text-center rounded-none sm:rounded-md w-[100vw] sm:w-[90vw] lg:w-[60rem]`}
>
Oops! No Ride Available
</div>
</div>
) : (
<div className="sm:my-10">
{filteredBookings?.map((item, index) => {
if (show_all || item.capacity > item.travellers.length) {
return (
<CabShareSmall
fetchFilteredBookings={fetchFilteredBookings}
userSpecific={false}
key={index}
index={index}
bookingData={item}
username={username}
email={email}
phone={phone}
loaded_phone={loaded_phone}
is_there_a_phone_number={is_there_a_phone_number}
setIsThereAPhoneNumber={setIsThereAPhoneNumber}
setPhone={setPhone}
setLoadedPhone={setLoadedPhone}
/>
);
}
})}
</div>
)}
</div>
)}
</div>
Expand Down
20 changes: 18 additions & 2 deletions src/components/commonForAll/CabSharing.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,29 @@ import FavoriteIcon from "@mui/icons-material/Favorite";
import { keyframes } from "@emotion/react";
import styled from "@emotion/styled";
import LogoutButton from "./Logout";
import ReportBugButton from "./ReportBug";
import UserGuide from "./UserGuide";
import { ToastContainer, toast } from "react-toastify";

// 1 -> All Rides, 2 -> User Rides

export default function CabSharing() {
const [tab, setTab] = useState(1);
// Tab 1 - All Rides, Tab 0 - My Rides
const [username, setUsername] = useState("");
const router = useRouter();
const findRides = router.query.findRides;
const startTimeProp = router.query.startTimeProp|| null;
const endTimeProp = router.query.endTimeProp || null;
const fromValueProp = router.query.fromValueProp || null;
const toValueProp = router.query.toValueProp || null;

useEffect(() => {
setUsername(localStorage.getItem("user_name"));
retrieveAuthToken(router);
}, []);
if(findRides === 'true' || findRides==null) setTab(1);
else setTab(0);
}, [findRides]);

const pulse = keyframes`
0% {
Expand All @@ -47,6 +57,7 @@ export default function CabSharing() {
<ToastContainer />
<div className="flex flex-row ml-auto">
{/* <UserGuide /> */}
<ReportBugButton />
<LogoutButton />
</div>
<div className="flex bg-purple-100 flex-col overflow-x-auto min-h-screen ">
Expand Down Expand Up @@ -74,7 +85,12 @@ export default function CabSharing() {
</div>
<div className="flex flex-nowrap overflow-x-auto">
{tab === 0 && <UserBookings />}
{tab === 1 && <AllUserBookings />}
{tab === 1 && <AllUserBookings
startTimeProp={startTimeProp}
endTimeProp={endTimeProp}
fromValueProp={fromValueProp}
toValueProp={toValueProp}
/>}
</div>
</div>
<footer className="flex justify-center gap-2 text-[1.1rem] border-t-2 border-black/20 items-center bg-secondary/20 py-4">
Expand Down
22 changes: 22 additions & 0 deletions src/components/commonForAll/ReportBug.jsx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open this form in a new tab

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from "react";
import { useRouter } from "next/router";
import BugReportIcon from '@mui/icons-material/BugReport';

function ReportBugButton() {
const router = useRouter();

const handleReport = () => {
window.location.href = "https://docs.google.com/forms/d/e/1FAIpQLScEKZIbE45xn8TzD_OzehhNnS0BDXdSfvJBm1FAG_l0KywSEw/viewform";
};

return (
<button
className="btn bg-transparent h-1 min-h-8 p-1 border-none text-black mx-5 mb-5 hover:bg-secondary/80 hover:text-white/80 capitalize font-[400] text-sm my-3 transition-all hover:-translate-y-[.5px] ml-[auto]"
onClick={handleReport}
>
Report Bug <BugReportIcon className="text-[.9rem] text-black/50" />
</button>
);
}

export default ReportBugButton;
77 changes: 77 additions & 0 deletions src/components/modals/OverlappingModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { useRouter } from "next/router";
import React, { useEffect, useState } from "react";

const OverlappingModal = ({
numOverlapping,
findFunction,
bookFunction,
}) => {
const [isModalOpen, setModalOpen] = useState(false);

const router = useRouter();

useEffect(() => {
if (numOverlapping > 0) {
setModalOpen(true);
} else {
setModalOpen(false);
}
}, [numOverlapping]);

const closeModal = () => {
setModalOpen(false);
};

return (
<>
{isModalOpen && (
<dialog
id="my_modal_3"
className="modal modal-open"
onClick={(e) => e.stopPropagation()}
>
<form
method="dialog"
className="modal-box bg-white text-black border-black border-2"
>
<button
className="btn btn-sm btn-circle btn-ghost absolute right-2"
onClick={() => closeModal()}
>
</button>
<div className="flex flex-col gap-4">
<h3 className="font-bold text-lg text-secondary/80 border-secondary border-b-2 w-fit">
Overlapping Rides
</h3>
{"There are " + numOverlapping + " rides matching your info. Would you like to check them out?"}
<button
className="btn ml-auto bg-secondary/70 text-white/80 hover:bg-secondary/80 "
onClick={() => {
findFunction();
closeModal();
}}
>
{"Yes, Find Rides"}
</button>
<button
className="btn ml-auto bg-secondary/70 text-white/80 hover:bg-secondary/80 "
onClick={() => {
bookFunction();
closeModal();
}}
>
{"No, Continue booking"}
</button>
</div>
</form>
<form method="dialog" className="modal-backdrop">
<button onClick={() => closeModal()}>close</button>
</form>
</dialog>
)}
</>
);
};

export default OverlappingModal;
Loading