style: onboarding screens (#1539)

* fix: onboarding screen styling

* chore: minor styling fixes

* chore: disable buttons if form is invalid
This commit is contained in:
Aaryan Khandelwal 2023-07-18 15:20:05 +05:30 committed by GitHub
parent 55a1291b1d
commit 0feab162ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 38 additions and 28 deletions

View File

@ -178,7 +178,7 @@ export const EmailCodeForm = ({ handleSignIn }: any) => {
) : errorResendingCode ? ( ) : errorResendingCode ? (
"Please try again later" "Please try again later"
) : ( ) : (
"Resend code" <span className="font-medium">Resend code</span>
)} )}
</button> </button>
</> </>

View File

@ -21,11 +21,11 @@ type Props = {
}; };
const defaultValues: ICustomTheme = { const defaultValues: ICustomTheme = {
background: "#292d3e", background: "#0d101b",
text: "#ffffff", text: "#c5c5c5",
primary: "#7d57c1", primary: "#3f76ff",
sidebarBackground: "#292d3e", sidebarBackground: "#0d101b",
sidebarText: "#ffffff", sidebarText: "#c5c5c5",
darkPalette: false, darkPalette: false,
palette: "", palette: "",
}; };

View File

@ -41,7 +41,7 @@ export const InviteMembers: React.FC<Props> = ({ workspace, user, stepChange })
const { const {
control, control,
handleSubmit, handleSubmit,
formState: { isSubmitting, errors }, formState: { isSubmitting, errors, isValid },
} = useForm<FormValues>(); } = useForm<FormValues>();
const { fields, append, remove } = useFieldArray({ const { fields, append, remove } = useFieldArray({
@ -204,7 +204,7 @@ export const InviteMembers: React.FC<Props> = ({ workspace, user, stepChange })
</button> </button>
</div> </div>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<PrimaryButton type="submit" loading={isSubmitting} size="md"> <PrimaryButton type="submit" disabled={!isValid} loading={isSubmitting} size="md">
{isSubmitting ? "Sending..." : "Send Invite"} {isSubmitting ? "Sending..." : "Send Invite"}
</PrimaryButton> </PrimaryButton>
<SecondaryButton size="md" onClick={nextStep} outline> <SecondaryButton size="md" onClick={nextStep} outline>

View File

@ -53,7 +53,7 @@ const TOUR_STEPS: {
key: "modules", key: "modules",
title: "Break into modules", title: "Break into modules",
description: description:
"Modules break your big think into Projects or Features, to help you organize better.", "Modules break your big thing into Projects or Features, to help you organize better.",
image: ModulesTour, image: ModulesTour,
prevStep: "cycles", prevStep: "cycles",
nextStep: "views", nextStep: "views",
@ -132,7 +132,7 @@ export const TourRoot: React.FC<Props> = ({ onComplete }) => {
<Image src={currentStep?.image} alt={currentStep?.title} /> <Image src={currentStep?.image} alt={currentStep?.title} />
</div> </div>
<div className="flex flex-col h-1/2 sm:h-2/5 p-4 overflow-y-auto"> <div className="flex flex-col h-1/2 sm:h-2/5 p-4 overflow-y-auto">
<h3 className="font-medium text-lg">{currentStep?.title}</h3> <h3 className="font-semibold sm:text-xl">{currentStep?.title}</h3>
<p className="text-custom-text-200 text-sm mt-3">{currentStep?.description}</p> <p className="text-custom-text-200 text-sm mt-3">{currentStep?.description}</p>
<div className="h-full flex items-end justify-between gap-4 mt-3"> <div className="h-full flex items-end justify-between gap-4 mt-3">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">

View File

@ -35,7 +35,7 @@ export const UserDetails: React.FC<Props> = ({ user }) => {
handleSubmit, handleSubmit,
control, control,
reset, reset,
formState: { errors, isSubmitting }, formState: { errors, isSubmitting, isValid },
} = useForm<IUser>({ } = useForm<IUser>({
defaultValues, defaultValues,
}); });
@ -164,7 +164,7 @@ export const UserDetails: React.FC<Props> = ({ user }) => {
</div> </div>
</div> </div>
<PrimaryButton type="submit" size="md" disabled={isSubmitting}> <PrimaryButton type="submit" size="md" disabled={!isValid} loading={isSubmitting}>
{isSubmitting ? "Updating..." : "Continue"} {isSubmitting ? "Updating..." : "Continue"}
</PrimaryButton> </PrimaryButton>
</form> </form>

View File

@ -38,6 +38,10 @@ export const Workspace: React.FC<Props> = ({ user, updateLastWorkspace, stepChan
defaultValues={defaultValues} defaultValues={defaultValues}
setDefaultValues={setDefaultValues} setDefaultValues={setDefaultValues}
user={user} user={user}
primaryButtonText={{
loading: "Creating...",
default: "Continue",
}}
secondaryButton={ secondaryButton={
<SecondaryButton onClick={() => stepChange({ profile_complete: false })}> <SecondaryButton onClick={() => stepChange({ profile_complete: false })}>
Back Back

View File

@ -19,11 +19,7 @@ export const PrimaryButton: React.FC<ButtonProps> = ({
: size === "md" : size === "md"
? "rounded-md px-3.5 py-2 text-sm" ? "rounded-md px-3.5 py-2 text-sm"
: "rounded-lg px-4 py-2 text-base" : "rounded-lg px-4 py-2 text-base"
} ${ } ${disabled ? "cursor-not-allowed opacity-70 hover:opacity-70" : ""} ${
disabled
? "cursor-not-allowed bg-opacity-70 border-opacity-70 hover:bg-opacity-70 hover:border-opacity-70"
: ""
} ${
outline outline
? "bg-transparent text-custom-primary hover:bg-custom-primary hover:text-white" ? "bg-transparent text-custom-primary hover:bg-custom-primary hover:text-white"
: "text-white bg-custom-primary hover:border-opacity-90 hover:bg-opacity-90" : "text-white bg-custom-primary hover:border-opacity-90 hover:bg-opacity-90"

View File

@ -9,7 +9,7 @@ import workspaceService from "services/workspace.service";
// hooks // hooks
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// ui // ui
import { CustomSelect, Input, PrimaryButton, SecondaryButton } from "components/ui"; import { CustomSelect, Input, PrimaryButton } from "components/ui";
// types // types
import { ICurrentUserResponse, IWorkspace } from "types"; import { ICurrentUserResponse, IWorkspace } from "types";
// fetch-keys // fetch-keys
@ -27,6 +27,10 @@ type Props = {
setDefaultValues: Dispatch<SetStateAction<any>>; setDefaultValues: Dispatch<SetStateAction<any>>;
user: ICurrentUserResponse | undefined; user: ICurrentUserResponse | undefined;
secondaryButton?: React.ReactNode; secondaryButton?: React.ReactNode;
primaryButtonText?: {
loading: string;
default: string;
};
}; };
const restrictedUrls = [ const restrictedUrls = [
@ -49,6 +53,10 @@ export const CreateWorkspaceForm: React.FC<Props> = ({
setDefaultValues, setDefaultValues,
user, user,
secondaryButton, secondaryButton,
primaryButtonText = {
loading: "Creating...",
default: "Create Workspace",
},
}) => { }) => {
const [slugError, setSlugError] = useState(false); const [slugError, setSlugError] = useState(false);
const [invalidSlug, setInvalidSlug] = useState(false); const [invalidSlug, setInvalidSlug] = useState(false);
@ -61,7 +69,7 @@ export const CreateWorkspaceForm: React.FC<Props> = ({
control, control,
setValue, setValue,
getValues, getValues,
formState: { errors, isSubmitting }, formState: { errors, isSubmitting, isValid },
} = useForm<IWorkspace>({ defaultValues, mode: "onChange" }); } = useForm<IWorkspace>({ defaultValues, mode: "onChange" });
const handleCreateWorkspace = async (formData: IWorkspace) => { const handleCreateWorkspace = async (formData: IWorkspace) => {
@ -202,8 +210,8 @@ export const CreateWorkspaceForm: React.FC<Props> = ({
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
{secondaryButton} {secondaryButton}
<PrimaryButton type="submit" size="md" disabled={isSubmitting}> <PrimaryButton type="submit" size="md" disabled={!isValid} loading={isSubmitting}>
{isSubmitting ? "Creating..." : "Create Workspace"} {isSubmitting ? primaryButtonText.loading : primaryButtonText.default}
</PrimaryButton> </PrimaryButton>
</div> </div>
</form> </form>

View File

@ -17,12 +17,11 @@ import useOutsideClickDetector from "hooks/use-outside-click-detector";
// components // components
import UpgradeToProModal from "./upgrade-to-pro-modal"; import UpgradeToProModal from "./upgrade-to-pro-modal";
// ui // ui
import { CircularProgress } from "components/ui"; import { CircularProgress, Icon } from "components/ui";
// icons // icons
import { import {
ArrowLongLeftIcon, ArrowLongLeftIcon,
ChatBubbleOvalLeftEllipsisIcon, ChatBubbleOvalLeftEllipsisIcon,
RocketLaunchIcon,
ArrowUpCircleIcon, ArrowUpCircleIcon,
XMarkIcon, XMarkIcon,
} from "@heroicons/react/24/outline"; } from "@heroicons/react/24/outline";
@ -171,7 +170,7 @@ export const WorkspaceHelpSection: React.FC<WorkspaceHelpSectionProps> = ({ setS
}} }}
title="Shortcuts" title="Shortcuts"
> >
<RocketLaunchIcon className="h-4 w-4 text-custom-text-200" /> <Icon iconName="bolt" />
</button> </button>
<button <button
type="button" type="button"

View File

@ -96,7 +96,7 @@ export const applyTheme = (palette: string, isDarkPalette: boolean) => {
?.style.setProperty(`--color-sidebar-text-${shade}`, sidebarTextRgbValues); ?.style.setProperty(`--color-sidebar-text-${shade}`, sidebarTextRgbValues);
if (i >= 100 && i <= 400) { if (i >= 100 && i <= 400) {
const borderShade = (shade + 100) as keyof TShades; const borderShade = i === 100 ? 70 : i === 200 ? 80 : i === 300 ? 90 : 100;
document document
.querySelector<HTMLElement>("[data-theme='custom']") .querySelector<HTMLElement>("[data-theme='custom']")

View File

@ -276,8 +276,8 @@ const WorkspaceSettings: NextPage = () => {
</div> </div>
<div className="grid grid-cols-12 gap-4 sm:gap-16"> <div className="grid grid-cols-12 gap-4 sm:gap-16">
<div className="col-span-12 sm:col-span-6"> <div className="col-span-12 sm:col-span-6">
<h4 className="text-lg font-semibold">Company Size</h4> <h4 className="text-lg font-semibold">Organization Size</h4>
<p className="text-sm text-custom-text-200">How big is your company?</p> <p className="text-sm text-custom-text-200">What size is your organization?</p>
</div> </div>
<div className="col-span-12 sm:col-span-6"> <div className="col-span-12 sm:col-span-6">
<Controller <Controller
@ -287,7 +287,10 @@ const WorkspaceSettings: NextPage = () => {
<CustomSelect <CustomSelect
value={value} value={value}
onChange={onChange} onChange={onChange}
label={ORGANIZATION_SIZE.find((c) => c === value) ?? "Select company size"} label={
ORGANIZATION_SIZE.find((c) => c === value) ?? "Select organization size"
}
width="w-full"
input input
> >
{ORGANIZATION_SIZE?.map((item) => ( {ORGANIZATION_SIZE?.map((item) => (