Skip to content

Commit

Permalink
Merge branch 'main' into Kai_Dev_Fall_2024
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaibanda authored Oct 3, 2024
2 parents a822126 + 1a2f7e4 commit 51162d2
Show file tree
Hide file tree
Showing 89 changed files with 2,241 additions and 1,123 deletions.
1 change: 1 addition & 0 deletions .github/workflows/deploy_development_app_engine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
echo "NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=${{ secrets.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID }}" >> .env.production
echo "NEXT_PUBLIC_DATABASE_NAME=${{ secrets.NEXT_PUBLIC_DATABASE_NAME }}" >> .env.production
echo "NEXT_PUBLIC_BRANCH_NAME=${{ secrets.NEXT_PUBLIC_BRANCH_NAME }}" >> .env.production
echo "NEXT_PUBLIC_GCP_LOG_NAME=${{ secrets.NEXT_PUBLIC_GCP_LOG_NAME }}" >> .env.production
- name: Install dependencies
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy_production_app_engine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
echo "NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=${{ secrets.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID }}" >> .env.production
echo "NEXT_PUBLIC_DATABASE_NAME=${{ secrets.NEXT_PUBLIC_DATABASE_NAME }}" >> .env.production
echo "NEXT_PUBLIC_BRANCH_NAME=${{ secrets.NEXT_PUBLIC_BRANCH_NAME }}" >> .env.production
echo "NEXT_PUBLIC_GCP_LOG_NAME=${{ secrets.NEXT_PUBLIC_GCP_LOG_NAME }}" >> .env.production
- name: Install dependencies
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy_staging_app_engine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
echo "NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=${{ secrets.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID }}" >> .env.production
echo "NEXT_PUBLIC_DATABASE_NAME=${{ secrets.NEXT_PUBLIC_DATABASE_NAME }}" >> .env.production
echo "NEXT_PUBLIC_BRANCH_NAME=${{ secrets.NEXT_PUBLIC_BRANCH_NAME }}" >> .env.production
echo "NEXT_PUBLIC_GCP_LOG_NAME=${{ secrets.NEXT_PUBLIC_GCP_LOG_NAME }}" >> .env.production
- name: Install dependencies
run: |
Expand Down
1 change: 1 addition & 0 deletions booking-app/app.development.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ automatic_scaling:
env_variables:
NEXT_PUBLIC_BRANCH_NAME: "development"
NODE_OPTIONS: "--max-old-space-size=4096"
TZ: "America/New_York"

build_env_variables:
NODE_OPTIONS: "--max-old-space-size=4096"
Expand Down
1 change: 1 addition & 0 deletions booking-app/app.production.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ automatic_scaling:
env_variables:
NEXT_PUBLIC_BRANCH_NAME: "production"
NODE_OPTIONS: "--max-old-space-size=4096"
TZ: "America/New_York"

build_env_variables:
NODE_OPTIONS: "--max-old-space-size=4096"
Expand Down
1 change: 1 addition & 0 deletions booking-app/app.staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ automatic_scaling:
env_variables:
NEXT_PUBLIC_BRANCH_NAME: "staging"
NODE_OPTIONS: "--max-old-space-size=4096"
TZ: "America/New_York"

build_env_variables:
NODE_OPTIONS: "--max-old-space-size=4096"
Expand Down
57 changes: 57 additions & 0 deletions booking-app/app/api/bookings/export/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Booking, BookingStatus } from "@/components/src/types";
import { NextRequest, NextResponse } from "next/server";

import { TableNames } from "@/components/src/policy";
import { parse } from "json2csv";
import { serverFetchAllDataFromCollection } from "@/lib/firebase/server/adminDb";

export async function GET(request: NextRequest) {
const bookings = await serverFetchAllDataFromCollection<Booking>(
TableNames.BOOKING,
);
const statuses = await serverFetchAllDataFromCollection<BookingStatus>(
TableNames.BOOKING_STATUS,
);

// need to find corresponding status row for booking row
const idsToData: {
[key: string]: {
booking: Booking;
status: BookingStatus;
};
} = {};

for (let booking of bookings) {
const calendarEventId = booking.calendarEventId;
const statusMatch = statuses.filter(
row => row.calendarEventId === calendarEventId,
)[0];
idsToData[calendarEventId] = {
booking,
status: statusMatch,
};
}

const rows = Object.entries(idsToData)
.map(([_, { booking, status }]) => {
const { requestNumber, ...otherBooking } = booking;
return { requestNumber, ...otherBooking, ...status };
})
.sort((a, b) => a.requestNumber - b.requestNumber);

try {
const csv = parse(rows);
return new NextResponse(csv, {
status: 200,
headers: {
"Content-Type": "text/csv",
"Content-Disposition": 'attachment; filename="data.csv"',
},
});
} catch (error) {
return NextResponse.json(
{ error: "Failed to fetch CSV data" },
{ status: 400 },
);
}
}
31 changes: 19 additions & 12 deletions booking-app/app/api/bookings/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,27 @@ import {
declineUrl,
getBookingToolDeployUrl,
} from "@/components/src/server/ui";
import { deleteEvent, insertEvent } from "@/components/src/server/calendars";
import {
firstApproverEmails,
serverApproveInstantBooking,
serverBookingContents,
serverDeleteDataByCalendarEventId,
serverUpdateDataByCalendarEventId,
} from "@/components/src/server/admin";
import { deleteEvent, insertEvent } from "@/components/src/server/calendars";
import {
serverFormatDate,
toFirebaseTimestampFromString,
} from "@/components/src/client/utils/serverDate";
import {
serverGetNextSequentialId,
serverSaveDataToFirestore,
} from "@/lib/firebase/server/adminDb";

import { DateSelectArg } from "fullcalendar";
import { TableNames } from "@/components/src/policy";
import { Timestamp } from "firebase-admin/firestore";
import { sendHTMLEmail } from "@/app/lib/sendHTMLEmail";
import {
serverGetNextSequentialId,
serverSaveDataToFirestore,
} from "@/lib/firebase/server/adminDb";
import {
serverFormatDate,
toFirebaseTimestampFromString,
} from "@/components/src/client/utils/serverDate";

async function createBookingCalendarEvent(
selectedRooms: RoomSetting[],
Expand Down Expand Up @@ -161,13 +162,11 @@ export async function POST(request: NextRequest) {
equipmentCheckedOut: false,
...data,
});
console.log(" Done serverSaveDataToFirestore booking");
await serverSaveDataToFirestore(TableNames.BOOKING_STATUS, {
calendarEventId,
email,
requestedAt: Timestamp.now(),
});
console.log(" Done serverSaveDataToFirestore booking status");

await handleBookingApprovalEmails(
isAutoApproval,
Expand All @@ -190,6 +189,7 @@ export async function PUT(request: NextRequest) {
const {
email,
selectedRooms,
allRooms,
bookingCalendarInfo,
data,
isAutoApproval,
Expand All @@ -202,13 +202,20 @@ export async function PUT(request: NextRequest) {
{ status: 500 },
);
}

const existingContents = await serverBookingContents(calendarEventId);
const oldRoomIds = existingContents.roomId.split(",").map(x => x.trim());
const oldRooms = allRooms.filter((room: RoomSetting) =>
oldRoomIds.includes(room.roomId + ""),
);

const selectedRoomIds = selectedRooms
.map((r: { roomId: number }) => r.roomId)
.join(", ");

// delete existing cal events
await Promise.all(
selectedRooms.map(async room => {
oldRooms.map(async room => {
await deleteEvent(room.calendarId, calendarEventId, room.roomId);
}),
);
Expand Down
18 changes: 12 additions & 6 deletions booking-app/app/api/calendarEvents/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { NextRequest, NextResponse } from "next/server";
import {
deleteEvent,
insertEvent,
updateEventPrefix,
updateCalendarEvent,
} from "@/components/src/server/calendars";

import { serverBookingContents } from "@/components/src/server/admin";
import { getCalendarClient } from "@/lib/googleClient";
import { serverBookingContents } from "@/components/src/server/admin";

const getCalendarEvents = async (calendarId: string) => {
const calendar = await getCalendarClient();
Expand Down Expand Up @@ -84,7 +84,13 @@ export async function GET(req: NextRequest) {

try {
const events = await getCalendarEvents(calendarId);
return NextResponse.json(events);
const res = NextResponse.json(events);
res.headers.set(
"Cache-Control",
"no-store, no-cache, must-revalidate, proxy-revalidate",
);
res.headers.set("Expires", "0");
return res;
} catch (error) {
console.error("Error fetching calendar events:", error);
return NextResponse.json(
Expand All @@ -95,17 +101,17 @@ export async function GET(req: NextRequest) {
}

export async function PUT(req: NextRequest) {
const { calendarEventId, newPrefix } = await req.json();
const { calendarEventId, newValues } = await req.json();

if (!calendarEventId || !newPrefix) {
if (!calendarEventId || !newValues) {
return NextResponse.json(
{ error: "Missing required fields" },
{ status: 400 },
);
}
const contents = await serverBookingContents(calendarEventId);
try {
await updateEventPrefix(calendarEventId, newPrefix, contents);
await updateCalendarEvent(calendarEventId, newValues, contents);
return NextResponse.json(
{ message: "Event updated successfully" },
{ status: 200 },
Expand Down
41 changes: 38 additions & 3 deletions booking-app/app/api/safety_training_users/route.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { getGoogleSheet } from "@/lib/googleClient";
import { NextRequest, NextResponse } from "next/server";
import { getGoogleSheet, getLoggingClient } from "@/lib/googleClient";

const SPREADSHEET_ID = process.env.GOOGLE_SPREADSHEET_ID;
const SHEET_GID = process.env.GOOGLE_SHEET_ID;
const COLUMN = "B";
const MAX_ROWS = 1000;

export const dynamic = "force-dynamic";
export async function GET(request: NextRequest) {
try {
const sheetsService = await getGoogleSheet(SPREADSHEET_ID);
const logger = await getLoggingClient();

const spreadsheet = await sheetsService.spreadsheets.get({
spreadsheetId: SPREADSHEET_ID,
Expand All @@ -33,16 +35,49 @@ export async function GET(request: NextRequest) {
});
console.log("emails", response.data.values);

const logEntry = {
logName: process.env.NEXT_PUBLIC_GCP_LOG_NAME + "/safety-training",
resource: { type: "global" },
entries: [
{
jsonPayload: {
message: "Fetched emails",
emails: response.data.values,
number: response.data.values.length,
branchName: process.env.NEXT_PUBLIC_BRANCH_NAME,
timestamp,
},
severity: "INFO",
},
],
};

logger.entries.write({
requestBody: logEntry,
});

const rows = response.data.values;
if (!rows || rows.length === 0) {
return NextResponse.json({ emails: [] });
const res = NextResponse.json({ emails: [] });
res.headers.set(
"Cache-Control",
"no-store, no-cache, must-revalidate, proxy-revalidate",
);
res.headers.set("Expires", "0");
return res;
}

const emails = rows
.flat()
.filter(email => email && typeof email === "string");

return NextResponse.json({ emails });
const res = NextResponse.json({ emails });
res.headers.set(
"Cache-Control",
"no-store, no-cache, must-revalidate, proxy-revalidate",
);
res.headers.set("Expires", "0");
return res;
} catch (error) {
console.error("Failed to fetch emails:", error);
if (
Expand Down
Loading

0 comments on commit 51162d2

Please sign in to comment.