mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
style: onboarding screens (#1539)
* fix: onboarding screen styling * chore: minor styling fixes * chore: disable buttons if form is invalid
This commit is contained in:
parent
55a1291b1d
commit
0feab162ff
@ -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>
|
||||||
</>
|
</>
|
||||||
|
@ -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: "",
|
||||||
};
|
};
|
||||||
|
@ -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>
|
||||||
|
@ -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">
|
||||||
|
@ -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>
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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>
|
||||||
|
@ -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"
|
||||||
|
@ -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']")
|
||||||
|
@ -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) => (
|
||||||
|
Loading…
Reference in New Issue
Block a user