Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/ITPNYU/booking-app
Browse files Browse the repository at this point in the history
  • Loading branch information
lucia-gomez committed Oct 8, 2024
2 parents 9afe8ef + 10c72dc commit 1a7a50e
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 58 deletions.
5 changes: 2 additions & 3 deletions booking-app/app/api/approve/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import { NextRequest, NextResponse } from "next/server";
import { serverApproveBooking } from "@/components/src/server/admin";

export async function POST(req: NextRequest) {
const { id } = await req.json();
const { id, email } = await req.json();

try {
console.log("id", id);
await serverApproveBooking(id);
await serverApproveBooking(id, email);
return NextResponse.json(
{ message: "Approved successfully" },
{ status: 200 },
Expand Down
19 changes: 13 additions & 6 deletions booking-app/app/approve/page.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
"use client";

import React, { Suspense, useState } from "react";
import React, { Suspense, useContext, useState } from "react";

import {
DatabaseContext,
DatabaseProvider,
} from "@/components/src/client/routes/components/Provider";
import { clientApproveBooking } from "@/components/src/server/db";
import { Button } from "@mui/material";
import { useSearchParams } from "next/navigation";
import { clientApproveBooking } from "@/components/src/server/db";

const ApprovePageContent: React.FC = () => {
const searchParams = useSearchParams();
const paramCalendarEventId = searchParams.get("calendarEventId");
const [loading, setLoading] = useState(false);
const [approved, setApproved] = useState(false);
const [error, setError] = useState<string | null>(null);
const { userEmail } = useContext(DatabaseContext);

const handleApprove = async () => {
if (paramCalendarEventId) {
setLoading(true);
setError(null);
try {
await clientApproveBooking(paramCalendarEventId);
await clientApproveBooking(paramCalendarEventId, userEmail);
setApproved(true);
} catch (err) {
setError("Failed to approve booking.");
Expand Down Expand Up @@ -55,9 +60,11 @@ const ApprovePageContent: React.FC = () => {
};

const ApprovePage: React.FC = () => (
<Suspense fallback={<div>Loading...</div>}>
<ApprovePageContent />
</Suspense>
<DatabaseProvider>
<Suspense fallback={<div>Loading...</div>}>
<ApprovePageContent />
</Suspense>
</DatabaseProvider>
);

export default ApprovePage;
42 changes: 31 additions & 11 deletions booking-app/app/decline/page.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
"use client";

import React, { Suspense, useState } from "react";

import { Button } from "@mui/material";
import { useSearchParams } from "next/navigation";
import {
DatabaseContext,
DatabaseProvider,
} from "@/components/src/client/routes/components/Provider";
import { decline } from "@/components/src/server/db";
import { Button, TextField } from "@mui/material";
import { useSearchParams } from "next/navigation";
import React, { Suspense, useContext, useState } from "react";

const DeclinePageContent: React.FC = () => {
const searchParams = useSearchParams();
const paramCalendarEventId = searchParams.get("calendarEventId");
const [loading, setLoading] = useState(false);
const [declined, setDeclined] = useState(false);
const [error, setError] = useState<string | null>(null);
const [reason, setReason] = useState("");
const { userEmail } = useContext(DatabaseContext);

const handleDecline = async () => {
if (paramCalendarEventId) {
if (paramCalendarEventId && reason.trim()) {
setLoading(true);
setError(null);
try {
await decline(paramCalendarEventId);
await decline(paramCalendarEventId, userEmail, reason);
setDeclined(true);
} catch (err) {
setError("Failed to decline booking.");
console.log(err);
} finally {
setLoading(false);
}
} else {
setError("Please provide a reason for declining.");
}
};

Expand All @@ -34,9 +41,20 @@ const DeclinePageContent: React.FC = () => {
{paramCalendarEventId ? (
<div>
<p>Event ID: {paramCalendarEventId}</p>
<TextField
label="Reason for Declining"
variant="outlined"
fullWidth
multiline
rows={4}
value={reason}
onChange={e => setReason(e.target.value)}
style={{ marginBottom: 16 }}
required
/>
<Button
onClick={() => handleDecline()}
disabled={loading || declined}
disabled={loading || declined || !reason.trim()}
variant="contained"
>
{loading
Expand All @@ -55,9 +73,11 @@ const DeclinePageContent: React.FC = () => {
};

const DeclinePage: React.FC = () => (
<Suspense fallback={<div>Loading...</div>}>
<DeclinePageContent />
</Suspense>
<DatabaseProvider>
<Suspense fallback={<div>Loading...</div>}>
<DeclinePageContent />
</Suspense>
</DatabaseProvider>
);

export default DeclinePage;
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default function BookingActions(props: Props) {
);
const { reloadBookings, reloadBookingStatuses } = useContext(DatabaseContext);
const [showError, setShowError] = useState(false);

const { actions, updateActions, options } = useBookingActions({
status,
calendarEventId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { useContext, useMemo, useState } from "react";

import { BookingContext } from "../../booking/bookingProvider";
import { DatabaseContext } from "../../components/Provider";
import { Timestamp } from "@firebase/firestore";
import useExistingBooking from "./useExistingBooking";
import { useRouter } from "next/navigation";
Expand Down Expand Up @@ -49,6 +50,7 @@ export default function useBookingActions({
}: Props) {
const [date, setDate] = useState(new Date());
const { reloadExistingCalendarEvents } = useContext(BookingContext);
const { userEmail } = useContext(DatabaseContext);
const loadExistingBookingData = useExistingBooking();
const router = useRouter();

Expand All @@ -59,44 +61,44 @@ export default function useBookingActions({
const actions: { [key in Actions]: ActionDefinition } = {
[Actions.CANCEL]: {
action: async () => {
await cancel(calendarEventId);
await cancel(calendarEventId, userEmail);
},
optimisticNextStatus: BookingStatusLabel.CANCELED,
confirmation: true,
},
[Actions.NO_SHOW]: {
action: async () => {
await noShow(calendarEventId);
await noShow(calendarEventId, userEmail);
},
optimisticNextStatus: BookingStatusLabel.NO_SHOW,
},
[Actions.CHECK_IN]: {
action: async () => {
await checkin(calendarEventId);
await checkin(calendarEventId, userEmail);
},
optimisticNextStatus: BookingStatusLabel.CHECKED_IN,
},
[Actions.CHECK_OUT]: {
action: async () => {
await checkOut(calendarEventId);
await checkOut(calendarEventId, userEmail);
},
optimisticNextStatus: BookingStatusLabel.CHECKED_OUT,
},
[Actions.FIRST_APPROVE]: {
action: async () => {
await clientApproveBooking(calendarEventId);
await clientApproveBooking(calendarEventId, userEmail);
},
optimisticNextStatus: BookingStatusLabel.PENDING,
},
[Actions.FINAL_APPROVE]: {
action: async () => {
await clientApproveBooking(calendarEventId);
await clientApproveBooking(calendarEventId, userEmail);
},
optimisticNextStatus: BookingStatusLabel.APPROVED,
},
[Actions.DECLINE]: {
action: async () => {
await decline(calendarEventId);
await decline(calendarEventId, userEmail);
},
optimisticNextStatus: BookingStatusLabel.DECLINED,
confirmation: true,
Expand Down
26 changes: 14 additions & 12 deletions booking-app/components/src/server/admin.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
import {
BookingFormDetails,
BookingStatus,
BookingStatusLabel,
PolicySettings,
RoomSetting,
} from "../types";
import {
Constraint,
serverDeleteData,
Expand All @@ -14,6 +7,12 @@ import {
serverUpdateInFirestore,
} from "@/lib/firebase/server/adminDb";
import { TableNames, getApprovalCcEmail } from "../policy";
import {
BookingFormDetails,
BookingStatus,
BookingStatusLabel,
RoomSetting,
} from "../types";
import { approvalUrl, declineUrl, getBookingToolDeployUrl } from "./ui";

import { Timestamp } from "firebase-admin/firestore";
Expand Down Expand Up @@ -72,15 +71,17 @@ export const serverDeleteDataByCalendarEventId = async (
};

// from server
const serverFirstApprove = (id: string) => {
const serverFirstApprove = (id: string, email?: string) => {
serverUpdateDataByCalendarEventId(TableNames.BOOKING_STATUS, id, {
firstApprovedAt: Timestamp.now(),
firstApprovedBy: email,
});
};

const serverFinalApprove = (id: string) => {
const serverFinalApprove = (id: string, email?: string) => {
serverUpdateDataByCalendarEventId(TableNames.BOOKING_STATUS, id, {
finalApprovedAt: Timestamp.now(),
finalApprovedBy: email,
});
};

Expand All @@ -92,7 +93,7 @@ export const serverApproveInstantBooking = (id: string) => {
};

// both first approve and second approve flows hit here
export const serverApproveBooking = async (id: string) => {
export const serverApproveBooking = async (id: string, email: string) => {
const bookingStatus = await serverGetDataByCalendarEventId<BookingStatus>(
TableNames.BOOKING_STATUS,
id
Expand All @@ -106,10 +107,11 @@ export const serverApproveBooking = async (id: string) => {

// if already first approved, then this is a second approve
if (firstApproveDateRange !== null) {
serverFinalApprove(id);
serverFinalApprove(id, email);
await serverApproveEvent(id);
} else {
serverFirstApprove(id);
console.log("email", email);
serverFirstApprove(id, email);

const response = await fetch(
`${process.env.NEXT_PUBLIC_BASE_URL}/api/calendarEvents`,
Expand Down
Loading

0 comments on commit 1a7a50e

Please sign in to comment.