feat(dashboard): Log in, reset password, and accept invite pages (#6310)
This commit is contained in:
committed by
GitHub
parent
b1276cfcd5
commit
73fd92a1af
@@ -177,7 +177,7 @@ const ErrorMessage = forwardRef<
|
||||
const { error, formErrorMessageId } = useFormField()
|
||||
const msg = error ? String(error?.message) : children
|
||||
|
||||
if (!msg) {
|
||||
if (!msg || msg === "undefined") {
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./logo-box"
|
||||
@@ -0,0 +1,74 @@
|
||||
import { clx } from "@medusajs/ui"
|
||||
import { Transition, motion } from "framer-motion"
|
||||
|
||||
type LogoBoxProps = {
|
||||
className?: string
|
||||
checked?: boolean
|
||||
containerTransition?: Transition
|
||||
pathTransition?: Transition
|
||||
}
|
||||
|
||||
export const LogoBox = ({
|
||||
className,
|
||||
checked,
|
||||
containerTransition = {
|
||||
duration: 0.8,
|
||||
delay: 0.5,
|
||||
ease: [0, 0.71, 0.2, 1.01],
|
||||
},
|
||||
pathTransition = {
|
||||
duration: 0.8,
|
||||
delay: 0.6,
|
||||
ease: [0.1, 0.8, 0.2, 1.01],
|
||||
},
|
||||
}: LogoBoxProps) => {
|
||||
return (
|
||||
<div
|
||||
className={clx(
|
||||
"size-14 bg-ui-button-neutral shadow-buttons-neutral relative flex items-center justify-center rounded-xl",
|
||||
"after:button-neutral-gradient after:inset-0 after:content-['']",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{checked && (
|
||||
<motion.div
|
||||
className="size-5 absolute -right-[5px] -top-1 flex items-center justify-center rounded-full border-[0.5px] border-[rgba(3,7,18,0.2)] bg-[#3B82F6] bg-gradient-to-b from-white/0 to-white/20 shadow-[0px_1px_2px_0px_rgba(3,7,18,0.12),0px_1px_2px_0px_rgba(255,255,255,0.10)_inset,0px_-1px_5px_0px_rgba(255,255,255,0.10)_inset,0px_0px_0px_0px_rgba(3,7,18,0.06)_inset]"
|
||||
initial={{ opacity: 0, scale: 0.5 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={containerTransition}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
>
|
||||
<motion.path
|
||||
d="M5.8335 10.4167L9.16683 13.75L14.1668 6.25"
|
||||
stroke="white"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
initial={{ pathLength: 0, opacity: 0 }}
|
||||
animate={{ pathLength: 1, opacity: 1 }}
|
||||
transition={pathTransition}
|
||||
/>
|
||||
</svg>
|
||||
</motion.div>
|
||||
)}
|
||||
<svg
|
||||
width="36"
|
||||
height="38"
|
||||
viewBox="0 0 36 38"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M30.85 6.16832L22.2453 1.21782C19.4299 -0.405941 15.9801 -0.405941 13.1648 1.21782L4.52043 6.16832C1.74473 7.79208 0 10.802 0 14.0099V23.9505C0 27.198 1.74473 30.1683 4.52043 31.7921L13.1251 36.7822C15.9405 38.4059 19.3903 38.4059 22.2056 36.7822L30.8103 31.7921C33.6257 30.1683 35.3307 27.198 35.3307 23.9505V14.0099C35.41 10.802 33.6653 7.79208 30.85 6.16832ZM17.6852 27.8317C12.8079 27.8317 8.8426 23.8713 8.8426 19C8.8426 14.1287 12.8079 10.1683 17.6852 10.1683C22.5625 10.1683 26.5674 14.1287 26.5674 19C26.5674 23.8713 22.6022 27.8317 17.6852 27.8317Z"
|
||||
className="fill-ui-button-inverted relative drop-shadow-sm"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
|
||||
import { Skeleton } from "../../common/skeleton"
|
||||
|
||||
import { queryClient } from "../../../lib/medusa"
|
||||
import { useSearch } from "../../../providers/search-provider"
|
||||
import { useSidebar } from "../../../providers/sidebar-provider"
|
||||
import { useTheme } from "../../../providers/theme-provider"
|
||||
@@ -35,7 +36,7 @@ export const Shell = ({ children }: PropsWithChildren) => {
|
||||
<MobileSidebarContainer>{children}</MobileSidebarContainer>
|
||||
<DesktopSidebarContainer>{children}</DesktopSidebarContainer>
|
||||
</div>
|
||||
<div className="flex flex-col h-screen w-full overflow-auto">
|
||||
<div className="flex h-screen w-full flex-col overflow-auto">
|
||||
<Topbar />
|
||||
<main className="flex h-full w-full flex-col items-center overflow-y-auto">
|
||||
<Gutter>
|
||||
@@ -73,7 +74,7 @@ const Breadcrumbs = () => {
|
||||
})
|
||||
|
||||
return (
|
||||
<ol className={clx("text-ui-fg-muted flex items-center select-none")}>
|
||||
<ol className={clx("text-ui-fg-muted flex select-none items-center")}>
|
||||
{crumbs.map((crumb, index) => {
|
||||
const isLast = index === crumbs.length - 1
|
||||
const isSingle = crumbs.length === 1
|
||||
@@ -106,7 +107,7 @@ const Breadcrumbs = () => {
|
||||
</div>
|
||||
)}
|
||||
{/* {!isLast && <TriangleRightMini className="-mt-0.5 mx-2" />} */}
|
||||
{!isLast && <span className="-mt-0.5 mx-2">›</span>}
|
||||
{!isLast && <span className="mx-2 -mt-0.5">›</span>}
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
@@ -115,18 +116,22 @@ const Breadcrumbs = () => {
|
||||
}
|
||||
|
||||
const UserBadge = () => {
|
||||
const { user, isError, error } = useAdminGetSession()
|
||||
const { user, isLoading, isError, error } = useAdminGetSession()
|
||||
|
||||
const displayName = user
|
||||
? user.first_name && user.last_name
|
||||
? `${user.first_name} ${user.last_name}`
|
||||
: user.first_name
|
||||
? user.first_name
|
||||
: user.email
|
||||
: null
|
||||
const name = [user?.first_name, user?.last_name].filter(Boolean).join(" ")
|
||||
const displayName = name || user?.email
|
||||
|
||||
const fallback = displayName ? displayName[0].toUpperCase() : null
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<button className="shadow-borders-base flex max-w-[192px] select-none items-center gap-x-2 overflow-hidden text-ellipsis whitespace-nowrap rounded-full py-1 pl-1 pr-2.5">
|
||||
<Skeleton className="h-5 w-5 rounded-full" />
|
||||
<Skeleton className="h-[9px] w-[70px]" />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
if (isError) {
|
||||
throw error
|
||||
}
|
||||
@@ -136,13 +141,13 @@ const UserBadge = () => {
|
||||
<button
|
||||
disabled={!user}
|
||||
className={clx(
|
||||
"shadow-borders-base flex max-w-[192px] items-center gap-x-2 overflow-hidden text-ellipsis whitespace-nowrap rounded-full py-1 pl-1 pr-2.5 select-none"
|
||||
"shadow-borders-base flex max-w-[192px] select-none items-center gap-x-2 overflow-hidden text-ellipsis whitespace-nowrap rounded-full py-1 pl-1 pr-2.5"
|
||||
)}
|
||||
>
|
||||
{fallback ? (
|
||||
<Avatar size="xsmall" fallback={fallback} />
|
||||
) : (
|
||||
<Skeleton className="w-5 h-5 rounded-full" />
|
||||
<Skeleton className="h-5 w-5 rounded-full" />
|
||||
)}
|
||||
{displayName ? (
|
||||
<Text
|
||||
@@ -154,7 +159,7 @@ const UserBadge = () => {
|
||||
{displayName}
|
||||
</Text>
|
||||
) : (
|
||||
<Skeleton className="w-[70px] h-[9px]" />
|
||||
<Skeleton className="h-[9px] w-[70px]" />
|
||||
)}
|
||||
</button>
|
||||
</DropdownMenu.Trigger>
|
||||
@@ -203,6 +208,11 @@ const Logout = () => {
|
||||
const handleLayout = async () => {
|
||||
await logoutMutation(undefined, {
|
||||
onSuccess: () => {
|
||||
/**
|
||||
* When the user logs out, we want to clear the query cache
|
||||
*/
|
||||
queryClient.clear()
|
||||
|
||||
navigate("/login")
|
||||
},
|
||||
})
|
||||
@@ -297,7 +307,7 @@ const Searchbar = () => {
|
||||
return (
|
||||
<button
|
||||
onClick={toggleSearch}
|
||||
className="shadow-borders-base bg-ui-bg-subtle hover:bg-ui-bg-subtle-hover transition-fg focus-visible:shadow-borders-focus text-ui-fg-muted flex w-full max-w-[280px] items-center gap-x-2 rounded-full py-1.5 pl-2 pr-1.5 outline-none select-none"
|
||||
className="shadow-borders-base bg-ui-bg-subtle hover:bg-ui-bg-subtle-hover transition-fg focus-visible:shadow-borders-focus text-ui-fg-muted flex w-full max-w-[280px] select-none items-center gap-x-2 rounded-full py-1.5 pl-2 pr-1.5 outline-none"
|
||||
>
|
||||
<MagnifyingGlass />
|
||||
<div className="flex-1 text-left">
|
||||
@@ -335,7 +345,7 @@ const ToggleSidebar = () => {
|
||||
|
||||
const Topbar = () => {
|
||||
return (
|
||||
<div className="w-full grid-cols-3 border-b p-3 grid">
|
||||
<div className="grid w-full grid-cols-3 border-b p-3">
|
||||
<div className="flex items-center gap-x-1.5">
|
||||
<ToggleSidebar />
|
||||
<Breadcrumbs />
|
||||
@@ -374,8 +384,8 @@ const MobileSidebarContainer = ({ children }: PropsWithChildren) => {
|
||||
return (
|
||||
<Dialog.Root open={mobile} onOpenChange={() => toggle("mobile")}>
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay className="fixed inset-0 bg-ui-bg-overlay" />
|
||||
<Dialog.Content className="h-screen fixed left-0 inset-y-0 w-[220px] border-r bg-ui-bg-subtle">
|
||||
<Dialog.Overlay className="bg-ui-bg-overlay fixed inset-0" />
|
||||
<Dialog.Content className="bg-ui-bg-subtle fixed inset-y-0 left-0 h-screen w-[220px] border-r">
|
||||
{children}
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
|
||||
Reference in New Issue
Block a user