style: auth screens (#1531)
* chore: invitations empty state * style: new auth screens * chore: update typography * chore: update border colors * chore: resend code text
This commit is contained in:
parent
da6ecd439c
commit
5fadf53580
181 changed files with 682 additions and 645 deletions
|
|
@ -96,12 +96,12 @@ const Analytics = () => {
|
|||
projects.length > 0 ? (
|
||||
<div className="h-full flex flex-col overflow-hidden bg-custom-background-100">
|
||||
<Tab.Group as={Fragment}>
|
||||
<Tab.List as="div" className="space-x-2 border-b border-custom-border-100 px-5 py-3">
|
||||
<Tab.List as="div" className="space-x-2 border-b border-custom-border-300 px-5 py-3">
|
||||
{tabsList.map((tab) => (
|
||||
<Tab
|
||||
key={tab}
|
||||
className={({ selected }) =>
|
||||
`rounded-3xl border border-custom-border-100 px-4 py-2 text-xs hover:bg-custom-background-80 ${
|
||||
`rounded-3xl border border-custom-border-300 px-4 py-2 text-xs hover:bg-custom-background-80 ${
|
||||
selected ? "bg-custom-background-80" : ""
|
||||
}`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,21 +93,21 @@ const WorkspacePage: NextPage = () => {
|
|||
projects.length > 0 ? (
|
||||
<div className="p-8">
|
||||
<div className="flex flex-col gap-8">
|
||||
<div className="text-custom-text-200 flex flex-col justify-between gap-x-2 gap-y-6 rounded-lg border border-custom-border-100 bg-custom-background-100 px-4 py-6 md:flex-row md:items-center md:py-3">
|
||||
<div className="text-custom-text-200 flex flex-col justify-between gap-x-2 gap-y-6 rounded-lg border border-custom-border-300 bg-custom-background-100 px-4 py-6 md:flex-row md:items-center md:py-3">
|
||||
<p className="font-semibold">
|
||||
Plane is open source, support us by starring us on GitHub.
|
||||
</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={() => setIsProductUpdatesModalOpen(true)}
|
||||
className="rounded-md border-2 border-custom-border-100 px-3 py-1.5 text-sm font-medium duration-300"
|
||||
className="rounded-md border-2 border-custom-border-300 px-3 py-1.5 text-sm font-medium duration-300"
|
||||
>
|
||||
{`What's New?`}
|
||||
</button>
|
||||
<a
|
||||
href="https://github.com/makeplane/plane"
|
||||
target="_blank"
|
||||
className="rounded-md border-2 border-custom-border-100 px-3 py-1.5 text-sm font-medium duration-300"
|
||||
className="rounded-md border-2 border-custom-border-300 px-3 py-1.5 text-sm font-medium duration-300"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Star us on GitHub
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ const MyIssuesPage: NextPage = () => {
|
|||
{({ open }) => (
|
||||
<>
|
||||
<Popover.Button
|
||||
className={`group flex items-center gap-2 rounded-md border border-custom-border-100 bg-transparent px-3 py-1.5 text-xs hover:bg-custom-background-90 hover:text-custom-text-100 focus:outline-none ${
|
||||
className={`group flex items-center gap-2 rounded-md border border-custom-border-300 bg-transparent px-3 py-1.5 text-xs hover:bg-custom-background-90 hover:text-custom-text-100 focus:outline-none ${
|
||||
open ? "bg-custom-background-90 text-custom-text-100" : "text-custom-text-200"
|
||||
}`}
|
||||
>
|
||||
|
|
@ -81,7 +81,7 @@ const MyIssuesPage: NextPage = () => {
|
|||
className={`rounded border px-2 py-1 text-xs capitalize ${
|
||||
properties[key as keyof Properties]
|
||||
? "border-custom-primary bg-custom-primary text-white"
|
||||
: "border-custom-border-100"
|
||||
: "border-custom-border-300"
|
||||
}`}
|
||||
onClick={() => setProperties(key as keyof Properties)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ const ArchivedIssueDetailsPage: NextPage = () => {
|
|||
</button>
|
||||
</div>
|
||||
)}
|
||||
<div className="space-y-5 divide-y-2 divide-custom-border-100 opacity-60">
|
||||
<div className="space-y-5 divide-y-2 divide-custom-border-300 opacity-60">
|
||||
<IssueMainContent
|
||||
issueDetails={issueDetails}
|
||||
submitChanges={submitChanges}
|
||||
|
|
@ -178,7 +178,7 @@ const ArchivedIssueDetailsPage: NextPage = () => {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-1/3 space-y-5 border-l border-custom-border-100 p-5">
|
||||
<div className="w-1/3 space-y-5 border-l border-custom-border-300 p-5">
|
||||
<IssueDetailsSidebar
|
||||
control={control}
|
||||
issueDetail={issueDetails}
|
||||
|
|
|
|||
|
|
@ -55,11 +55,11 @@ const ProjectArchivedIssues: NextPage = () => {
|
|||
}
|
||||
>
|
||||
<div className="h-full w-full flex flex-col">
|
||||
<div className="flex items-center ga-1 px-4 py-2.5 shadow-sm border-b border-custom-border-100">
|
||||
<div className="flex items-center ga-1 px-4 py-2.5 shadow-sm border-b border-custom-border-300">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => router.push(`/${workspaceSlug}/projects/${projectId}/issues/`)}
|
||||
className="flex items-center gap-1.5 rounded-full border border-custom-border-100 px-3 py-1.5 text-xs"
|
||||
className="flex items-center gap-1.5 rounded-full border border-custom-border-300 px-3 py-1.5 text-xs"
|
||||
>
|
||||
<Icon iconName="archive" className="text-base" />
|
||||
<span>Archived Issues</span>
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ const ProjectCycles: NextPage = () => {
|
|||
`rounded-3xl border px-6 py-1 outline-none ${
|
||||
selected
|
||||
? "border-custom-primary bg-custom-primary text-white font-medium"
|
||||
: "border-custom-border-100 bg-custom-background-100 hover:bg-custom-background-80"
|
||||
: "border-custom-border-300 bg-custom-background-100 hover:bg-custom-background-80"
|
||||
}`
|
||||
}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ const ProjectInbox: NextPage = () => {
|
|||
>
|
||||
<div className="flex flex-col h-full">
|
||||
<InboxActionHeader />
|
||||
<div className="grid grid-cols-4 flex-1 divide-x divide-custom-border-100 overflow-hidden">
|
||||
<div className="grid grid-cols-4 flex-1 divide-x divide-custom-border-300 overflow-hidden">
|
||||
<IssuesListSidebar />
|
||||
<div className="col-span-3 h-full overflow-auto">
|
||||
<InboxMainContent />
|
||||
|
|
|
|||
|
|
@ -120,10 +120,10 @@ const IssueDetailsPage: NextPage = () => {
|
|||
>
|
||||
{issueDetails && projectId ? (
|
||||
<div className="flex h-full">
|
||||
<div className="w-2/3 space-y-5 divide-y-2 divide-custom-border-100 p-5">
|
||||
<div className="w-2/3 space-y-5 divide-y-2 divide-custom-border-300 p-5">
|
||||
<IssueMainContent issueDetails={issueDetails} submitChanges={submitChanges} />
|
||||
</div>
|
||||
<div className="w-1/3 space-y-5 border-l border-custom-border-100 p-5">
|
||||
<div className="w-1/3 space-y-5 border-l border-custom-border-300 p-5">
|
||||
<IssueDetailsSidebar
|
||||
control={control}
|
||||
issueDetail={issueDetails}
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ const SinglePage: NextPage = () => {
|
|||
return (
|
||||
<div
|
||||
key={label.id}
|
||||
className="group flex cursor-pointer items-center gap-1 rounded-2xl border border-custom-border-100 px-2 py-0.5 text-xs hover:border-red-500 hover:bg-red-50"
|
||||
className="group flex cursor-pointer items-center gap-1 rounded-2xl border border-custom-border-300 px-2 py-0.5 text-xs hover:border-red-500 hover:bg-red-50"
|
||||
onClick={() => {
|
||||
const updatedLabels = pageDetails.labels.filter((l) => l !== labelId);
|
||||
partialUpdatePage({ labels_list: updatedLabels });
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ const ProjectPages: NextPage = () => {
|
|||
`rounded-full border px-5 py-1.5 text-sm outline-none ${
|
||||
selected
|
||||
? "border-custom-primary bg-custom-primary text-white"
|
||||
: "border-custom-border-100 bg-custom-background-100 hover:bg-custom-background-90"
|
||||
: "border-custom-border-300 bg-custom-background-100 hover:bg-custom-background-90"
|
||||
}`
|
||||
}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ const EstimatesSettings: NextPage = () => {
|
|||
</section>
|
||||
{estimatesList ? (
|
||||
estimatesList.length > 0 ? (
|
||||
<section className="h-full mt-5 divide-y divide-custom-border-100 rounded-xl border border-custom-border-100 bg-custom-background-100 px-6 overflow-y-auto">
|
||||
<section className="h-full mt-5 divide-y divide-custom-border-300 rounded-xl border border-custom-border-300 bg-custom-background-100 px-6 overflow-y-auto">
|
||||
{estimatesList.map((estimate) => (
|
||||
<SingleEstimate
|
||||
key={estimate.id}
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ const FeaturesSettings: NextPage = () => {
|
|||
{featuresList.map((feature) => (
|
||||
<div
|
||||
key={feature.property}
|
||||
className="flex items-center justify-between gap-x-8 gap-y-2 rounded-[10px] border border-custom-border-100 bg-custom-background-100 p-5"
|
||||
className="flex items-center justify-between gap-x-8 gap-y-2 rounded-[10px] border border-custom-border-300 bg-custom-background-100 p-5"
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
{feature.icon}
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ const GeneralSettings: NextPage = () => {
|
|||
</div>
|
||||
<div className="col-span-12 sm:col-span-6">
|
||||
{watch("cover_image") ? (
|
||||
<div className="h-32 w-full rounded border border-custom-border-100 p-1">
|
||||
<div className="h-32 w-full rounded border border-custom-border-300 p-1">
|
||||
<div className="relative h-full w-full rounded">
|
||||
<img
|
||||
src={watch("cover_image")!}
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ const MembersSettings: NextPage = () => {
|
|||
<Loader.Item height="40px" />
|
||||
</Loader>
|
||||
) : (
|
||||
<div className="divide-y divide-custom-border-100 rounded-[10px] border border-custom-border-100 bg-custom-background-100 px-6">
|
||||
<div className="divide-y divide-custom-border-300 rounded-[10px] border border-custom-border-300 bg-custom-background-100 px-6">
|
||||
{members.length > 0
|
||||
? members.map((member) => (
|
||||
<div key={member.id} className="flex items-center justify-between py-6">
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ const StatesSettings: NextPage = () => {
|
|||
Add
|
||||
</button>
|
||||
</div>
|
||||
<div className="divide-y divide-custom-border-100 rounded-[10px] border border-custom-border-100">
|
||||
<div className="divide-y divide-custom-border-300 rounded-[10px] border border-custom-border-300">
|
||||
{key === activeGroup && (
|
||||
<CreateUpdateStateInline
|
||||
groupLength={orderedStateGroups[key].length}
|
||||
|
|
@ -121,7 +121,7 @@ const StatesSettings: NextPage = () => {
|
|||
/>
|
||||
) : (
|
||||
<div
|
||||
className="border-b border-custom-border-100 last:border-b-0"
|
||||
className="border-b border-custom-border-300 last:border-b-0"
|
||||
key={state.id}
|
||||
>
|
||||
<CreateUpdateStateInline
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ const ProjectViews: NextPage = () => {
|
|||
views.length > 0 ? (
|
||||
<div className="space-y-5 p-8">
|
||||
<h3 className="text-2xl font-semibold text-custom-text-100">Views</h3>
|
||||
<div className="divide-y divide-custom-border-100 rounded-[10px] border border-custom-border-100">
|
||||
<div className="divide-y divide-custom-border-300 rounded-[10px] border border-custom-border-300">
|
||||
{views.map((view) => (
|
||||
<SingleViewItem
|
||||
key={view.id}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ const BillingSettings: NextPage = () => {
|
|||
</div>
|
||||
<div className="space-y-8 md:w-2/3">
|
||||
<div>
|
||||
<div className="w-80 rounded-md border border-custom-border-100 bg-custom-background-100 p-4 text-center">
|
||||
<div className="w-80 rounded-md border border-custom-border-300 bg-custom-background-100 p-4 text-center">
|
||||
<h4 className="text-md mb-1 leading-6">Payment due</h4>
|
||||
<h2 className="text-3xl font-extrabold">--</h2>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ const MembersSettings: NextPage = () => {
|
|||
<Loader.Item height="40px" />
|
||||
</Loader>
|
||||
) : (
|
||||
<div className="divide-y divide-custom-border-100 rounded-[10px] border border-custom-border-100 bg-custom-background-100 px-6">
|
||||
<div className="divide-y divide-custom-border-300 rounded-[10px] border border-custom-border-300 bg-custom-background-100 px-6">
|
||||
{members.length > 0
|
||||
? members.map((member) => (
|
||||
<div key={member.id} className="flex items-center justify-between py-6">
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
import React from "react";
|
||||
// next imports
|
||||
|
||||
import Image from "next/image";
|
||||
// next types
|
||||
|
||||
import type { NextPage } from "next";
|
||||
|
||||
// layouts
|
||||
import DefaultLayout from "layouts/default-layout";
|
||||
// services
|
||||
import authenticationService from "services/authentication.service";
|
||||
// hooks
|
||||
import useUserAuth from "hooks/use-user-auth";
|
||||
import useToast from "hooks/use-toast";
|
||||
// services
|
||||
import authenticationService from "services/authentication.service";
|
||||
// social auth buttons
|
||||
// components
|
||||
import {
|
||||
GoogleLoginButton,
|
||||
GithubLoginButton,
|
||||
|
|
@ -19,8 +20,8 @@ import {
|
|||
} from "components/account";
|
||||
// ui
|
||||
import { Spinner } from "components/ui";
|
||||
// icons
|
||||
import Logo from "public/plane-logos/blue-without-text.png";
|
||||
// images
|
||||
import BluePlaneLogoWithoutText from "public/plane-logos/blue-without-text.png";
|
||||
// types
|
||||
type EmailPasswordFormValues = {
|
||||
email: string;
|
||||
|
|
@ -29,7 +30,7 @@ type EmailPasswordFormValues = {
|
|||
};
|
||||
|
||||
const HomePage: NextPage = () => {
|
||||
const { user, isLoading, mutateUser } = useUserAuth("sign-in");
|
||||
const { isLoading, mutateUser } = useUserAuth("sign-in");
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
|
|
@ -56,7 +57,7 @@ const HomePage: NextPage = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleGithubSignIn = async (credential: string) => {
|
||||
const handleGitHubSignIn = async (credential: string) => {
|
||||
try {
|
||||
if (process.env.NEXT_PUBLIC_GITHUB_ID && credential) {
|
||||
const socialAuthPayload = {
|
||||
|
|
@ -122,38 +123,58 @@ const HomePage: NextPage = () => {
|
|||
return (
|
||||
<DefaultLayout>
|
||||
{isLoading ? (
|
||||
<div className="flex flex-col gap-3 w-full h-screen justify-center items-center">
|
||||
<div>
|
||||
<Spinner />
|
||||
</div>
|
||||
<div className="grid place-items-center h-screen">
|
||||
<Spinner />
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex h-screen w-full items-center justify-center overflow-auto">
|
||||
<div className="flex min-h-full w-full flex-col justify-center py-12 px-6 lg:px-8">
|
||||
<div className="flex flex-col gap-10 sm:mx-auto sm:w-full sm:max-w-md">
|
||||
<div className="flex flex-col items-center justify-center gap-10">
|
||||
<Image src={Logo} height={80} width={80} alt="Plane Web Logo" />
|
||||
<div className="text-center text-xl font-medium text-custom-text-100">
|
||||
Sign In to your Plane Account
|
||||
<>
|
||||
<>
|
||||
<div className="hidden sm:block sm:fixed border-r-[0.5px] border-custom-border-200 h-screen w-[0.5px] top-0 left-20 lg:left-32" />
|
||||
<div className="fixed grid place-items-center bg-custom-background-100 sm:py-5 top-11 sm:top-12 left-7 sm:left-16 lg:left-28">
|
||||
<div className="grid place-items-center bg-custom-background-100">
|
||||
<div className="h-[30px] w-[30px]">
|
||||
<Image src={BluePlaneLogoWithoutText} alt="Plane Logo" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col rounded-[10px] bg-custom-background-100 shadow-md">
|
||||
{parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0") ? (
|
||||
<>
|
||||
<EmailCodeForm handleSignIn={handleEmailCodeSignIn} />
|
||||
<div className="flex flex-col items-center justify-center gap-3 border-t border-custom-border-100 py-5 px-5">
|
||||
<GoogleLoginButton handleSignIn={handleGoogleSignIn} />
|
||||
<GithubLoginButton handleSignIn={handleGithubSignIn} />
|
||||
</div>
|
||||
</>
|
||||
<div className="grid place-items-center h-full overflow-y-auto px-7">
|
||||
<div>
|
||||
{parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0") ? (
|
||||
<>
|
||||
<h1 className="text-center text-2xl sm:text-2.5xl font-semibold text-custom-text-100">
|
||||
Sign in to Plane
|
||||
</h1>
|
||||
<div className="divide-y divide-custom-border-200">
|
||||
<div className="pb-7">
|
||||
<EmailCodeForm handleSignIn={handleEmailCodeSignIn} />
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<EmailPasswordForm onSubmit={handlePasswordSignIn} />
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-4 pt-7 w-full sm:w-[360px] mx-auto">
|
||||
<GoogleLoginButton handleSignIn={handleGoogleSignIn} />
|
||||
<GithubLoginButton handleSignIn={handleGitHubSignIn} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<EmailPasswordForm onSubmit={handlePasswordSignIn} />
|
||||
)}
|
||||
|
||||
{parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0") ? (
|
||||
<p className="pt-16 text-custom-text-200 text-sm text-center">
|
||||
By signing up, you agree to the{" "}
|
||||
<a
|
||||
href="https://plane.so/terms-and-conditions"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="font-medium underline"
|
||||
>
|
||||
Terms & Conditions
|
||||
</a>
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</DefaultLayout>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import React, { useState } from "react";
|
|||
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import useSWR, { mutate } from "swr";
|
||||
|
||||
|
|
@ -16,12 +17,13 @@ import useToast from "hooks/use-toast";
|
|||
import DefaultLayout from "layouts/default-layout";
|
||||
import { UserAuthorizationLayout } from "layouts/auth-layout/user-authorization-wrapper";
|
||||
// ui
|
||||
import { SecondaryButton, PrimaryButton } from "components/ui";
|
||||
import { SecondaryButton, PrimaryButton, EmptyState } from "components/ui";
|
||||
// icons
|
||||
import { CheckCircleIcon } from "@heroicons/react/24/outline";
|
||||
// images
|
||||
import BlackHorizontalLogo from "public/plane-logos/black-horizontal-with-blue-logo.svg";
|
||||
import WhiteHorizontalLogo from "public/plane-logos/white-horizontal-with-blue-logo.svg";
|
||||
import emptyInvitation from "public/empty-state/invitation.svg";
|
||||
// helpers
|
||||
import { truncateText } from "helpers/string.helper";
|
||||
// types
|
||||
|
|
@ -36,6 +38,8 @@ const OnBoard: NextPage = () => {
|
|||
const [invitationsRespond, setInvitationsRespond] = useState<string[]>([]);
|
||||
const [isJoiningWorkspaces, setIsJoiningWorkspaces] = useState(false);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const { theme } = useTheme();
|
||||
|
||||
const { user } = useUser();
|
||||
|
|
@ -79,7 +83,7 @@ const OnBoard: NextPage = () => {
|
|||
|
||||
setIsJoiningWorkspaces(false);
|
||||
})
|
||||
.catch((err) => setIsJoiningWorkspaces(false));
|
||||
.catch(() => setIsJoiningWorkspaces(false));
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -101,13 +105,13 @@ const OnBoard: NextPage = () => {
|
|||
{user?.email}
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative flex justify-center sm:justify-start sm:items-center h-full px-8 pb-8 sm:p-0 sm:pr-[8.33%] sm:w-10/12 md:w-9/12 lg:w-4/5">
|
||||
<div className="w-full space-y-10">
|
||||
<h5 className="text-lg">We see that someone has invited you to</h5>
|
||||
<h4 className="text-2xl font-semibold">Join a workspace</h4>
|
||||
<div className="md:w-3/5 space-y-4">
|
||||
{invitations &&
|
||||
invitations.map((invitation) => {
|
||||
{invitations && invitations.length > 0 ? (
|
||||
<div className="relative flex justify-center sm:justify-start sm:items-center h-full px-8 pb-8 sm:p-0 sm:pr-[8.33%] sm:w-10/12 md:w-9/12 lg:w-4/5">
|
||||
<div className="w-full space-y-10">
|
||||
<h5 className="text-lg">We see that someone has invited you to</h5>
|
||||
<h4 className="text-2xl font-semibold">Join a workspace</h4>
|
||||
<div className="md:w-3/5 space-y-4">
|
||||
{invitations.map((invitation) => {
|
||||
const isSelected = invitationsRespond.includes(invitation.id);
|
||||
|
||||
return (
|
||||
|
|
@ -116,7 +120,7 @@ const OnBoard: NextPage = () => {
|
|||
className={`flex cursor-pointer items-center gap-2 border py-5 px-3.5 rounded ${
|
||||
isSelected
|
||||
? "border-custom-primary-100"
|
||||
: "border-custom-border-100 hover:bg-custom-background-80"
|
||||
: "border-custom-border-300 hover:bg-custom-background-80"
|
||||
}`}
|
||||
onClick={() =>
|
||||
handleInvitation(invitation, isSelected ? "withdraw" : "accepted")
|
||||
|
|
@ -155,26 +159,37 @@ const OnBoard: NextPage = () => {
|
|||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<PrimaryButton
|
||||
type="submit"
|
||||
size="md"
|
||||
onClick={submitInvitations}
|
||||
disabled={isJoiningWorkspaces || invitationsRespond.length === 0}
|
||||
>
|
||||
Accept & Join
|
||||
</PrimaryButton>
|
||||
<Link href="/">
|
||||
<a>
|
||||
<SecondaryButton size="md" outline>
|
||||
Go Home
|
||||
</SecondaryButton>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<PrimaryButton
|
||||
type="submit"
|
||||
size="md"
|
||||
onClick={submitInvitations}
|
||||
disabled={isJoiningWorkspaces || invitationsRespond.length === 0}
|
||||
>
|
||||
Accept & Join
|
||||
</PrimaryButton>
|
||||
<Link href="/">
|
||||
<a>
|
||||
<SecondaryButton size="md" outline>
|
||||
Go Home
|
||||
</SecondaryButton>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="fixed top-0 left-0 h-full w-full grid place-items-center">
|
||||
<EmptyState
|
||||
title="No pending invites"
|
||||
description="You can see here if someone invites you to a workspace."
|
||||
image={emptyInvitation}
|
||||
buttonText="Back to Dashboard"
|
||||
onClick={() => router.push("/")}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</DefaultLayout>
|
||||
</UserAuthorizationLayout>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
import Image from "next/image";
|
||||
|
|
@ -12,9 +12,9 @@ import userService from "services/user.service";
|
|||
// layouts
|
||||
import DefaultLayout from "layouts/default-layout";
|
||||
// ui
|
||||
import { Input, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import Logo from "public/plane-logos/blue-without-text.png";
|
||||
import { Input, PrimaryButton, Spinner } from "components/ui";
|
||||
// images
|
||||
import BluePlaneLogoWithoutText from "public/plane-logos/blue-without-text.png";
|
||||
// types
|
||||
import type { NextPage } from "next";
|
||||
|
||||
|
|
@ -24,6 +24,8 @@ type FormData = {
|
|||
};
|
||||
|
||||
const ResetPasswordPage: NextPage = () => {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const router = useRouter();
|
||||
const { uidb64, token } = router.query;
|
||||
|
||||
|
|
@ -74,58 +76,71 @@ const ResetPasswordPage: NextPage = () => {
|
|||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0")) router.push("/");
|
||||
else setIsLoading(false);
|
||||
}, [router]);
|
||||
|
||||
if (isLoading)
|
||||
return (
|
||||
<div className="grid place-items-center h-screen w-full">
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<div className="flex h-screen w-full items-center justify-center overflow-auto">
|
||||
<div className="flex min-h-full w-full flex-col justify-center py-12 px-6 lg:px-8">
|
||||
<div className="flex flex-col gap-10 sm:mx-auto sm:w-full sm:max-w-md">
|
||||
<div className="flex flex-col items-center justify-center gap-10">
|
||||
<Image src={Logo} height={80} width={80} alt="Plane Web Logo" />
|
||||
<h2 className="text-center text-xl font-medium text-custom-text-100">
|
||||
Reset your password
|
||||
</h2>
|
||||
</div>
|
||||
<div className="flex flex-col rounded-[10px] bg-custom-background-100 shadow-md">
|
||||
<form className="mt-5 py-5 px-5" onSubmit={handleSubmit(onSubmit)}>
|
||||
<div>
|
||||
<Input
|
||||
id="password"
|
||||
type="password"
|
||||
name="password"
|
||||
register={register}
|
||||
validations={{
|
||||
required: "Password is required",
|
||||
}}
|
||||
error={errors.password}
|
||||
placeholder="Enter new password"
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<Input
|
||||
id="confirmPassword"
|
||||
type="password"
|
||||
name="confirmPassword"
|
||||
register={register}
|
||||
validations={{
|
||||
required: "Confirm password is required",
|
||||
}}
|
||||
error={errors.confirmPassword}
|
||||
placeholder="Confirm new password"
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<SecondaryButton
|
||||
type="submit"
|
||||
className="w-full text-center"
|
||||
loading={isSubmitting}
|
||||
>
|
||||
{isSubmitting ? "Resetting..." : "Reset"}
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
</form>
|
||||
<>
|
||||
<div className="hidden sm:block sm:fixed border-r-[0.5px] border-custom-border-200 h-screen w-[0.5px] top-0 left-20 lg:left-32" />
|
||||
<div className="fixed grid place-items-center bg-custom-background-100 sm:py-5 top-11 sm:top-12 left-7 sm:left-16 lg:left-28">
|
||||
<div className="grid place-items-center bg-custom-background-100">
|
||||
<div className="h-[30px] w-[30px]">
|
||||
<Image src={BluePlaneLogoWithoutText} alt="Plane Logo" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
<div className="grid place-items-center h-full w-full overflow-y-auto px-7">
|
||||
<div className="w-full">
|
||||
<h1 className="text-center text-2xl sm:text-2.5xl font-semibold text-custom-text-100">
|
||||
Reset your password
|
||||
</h1>
|
||||
|
||||
<form
|
||||
className="space-y-4 mt-10 w-full sm:w-[360px] mx-auto"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
<div className="space-y-1">
|
||||
<Input
|
||||
id="password"
|
||||
type="password"
|
||||
name="password"
|
||||
register={register}
|
||||
validations={{
|
||||
required: "Password is required",
|
||||
}}
|
||||
error={errors.password}
|
||||
placeholder="Enter new password..."
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Input
|
||||
id="confirmPassword"
|
||||
type="password"
|
||||
name="confirmPassword"
|
||||
register={register}
|
||||
validations={{
|
||||
required: "Password confirmation is required",
|
||||
}}
|
||||
error={errors.confirmPassword}
|
||||
placeholder="Confirm new password..."
|
||||
/>
|
||||
</div>
|
||||
<PrimaryButton type="submit" className="w-full text-center" loading={isSubmitting}>
|
||||
{isSubmitting ? "Resetting..." : "Reset"}
|
||||
</PrimaryButton>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</DefaultLayout>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/router";
|
||||
|
|
@ -12,8 +12,10 @@ import useToast from "hooks/use-toast";
|
|||
import DefaultLayout from "layouts/default-layout";
|
||||
// components
|
||||
import { EmailPasswordForm } from "components/account";
|
||||
// ui
|
||||
import { Spinner } from "components/ui";
|
||||
// images
|
||||
import Logo from "public/plane-logos/blue-without-text.png";
|
||||
import BluePlaneLogoWithoutText from "public/plane-logos/blue-without-text.png";
|
||||
// types
|
||||
import type { NextPage } from "next";
|
||||
type EmailPasswordFormValues = {
|
||||
|
|
@ -23,6 +25,8 @@ type EmailPasswordFormValues = {
|
|||
};
|
||||
|
||||
const SignUp: NextPage = () => {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
|
@ -58,23 +62,34 @@ const SignUp: NextPage = () => {
|
|||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0")) router.push("/");
|
||||
else setIsLoading(false);
|
||||
}, [router]);
|
||||
|
||||
if (isLoading)
|
||||
return (
|
||||
<div className="grid place-items-center h-screen w-full">
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<div className="flex h-screen w-full items-center justify-center overflow-auto">
|
||||
<div className="flex min-h-full w-full flex-col justify-center py-12 px-6 lg:px-8">
|
||||
<div className="flex flex-col gap-10 sm:mx-auto sm:w-full sm:max-w-md">
|
||||
<div className="flex flex-col items-center justify-center gap-10">
|
||||
<Image src={Logo} height={80} width={80} alt="Plane Web Logo" />
|
||||
<div className="text-center text-xl font-medium text-custom-text-100">
|
||||
Create a new Plane Account
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col rounded-[10px] bg-custom-background-100 shadow-md">
|
||||
<EmailPasswordForm onSubmit={handleSignUp} />
|
||||
<>
|
||||
<div className="hidden sm:block sm:fixed border-r-[0.5px] border-custom-border-200 h-screen w-[0.5px] top-0 left-20 lg:left-32" />
|
||||
<div className="fixed grid place-items-center bg-custom-background-100 sm:py-5 top-11 sm:top-12 left-7 sm:left-16 lg:left-28">
|
||||
<div className="grid place-items-center bg-custom-background-100">
|
||||
<div className="h-[30px] w-[30px]">
|
||||
<Image src={BluePlaneLogoWithoutText} alt="Plane Logo" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
<div className="grid place-items-center h-full w-full overflow-y-auto px-7">
|
||||
<div>
|
||||
<EmailPasswordForm onSubmit={handleSignUp} />
|
||||
</div>
|
||||
</div>
|
||||
</DefaultLayout>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ const WorkspaceInvitation: NextPage = () => {
|
|||
{invitationDetail ? (
|
||||
<>
|
||||
{error ? (
|
||||
<div className="flex w-full flex-col space-y-4 rounded border border-custom-border-100 bg-custom-background-100 px-4 py-8 text-center shadow-2xl md:w-1/3">
|
||||
<div className="flex w-full flex-col space-y-4 rounded border border-custom-border-300 bg-custom-background-100 px-4 py-8 text-center shadow-2xl md:w-1/3">
|
||||
<h2 className="text-xl uppercase">INVITATION NOT FOUND</h2>
|
||||
</div>
|
||||
) : (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue