mirror of
https://github.com/aykhans/slash-e.git
synced 2026-09-23 14:26:49 +00:00
chore: refactor dialog components to simplify header structure
- Removed unnecessary button and icon from dialog headers in AboutDialog, ChangePasswordDialog, CreateAccessTokenDialog, CreateUserDialog, EditUserinfoDialog, and GenerateQRCodeDialog. - Updated dialog titles to be more straightforward by directly displaying the title text. - Simplified close button handling in ChangePasswordDialog, EditUserinfoDialog, and GenerateQRCodeDialog by directly using the onClose prop. - Enhanced Dropdown component to manage its open state internally.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,5 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||||
import Icon from "./Icon";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@@ -15,12 +13,7 @@ const AboutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
<Dialog open={true} onOpenChange={onClose}>
|
<Dialog open={true} onOpenChange={onClose}>
|
||||||
<DialogContent className="max-w-full w-80 sm:w-96">
|
<DialogContent className="max-w-full w-80 sm:w-96">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex flex-row justify-between items-center">
|
<DialogTitle>{t("common.about")}</DialogTitle>
|
||||||
<span>{t("common.about")}</span>
|
|
||||||
<Button variant="ghost" size="icon" onClick={onClose}>
|
|
||||||
<Icon.X className="w-5 h-auto" />
|
|
||||||
</Button>
|
|
||||||
</DialogTitle>
|
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { Input } from "@/components/ui/input";
|
|||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import useLoading from "@/hooks/useLoading";
|
import useLoading from "@/hooks/useLoading";
|
||||||
import { useUserStore } from "@/stores";
|
import { useUserStore } from "@/stores";
|
||||||
import Icon from "./Icon";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@@ -21,10 +20,6 @@ const ChangePasswordDialog: React.FC<Props> = (props: Props) => {
|
|||||||
const [newPasswordAgain, setNewPasswordAgain] = useState("");
|
const [newPasswordAgain, setNewPasswordAgain] = useState("");
|
||||||
const requestState = useLoading(false);
|
const requestState = useLoading(false);
|
||||||
|
|
||||||
const handleCloseBtnClick = () => {
|
|
||||||
onClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleNewPasswordChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleNewPasswordChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const text = e.target.value as string;
|
const text = e.target.value as string;
|
||||||
setNewPassword(text);
|
setNewPassword(text);
|
||||||
@@ -69,12 +64,7 @@ const ChangePasswordDialog: React.FC<Props> = (props: Props) => {
|
|||||||
<Dialog open={true} onOpenChange={onClose}>
|
<Dialog open={true} onOpenChange={onClose}>
|
||||||
<DialogContent className="w-80 sm:max-w-md">
|
<DialogContent className="w-80 sm:max-w-md">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex flex-row justify-between items-center">
|
<DialogTitle>Change Password</DialogTitle>
|
||||||
<span>Change Password</span>
|
|
||||||
<Button variant="ghost" size="icon" onClick={handleCloseBtnClick}>
|
|
||||||
<Icon.X className="w-5 h-auto" />
|
|
||||||
</Button>
|
|
||||||
</DialogTitle>
|
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
@@ -87,7 +77,7 @@ const ChangePasswordDialog: React.FC<Props> = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button variant="outline" disabled={requestState.isLoading} onClick={handleCloseBtnClick}>
|
<Button variant="outline" disabled={requestState.isLoading} onClick={onClose}>
|
||||||
{t("common.cancel")}
|
{t("common.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button disabled={requestState.isLoading} onClick={handleSaveBtnClick}>
|
<Button disabled={requestState.isLoading} onClick={handleSaveBtnClick}>
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
|||||||
import { userServiceClient } from "@/grpcweb";
|
import { userServiceClient } from "@/grpcweb";
|
||||||
import useLoading from "@/hooks/useLoading";
|
import useLoading from "@/hooks/useLoading";
|
||||||
import { useUserStore } from "@/stores";
|
import { useUserStore } from "@/stores";
|
||||||
import Icon from "./Icon";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@@ -92,12 +91,7 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
|
|||||||
<Dialog open={true} onOpenChange={onClose}>
|
<Dialog open={true} onOpenChange={onClose}>
|
||||||
<DialogContent className="w-80 sm:max-w-md">
|
<DialogContent className="w-80 sm:max-w-md">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex flex-row justify-between items-center">
|
<DialogTitle>Create Access Token</DialogTitle>
|
||||||
<span>Create Access Token</span>
|
|
||||||
<Button variant="ghost" size="icon" onClick={onClose}>
|
|
||||||
<Icon.X className="w-5 h-auto" />
|
|
||||||
</Button>
|
|
||||||
</DialogTitle>
|
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ import { Label } from "@/components/ui/label";
|
|||||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||||
import useLoading from "@/hooks/useLoading";
|
import useLoading from "@/hooks/useLoading";
|
||||||
import { useUserStore } from "@/stores";
|
import { useUserStore } from "@/stores";
|
||||||
import { Role, User } from "@/types/proto/api/v1/user_service";
|
import { Role, type User } from "@/types/proto/api/v1/user_service";
|
||||||
import Icon from "./Icon";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
user?: User;
|
user?: User;
|
||||||
@@ -134,12 +133,7 @@ const CreateUserDialog: React.FC<Props> = (props: Props) => {
|
|||||||
<Dialog open={true} onOpenChange={onClose}>
|
<Dialog open={true} onOpenChange={onClose}>
|
||||||
<DialogContent className="w-80 sm:w-96">
|
<DialogContent className="w-80 sm:w-96">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex flex-row justify-between items-center">
|
<DialogTitle>{isCreating ? "Create User" : "Edit User"}</DialogTitle>
|
||||||
<span>{isCreating ? "Create User" : "Edit User"}</span>
|
|
||||||
<Button variant="ghost" size="icon" onClick={onClose}>
|
|
||||||
<Icon.X className="w-5 h-auto" />
|
|
||||||
</Button>
|
|
||||||
</DialogTitle>
|
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { Input } from "@/components/ui/input";
|
|||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import useLoading from "@/hooks/useLoading";
|
import useLoading from "@/hooks/useLoading";
|
||||||
import { useUserStore } from "@/stores";
|
import { useUserStore } from "@/stores";
|
||||||
import Icon from "./Icon";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@@ -22,10 +21,6 @@ const EditUserinfoDialog: React.FC<Props> = (props: Props) => {
|
|||||||
const [nickname, setNickname] = useState(currentUser.nickname);
|
const [nickname, setNickname] = useState(currentUser.nickname);
|
||||||
const requestState = useLoading(false);
|
const requestState = useLoading(false);
|
||||||
|
|
||||||
const handleCloseBtnClick = () => {
|
|
||||||
onClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleEmailChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleEmailChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const text = e.target.value as string;
|
const text = e.target.value as string;
|
||||||
setEmail(text);
|
setEmail(text);
|
||||||
@@ -65,12 +60,7 @@ const EditUserinfoDialog: React.FC<Props> = (props: Props) => {
|
|||||||
<Dialog open={true} onOpenChange={onClose}>
|
<Dialog open={true} onOpenChange={onClose}>
|
||||||
<DialogContent className="w-80 sm:max-w-md">
|
<DialogContent className="w-80 sm:max-w-md">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex flex-row justify-between items-center">
|
<DialogTitle>Edit Userinfo</DialogTitle>
|
||||||
<span>Edit Userinfo</span>
|
|
||||||
<Button variant="ghost" size="icon" onClick={handleCloseBtnClick}>
|
|
||||||
<Icon.X className="w-5 h-auto" />
|
|
||||||
</Button>
|
|
||||||
</DialogTitle>
|
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
@@ -83,7 +73,7 @@ const EditUserinfoDialog: React.FC<Props> = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button variant="outline" disabled={requestState.isLoading} onClick={handleCloseBtnClick}>
|
<Button variant="outline" disabled={requestState.isLoading} onClick={onClose}>
|
||||||
{t("common.cancel")}
|
{t("common.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button disabled={requestState.isLoading} onClick={handleSaveBtnClick}>
|
<Button disabled={requestState.isLoading} onClick={handleSaveBtnClick}>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { toast } from "sonner";
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||||
import { absolutifyLink } from "@/helpers/utils";
|
import { absolutifyLink } from "@/helpers/utils";
|
||||||
import { Shortcut } from "@/types/proto/api/v1/shortcut_service";
|
import type { Shortcut } from "@/types/proto/api/v1/shortcut_service";
|
||||||
import Icon from "./Icon";
|
import Icon from "./Icon";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -19,10 +19,6 @@ const GenerateQRCodeDialog: React.FC<Props> = (props: Props) => {
|
|||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
const shortcutLink = absolutifyLink(`/s/${shortcut.name}`);
|
const shortcutLink = absolutifyLink(`/s/${shortcut.name}`);
|
||||||
|
|
||||||
const handleCloseBtnClick = () => {
|
|
||||||
onClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDownloadQRCodeClick = () => {
|
const handleDownloadQRCodeClick = () => {
|
||||||
const canvas = containerRef.current?.querySelector("canvas");
|
const canvas = containerRef.current?.querySelector("canvas");
|
||||||
if (!canvas) {
|
if (!canvas) {
|
||||||
@@ -34,19 +30,14 @@ const GenerateQRCodeDialog: React.FC<Props> = (props: Props) => {
|
|||||||
link.download = `${shortcut.title || shortcut.name}-qrcode.png`;
|
link.download = `${shortcut.title || shortcut.name}-qrcode.png`;
|
||||||
link.href = canvas.toDataURL();
|
link.href = canvas.toDataURL();
|
||||||
link.click();
|
link.click();
|
||||||
handleCloseBtnClick();
|
onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={true} onOpenChange={onClose}>
|
<Dialog open={true} onOpenChange={onClose}>
|
||||||
<DialogContent className="w-64 sm:max-w-xs">
|
<DialogContent className="w-64 sm:max-w-xs">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex flex-row justify-between items-center">
|
<DialogTitle>QR Code</DialogTitle>
|
||||||
<span>QR Code</span>
|
|
||||||
<Button variant="ghost" size="icon" onClick={handleCloseBtnClick}>
|
|
||||||
<Icon.X className="w-5 h-auto" />
|
|
||||||
</Button>
|
|
||||||
</DialogTitle>
|
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div ref={containerRef} className="w-full flex flex-row justify-center items-center">
|
<div ref={containerRef} className="w-full flex flex-row justify-center items-center">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ReactNode } from "react";
|
import { ReactNode, useState } from "react";
|
||||||
import Icon from "@/components/Icon";
|
import Icon from "@/components/Icon";
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||||
|
|
||||||
@@ -12,8 +12,10 @@ interface Props {
|
|||||||
const Dropdown: React.FC<Props> = (props: Props) => {
|
const Dropdown: React.FC<Props> = (props: Props) => {
|
||||||
const { trigger, actions, className, actionsClassName } = props;
|
const { trigger, actions, className, actionsClassName } = props;
|
||||||
|
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu open={open} onOpenChange={setOpen}>
|
||||||
<DropdownMenuTrigger className={className} asChild>
|
<DropdownMenuTrigger className={className} asChild>
|
||||||
{trigger ? (
|
{trigger ? (
|
||||||
<div>{trigger}</div>
|
<div>{trigger}</div>
|
||||||
@@ -23,7 +25,7 @@ const Dropdown: React.FC<Props> = (props: Props) => {
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className={actionsClassName} align="end">
|
<DropdownMenuContent className={actionsClassName} align="end" onClick={() => setOpen(false)}>
|
||||||
{actions}
|
{actions}
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
|||||||
Reference in New Issue
Block a user