完成修改密码删除用户
This commit is contained in:
@@ -26,38 +26,66 @@ import {
|
|||||||
AlertTitle,
|
AlertTitle,
|
||||||
} from "@/components/ui/alert"
|
} from "@/components/ui/alert"
|
||||||
import { AlertCircle } from "lucide-react";
|
import { AlertCircle } from "lucide-react";
|
||||||
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
|
||||||
|
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
|
||||||
|
|
||||||
export function UserInfoEditor({
|
export function UserInfoEditor({
|
||||||
onClose,
|
onClose,
|
||||||
onUserUpdate,
|
onUserUpdate,
|
||||||
|
onUserDelete,
|
||||||
userId,
|
userId,
|
||||||
}: {
|
}: {
|
||||||
onClose: () => void,
|
onClose: () => void,
|
||||||
onUserUpdate: (user: User) => void,
|
onUserUpdate: (user: User) => void,
|
||||||
|
onUserDelete: (userId: string) => void,
|
||||||
userId: string
|
userId: string
|
||||||
}) {
|
}) {
|
||||||
const { user, isLoading, error } = userId ? useUser(userId) : {};
|
const { user, isLoading, error } = useUser(userId);
|
||||||
|
|
||||||
|
const [saveLoading, setSaveLoading] = React.useState(false);
|
||||||
const handleSave = async (user: updateUser) => {
|
const handleSave = async (user: updateUser) => {
|
||||||
try {
|
try {
|
||||||
|
setSaveLoading(true);
|
||||||
const res = await AdminApi.user.update(userId, user);
|
const res = await AdminApi.user.update(userId, user);
|
||||||
if (res) {
|
if (res) {
|
||||||
toast.success("保存成功");
|
toast.success("保存成功");
|
||||||
onUserUpdate(res);
|
onUserUpdate(res);
|
||||||
onClose();
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error((error as Error).message || "保存失败");
|
toast.error((error as Error).message || "保存失败");
|
||||||
|
} finally {
|
||||||
|
setSaveLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRemove = async () => {
|
const [removeLoading, setRemoveLoading] = React.useState(false);
|
||||||
|
const handleRemove = async (userId: string) => {
|
||||||
|
try {
|
||||||
|
setRemoveLoading(true);
|
||||||
|
await AdminApi.user.remove(userId);
|
||||||
|
toast.success("删除成功");
|
||||||
|
onUserDelete(userId);
|
||||||
|
onClose();
|
||||||
|
} catch (error) {
|
||||||
|
toast.error((error as Error).message || "删除失败");
|
||||||
|
} finally {
|
||||||
|
setRemoveLoading(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSetPassword = async () => {
|
const [setPasswordLoading, setSetPasswordLoading] = React.useState(false);
|
||||||
|
const handleSetPassword = async (userId: string, password: string) => {
|
||||||
|
try {
|
||||||
|
setSetPasswordLoading(true);
|
||||||
|
await AdminApi.user.setPassword(userId, password);
|
||||||
|
toast.success("密码修改成功");
|
||||||
|
} catch (error) {
|
||||||
|
toast.error((error as Error).message || "密码修改失败");
|
||||||
|
} finally {
|
||||||
|
setSetPasswordLoading(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -112,9 +140,11 @@ export function UserInfoEditor({
|
|||||||
function ProfileForm({ className, user, onSetPassword, onRemove, ...props }:
|
function ProfileForm({ className, user, onSetPassword, onRemove, ...props }:
|
||||||
React.ComponentProps<"form"> & {
|
React.ComponentProps<"form"> & {
|
||||||
user: User,
|
user: User,
|
||||||
onSetPassword: () => Promise<void>,
|
onSetPassword: (userId: string, password: string) => Promise<void>,
|
||||||
onRemove: () => Promise<void>,
|
onRemove: (userId: string) => Promise<void>,
|
||||||
}) {
|
}) {
|
||||||
|
const [newPassword, setNewPassword] = React.useState<string>("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className={cn("grid items-start gap-4", className)} {...props}>
|
<form className={cn("grid items-start gap-4", className)} {...props}>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
@@ -138,8 +168,56 @@ function ProfileForm({ className, user, onSetPassword, onRemove, ...props }:
|
|||||||
<Input id="phone" name="phone" defaultValue={user.phone} />
|
<Input id="phone" name="phone" defaultValue={user.phone} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex gap-5">
|
<div className="w-full flex gap-5">
|
||||||
<Button type="button" variant="secondary" className="flex-1" onClick={onSetPassword}>修改密码</Button>
|
<Dialog>
|
||||||
<Button type="button" variant="destructive" className="flex-1" onClick={onRemove}>删除用户</Button>
|
<DialogTrigger asChild>
|
||||||
|
<Button type="button" variant="secondary" className="flex-1" onClick={() => setNewPassword('')}>修改密码</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="sm:max-w-[425px]" >
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>修改密码</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
新密码长度在6-32位之间,且至少包含一个字母和一个数字,可以包含特殊字符
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<div className="grid gap-4 py-4">
|
||||||
|
<div className="grid grid-cols-4 items-center gap-4">
|
||||||
|
<Label htmlFor="password" className="text-right">
|
||||||
|
新密码
|
||||||
|
</Label>
|
||||||
|
<Input
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
value={newPassword}
|
||||||
|
onChange={(e) => setNewPassword(e.target.value)}
|
||||||
|
className="col-span-3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DialogFooter>
|
||||||
|
<DialogClose asChild>
|
||||||
|
<Button type="button" onClick={() => onSetPassword(user.userId, newPassword)}>保存密码</Button>
|
||||||
|
</DialogClose>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
<AlertDialog>
|
||||||
|
<AlertDialogTrigger asChild>
|
||||||
|
<Button type="button" variant="destructive" className="flex-1">删除用户</Button>
|
||||||
|
</AlertDialogTrigger>
|
||||||
|
<AlertDialogContent>
|
||||||
|
<AlertDialogHeader>
|
||||||
|
<AlertDialogTitle>是否要删除该用户?</AlertDialogTitle>
|
||||||
|
<AlertDialogDescription>
|
||||||
|
该操作无法撤销,这会永久删除该用户的所有数据
|
||||||
|
</AlertDialogDescription>
|
||||||
|
</AlertDialogHeader>
|
||||||
|
<AlertDialogFooter>
|
||||||
|
<AlertDialogCancel>取消</AlertDialogCancel>
|
||||||
|
<AlertDialogAction onClick={() => onRemove(user.userId)}>删除</AlertDialogAction>
|
||||||
|
</AlertDialogFooter>
|
||||||
|
</AlertDialogContent>
|
||||||
|
</AlertDialog>
|
||||||
</div>
|
</div>
|
||||||
<Button type="submit">保存</Button>
|
<Button type="submit">保存</Button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -30,6 +30,21 @@ export default function Page() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleUserDelete = async (userId: string) => {
|
||||||
|
await mutate(
|
||||||
|
(data) => {
|
||||||
|
if (!data) return data;
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
items: data.items.filter((user) => user.userId !== userId),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
revalidate: false,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Table>
|
<Table>
|
||||||
@@ -89,6 +104,7 @@ export default function Page() {
|
|||||||
onClose={() => setEditorUserId('')}
|
onClose={() => setEditorUserId('')}
|
||||||
userId={editorUserId}
|
userId={editorUserId}
|
||||||
onUserUpdate={handleUserUpdate}
|
onUserUpdate={handleUserUpdate}
|
||||||
|
onUserDelete={handleUserDelete}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
157
tone-page-web/components/ui/alert-dialog.tsx
Normal file
157
tone-page-web/components/ui/alert-dialog.tsx
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { buttonVariants } from "@/components/ui/button"
|
||||||
|
|
||||||
|
function AlertDialog({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
|
||||||
|
return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />
|
||||||
|
}
|
||||||
|
|
||||||
|
function AlertDialogTrigger({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
|
||||||
|
return (
|
||||||
|
<AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function AlertDialogPortal({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
|
||||||
|
return (
|
||||||
|
<AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function AlertDialogOverlay({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
|
||||||
|
return (
|
||||||
|
<AlertDialogPrimitive.Overlay
|
||||||
|
data-slot="alert-dialog-overlay"
|
||||||
|
className={cn(
|
||||||
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function AlertDialogContent({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {
|
||||||
|
return (
|
||||||
|
<AlertDialogPortal>
|
||||||
|
<AlertDialogOverlay />
|
||||||
|
<AlertDialogPrimitive.Content
|
||||||
|
data-slot="alert-dialog-content"
|
||||||
|
className={cn(
|
||||||
|
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</AlertDialogPortal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function AlertDialogHeader({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="alert-dialog-header"
|
||||||
|
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function AlertDialogFooter({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="alert-dialog-footer"
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function AlertDialogTitle({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
|
||||||
|
return (
|
||||||
|
<AlertDialogPrimitive.Title
|
||||||
|
data-slot="alert-dialog-title"
|
||||||
|
className={cn("text-lg font-semibold", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function AlertDialogDescription({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
|
||||||
|
return (
|
||||||
|
<AlertDialogPrimitive.Description
|
||||||
|
data-slot="alert-dialog-description"
|
||||||
|
className={cn("text-muted-foreground text-sm", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function AlertDialogAction({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {
|
||||||
|
return (
|
||||||
|
<AlertDialogPrimitive.Action
|
||||||
|
className={cn(buttonVariants(), className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function AlertDialogCancel({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {
|
||||||
|
return (
|
||||||
|
<AlertDialogPrimitive.Cancel
|
||||||
|
className={cn(buttonVariants({ variant: "outline" }), className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
AlertDialog,
|
||||||
|
AlertDialogPortal,
|
||||||
|
AlertDialogOverlay,
|
||||||
|
AlertDialogTrigger,
|
||||||
|
AlertDialogContent,
|
||||||
|
AlertDialogHeader,
|
||||||
|
AlertDialogFooter,
|
||||||
|
AlertDialogTitle,
|
||||||
|
AlertDialogDescription,
|
||||||
|
AlertDialogAction,
|
||||||
|
AlertDialogCancel,
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ export function useUser(userId: string) {
|
|||||||
['/api/admin/user', userId],
|
['/api/admin/user', userId],
|
||||||
() => AdminApi.user.get(userId),
|
() => AdminApi.user.get(userId),
|
||||||
{
|
{
|
||||||
revalidateOnFocus: false,
|
|
||||||
revalidateOnReconnect: false,
|
revalidateOnReconnect: false,
|
||||||
revalidateIfStale: false,
|
revalidateIfStale: false,
|
||||||
dedupingInterval: 0,
|
dedupingInterval: 0,
|
||||||
|
|||||||
@@ -2,4 +2,5 @@ export * from './list';
|
|||||||
export * from './get';
|
export * from './get';
|
||||||
export * from './create';
|
export * from './create';
|
||||||
export * from './update';
|
export * from './update';
|
||||||
export * from './set-password';
|
export * from './set-password';
|
||||||
|
export * from './remove';
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import fetcher from "../../fetcher";
|
import fetcher from "../../fetcher";
|
||||||
|
|
||||||
export async function remove(userId: string) {
|
export async function remove(userId: string) {
|
||||||
return fetcher(`/admin/user/${userId}`, {
|
return fetcher(`/api/admin/user/${userId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import fetcher from "../../fetcher";
|
import fetcher from "../../fetcher";
|
||||||
|
|
||||||
export async function setPassword(userId: string, password: string) {
|
export async function setPassword(userId: string, password: string) {
|
||||||
return fetcher(`/admin/user/${userId}/password`, {
|
return fetcher(`/api/admin/user/${userId}/password`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
password,
|
password,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@radix-ui/react-alert-dialog": "^1.1.13",
|
||||||
"@radix-ui/react-avatar": "^1.1.7",
|
"@radix-ui/react-avatar": "^1.1.7",
|
||||||
"@radix-ui/react-collapsible": "^1.1.10",
|
"@radix-ui/react-collapsible": "^1.1.10",
|
||||||
"@radix-ui/react-dialog": "^1.1.11",
|
"@radix-ui/react-dialog": "^1.1.11",
|
||||||
|
|||||||
65
tone-page-web/pnpm-lock.yaml
generated
65
tone-page-web/pnpm-lock.yaml
generated
@@ -8,6 +8,9 @@ importers:
|
|||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@radix-ui/react-alert-dialog':
|
||||||
|
specifier: ^1.1.13
|
||||||
|
version: 1.1.13(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
'@radix-ui/react-avatar':
|
'@radix-ui/react-avatar':
|
||||||
specifier: ^1.1.7
|
specifier: ^1.1.7
|
||||||
version: 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
version: 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
@@ -415,6 +418,19 @@ packages:
|
|||||||
'@radix-ui/primitive@1.1.2':
|
'@radix-ui/primitive@1.1.2':
|
||||||
resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==}
|
resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==}
|
||||||
|
|
||||||
|
'@radix-ui/react-alert-dialog@1.1.13':
|
||||||
|
resolution: {integrity: sha512-/uPs78OwxGxslYOG5TKeUsv9fZC0vo376cXSADdKirTmsLJU2au6L3n34c3p6W26rFDDDze/hwy4fYeNd0qdGA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@radix-ui/react-arrow@1.1.4':
|
'@radix-ui/react-arrow@1.1.4':
|
||||||
resolution: {integrity: sha512-qz+fxrqgNxG0dYew5l7qR3c7wdgRu1XVUHGnGYX7rg5HM4p9SWaRmJwfgR3J0SgyUKayLmzQIun+N6rWRgiRKw==}
|
resolution: {integrity: sha512-qz+fxrqgNxG0dYew5l7qR3c7wdgRu1XVUHGnGYX7rg5HM4p9SWaRmJwfgR3J0SgyUKayLmzQIun+N6rWRgiRKw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -524,6 +540,19 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-dialog@1.1.13':
|
||||||
|
resolution: {integrity: sha512-ARFmqUyhIVS3+riWzwGTe7JLjqwqgnODBUZdqpWar/z1WFs9z76fuOs/2BOWCR+YboRn4/WN9aoaGVwqNRr8VA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@radix-ui/react-direction@1.1.1':
|
'@radix-ui/react-direction@1.1.1':
|
||||||
resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==}
|
resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -2759,6 +2788,20 @@ snapshots:
|
|||||||
|
|
||||||
'@radix-ui/primitive@1.1.2': {}
|
'@radix-ui/primitive@1.1.2': {}
|
||||||
|
|
||||||
|
'@radix-ui/react-alert-dialog@1.1.13(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/primitive': 1.1.2
|
||||||
|
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
'@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
'@radix-ui/react-dialog': 1.1.13(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
'@radix-ui/react-primitive': 2.1.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
'@radix-ui/react-slot': 1.2.2(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
react: 19.1.0
|
||||||
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 19.1.2
|
||||||
|
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||||
|
|
||||||
'@radix-ui/react-arrow@1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
|
'@radix-ui/react-arrow@1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
'@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
@@ -2864,6 +2907,28 @@ snapshots:
|
|||||||
'@types/react': 19.1.2
|
'@types/react': 19.1.2
|
||||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||||
|
|
||||||
|
'@radix-ui/react-dialog@1.1.13(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/primitive': 1.1.2
|
||||||
|
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
'@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.1.9(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
'@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
'@radix-ui/react-focus-scope': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
'@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
'@radix-ui/react-portal': 1.1.8(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
'@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
'@radix-ui/react-primitive': 2.1.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
'@radix-ui/react-slot': 1.2.2(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
aria-hidden: 1.2.4
|
||||||
|
react: 19.1.0
|
||||||
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
|
react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 19.1.2
|
||||||
|
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||||
|
|
||||||
'@radix-ui/react-direction@1.1.1(@types/react@19.1.2)(react@19.1.0)':
|
'@radix-ui/react-direction@1.1.1(@types/react@19.1.2)(react@19.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
|
|||||||
Reference in New Issue
Block a user