-
Notifications
You must be signed in to change notification settings - Fork 8.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 重构用户菜单组件,引入新的对话框组件以替代链接跳转方式,优化用户交互体验。
- Loading branch information
Showing
4 changed files
with
151 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Dialog, DialogTitle, DialogDescription, DialogRoot } from '~/components/ui/Dialog'; | ||
import { useAuth } from '~/hooks/useAuth'; | ||
|
||
interface ProfileDialogProps { | ||
isOpen: boolean; | ||
onClose: () => void; | ||
} | ||
|
||
export function ProfileDialog({ isOpen, onClose }: ProfileDialogProps) { | ||
const { user } = useAuth(); | ||
|
||
if (!user) return null; | ||
|
||
return ( | ||
<DialogRoot open={isOpen}> | ||
<Dialog onBackdrop={onClose} onClose={onClose}> | ||
<DialogTitle>个人信息</DialogTitle> | ||
<DialogDescription> | ||
<div className="space-y-4"> | ||
<div> | ||
<label className="block text-sm font-medium text-bolt-elements-textPrimary"> | ||
昵称 | ||
</label> | ||
<p className="mt-1 text-bolt-elements-textSecondary">{user.nickname}</p> | ||
</div> | ||
<div> | ||
<label className="block text-sm font-medium text-bolt-elements-textPrimary"> | ||
手机号 | ||
</label> | ||
<p className="mt-1 text-bolt-elements-textSecondary">{user.phone}</p> | ||
</div> | ||
{/* 可以根据需要添加更多用户信息 */} | ||
</div> | ||
</DialogDescription> | ||
</Dialog> | ||
</DialogRoot> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { Dialog, DialogTitle, DialogDescription, DialogRoot } from '~/components/ui/Dialog'; | ||
|
||
interface SubscriptionDialogProps { | ||
isOpen: boolean; | ||
onClose: () => void; | ||
} | ||
|
||
export function SubscriptionDialog({ isOpen, onClose }: SubscriptionDialogProps) { | ||
return ( | ||
<DialogRoot open={isOpen}> | ||
<Dialog onBackdrop={onClose} onClose={onClose}> | ||
<DialogTitle>订阅信息</DialogTitle> | ||
<DialogDescription> | ||
<div className="space-y-4"> | ||
<p className="text-bolt-elements-textSecondary"> | ||
这里显示用户的订阅信息。您可以根据实际需求添加更多详细内容。 | ||
</p> | ||
{/* 可以添加更多订阅相关的信息 */} | ||
</div> | ||
</DialogDescription> | ||
</Dialog> | ||
</DialogRoot> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,82 @@ | ||
import { Menu, Transition } from '@headlessui/react'; | ||
import { Fragment } from 'react'; | ||
import { Fragment, useState } from 'react'; | ||
import { useAuth } from '~/hooks/useAuth'; | ||
import { Avatar } from '~/components/ui/Avatar'; | ||
import { Link } from '@remix-run/react'; | ||
import { ProfileDialog } from '~/components/auth/ProfileDialog'; | ||
import { SubscriptionDialog } from '~/components/auth/SubscriptionDialog'; | ||
|
||
export function UserMenu() { | ||
const { user, logout } = useAuth(); | ||
const [isProfileOpen, setIsProfileOpen] = useState(false); | ||
const [isSubscriptionOpen, setIsSubscriptionOpen] = useState(false); | ||
|
||
if (!user) return null; | ||
|
||
return ( | ||
<Menu as="div" className="relative inline-block text-left"> | ||
<div> | ||
<Menu.Button className="inline-flex items-center gap-x-1.5 rounded-md bg-bolt-elements-background-depth-2 px-3 py-2 text-sm font-medium text-bolt-elements-textPrimary hover:bg-bolt-elements-background-depth-3 transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-bolt-elements-button-primary-background"> | ||
<Avatar src={user.avatarUrl} alt={user.nickname} /> | ||
<span className="ml-2">{user.nickname}</span> | ||
<div className="i-ph:caret-down-fill text-bolt-elements-textSecondary" aria-hidden="true" /> | ||
</Menu.Button> | ||
</div> | ||
<> | ||
<Menu as="div" className="relative inline-block text-left"> | ||
<div> | ||
<Menu.Button className="inline-flex items-center gap-x-1.5 rounded-md bg-bolt-elements-background-depth-1 px-3 py-2 text-sm font-medium text-bolt-elements-textPrimary hover:bg-bolt-elements-background-depth-2 transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-bolt-elements-button-primary-background"> | ||
<Avatar src={user.avatarUrl} alt={user.nickname} /> | ||
<span className="ml-2">{user.nickname}</span> | ||
<div className="i-ph:caret-down-fill text-bolt-elements-textSecondary" aria-hidden="true" /> | ||
</Menu.Button> | ||
</div> | ||
|
||
<Transition | ||
as={Fragment} | ||
enter="transition ease-out duration-100" | ||
enterFrom="transform opacity-0 scale-95" | ||
enterTo="transform opacity-100 scale-100" | ||
leave="transition ease-in duration-75" | ||
leaveFrom="transform opacity-100 scale-100" | ||
leaveTo="transform opacity-0 scale-95" | ||
> | ||
<Menu.Items className="absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-md bg-bolt-elements-background-depth-2 shadow-lg ring-1 ring-bolt-elements-borderColor focus:outline-none"> | ||
<div className="py-1"> | ||
<Menu.Item> | ||
{({ active }) => ( | ||
<Link | ||
to="/profile" | ||
className={`${ | ||
active ? 'bg-bolt-elements-button-primary-background text-bolt-elements-button-primary-text' : 'text-bolt-elements-textSecondary' | ||
} block px-4 py-2 text-sm transition-colors duration-150 ease-in-out`} | ||
> | ||
个人信息 | ||
</Link> | ||
)} | ||
</Menu.Item> | ||
<Menu.Item> | ||
{({ active }) => ( | ||
<Link | ||
to="/subscription" | ||
className={`${ | ||
active ? 'bg-bolt-elements-button-primary-background text-bolt-elements-button-primary-text' : 'text-bolt-elements-textSecondary' | ||
} block px-4 py-2 text-sm transition-colors duration-150 ease-in-out`} | ||
> | ||
订阅信息 | ||
</Link> | ||
)} | ||
</Menu.Item> | ||
<Menu.Item> | ||
{({ active }) => ( | ||
<button | ||
onClick={logout} | ||
className={`${ | ||
active ? 'bg-bolt-elements-button-primary-background text-bolt-elements-button-primary-text' : 'text-bolt-elements-textSecondary' | ||
} block w-full text-left px-4 py-2 text-sm transition-colors duration-150 ease-in-out`} | ||
> | ||
退出登录 | ||
</button> | ||
)} | ||
</Menu.Item> | ||
</div> | ||
</Menu.Items> | ||
</Transition> | ||
</Menu> | ||
<Transition | ||
as={Fragment} | ||
enter="transition ease-out duration-100" | ||
enterFrom="transform opacity-0 scale-95" | ||
enterTo="transform opacity-100 scale-100" | ||
leave="transition ease-in duration-75" | ||
leaveFrom="transform opacity-100 scale-100" | ||
leaveTo="transform opacity-0 scale-95" | ||
> | ||
<Menu.Items className="absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-md bg-bolt-elements-background-depth-1 shadow-lg ring-1 ring-bolt-elements-borderColor focus:outline-none"> | ||
<div className="py-1"> | ||
<Menu.Item> | ||
{({ active }) => ( | ||
<button | ||
onClick={() => setIsProfileOpen(true)} | ||
className={`${ | ||
active ? 'bg-bolt-elements-background-depth-2 text-bolt-elements-textPrimary' : 'text-bolt-elements-textSecondary' | ||
} block w-full text-left px-4 py-2 text-sm transition-colors duration-150 ease-in-out`} | ||
> | ||
个人信息 | ||
</button> | ||
)} | ||
</Menu.Item> | ||
<Menu.Item> | ||
{({ active }) => ( | ||
<button | ||
onClick={() => setIsSubscriptionOpen(true)} | ||
className={`${ | ||
active ? 'bg-bolt-elements-background-depth-2 text-bolt-elements-textPrimary' : 'text-bolt-elements-textSecondary' | ||
} block w-full text-left px-4 py-2 text-sm transition-colors duration-150 ease-in-out`} | ||
> | ||
订阅信息 | ||
</button> | ||
)} | ||
</Menu.Item> | ||
<Menu.Item> | ||
{({ active }) => ( | ||
<button | ||
onClick={logout} | ||
className={`${ | ||
active ? 'bg-bolt-elements-background-depth-2 text-bolt-elements-textPrimary' : 'text-bolt-elements-textSecondary' | ||
} block w-full text-left px-4 py-2 text-sm transition-colors duration-150 ease-in-out`} | ||
> | ||
退出登录 | ||
</button> | ||
)} | ||
</Menu.Item> | ||
</div> | ||
</Menu.Items> | ||
</Transition> | ||
</Menu> | ||
|
||
<ProfileDialog isOpen={isProfileOpen} onClose={() => setIsProfileOpen(false)} /> | ||
<SubscriptionDialog isOpen={isSubscriptionOpen} onClose={() => setIsSubscriptionOpen(false)} /> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters