diff --git a/components/Shell.tsx b/components/Shell.tsx index caccb5409b..a102128770 100644 --- a/components/Shell.tsx +++ b/components/Shell.tsx @@ -8,6 +8,7 @@ import { LinkIcon, LogoutIcon, PuzzleIcon, + MoonIcon, } from "@heroicons/react/solid"; import { signOut, useSession } from "next-auth/react"; import Link from "next/link"; @@ -356,14 +357,25 @@ function UserDropdown({ small }: { small?: boolean }) { const { t } = useLocale(); const query = useMeQuery(); const user = query.data; + const mutation = trpc.useMutation("viewer.away"); + const utils = trpc.useContext(); return (
+ className={classNames( + small ? "w-8 h-8" : "w-10 h-10", + "bg-gray-300 rounded-full flex-shrink-0 relative" + )}> + {!user?.away && ( +
+ )} + {user?.away && ( +
+ )}
{!small && ( @@ -384,6 +396,26 @@ function UserDropdown({ small }: { small?: boolean }) {
+ + { + mutation.mutate({ away: !user?.away }); + utils.invalidateQueries("viewer.me"); + }} + className="flex px-4 py-2 text-sm cursor-pointer hover:bg-gray-100 hover:text-gray-900"> + + + {user?.username && ( {children} diff --git a/pages/[user].tsx b/pages/[user].tsx index 4dd7f39606..d570eef5f3 100644 --- a/pages/[user].tsx +++ b/pages/[user].tsx @@ -1,4 +1,5 @@ import { ArrowRightIcon } from "@heroicons/react/outline"; +import { MoonIcon } from "@heroicons/react/solid"; import { GetServerSidePropsContext } from "next"; import Link from "next/link"; import { useRouter } from "next/router"; @@ -49,23 +50,31 @@ export default function User(props: inferSSRProps) {

{user.bio}

- {eventTypes.map((type) => ( -
- - - -

{type.title}

- -
- + {user.away && ( +
+ +

{t("user_away")}

+

{t("user_away_description")}

- ))} + )} + {!user.away && + eventTypes.map((type) => ( + + ))}
{eventTypes.length === 0 && (
@@ -102,6 +111,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => avatar: true, theme: true, plan: true, + away: true, }, }); diff --git a/prisma/migrations/20220105104913_add_away_field/migration.sql b/prisma/migrations/20220105104913_add_away_field/migration.sql new file mode 100644 index 0000000000..7f2996fbb7 --- /dev/null +++ b/prisma/migrations/20220105104913_add_away_field/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "users" ADD COLUMN "away" BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f64c8e2687..2f5e8abdb9 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -118,6 +118,7 @@ model User { brandColor String @default("#292929") // the location where the events will end up destinationCalendar DestinationCalendar? + away Boolean @default(false) metadata Json? @@map(name: "users") diff --git a/public/static/locales/en/common.json b/public/static/locales/en/common.json index 3c960f86b3..e342647375 100644 --- a/public/static/locales/en/common.json +++ b/public/static/locales/en/common.json @@ -570,5 +570,9 @@ "error_required_field": "This field is required.", "status": "Status", "team_view_user_availability": "View user availability", - "team_view_user_availability_disabled": "User needs to accept invite to view availability" + "team_view_user_availability_disabled": "User needs to accept invite to view availability", + "set_as_away": "Set yourself as away", + "set_as_free": "Disable away status", + "user_away": "This user is currently away.", + "user_away_description": "The person you are trying to book has set themselves to away, and therefore is not accepting new bookings." } diff --git a/server/createContext.ts b/server/createContext.ts index d56103d136..ac410c8c62 100644 --- a/server/createContext.ts +++ b/server/createContext.ts @@ -45,6 +45,7 @@ async function getUserFromSession({ twoFactorEnabled: true, brandColor: true, plan: true, + away: true, credentials: { select: { id: true, diff --git a/server/routers/viewer.tsx b/server/routers/viewer.tsx index 8669794116..c01eb20ed3 100644 --- a/server/routers/viewer.tsx +++ b/server/routers/viewer.tsx @@ -57,6 +57,7 @@ const loggedInViewerRouter = createProtectedRouter() twoFactorEnabled, brandColor, plan, + away, } = ctx.user; const me = { id, @@ -73,10 +74,26 @@ const loggedInViewerRouter = createProtectedRouter() twoFactorEnabled, brandColor, plan, + away, }; return me; }, }) + .mutation("away", { + input: z.object({ + away: z.boolean(), + }), + async resolve({ input, ctx }) { + await ctx.prisma.user.update({ + where: { + email: ctx.user.email, + }, + data: { + away: input.away, + }, + }); + }, + }) .query("eventTypes", { async resolve({ ctx }) { const { prisma } = ctx;