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