mirror of
https://github.com/tomru/pfadi-bussle.git
synced 2026-03-02 22:17:11 +01:00
fix all the formatting
This commit is contained in:
@@ -107,7 +107,7 @@ export default function MyCalendar({
|
||||
return
|
||||
}
|
||||
|
||||
const dateAsBackendFormat = dateFormatBackend(date);
|
||||
const dateAsBackendFormat = dateFormatBackend(date)
|
||||
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
@@ -132,7 +132,10 @@ export default function MyCalendar({
|
||||
if (isAfter(date, startDate)) {
|
||||
onChange({ endDate: dateAsBackendFormat })
|
||||
} else {
|
||||
onChange({ startDate: dateAsBackendFormat, endDate: dateAsBackendFormat })
|
||||
onChange({
|
||||
startDate: dateAsBackendFormat,
|
||||
endDate: dateAsBackendFormat,
|
||||
})
|
||||
}
|
||||
}}
|
||||
tileClassName={tileClassName}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { dateFormatBackend, getDays, nowInTz, dateParseBackend } from '../helpers/date'
|
||||
import {
|
||||
dateFormatBackend,
|
||||
getDays,
|
||||
nowInTz,
|
||||
dateParseBackend,
|
||||
} from '../helpers/date'
|
||||
import { createCalendarEvent, deleteCalendarEvent } from '../lib/googlecalendar'
|
||||
|
||||
import { Bill } from './bill'
|
||||
@@ -16,9 +21,9 @@ export type Booking = {
|
||||
city: string
|
||||
bill?: Bill
|
||||
// format YYYY-MM-DD
|
||||
startDate: string,
|
||||
startDate: string
|
||||
// format YYYY-MM-DD
|
||||
endDate: string,
|
||||
endDate: string
|
||||
status?: BOOKING_STATUS
|
||||
purpose?: string
|
||||
org?: string
|
||||
@@ -58,14 +63,14 @@ const BookingSchema = new mongoose.Schema<BookingDocument>(
|
||||
type: String,
|
||||
required: true,
|
||||
validator: function (value: string): boolean {
|
||||
return !!dateParseBackend(value);
|
||||
return !!dateParseBackend(value)
|
||||
},
|
||||
},
|
||||
endDate: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: function (value: string): boolean {
|
||||
return !!dateParseBackend(value);
|
||||
return !!dateParseBackend(value)
|
||||
},
|
||||
},
|
||||
days: {
|
||||
@@ -160,4 +165,4 @@ const BookingModel = (mongoose.models.Booking ||
|
||||
BookingSchema
|
||||
)) as BookingModel
|
||||
|
||||
export default BookingModel;
|
||||
export default BookingModel
|
||||
|
||||
12
db/index.ts
12
db/index.ts
@@ -23,12 +23,10 @@ export async function getBookedDays(
|
||||
uuidsToIngore?: string[]
|
||||
): Promise<string[]> {
|
||||
await connect()
|
||||
const bookedInDatabase = await BookingModel.findBookedDays(uuidsToIngore);
|
||||
const bookedInCalendar = await calendarGetBookedDays();
|
||||
const bookedInDatabase = await BookingModel.findBookedDays(uuidsToIngore)
|
||||
const bookedInCalendar = await calendarGetBookedDays()
|
||||
|
||||
return [ ...bookedInDatabase, ...bookedInCalendar]
|
||||
.filter(uniqueFilter)
|
||||
.sort();
|
||||
return [...bookedInDatabase, ...bookedInCalendar].filter(uniqueFilter).sort()
|
||||
}
|
||||
|
||||
export async function getBookingByUUID(uuid: string): Promise<BookingDocument> {
|
||||
@@ -85,11 +83,11 @@ export async function createBooking({
|
||||
|
||||
export async function patchBooking(
|
||||
bookingUUID: string,
|
||||
bookingData: Booking,
|
||||
bookingData: Booking
|
||||
): Promise<Booking> {
|
||||
await connect()
|
||||
const booking = await getBookingByUUID(bookingUUID)
|
||||
booking.set(bookingData);
|
||||
booking.set(bookingData)
|
||||
await booking.save()
|
||||
|
||||
return booking.toJSON()
|
||||
|
||||
@@ -18,5 +18,5 @@ export function getNextBigger<T>(array: T[], pivot: T): T {
|
||||
}
|
||||
|
||||
export function uniqueFilter(value, index, self) {
|
||||
return self.indexOf(value) === index;
|
||||
return self.indexOf(value) === index
|
||||
}
|
||||
|
||||
@@ -31,7 +31,10 @@ export async function cancelBooking(uuid: string) {
|
||||
})
|
||||
}
|
||||
|
||||
export async function patchBooking(uuid: string, bookingData: Partial<BookFormData>) {
|
||||
export async function patchBooking(
|
||||
uuid: string,
|
||||
bookingData: Partial<BookFormData>
|
||||
) {
|
||||
return fetch(`/api/bookings/${uuid}`, {
|
||||
method: 'PATCH',
|
||||
body: bookingData,
|
||||
|
||||
@@ -34,7 +34,7 @@ export function getDays({
|
||||
return days
|
||||
}
|
||||
|
||||
const inclusiveEndDate = endDateExclusive ? subDays(endDate, 1) : endDate;
|
||||
const inclusiveEndDate = endDateExclusive ? subDays(endDate, 1) : endDate
|
||||
|
||||
while (currentDay < inclusiveEndDate) {
|
||||
currentDay = addDays(currentDay, 1)
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import { google } from 'googleapis'
|
||||
import { getBaseURL } from '../helpers/url';
|
||||
import { getBaseURL } from '../helpers/url'
|
||||
import { Booking } from '../db/booking'
|
||||
import { getDays } from '../helpers/date';
|
||||
import { getDays } from '../helpers/date'
|
||||
|
||||
const calendarId = process.env.GOOGLE_CALENDAR_ID
|
||||
let credentials: object
|
||||
|
||||
try {
|
||||
credentials = JSON.parse(process.env.GOOGLE_SERVICE_ACCOUNT_KEY_JSON);
|
||||
credentials = JSON.parse(process.env.GOOGLE_SERVICE_ACCOUNT_KEY_JSON)
|
||||
} catch (error) {
|
||||
console.error('Unable to parse process.env.GOOGLE_SERVICE_ACCOUNT_KEY_JSON - invalid JSON?');
|
||||
throw error;
|
||||
console.error(
|
||||
'Unable to parse process.env.GOOGLE_SERVICE_ACCOUNT_KEY_JSON - invalid JSON?'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
|
||||
const auth = new google.auth.GoogleAuth({
|
||||
credentials,
|
||||
scopes: [
|
||||
'https://www.googleapis.com/auth/calendar',
|
||||
],
|
||||
scopes: ['https://www.googleapis.com/auth/calendar'],
|
||||
})
|
||||
|
||||
const calendar = google.calendar({
|
||||
@@ -32,14 +32,18 @@ export async function getBookedDays() {
|
||||
timeZone: 'utc',
|
||||
})
|
||||
|
||||
return data.items
|
||||
// ignore non all-day events
|
||||
.filter(event => !!event.start.date)
|
||||
.flatMap(event => getDays({
|
||||
startDate: new Date(event.start.date),
|
||||
endDate: new Date(event.end.date),
|
||||
endDateExclusive: true
|
||||
}))
|
||||
return (
|
||||
data.items
|
||||
// ignore non all-day events
|
||||
.filter((event) => !!event.start.date)
|
||||
.flatMap((event) =>
|
||||
getDays({
|
||||
startDate: new Date(event.start.date),
|
||||
endDate: new Date(event.end.date),
|
||||
endDateExclusive: true,
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
function getSummary(booking: Partial<Booking>): string {
|
||||
@@ -55,21 +59,24 @@ function getSummary(booking: Partial<Booking>): string {
|
||||
}
|
||||
|
||||
function getDescription(booking: Booking): string {
|
||||
const bookingUrl = `${getBaseURL()}/admin/booking/${booking.uuid}`;
|
||||
const bookingUrl = `${getBaseURL()}/admin/booking/${booking.uuid}`
|
||||
|
||||
return `Managelink ${bookingUrl}`;
|
||||
return `Managelink ${bookingUrl}`
|
||||
}
|
||||
|
||||
export async function createCalendarEvent(booking: Booking): Promise<Booking> {
|
||||
const response = await calendar.events.insert({
|
||||
calendarId,
|
||||
requestBody: {
|
||||
summary: getSummary(booking),
|
||||
description: getDescription(booking),
|
||||
start: { date: booking.startDate },
|
||||
end: { date: booking.endDate },
|
||||
const response = await calendar.events.insert(
|
||||
{
|
||||
calendarId,
|
||||
requestBody: {
|
||||
summary: getSummary(booking),
|
||||
description: getDescription(booking),
|
||||
start: { date: booking.startDate },
|
||||
end: { date: booking.endDate },
|
||||
},
|
||||
},
|
||||
}, {})
|
||||
{}
|
||||
)
|
||||
|
||||
booking.calendarEventId = response.data.id
|
||||
|
||||
@@ -82,7 +89,7 @@ export async function deleteCalendarEvent(booking: Booking) {
|
||||
eventId: booking.calendarEventId,
|
||||
// TODO: really useful?
|
||||
sendNotifications: true,
|
||||
});
|
||||
})
|
||||
|
||||
booking.calendarEventId = null
|
||||
}
|
||||
|
||||
@@ -9,9 +9,13 @@ export const getServerSideProps = getServerSideRecentBookings
|
||||
|
||||
function AdminRecentBookings({ bookings }) {
|
||||
if (!bookings || !bookings.length) {
|
||||
return <Layout>
|
||||
<h3 className="text-lg leading-6 font-medium text-gray-900">No recent bookings 😿</h3>
|
||||
</Layout>
|
||||
return (
|
||||
<Layout>
|
||||
<h3 className="text-lg leading-6 font-medium text-gray-900">
|
||||
No recent bookings 😿
|
||||
</h3>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import NextAuth from 'next-auth'
|
||||
import EmailProvider from 'next-auth/providers/email'
|
||||
import GitHubProvider from "next-auth/providers/github";
|
||||
import GitHubProvider from 'next-auth/providers/github'
|
||||
|
||||
import { MongoDBAdapter } from '@next-auth/mongodb-adapter'
|
||||
import { MONGO_URI } from '../../../db'
|
||||
@@ -10,7 +10,7 @@ import { MongoClient } from 'mongodb'
|
||||
let client: MongoClient
|
||||
|
||||
const ADMIN_EMAIL = process.env.ADMIN_EMAIL
|
||||
const GITHUB_USERS_GRANTED = ['111471'];
|
||||
const GITHUB_USERS_GRANTED = ['111471']
|
||||
|
||||
async function getMongoClient() {
|
||||
if (!client) {
|
||||
@@ -28,7 +28,7 @@ export default async function auth(req: NextApiRequest, res: NextApiResponse) {
|
||||
providers: [
|
||||
GitHubProvider({
|
||||
clientId: process.env.GITHUB_CLIENT_ID,
|
||||
clientSecret: process.env.GITHUB_CLIENT_SECRET
|
||||
clientSecret: process.env.GITHUB_CLIENT_SECRET,
|
||||
}),
|
||||
EmailProvider({
|
||||
server: {
|
||||
@@ -48,17 +48,17 @@ export default async function auth(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (account.provider === 'email') {
|
||||
if (email.verificationRequest) {
|
||||
// only allow admins by email entered
|
||||
return account.providerAccountId === ADMIN_EMAIL;
|
||||
return account.providerAccountId === ADMIN_EMAIL
|
||||
}
|
||||
|
||||
// if user accesses with magic link, also only allow admin
|
||||
return account.providerAccountId === ADMIN_EMAIL
|
||||
} else if (account.provider === 'github') {
|
||||
// only one and only one user
|
||||
return GITHUB_USERS_GRANTED.includes(account.providerAccountId);
|
||||
return GITHUB_USERS_GRANTED.includes(account.providerAccountId)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { createBill, patchBill } from '../../../../db/index'
|
||||
export default async function billHandler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
): Promise<void> {
|
||||
): Promise<void> {
|
||||
const {
|
||||
method,
|
||||
query: { uuid: uuids },
|
||||
|
||||
@@ -27,10 +27,10 @@ export default async function userHandler(
|
||||
}
|
||||
|
||||
try {
|
||||
const booking = await patchBooking(uuid, req.body);
|
||||
const booking = await patchBooking(uuid, req.body)
|
||||
res.status(200).json(booking)
|
||||
} catch (error) {
|
||||
console.error('failed patch booking', error);
|
||||
console.error('failed patch booking', error)
|
||||
res.status(400).end(`Failed to save booking: ${error.message}`)
|
||||
}
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user