diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index 54cd657f..bb50d4db 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -6,8 +6,12 @@ import { useRouter } from 'next/router'; const dayjs = require('dayjs'); const isSameOrBefore = require('dayjs/plugin/isSameOrBefore'); const isBetween = require('dayjs/plugin/isBetween'); +const utc = require('dayjs/plugin/utc'); +const timezone = require('dayjs/plugin/timezone'); dayjs.extend(isSameOrBefore); dayjs.extend(isBetween); +dayjs.extend(utc); +dayjs.extend(timezone); export default function Type(props) { // Initialise state @@ -61,9 +65,12 @@ export default function Type(props) { var i = props.user.startTime; } + // Adding first availability time + times.push(dayjs(selectedDate).tz(props.user.timeZone).hour(Math.floor(i / 60)).minute(i % 60).startOf(props.eventType.length, 'minute')); + // Until day end, push new times every x minutes for (;i < props.user.endTime; i += parseInt(props.eventType.length)) { - times.push(dayjs(selectedDate).hour(Math.floor(i / 60)).minute(i % 60).startOf(props.eventType.length, 'minute').add(props.eventType.length, 'minute').format("YYYY-MM-DD HH:mm:ss")); + times.push(dayjs(selectedDate).tz(props.user.timeZone).hour(Math.floor(i / 60)).minute(i % 60).startOf(props.eventType.length, 'minute').add(props.eventType.length, 'minute')); } // Check for conflicts @@ -87,13 +94,23 @@ export default function Type(props) { times.splice(i, 1); } }); + + // If event ends after endTime, remove the slot + if(dayjs(times[i]).add(props.eventType.length, 'minute') > dayjs(times[i]).hour(0).minute(0).add(props.user.endTime, 'minute') ) { + times.splice(i, 1); + } + + //If slot starts before startTime, remove it + if(dayjs(times[i]) < dayjs(times[i]).hour(0).minute(0).add(props.user.startTime, 'minute') ) { + times.splice(i, 1); + } } // Display available times const availableTimes = times.map((time) => -
- {dayjs(time).format("hh:mma")} +
+ + {dayjs(time).tz(dayjs.tz.guess()).format("hh:mma")}
); @@ -165,6 +182,7 @@ export async function getServerSideProps(context) { avatar: true, eventTypes: true, startTime: true, + timeZone: true, endTime: true } }); diff --git a/pages/api/availability/[user].ts b/pages/api/availability/[user].ts index 71236e2f..00a7a38c 100644 --- a/pages/api/availability/[user].ts +++ b/pages/api/availability/[user].ts @@ -12,7 +12,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) username: user, }, select: { - credentials: true + credentials: true, + timeZone: true } }); @@ -34,6 +35,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) requestBody: { timeMin: req.query.date + "T00:00:00.00Z", timeMax: req.query.date + "T23:59:59.59Z", + timeZone: currentUser.timeZone, items: [{ "id": "primary" }] @@ -44,4 +46,4 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) res.status(200).json(availability); }); } -} \ No newline at end of file +} diff --git a/pages/api/book/[user].ts b/pages/api/book/[user].ts index 6fee253b..eadfb61a 100644 --- a/pages/api/book/[user].ts +++ b/pages/api/book/[user].ts @@ -12,7 +12,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) username: user, }, select: { - credentials: true + credentials: true, + timeZone: true, } }); @@ -32,11 +33,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) 'description': req.body.notes, 'start': { 'dateTime': req.body.start, - 'timeZone': 'Europe/London', + 'timeZone': currentUser.timeZone, }, 'end': { 'dateTime': req.body.end, - 'timeZone': 'Europe/London', + 'timeZone': currentUser.timeZone, }, 'attendees': [ {'email': req.body.email}, @@ -62,4 +63,4 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) res.status(200).json({message: 'Event created'}); }); } -} \ No newline at end of file +} diff --git a/pages/api/user/profile.ts b/pages/api/user/profile.ts index 88793a1f..dcc43630 100644 --- a/pages/api/user/profile.ts +++ b/pages/api/user/profile.ts @@ -26,6 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) const username = req.body.username; const name = req.body.name; const description = req.body.description; + const timeZone = req.body.timeZone; const updateUser = await prisma.user.update({ where: { @@ -34,7 +35,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) data: { username: username, name: name, - bio: description + bio: description, + timeZone: timeZone, }, }); diff --git a/pages/settings/profile.tsx b/pages/settings/profile.tsx index 18a97c28..e2f8afa3 100644 --- a/pages/settings/profile.tsx +++ b/pages/settings/profile.tsx @@ -11,6 +11,7 @@ export default function Settings(props) { const usernameRef = useRef(); const nameRef = useRef(); const descriptionRef = useRef(); + const timezoneRef = useRef(); if (loading) { return

Loading...

; @@ -26,12 +27,13 @@ export default function Settings(props) { const enteredUsername = usernameRef.current.value; const enteredName = nameRef.current.value; const enteredDescription = descriptionRef.current.value; + const enteredTimezone = timezoneRef.current.value; // TODO: Add validation const response = await fetch('/api/user/profile', { method: 'PATCH', - body: JSON.stringify({username: enteredUsername, name: enteredName, description: enteredDescription}), + body: JSON.stringify({username: enteredUsername, name: enteredName, description: enteredDescription, timeZone: enteredTimezone}), headers: { 'Content-Type': 'application/json' } @@ -84,6 +86,511 @@ export default function Settings(props) {
+
+ +
+ +
+
@@ -147,7 +654,8 @@ export async function getServerSideProps(context) { name: true, email: true, bio: true, - avatar: true + avatar: true, + timeZone: true, } }); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b9724c95..02b85db9 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -35,6 +35,7 @@ model User { password String? bio String? avatar String? + timeZone String @default("Europe/London") startTime Int @default(0) endTime Int @default(1440) createdDate DateTime @default(now()) @map(name: "created")