* fix #582: send user back to onboarding after adding integration if incomplete * use more accurate, descriptive typings Co-authored-by: Alex van Andel <me@alexvanandel.com>
This commit is contained in:
parent
2c9b301b77
commit
015b7c18af
3 changed files with 73 additions and 55 deletions
|
@ -1,3 +1,15 @@
|
||||||
|
import { User } from "@prisma/client";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
export const ONBOARDING_INTRODUCED_AT = dayjs("September 1 2021").toISOString();
|
export const ONBOARDING_INTRODUCED_AT = dayjs("September 1 2021").toISOString();
|
||||||
|
|
||||||
|
export const ONBOARDING_NEXT_REDIRECT = {
|
||||||
|
redirect: {
|
||||||
|
permanent: false,
|
||||||
|
destination: "/getting-started",
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const shouldShowOnboarding = (user: Pick<User, "createdDate" | "completedOnboarding">) => {
|
||||||
|
return !user.completedOnboarding && dayjs(user.createdDate).isAfter(ONBOARDING_INTRODUCED_AT);
|
||||||
|
};
|
||||||
|
|
|
@ -8,9 +8,8 @@ import {
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
UsersIcon,
|
UsersIcon,
|
||||||
} from "@heroicons/react/solid";
|
} from "@heroicons/react/solid";
|
||||||
import { SchedulingType } from "@prisma/client";
|
import { SchedulingType, Prisma } from "@prisma/client";
|
||||||
import { Prisma } from "@prisma/client";
|
import { GetServerSidePropsContext } from "next";
|
||||||
import dayjs from "dayjs";
|
|
||||||
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
@ -23,7 +22,7 @@ import { getSession } from "@lib/auth";
|
||||||
import classNames from "@lib/classNames";
|
import classNames from "@lib/classNames";
|
||||||
import { HttpError } from "@lib/core/http/error";
|
import { HttpError } from "@lib/core/http/error";
|
||||||
import { getOrSetUserLocaleFromHeaders } from "@lib/core/i18n/i18n.utils";
|
import { getOrSetUserLocaleFromHeaders } from "@lib/core/i18n/i18n.utils";
|
||||||
import { ONBOARDING_INTRODUCED_AT } from "@lib/getting-started";
|
import { shouldShowOnboarding, ONBOARDING_NEXT_REDIRECT } from "@lib/getting-started";
|
||||||
import { useLocale } from "@lib/hooks/useLocale";
|
import { useLocale } from "@lib/hooks/useLocale";
|
||||||
import { useToggleQuery } from "@lib/hooks/useToggleQuery";
|
import { useToggleQuery } from "@lib/hooks/useToggleQuery";
|
||||||
import createEventType from "@lib/mutations/event-types/create-event-type";
|
import createEventType from "@lib/mutations/event-types/create-event-type";
|
||||||
|
@ -145,7 +144,7 @@ const EventTypesPage = (props: PageProps) => {
|
||||||
"hover:bg-neutral-50 flex justify-between items-center ",
|
"hover:bg-neutral-50 flex justify-between items-center ",
|
||||||
type.$disabled && "pointer-events-none"
|
type.$disabled && "pointer-events-none"
|
||||||
)}>
|
)}>
|
||||||
<div className="flex items-center w-full justify-between px-4 py-4 sm:px-6 hover:bg-neutral-50">
|
<div className="flex items-center justify-between w-full px-4 py-4 sm:px-6 hover:bg-neutral-50">
|
||||||
<Link href={"/event-types/" + type.id}>
|
<Link href={"/event-types/" + type.id}>
|
||||||
<a className="flex-grow text-sm truncate">
|
<a className="flex-grow text-sm truncate">
|
||||||
<div>
|
<div>
|
||||||
|
@ -224,7 +223,7 @@ const EventTypesPage = (props: PageProps) => {
|
||||||
leaveTo="transform opacity-0 scale-95">
|
leaveTo="transform opacity-0 scale-95">
|
||||||
<Menu.Items
|
<Menu.Items
|
||||||
static
|
static
|
||||||
className="absolute z-10 right-0 w-56 mt-2 origin-top-right bg-white divide-y rounded-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none divide-neutral-100">
|
className="absolute right-0 z-10 w-56 mt-2 origin-top-right bg-white divide-y rounded-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none divide-neutral-100">
|
||||||
<div className="py-1">
|
<div className="py-1">
|
||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
{({ active }) => (
|
{({ active }) => (
|
||||||
|
@ -558,7 +557,7 @@ const CreateNewEventDialog = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function getServerSideProps(context) {
|
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||||
const session = await getSession(context);
|
const session = await getSession(context);
|
||||||
const locale = await getOrSetUserLocaleFromHeaders(context.req);
|
const locale = await getOrSetUserLocaleFromHeaders(context.req);
|
||||||
|
|
||||||
|
@ -647,13 +646,10 @@ export async function getServerSideProps(context) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.completedOnboarding && dayjs(user.createdDate).isAfter(ONBOARDING_INTRODUCED_AT)) {
|
if (
|
||||||
return {
|
shouldShowOnboarding({ completedOnboarding: user.completedOnboarding, createdDate: user.createdDate })
|
||||||
redirect: {
|
) {
|
||||||
permanent: false,
|
return ONBOARDING_NEXT_REDIRECT;
|
||||||
destination: "/getting-started",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// backwards compatibility, TMP:
|
// backwards compatibility, TMP:
|
||||||
|
|
|
@ -6,6 +6,7 @@ import Link from "next/link";
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
import { getSession } from "@lib/auth";
|
import { getSession } from "@lib/auth";
|
||||||
|
import { ONBOARDING_NEXT_REDIRECT, shouldShowOnboarding } from "@lib/getting-started";
|
||||||
import AddAppleIntegration, {
|
import AddAppleIntegration, {
|
||||||
ADD_APPLE_INTEGRATION_FORM_TITLE,
|
ADD_APPLE_INTEGRATION_FORM_TITLE,
|
||||||
} from "@lib/integrations/Apple/components/AddAppleIntegration";
|
} from "@lib/integrations/Apple/components/AddAppleIntegration";
|
||||||
|
@ -138,8 +139,8 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
|
|
||||||
const ConnectNewAppDialog = () => (
|
const ConnectNewAppDialog = () => (
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger className="py-2 px-4 mt-6 border border-transparent rounded-sm shadow-sm text-sm font-medium text-white bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
|
<DialogTrigger className="px-4 py-2 mt-6 text-sm font-medium text-white border border-transparent rounded-sm shadow-sm bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
|
||||||
<PlusIcon className="w-5 h-5 mr-1 inline" />
|
<PlusIcon className="inline w-5 h-5 mr-1" />
|
||||||
Connect a new App
|
Connect a new App
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
||||||
|
@ -152,14 +153,14 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
.map((integration) => {
|
.map((integration) => {
|
||||||
return (
|
return (
|
||||||
<li key={integration.type} className="flex py-4">
|
<li key={integration.type} className="flex py-4">
|
||||||
<div className="w-1/12 mr-4 pt-2">
|
<div className="w-1/12 pt-2 mr-4">
|
||||||
<img className="h-8 w-8 mr-2" src={integration.imageSrc} alt={integration.title} />
|
<img className="w-8 h-8 mr-2" src={integration.imageSrc} alt={integration.title} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-10/12">
|
<div className="w-10/12">
|
||||||
<h2 className="font-cal text-gray-800 font-medium">{integration.title}</h2>
|
<h2 className="font-medium text-gray-800 font-cal">{integration.title}</h2>
|
||||||
<p className="text-gray-400 text-sm">{integration.description}</p>
|
<p className="text-sm text-gray-400">{integration.description}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-2/12 text-right pt-2">
|
<div className="w-2/12 pt-2 text-right">
|
||||||
<button
|
<button
|
||||||
onClick={() => integrationHandler(integration.type)}
|
onClick={() => integrationHandler(integration.type)}
|
||||||
className="font-medium text-neutral-900 hover:text-neutral-500">
|
className="font-medium text-neutral-900 hover:text-neutral-500">
|
||||||
|
@ -171,7 +172,7 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse gap-2">
|
<div className="gap-2 mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
||||||
<DialogClose asChild>
|
<DialogClose asChild>
|
||||||
<Button color="secondary">Cancel</Button>
|
<Button color="secondary">Cancel</Button>
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
|
@ -182,7 +183,7 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
|
|
||||||
const SelectCalendarDialog = () => (
|
const SelectCalendarDialog = () => (
|
||||||
<Dialog onOpenChange={(open) => !open && onCloseSelectCalendar()}>
|
<Dialog onOpenChange={(open) => !open && onCloseSelectCalendar()}>
|
||||||
<DialogTrigger className="py-2 px-4 mt-6 border border-transparent rounded-sm shadow-sm text-sm font-medium text-white bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
|
<DialogTrigger className="px-4 py-2 mt-6 text-sm font-medium text-white border border-transparent rounded-sm shadow-sm bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
|
||||||
Select calendars
|
Select calendars
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
||||||
|
@ -192,20 +193,20 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
subtitle="If no entry is selected, all calendars will be checked"
|
subtitle="If no entry is selected, all calendars will be checked"
|
||||||
/>
|
/>
|
||||||
<div className="my-4">
|
<div className="my-4">
|
||||||
<ul className="divide-y divide-gray-200 max-h-96 overflow-y-auto">
|
<ul className="overflow-y-auto divide-y divide-gray-200 max-h-96">
|
||||||
{selectableCalendars.map((calendar) => (
|
{selectableCalendars.map((calendar) => (
|
||||||
<li key={calendar.name} className="flex py-4">
|
<li key={calendar.name} className="flex py-4">
|
||||||
<div className="w-1/12 mr-4 pt-2">
|
<div className="w-1/12 pt-2 mr-4">
|
||||||
<img
|
<img
|
||||||
className="h-8 w-8 mr-2"
|
className="w-8 h-8 mr-2"
|
||||||
src={getCalendarIntegrationImage(calendar.integration)}
|
src={getCalendarIntegrationImage(calendar.integration)}
|
||||||
alt={calendar.integration}
|
alt={calendar.integration}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-10/12 pt-3">
|
<div className="w-10/12 pt-3">
|
||||||
<h2 className="text-gray-800 font-medium">{calendar.name}</h2>
|
<h2 className="font-medium text-gray-800">{calendar.name}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-2/12 text-right pt-3">
|
<div className="w-2/12 pt-3 text-right">
|
||||||
<Switch
|
<Switch
|
||||||
defaultChecked={calendar.selected}
|
defaultChecked={calendar.selected}
|
||||||
onCheckedChange={calendarSelectionHandler(calendar)}
|
onCheckedChange={calendarSelectionHandler(calendar)}
|
||||||
|
@ -215,7 +216,7 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse gap-2">
|
<div className="gap-2 mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
||||||
<DialogClose asChild>
|
<DialogClose asChild>
|
||||||
<Button color="secondary">Confirm</Button>
|
<Button color="secondary">Confirm</Button>
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
|
@ -275,7 +276,7 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
/>
|
/>
|
||||||
<div className="my-4">
|
<div className="my-4">
|
||||||
{addCalDavError && (
|
{addCalDavError && (
|
||||||
<p className="text-red-700 text-sm">
|
<p className="text-sm text-red-700">
|
||||||
<span className="font-bold">Error: </span>
|
<span className="font-bold">Error: </span>
|
||||||
{addCalDavError.message}
|
{addCalDavError.message}
|
||||||
</p>
|
</p>
|
||||||
|
@ -285,11 +286,11 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
onSubmit={handleAddCalDavIntegrationSaveButtonPress}
|
onSubmit={handleAddCalDavIntegrationSaveButtonPress}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse gap-2">
|
<div className="gap-2 mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
form={ADD_CALDAV_INTEGRATION_FORM_TITLE}
|
form={ADD_CALDAV_INTEGRATION_FORM_TITLE}
|
||||||
className="flex justify-center py-2 px-4 border border-transparent rounded-sm shadow-sm text-sm font-medium text-white bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
|
className="flex justify-center px-4 py-2 text-sm font-medium text-white border border-transparent rounded-sm shadow-sm bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<DialogClose
|
<DialogClose
|
||||||
|
@ -329,7 +330,7 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
/>
|
/>
|
||||||
<div className="my-4">
|
<div className="my-4">
|
||||||
{addAppleError && (
|
{addAppleError && (
|
||||||
<p className="text-red-700 text-sm">
|
<p className="text-sm text-red-700">
|
||||||
<span className="font-bold">Error: </span>
|
<span className="font-bold">Error: </span>
|
||||||
{addAppleError.message}
|
{addAppleError.message}
|
||||||
</p>
|
</p>
|
||||||
|
@ -339,11 +340,11 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
onSubmit={handleAddAppleIntegrationSaveButtonPress}
|
onSubmit={handleAddAppleIntegrationSaveButtonPress}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse gap-2">
|
<div className="gap-2 mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
form={ADD_APPLE_INTEGRATION_FORM_TITLE}
|
form={ADD_APPLE_INTEGRATION_FORM_TITLE}
|
||||||
className="flex justify-center py-2 px-4 border border-transparent rounded-sm shadow-sm text-sm font-medium text-white bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
|
className="flex justify-center px-4 py-2 text-sm font-medium text-white border border-transparent rounded-sm shadow-sm bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
<DialogClose
|
<DialogClose
|
||||||
|
@ -366,7 +367,7 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Shell heading="Integrations" subtitle="Connect your favourite apps." CTA={<ConnectNewAppDialog />}>
|
<Shell heading="Integrations" subtitle="Connect your favourite apps." CTA={<ConnectNewAppDialog />}>
|
||||||
<div className="bg-white border border-gray-200 overflow-hidden rounded-sm mb-8">
|
<div className="mb-8 overflow-hidden bg-white border border-gray-200 rounded-sm">
|
||||||
{integrations.filter((ig) => ig.credential).length !== 0 ? (
|
{integrations.filter((ig) => ig.credential).length !== 0 ? (
|
||||||
<ul className="divide-y divide-gray-200">
|
<ul className="divide-y divide-gray-200">
|
||||||
{integrations
|
{integrations
|
||||||
|
@ -376,13 +377,13 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
<Link href={"/integrations/" + ig.credential.id}>
|
<Link href={"/integrations/" + ig.credential.id}>
|
||||||
<a className="block hover:bg-gray-50">
|
<a className="block hover:bg-gray-50">
|
||||||
<div className="flex items-center px-4 py-4 sm:px-6">
|
<div className="flex items-center px-4 py-4 sm:px-6">
|
||||||
<div className="min-w-0 flex-1 flex items-center">
|
<div className="flex items-center flex-1 min-w-0">
|
||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
<img className="h-10 w-10 mr-2" src={ig.imageSrc} alt={ig.title} />
|
<img className="w-10 h-10 mr-2" src={ig.imageSrc} alt={ig.title} />
|
||||||
</div>
|
</div>
|
||||||
<div className="min-w-0 flex-1 px-4 md:grid md:grid-cols-2 md:gap-4">
|
<div className="flex-1 min-w-0 px-4 md:grid md:grid-cols-2 md:gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-medium text-neutral-900 truncate">{ig.title}</p>
|
<p className="text-sm font-medium truncate text-neutral-900">{ig.title}</p>
|
||||||
<p className="flex items-center text-sm text-gray-500">
|
<p className="flex items-center text-sm text-gray-500">
|
||||||
{ig.type.endsWith("_calendar") && (
|
{ig.type.endsWith("_calendar") && (
|
||||||
<span className="truncate">Calendar Integration</span>
|
<span className="truncate">Calendar Integration</span>
|
||||||
|
@ -394,13 +395,13 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
</div>
|
</div>
|
||||||
<div className="hidden md:block">
|
<div className="hidden md:block">
|
||||||
{ig.credential.key && (
|
{ig.credential.key && (
|
||||||
<p className="mt-2 flex items-center text text-gray-500">
|
<p className="flex items-center mt-2 text-gray-500 text">
|
||||||
<CheckCircleIcon className="flex-shrink-0 mr-1.5 h-5 w-5 text-green-400" />
|
<CheckCircleIcon className="flex-shrink-0 mr-1.5 h-5 w-5 text-green-400" />
|
||||||
Connected
|
Connected
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{!ig.credential.key && (
|
{!ig.credential.key && (
|
||||||
<p className="mt-3 flex items-center text text-gray-500">
|
<p className="flex items-center mt-3 text-gray-500 text">
|
||||||
<XCircleIcon className="flex-shrink-0 mr-1.5 h-5 w-5 text-yellow-400" />
|
<XCircleIcon className="flex-shrink-0 mr-1.5 h-5 w-5 text-yellow-400" />
|
||||||
Not connected
|
Not connected
|
||||||
</p>
|
</p>
|
||||||
|
@ -408,7 +409,7 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<ChevronRightIcon className="h-5 w-5 text-gray-400" />
|
<ChevronRightIcon className="w-5 h-5 text-gray-400" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -418,13 +419,13 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
) : (
|
) : (
|
||||||
<div className="bg-white shadow rounded-sm">
|
<div className="bg-white rounded-sm shadow">
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<div className="py-9 pl-8">
|
<div className="pl-8 py-9">
|
||||||
<InformationCircleIcon className="text-neutral-900 w-16" />
|
<InformationCircleIcon className="w-16 text-neutral-900" />
|
||||||
</div>
|
</div>
|
||||||
<div className="py-5 sm:p-6">
|
<div className="py-5 sm:p-6">
|
||||||
<h3 className="text-lg leading-6 font-medium text-gray-900">
|
<h3 className="text-lg font-medium leading-6 text-gray-900">
|
||||||
You don't have any apps connected.
|
You don't have any apps connected.
|
||||||
</h3>
|
</h3>
|
||||||
<div className="mt-2 text-sm text-gray-500">
|
<div className="mt-2 text-sm text-gray-500">
|
||||||
|
@ -438,10 +439,10 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-white border border-gray-200 rounded-sm mb-8">
|
<div className="mb-8 bg-white border border-gray-200 rounded-sm">
|
||||||
<div className="px-4 py-5 sm:p-6">
|
<div className="px-4 py-5 sm:p-6">
|
||||||
<h3 className="font-cal text-lg leading-6 font-medium text-gray-900">Select calendars</h3>
|
<h3 className="text-lg font-medium leading-6 text-gray-900 font-cal">Select calendars</h3>
|
||||||
<div className="mt-2 max-w-xl text-sm text-gray-500">
|
<div className="max-w-xl mt-2 text-sm text-gray-500">
|
||||||
<p>Select which calendars are checked for availability to prevent double bookings.</p>
|
<p>Select which calendars are checked for availability to prevent double bookings.</p>
|
||||||
</div>
|
</div>
|
||||||
<SelectCalendarDialog />
|
<SelectCalendarDialog />
|
||||||
|
@ -449,8 +450,8 @@ export default function Home({ integrations }: inferSSRProps<typeof getServerSid
|
||||||
</div>
|
</div>
|
||||||
<div className="border border-gray-200 rounded-sm">
|
<div className="border border-gray-200 rounded-sm">
|
||||||
<div className="px-4 py-5 sm:p-6">
|
<div className="px-4 py-5 sm:p-6">
|
||||||
<h3 className="font-cal text-lg leading-6 font-medium text-gray-900">Launch your own App</h3>
|
<h3 className="text-lg font-medium leading-6 text-gray-900 font-cal">Launch your own App</h3>
|
||||||
<div className="mt-2 max-w-xl text-sm text-gray-500">
|
<div className="max-w-xl mt-2 text-sm text-gray-500">
|
||||||
<p>If you want to add your own App here, get in touch with us.</p>
|
<p>If you want to add your own App here, get in touch with us.</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-5">
|
<div className="mt-5">
|
||||||
|
@ -485,14 +486,23 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||||
key: true,
|
key: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
completedOnboarding: true,
|
||||||
|
createdDate: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user) return { redirect: { permanent: false, destination: "/auth/login" } };
|
if (!user)
|
||||||
|
return {
|
||||||
|
redirect: { permanent: false, destination: "/auth/login" },
|
||||||
|
};
|
||||||
|
|
||||||
const { credentials } = user;
|
if (
|
||||||
|
shouldShowOnboarding({ completedOnboarding: user.completedOnboarding, createdDate: user.createdDate })
|
||||||
|
) {
|
||||||
|
return ONBOARDING_NEXT_REDIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
const integrations = getIntegrations(credentials);
|
const integrations = getIntegrations(user.credentials);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: { session, integrations },
|
props: { session, integrations },
|
||||||
|
|
Loading…
Reference in a new issue