diff --git a/.gitignore b/.gitignore index 17568606..126df069 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ yarn-error.log* # vercel .vercel + +# Webstorm +.idea diff --git a/calendso.yaml b/calendso.yaml index 8f052f87..d45d0f7d 100644 --- a/calendso.yaml +++ b/calendso.yaml @@ -110,6 +110,17 @@ paths: summary: Deletes an event type tags: - Availability + /api/availability/calendars: + post: + description: Selects calendar for availability checking. + summary: Adds selected calendar + tags: + - Availability + delete: + description: Removes a calendar from availability checking. + summary: Deletes a selected calendar + tags: + - Availability /api/book/:user: post: description: Creates a booking in the user's calendar. @@ -144,4 +155,4 @@ paths: description: Updates a user's profile. summary: Updates a user's profile tags: - - User \ No newline at end of file + - User diff --git a/components/ActiveLink.tsx b/components/ActiveLink.tsx index f4da7d65..67b3c1d6 100644 --- a/components/ActiveLink.tsx +++ b/components/ActiveLink.tsx @@ -1,7 +1,6 @@ -import { useRouter } from 'next/router' -import PropTypes from 'prop-types' +import {useRouter} from 'next/router' import Link from 'next/link' -import React, { Children } from 'react' +import React, {Children} from 'react' const ActiveLink = ({ children, activeClassName, ...props }) => { const { asPath } = useRouter() diff --git a/components/Settings.tsx b/components/Settings.tsx index ff23e35b..1969c1ff 100644 --- a/components/Settings.tsx +++ b/components/Settings.tsx @@ -1,5 +1,5 @@ import ActiveLink from '../components/ActiveLink'; -import { UserCircleIcon, KeyIcon, CodeIcon, UserGroupIcon } from '@heroicons/react/outline'; +import {CodeIcon, CreditCardIcon, KeyIcon, UserCircleIcon, UserGroupIcon} from '@heroicons/react/outline'; export default function SettingsShell(props) { return ( @@ -37,6 +37,11 @@ export default function SettingsShell(props) { Teams + {/* Change/remove me, if you're self-hosting */} + + Billing + + {/*

Loading...

; @@ -40,11 +36,12 @@ export default function EventType(props) { const enteredDescription = descriptionRef.current.value; const enteredLength = lengthRef.current.value; const enteredIsHidden = isHiddenRef.current.checked; + const enteredEventName = eventNameRef.current.value; // TODO: Add validation const response = await fetch('/api/availability/eventtype', { method: 'PATCH', - body: JSON.stringify({id: props.eventType.id, title: enteredTitle, slug: enteredSlug, description: enteredDescription, length: enteredLength, hidden: enteredIsHidden, locations }), + body: JSON.stringify({id: props.eventType.id, title: enteredTitle, slug: enteredSlug, description: enteredDescription, length: enteredLength, hidden: enteredIsHidden, locations, eventName: enteredEventName }), headers: { 'Content-Type': 'application/json' } @@ -140,8 +137,8 @@ export default function EventType(props) { -
-
+
+
@@ -232,6 +229,12 @@ export default function EventType(props) {
+
+ +
+ +
+
@@ -258,7 +261,7 @@ export default function EventType(props) {
-
+

@@ -348,6 +351,7 @@ export async function getServerSideProps(context) { length: true, hidden: true, locations: true, + eventName: true, } }); @@ -357,4 +361,4 @@ export async function getServerSideProps(context) { eventType }, } -} \ No newline at end of file +} diff --git a/pages/availability/index.tsx b/pages/availability/index.tsx index d79b5072..1d170986 100644 --- a/pages/availability/index.tsx +++ b/pages/availability/index.tsx @@ -3,11 +3,10 @@ import Link from 'next/link'; import prisma from '../../lib/prisma'; import Modal from '../../components/Modal'; import Shell from '../../components/Shell'; -import { useRouter } from 'next/router'; -import { useRef } from 'react'; -import { useState } from 'react'; -import { useSession, getSession } from 'next-auth/client'; -import { PlusIcon, ClockIcon } from '@heroicons/react/outline'; +import {useRouter} from 'next/router'; +import {useRef, useState} from 'react'; +import {getSession, useSession} from 'next-auth/client'; +import {ClockIcon, PlusIcon} from '@heroicons/react/outline'; export default function Availability(props) { const [ session, loading ] = useSession(); @@ -25,6 +24,8 @@ export default function Availability(props) { const startMinsRef = useRef(); const endHoursRef = useRef(); const endMinsRef = useRef(); + const bufferHoursRef = useRef(); + const bufferMinsRef = useRef(); if (loading) { return

Loading...

; @@ -80,15 +81,18 @@ export default function Availability(props) { const enteredStartMins = parseInt(startMinsRef.current.value); const enteredEndHours = parseInt(endHoursRef.current.value); const enteredEndMins = parseInt(endMinsRef.current.value); + const enteredBufferHours = parseInt(bufferHoursRef.current.value); + const enteredBufferMins = parseInt(bufferMinsRef.current.value); const startMins = enteredStartHours * 60 + enteredStartMins; const endMins = enteredEndHours * 60 + enteredEndMins; + const bufferMins = enteredBufferHours * 60 + enteredBufferMins; // TODO: Add validation const response = await fetch('/api/availability/day', { method: 'PATCH', - body: JSON.stringify({start: startMins, end: endMins}), + body: JSON.stringify({start: startMins, end: endMins, buffer: bufferMins}), headers: { 'Content-Type': 'application/json' } @@ -298,7 +302,7 @@ export default function Availability(props) {

- Set the start and end time of your day. + Set the start and end time of your day and a minimum buffer between your meetings.

@@ -316,7 +320,7 @@ export default function Availability(props) {
-
+
@@ -328,6 +332,18 @@ export default function Availability(props) {
+
+ +
+ + +
+ : +
+ + +
+
-
+
{integrations.filter( (ig) => ig.credential ).length !== 0 ?
    {integrations.filter(ig => ig.credential).map( (ig) => (
  • @@ -165,6 +219,104 @@ export default function Home({ integrations }) {
} +
+
+

+ Select calendars +

+
+

+ Select which calendars are checked for availability to prevent double bookings. +

+
+
+ +
+
+
+ {showSelectCalendarModal && +
+
+ {/* */} + + + {/* */} +
+
+
+ +
+
+ +
+

+ If no entry is selected, all calendars will be checked +

+
+
+
+
+
    + {selectableCalendars.map( (calendar) => (
  • +
    + {calendar.integration} +
    +
    +

    { calendar.name }

    +
    +
    + + Select calendar + +
    +
  • ))} +
+
+
+ +
+
+
+
+ }
); diff --git a/pages/settings/billing.tsx b/pages/settings/billing.tsx new file mode 100644 index 00000000..57acc64f --- /dev/null +++ b/pages/settings/billing.tsx @@ -0,0 +1,66 @@ +import Head from 'next/head'; +import Shell from '../../components/Shell'; +import SettingsShell from '../../components/Settings'; +import prisma from '../../lib/prisma'; +import {getSession, useSession} from 'next-auth/client'; + +export default function Billing(props) { + const [ session, loading ] = useSession(); + + if (loading) { + return

Loading...

; + } + + return ( + + + Billing | Calendso + + +
+
+

+ Change your Subscription +

+

+ Cancel, update credit card or change plan +

+
+
+